4 changed files with 948 additions and 12 deletions
-
8src/api/yieldReport/produce_report_normal.js
-
84src/views/modules/warehouse/labelTransactionLog.vue
-
38src/views/modules/yieldReport/com_produce_report_normal.vue
-
830src/views/modules/yieldReport/com_tid_upload_order.vue
@ -0,0 +1,830 @@ |
|||||
|
<template> |
||||
|
<div class="customer-css"> |
||||
|
<el-dialog |
||||
|
:title="titleCon" |
||||
|
v-drag |
||||
|
width="1280px" |
||||
|
top="4vh" |
||||
|
custom-class="machine-workbench-dialog" |
||||
|
:close-on-click-modal="false" |
||||
|
v-bind="$attrs" |
||||
|
v-on="$listeners" |
||||
|
@closed="handleDialogClosed"> |
||||
|
<div class="upload-order-layout" :style="{ height: layoutHeight + 'px' }"> |
||||
|
<div class="shift-panel"> |
||||
|
<div class="panel-header"> |
||||
|
<span>班次数据</span> |
||||
|
<el-button type="text" size="mini" @click="loadMesShiftData()" :loading="shiftLoading">刷新班次</el-button> |
||||
|
</div> |
||||
|
<div class="summary-grid"> |
||||
|
<div class="summary-item"> |
||||
|
<div class="summary-label">成功卷数</div> |
||||
|
<div class="summary-value">{{ getMesFieldValue('rollCountSuccess') }}</div> |
||||
|
</div> |
||||
|
<div class="summary-item"> |
||||
|
<div class="summary-label">失败卷数</div> |
||||
|
<div class="summary-value">{{ getMesFieldValue('rollCountFail') }}</div> |
||||
|
</div> |
||||
|
<div class="summary-item"> |
||||
|
<div class="summary-label">上传总数</div> |
||||
|
<div class="summary-value">{{ getMesFieldValue('quantityTotal') }}</div> |
||||
|
</div> |
||||
|
<div class="summary-item"> |
||||
|
<div class="summary-label">良品数</div> |
||||
|
<div class="summary-value">{{ getMesFieldValue('quantityGood') }}</div> |
||||
|
</div> |
||||
|
<div class="summary-item"> |
||||
|
<div class="summary-label">不良数</div> |
||||
|
<div class="summary-value">{{ getMesFieldValue('quantityBad') }}</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<el-table |
||||
|
:data="mesShiftLogs" |
||||
|
border |
||||
|
:height="leftTableHeight" |
||||
|
v-loading="shiftLoading" |
||||
|
style="width: 100%; margin-top: 10px;"> |
||||
|
<el-table-column prop="filename" label="文件名" min-width="180" show-overflow-tooltip></el-table-column> |
||||
|
<el-table-column label="状态" width="90" align="center"> |
||||
|
<template slot-scope="scope"> |
||||
|
<el-tag :type="getLogStatusType(scope.row.status)" size="mini"> |
||||
|
{{ Number(scope.row.status) === 1 ? '成功' : '失败' }} |
||||
|
</el-tag> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column prop="message" label="结果" min-width="140" show-overflow-tooltip></el-table-column> |
||||
|
</el-table> |
||||
|
</div> |
||||
|
|
||||
|
<div class="upload-panel"> |
||||
|
<div class="panel-card config-card"> |
||||
|
<div class="panel-header panel-header-card"> |
||||
|
<span class="panel-title"><i class="el-icon-setting"></i>上传配置</span> |
||||
|
</div> |
||||
|
<el-form label-position="top" label-width="90px" class="upload-form"> |
||||
|
<el-row :gutter="10"> |
||||
|
<el-col :span="8"> |
||||
|
<el-form-item label="机器账号"> |
||||
|
<el-input v-model="uploadForm.machineNo" readonly></el-input> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
<el-col :span="8"> |
||||
|
<el-form-item label="班次"> |
||||
|
<el-input v-model="uploadForm.shift" readonly></el-input> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
<el-col :span="8"> |
||||
|
<el-form-item label="日期"> |
||||
|
<el-input v-model="uploadForm.date" readonly></el-input> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
</el-row> |
||||
|
|
||||
|
<el-row :gutter="10"> |
||||
|
<el-col :span="12"> |
||||
|
<el-form-item label="工序"> |
||||
|
<el-select v-model="uploadForm.process" placeholder="请选择工序" style="width: 100%;"> |
||||
|
<el-option |
||||
|
v-for="item in processOptions" |
||||
|
:key="item.value" |
||||
|
:label="item.label" |
||||
|
:value="item.value"> |
||||
|
</el-option> |
||||
|
</el-select> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
<el-col :span="12"> |
||||
|
<el-form-item label="员工号"> |
||||
|
<el-select |
||||
|
v-model="uploadForm.operatorNo" |
||||
|
filterable |
||||
|
placeholder="请选择员工号" |
||||
|
style="width: 100%;"> |
||||
|
<el-option |
||||
|
v-for="item in operatorOptions" |
||||
|
:key="item.operatorNo" |
||||
|
:label="item.operatorLabel" |
||||
|
:value="item.operatorNo"> |
||||
|
</el-option> |
||||
|
</el-select> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
</el-row> |
||||
|
</el-form> |
||||
|
</div> |
||||
|
|
||||
|
<div class="panel-card upload-drop-card"> |
||||
|
<div class="upload-field-label">订单日志文件(支持多选)</div> |
||||
|
<div class="upload-zone-wrap"> |
||||
|
<input |
||||
|
ref="orderFileInput" |
||||
|
class="upload-file-input" |
||||
|
type="file" |
||||
|
multiple |
||||
|
accept=".txt,.log" |
||||
|
@change="handleOrderFileInputChange"> |
||||
|
<div |
||||
|
class="upload-drop-zone" |
||||
|
@click="triggerOrderFileSelect" |
||||
|
@dragover.prevent |
||||
|
@dragenter.prevent |
||||
|
@drop.prevent="handleOrderFileDrop"> |
||||
|
<i class="el-icon-upload"></i> |
||||
|
<div class="upload-main-text">将文件拖到此处,或<em>点击上传</em></div> |
||||
|
</div> |
||||
|
<div class="upload-tip-text">可一次选择多个日志文件,保存时会逐个上传</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="upload-list-row"> |
||||
|
<div class="panel-card selected-file-wrap"> |
||||
|
<div class="panel-header list-header"> |
||||
|
<span>待上传文件</span> |
||||
|
<span>共 {{ uploadOrderFileList.length }} 个</span> |
||||
|
</div> |
||||
|
<el-table :data="uploadOrderFileList" border :height="rightTableHeight" style="width: 100%;"> |
||||
|
<el-table-column label="文件名" header-align="center" min-width="180" show-overflow-tooltip> |
||||
|
<template slot-scope="scope"> |
||||
|
{{ scope.row.name }} |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column label="大小(KB)" header-align="center" width="70" align="right"> |
||||
|
<template slot-scope="scope"> |
||||
|
{{ formatFileSize(scope.row.size) }} |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column fixed="right" label="操作" width="70" header-align="center" align="center"> |
||||
|
<template slot-scope="scope"> |
||||
|
<el-link style="cursor: pointer" @click="removePendingUploadFile(scope.$index)">移除</el-link> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
</el-table> |
||||
|
</div> |
||||
|
|
||||
|
<div class="panel-card upload-result-wrap"> |
||||
|
<div class="panel-header list-header"> |
||||
|
<span>上传结果</span> |
||||
|
</div> |
||||
|
<el-table :data="uploadResults" border :height="rightTableHeight" style="width: 100%;"> |
||||
|
<el-table-column prop="fileName" header-align="center" label="文件名" min-width="150" show-overflow-tooltip></el-table-column> |
||||
|
<el-table-column prop="statusText" header-align="center" label="状态" width="70" align="center"> |
||||
|
<template slot-scope="scope"> |
||||
|
<el-tag :type="scope.row.success ? 'success' : 'danger'" size="mini"> |
||||
|
{{ scope.row.statusText }} |
||||
|
</el-tag> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column prop="message" label="信息" header-align="center" min-width="100" show-overflow-tooltip></el-table-column> |
||||
|
</el-table> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<span slot="footer" class="dialog-footer"> |
||||
|
<el-button @click="closeDialog" size="small">关闭</el-button> |
||||
|
<el-button type="primary" :loading="saveLoading" @click="saveUploadOrder" size="small">保存上传</el-button> |
||||
|
</span> |
||||
|
</el-dialog> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import { getMesShiftData, uploadMesOrderLog } from '@/api/yieldReport/produce_report_normal.js' |
||||
|
import { getOperatorList2 } from '@/api/yieldReport/produce_order.js' |
||||
|
|
||||
|
export default { |
||||
|
data () { |
||||
|
return { |
||||
|
titleCon: '上传订单', |
||||
|
saveLoading: false, |
||||
|
shiftLoading: false, |
||||
|
processOptions: [ |
||||
|
{ label: 'bonging', value: 'bonging' }, |
||||
|
{ label: 'testing', value: 'testing' } |
||||
|
], |
||||
|
pageData: { |
||||
|
site: '', |
||||
|
orderNo: '', |
||||
|
itemNo: '', |
||||
|
seqNo: '', |
||||
|
resourceId: '', |
||||
|
resourceDesc: '', |
||||
|
shiftNo: '', |
||||
|
scheduledDate: '' |
||||
|
}, |
||||
|
uploadForm: { |
||||
|
process: 'bonging', |
||||
|
machineNo: '', |
||||
|
shift: '', |
||||
|
operatorNo: '', |
||||
|
date: '' |
||||
|
}, |
||||
|
operatorOptions: [], |
||||
|
mesShiftData: {}, |
||||
|
mesShiftLogs: [], |
||||
|
uploadOrderFileList: [], |
||||
|
uploadResults: [], |
||||
|
uploadFileUid: 1, |
||||
|
layoutHeight: 560, |
||||
|
leftTableHeight: 340, |
||||
|
rightTableHeight: 150 |
||||
|
} |
||||
|
}, |
||||
|
mounted () { |
||||
|
this.updateDialogLayout() |
||||
|
window.addEventListener('resize', this.updateDialogLayout) |
||||
|
}, |
||||
|
beforeDestroy () { |
||||
|
window.removeEventListener('resize', this.updateDialogLayout) |
||||
|
}, |
||||
|
methods: { |
||||
|
async init (scheduleData) { |
||||
|
this.pageData = { |
||||
|
site: scheduleData.site || '', |
||||
|
orderNo: scheduleData.orderNo || '', |
||||
|
itemNo: scheduleData.itemNo || '', |
||||
|
seqNo: scheduleData.seqNo || '', |
||||
|
resourceId: scheduleData.resourceId || '', |
||||
|
resourceDesc: scheduleData.resourceDesc || '', |
||||
|
shiftNo: scheduleData.shiftNo || '', |
||||
|
scheduledDate: scheduleData.scheduledDate || '' |
||||
|
} |
||||
|
|
||||
|
this.uploadForm.process = 'bonging' |
||||
|
this.uploadForm.machineNo = scheduleData.resourceId || scheduleData.resourceDesc || '' |
||||
|
this.uploadForm.shift = scheduleData.shiftNo || '' |
||||
|
this.uploadForm.operatorNo = '' |
||||
|
this.uploadForm.date = this.extractDatePart(scheduleData.scheduledDate) |
||||
|
this.uploadResults = [] |
||||
|
this.uploadOrderFileList = [] |
||||
|
this.mesShiftData = {} |
||||
|
this.mesShiftLogs = [] |
||||
|
this.operatorOptions = [] |
||||
|
|
||||
|
this.updateDialogLayout() |
||||
|
await this.loadOperatorOptions() |
||||
|
await this.loadMesShiftData(false) |
||||
|
}, |
||||
|
|
||||
|
updateDialogLayout () { |
||||
|
const viewportHeight = window.innerHeight || 900 |
||||
|
let nextLayoutHeight = viewportHeight - 230 |
||||
|
if (nextLayoutHeight > 620) { |
||||
|
nextLayoutHeight = 620 |
||||
|
} |
||||
|
if (nextLayoutHeight < 500) { |
||||
|
nextLayoutHeight = 500 |
||||
|
} |
||||
|
this.layoutHeight = nextLayoutHeight |
||||
|
|
||||
|
let nextLeftTableHeight = nextLayoutHeight - 230 |
||||
|
if (nextLeftTableHeight < 220) { |
||||
|
nextLeftTableHeight = 220 |
||||
|
} |
||||
|
this.leftTableHeight = nextLeftTableHeight |
||||
|
|
||||
|
let nextRightTableHeight = nextLayoutHeight - 370 |
||||
|
if (nextRightTableHeight < 120) { |
||||
|
nextRightTableHeight = 120 |
||||
|
} |
||||
|
this.rightTableHeight = nextRightTableHeight |
||||
|
}, |
||||
|
|
||||
|
extractDatePart (dateValue) { |
||||
|
if (!dateValue) { |
||||
|
return this.getTodayDateString() |
||||
|
} |
||||
|
if (Object.prototype.toString.call(dateValue) === '[object Date]') { |
||||
|
return this.formatDateValue(dateValue) |
||||
|
} |
||||
|
var value = String(dateValue) |
||||
|
if (value.indexOf(' ') > -1) { |
||||
|
return value.split(' ')[0] |
||||
|
} |
||||
|
if (value.indexOf('T') > -1) { |
||||
|
return value.split('T')[0] |
||||
|
} |
||||
|
return value |
||||
|
}, |
||||
|
|
||||
|
getTodayDateString () { |
||||
|
return this.formatDateValue(new Date()) |
||||
|
}, |
||||
|
|
||||
|
formatDateValue (dateObj) { |
||||
|
var year = dateObj.getFullYear() |
||||
|
var month = dateObj.getMonth() + 1 |
||||
|
var day = dateObj.getDate() |
||||
|
return year + '-' + this.padZero(month) + '-' + this.padZero(day) |
||||
|
}, |
||||
|
|
||||
|
padZero (value) { |
||||
|
return value < 10 ? '0' + value : '' + value |
||||
|
}, |
||||
|
|
||||
|
async loadOperatorOptions () { |
||||
|
if (!this.pageData.seqNo) { |
||||
|
return |
||||
|
} |
||||
|
const params = { |
||||
|
site: this.pageData.site, |
||||
|
orderNo: this.pageData.orderNo, |
||||
|
itemNo: this.pageData.itemNo, |
||||
|
seqNo: this.pageData.seqNo, |
||||
|
isOnDuty: 'Y' |
||||
|
} |
||||
|
try { |
||||
|
const { data } = await getOperatorList2(params) |
||||
|
const rowList = (data && data.rows) || [] |
||||
|
const optionList = [] |
||||
|
const optionMap = {} |
||||
|
for (let i = 0; i < rowList.length; i++) { |
||||
|
const row = rowList[i] || {} |
||||
|
const operatorNo = row.operatorNo || row.userNo || row.operator || '' |
||||
|
if (!operatorNo || optionMap[operatorNo]) { |
||||
|
continue |
||||
|
} |
||||
|
optionMap[operatorNo] = true |
||||
|
optionList.push({ |
||||
|
operatorNo: operatorNo, |
||||
|
operatorLabel: (row.operatorName || row.operator || operatorNo) + '(' + operatorNo + ')' |
||||
|
}) |
||||
|
} |
||||
|
this.operatorOptions = optionList |
||||
|
this.uploadForm.operatorNo = optionList.length > 0 ? optionList[0].operatorNo : '' |
||||
|
} catch (e) { |
||||
|
this.operatorOptions = [] |
||||
|
this.uploadForm.operatorNo = '' |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
async loadMesShiftData (showWarning = true) { |
||||
|
if (!this.uploadForm.machineNo || !this.uploadForm.date) { |
||||
|
this.mesShiftData = {} |
||||
|
this.mesShiftLogs = [] |
||||
|
return |
||||
|
} |
||||
|
const params = { |
||||
|
machineNo: this.uploadForm.machineNo, |
||||
|
date: this.uploadForm.date, |
||||
|
shift: this.uploadForm.shift, |
||||
|
type: '' |
||||
|
} |
||||
|
this.shiftLoading = true |
||||
|
try { |
||||
|
const { data } = await getMesShiftData(params) |
||||
|
if (data && data.code === 0) { |
||||
|
this.mesShiftData = data.row || {} |
||||
|
this.mesShiftLogs = Array.isArray(this.mesShiftData.logs) ? this.mesShiftData.logs : [] |
||||
|
} else { |
||||
|
this.mesShiftData = {} |
||||
|
this.mesShiftLogs = [] |
||||
|
if (showWarning) { |
||||
|
this.$message.warning((data && data.msg) || '获取班次数据失败') |
||||
|
} |
||||
|
} |
||||
|
} catch (e) { |
||||
|
this.mesShiftData = {} |
||||
|
this.mesShiftLogs = [] |
||||
|
if (showWarning) { |
||||
|
this.$message.error(this.extractErrorMessage(e, '获取班次数据失败')) |
||||
|
} |
||||
|
} finally { |
||||
|
this.shiftLoading = false |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
getMesFieldValue (fieldName) { |
||||
|
if (!this.mesShiftData || this.mesShiftData[fieldName] === undefined || this.mesShiftData[fieldName] === null || this.mesShiftData[fieldName] === '') { |
||||
|
return '-' |
||||
|
} |
||||
|
return this.mesShiftData[fieldName] |
||||
|
}, |
||||
|
|
||||
|
getLogStatusType (status) { |
||||
|
return Number(status) === 1 ? 'success' : 'danger' |
||||
|
}, |
||||
|
|
||||
|
triggerOrderFileSelect () { |
||||
|
if (this.$refs.orderFileInput) { |
||||
|
this.$refs.orderFileInput.click() |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
handleOrderFileInputChange (event) { |
||||
|
const files = event && event.target && event.target.files |
||||
|
? Array.prototype.slice.call(event.target.files) |
||||
|
: [] |
||||
|
this.appendUploadFiles(files) |
||||
|
if (event && event.target) { |
||||
|
event.target.value = '' |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
handleOrderFileDrop (event) { |
||||
|
const files = event && event.dataTransfer && event.dataTransfer.files |
||||
|
? Array.prototype.slice.call(event.dataTransfer.files) |
||||
|
: [] |
||||
|
this.appendUploadFiles(files) |
||||
|
}, |
||||
|
|
||||
|
appendUploadFiles (files) { |
||||
|
if (!files || files.length === 0) { |
||||
|
return |
||||
|
} |
||||
|
const allowedExtMap = { |
||||
|
'.txt': true, |
||||
|
'.log': true |
||||
|
} |
||||
|
const keyMap = {} |
||||
|
for (let i = 0; i < this.uploadOrderFileList.length; i++) { |
||||
|
const item = this.uploadOrderFileList[i] |
||||
|
const itemKey = [item.name || '', item.size || 0, item.lastModified || 0].join('|') |
||||
|
keyMap[itemKey] = true |
||||
|
} |
||||
|
|
||||
|
let invalidCount = 0 |
||||
|
let duplicateCount = 0 |
||||
|
let addedCount = 0 |
||||
|
for (let i = 0; i < files.length; i++) { |
||||
|
const file = files[i] |
||||
|
const lowerName = (file.name || '').toLowerCase() |
||||
|
const ext = lowerName.lastIndexOf('.') > -1 ? lowerName.substring(lowerName.lastIndexOf('.')) : '' |
||||
|
if (!allowedExtMap[ext]) { |
||||
|
invalidCount++ |
||||
|
continue |
||||
|
} |
||||
|
const fileKey = [file.name || '', file.size || 0, file.lastModified || 0].join('|') |
||||
|
if (keyMap[fileKey]) { |
||||
|
duplicateCount++ |
||||
|
continue |
||||
|
} |
||||
|
keyMap[fileKey] = true |
||||
|
addedCount++ |
||||
|
this.uploadOrderFileList.push({ |
||||
|
uid: 'local_' + this.uploadFileUid++, |
||||
|
name: file.name, |
||||
|
size: file.size, |
||||
|
lastModified: file.lastModified, |
||||
|
raw: file |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
if (invalidCount > 0) { |
||||
|
this.$message.warning('仅支持 .txt/.log 文件,已忽略 ' + invalidCount + ' 个') |
||||
|
} |
||||
|
if (duplicateCount > 0) { |
||||
|
this.$message.info('已自动忽略重复文件 ' + duplicateCount + ' 个') |
||||
|
} |
||||
|
if (addedCount > 0) { |
||||
|
this.$message.success('已添加文件 ' + addedCount + ' 个') |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
removePendingUploadFile (index) { |
||||
|
this.uploadOrderFileList.splice(index, 1) |
||||
|
}, |
||||
|
|
||||
|
formatFileSize (size) { |
||||
|
if (!size) { |
||||
|
return '-' |
||||
|
} |
||||
|
return (size / 1024).toFixed(2) |
||||
|
}, |
||||
|
|
||||
|
validateUploadOrderForm () { |
||||
|
if (!this.uploadForm.process) { |
||||
|
this.$message.warning('请选择工序') |
||||
|
return false |
||||
|
} |
||||
|
if (!this.uploadForm.machineNo) { |
||||
|
this.$message.warning('机器账号不能为空') |
||||
|
return false |
||||
|
} |
||||
|
if (!this.uploadForm.shift) { |
||||
|
this.$message.warning('班次为空,暂不能上传') |
||||
|
return false |
||||
|
} |
||||
|
if (!this.uploadForm.operatorNo) { |
||||
|
this.$message.warning('请先维护上岗人员后再上传') |
||||
|
return false |
||||
|
} |
||||
|
if (!this.uploadOrderFileList || this.uploadOrderFileList.length === 0) { |
||||
|
this.$message.warning('请先选择上传文件') |
||||
|
return false |
||||
|
} |
||||
|
return true |
||||
|
}, |
||||
|
|
||||
|
async saveUploadOrder () { |
||||
|
if (!this.validateUploadOrderForm()) { |
||||
|
return |
||||
|
} |
||||
|
this.saveLoading = true |
||||
|
const resultList = [] |
||||
|
let successCount = 0 |
||||
|
|
||||
|
for (let i = 0; i < this.uploadOrderFileList.length; i++) { |
||||
|
const fileItem = this.uploadOrderFileList[i] |
||||
|
const realFile = fileItem.raw || fileItem |
||||
|
if (!realFile) { |
||||
|
resultList.push({ |
||||
|
fileName: fileItem.name || '未知文件', |
||||
|
success: false, |
||||
|
statusText: '失败', |
||||
|
message: '文件内容为空' |
||||
|
}) |
||||
|
continue |
||||
|
} |
||||
|
|
||||
|
const formData = new FormData() |
||||
|
formData.append('process', this.uploadForm.process) |
||||
|
formData.append('machineNo', this.uploadForm.machineNo) |
||||
|
formData.append('date', this.uploadForm.date) |
||||
|
formData.append('shift', this.uploadForm.shift) |
||||
|
formData.append('operatorNo', this.uploadForm.operatorNo) |
||||
|
formData.append('log', realFile, fileItem.name || realFile.name || ('log_' + (i + 1) + '.txt')) |
||||
|
|
||||
|
try { |
||||
|
const { data } = await uploadMesOrderLog(formData) |
||||
|
const isSuccess = data && data.code === 0 |
||||
|
if (isSuccess) { |
||||
|
successCount += 1 |
||||
|
} |
||||
|
resultList.push({ |
||||
|
fileName: fileItem.name || realFile.name || ('log_' + (i + 1)), |
||||
|
success: isSuccess, |
||||
|
statusText: isSuccess ? '成功' : '失败', |
||||
|
message: (data && data.msg) || (isSuccess ? '上传成功' : '上传失败') |
||||
|
}) |
||||
|
} catch (e) { |
||||
|
resultList.push({ |
||||
|
fileName: fileItem.name || realFile.name || ('log_' + (i + 1)), |
||||
|
success: false, |
||||
|
statusText: '失败', |
||||
|
message: this.extractErrorMessage(e, '上传失败') |
||||
|
}) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
this.uploadResults = resultList |
||||
|
const failCount = resultList.length - successCount |
||||
|
if (failCount === 0) { |
||||
|
this.$message.success('上传完成:' + successCount + ' 个成功') |
||||
|
} else if (successCount > 0) { |
||||
|
this.$message.warning('上传完成:成功 ' + successCount + ' 个,失败 ' + failCount + ' 个') |
||||
|
} else { |
||||
|
this.$message.error('上传完成:全部失败') |
||||
|
} |
||||
|
|
||||
|
await this.loadMesShiftData(false) |
||||
|
this.saveLoading = false |
||||
|
}, |
||||
|
|
||||
|
extractErrorMessage (error, defaultMessage) { |
||||
|
if (error && error.response && error.response.data) { |
||||
|
const responseData = error.response.data |
||||
|
if (typeof responseData === 'string') { |
||||
|
return responseData |
||||
|
} |
||||
|
return responseData.msg || responseData.message || defaultMessage |
||||
|
} |
||||
|
if (error && error.message) { |
||||
|
return error.message |
||||
|
} |
||||
|
return defaultMessage |
||||
|
}, |
||||
|
|
||||
|
closeDialog () { |
||||
|
this.$emit('update:visible', false) |
||||
|
}, |
||||
|
|
||||
|
handleDialogClosed () { |
||||
|
this.uploadOrderFileList = [] |
||||
|
this.uploadResults = [] |
||||
|
if (this.$refs.orderFileInput) { |
||||
|
this.$refs.orderFileInput.value = '' |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped lang="scss"> |
||||
|
.upload-order-layout { |
||||
|
display: flex; |
||||
|
gap: 10px; |
||||
|
align-items: stretch; |
||||
|
} |
||||
|
|
||||
|
.shift-panel { |
||||
|
width: 44%; |
||||
|
height: 100%; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
} |
||||
|
|
||||
|
.upload-panel { |
||||
|
width: 56%; |
||||
|
height: 100%; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
gap: 8px; |
||||
|
} |
||||
|
|
||||
|
.panel-card, |
||||
|
.shift-panel { |
||||
|
background: #ffffff; |
||||
|
border: 1px solid #dfe6ee; |
||||
|
border-radius: 8px; |
||||
|
padding: 10px; |
||||
|
box-sizing: border-box; |
||||
|
} |
||||
|
|
||||
|
.panel-header { |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
align-items: center; |
||||
|
font-weight: 600; |
||||
|
color: #2f3b4f; |
||||
|
} |
||||
|
|
||||
|
.panel-title { |
||||
|
display: inline-flex; |
||||
|
align-items: center; |
||||
|
font-size: 15px; |
||||
|
} |
||||
|
|
||||
|
.panel-title i { |
||||
|
margin-right: 6px; |
||||
|
color: #18a5a3; |
||||
|
} |
||||
|
|
||||
|
.panel-header-card { |
||||
|
margin-bottom: 8px; |
||||
|
padding-bottom: 6px; |
||||
|
border-bottom: 1px solid #edf1f7; |
||||
|
} |
||||
|
|
||||
|
.list-header { |
||||
|
margin-bottom: 6px; |
||||
|
padding-bottom: 4px; |
||||
|
border-bottom: 1px solid #edf1f7; |
||||
|
font-size: 13px; |
||||
|
} |
||||
|
|
||||
|
.shift-panel /deep/ .el-button--text { |
||||
|
color: #18a5a3; |
||||
|
font-weight: 500; |
||||
|
} |
||||
|
|
||||
|
.summary-grid { |
||||
|
display: grid; |
||||
|
grid-template-columns: repeat(2, minmax(0, 1fr)); |
||||
|
gap: 8px; |
||||
|
margin-top: 8px; |
||||
|
} |
||||
|
|
||||
|
.summary-item { |
||||
|
border: 1px solid #edf2f7; |
||||
|
border-left: 3px solid #18a5a3; |
||||
|
border-radius: 6px; |
||||
|
padding: 8px; |
||||
|
background: #fcfdff; |
||||
|
min-height: 54px; |
||||
|
box-sizing: border-box; |
||||
|
} |
||||
|
|
||||
|
.summary-label { |
||||
|
font-size: 12px; |
||||
|
color: #7c8797; |
||||
|
} |
||||
|
|
||||
|
.summary-value { |
||||
|
margin-top: 4px; |
||||
|
font-size: 16px; |
||||
|
color: #1f2d3d; |
||||
|
font-weight: 700; |
||||
|
line-height: 1; |
||||
|
} |
||||
|
|
||||
|
.shift-panel /deep/ .el-table { |
||||
|
margin-top: 12px; |
||||
|
} |
||||
|
|
||||
|
.upload-form { |
||||
|
margin-bottom: 0; |
||||
|
} |
||||
|
|
||||
|
.upload-field-label { |
||||
|
margin-bottom: 6px; |
||||
|
font-size: 13px; |
||||
|
color: #3f4c5f; |
||||
|
line-height: 18px; |
||||
|
font-weight: 600; |
||||
|
} |
||||
|
|
||||
|
.upload-zone-wrap { |
||||
|
border: 1px dashed #9ad1d0; |
||||
|
border-radius: 8px; |
||||
|
background: linear-gradient(180deg, #f9fdfd 0%, #f3f9f9 100%); |
||||
|
overflow: hidden; |
||||
|
} |
||||
|
|
||||
|
.upload-file-input { |
||||
|
display: none; |
||||
|
} |
||||
|
|
||||
|
.upload-drop-zone { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
width: 100%; |
||||
|
height: 86px; |
||||
|
box-sizing: border-box; |
||||
|
cursor: pointer; |
||||
|
background: transparent; |
||||
|
} |
||||
|
|
||||
|
.upload-drop-zone:hover { |
||||
|
background: rgba(24, 165, 163, 0.06); |
||||
|
} |
||||
|
|
||||
|
.upload-drop-zone .el-icon-upload { |
||||
|
margin: 0 0 6px; |
||||
|
line-height: 1; |
||||
|
font-size: 28px; |
||||
|
color: #91b5c7; |
||||
|
} |
||||
|
|
||||
|
.upload-main-text { |
||||
|
margin: 0; |
||||
|
line-height: 18px; |
||||
|
color: #4a5568; |
||||
|
font-size: 13px; |
||||
|
} |
||||
|
|
||||
|
.upload-main-text em { |
||||
|
color: #1b8f8f; |
||||
|
font-style: normal; |
||||
|
} |
||||
|
|
||||
|
.upload-tip-text { |
||||
|
padding: 6px 10px; |
||||
|
font-size: 11px; |
||||
|
color: #6b7a90; |
||||
|
border-top: 1px solid #dfecef; |
||||
|
background: rgba(24, 165, 163, 0.05); |
||||
|
} |
||||
|
|
||||
|
.upload-list-row { |
||||
|
display: flex; |
||||
|
gap: 8px; |
||||
|
flex: 1; |
||||
|
min-height: 0; |
||||
|
} |
||||
|
|
||||
|
.selected-file-wrap, |
||||
|
.upload-result-wrap { |
||||
|
flex: 1; |
||||
|
min-width: 0; |
||||
|
padding: 10px; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
} |
||||
|
|
||||
|
.selected-file-wrap /deep/ .el-table, |
||||
|
.upload-result-wrap /deep/ .el-table { |
||||
|
margin-top: 0; |
||||
|
} |
||||
|
|
||||
|
.upload-panel /deep/ .el-form-item { |
||||
|
margin-bottom: 6px; |
||||
|
} |
||||
|
|
||||
|
.upload-panel /deep/ .el-form-item__label { |
||||
|
padding-bottom: 2px; |
||||
|
line-height: 18px; |
||||
|
color: #627089; |
||||
|
font-size: 12px; |
||||
|
} |
||||
|
|
||||
|
@media (max-width: 1280px) { |
||||
|
.upload-order-layout { |
||||
|
flex-direction: column; |
||||
|
height: auto !important; |
||||
|
} |
||||
|
|
||||
|
.shift-panel, |
||||
|
.upload-panel { |
||||
|
width: 100%; |
||||
|
height: auto; |
||||
|
} |
||||
|
|
||||
|
.upload-list-row { |
||||
|
flex-direction: column; |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue