|
|
|
@ -30,7 +30,20 @@ |
|
|
|
<div class="search-header-actions"> |
|
|
|
<el-button type="primary" @click="getDataList('Y')">查询</el-button> |
|
|
|
<el-button @click="resetSearch">重置</el-button> |
|
|
|
<el-button type="success" :loading="exportLoading" @click="exportTrackingData">导出</el-button> |
|
|
|
<el-dropdown |
|
|
|
class="tracking-export-dropdown" |
|
|
|
trigger="click" |
|
|
|
:disabled="trackingExporting" |
|
|
|
@command="downloadTrackingExport"> |
|
|
|
<el-button type="success" :loading="trackingExporting"> |
|
|
|
导出<i class="el-icon-arrow-down el-icon--right"></i> |
|
|
|
</el-button> |
|
|
|
<el-dropdown-menu slot="dropdown"> |
|
|
|
<el-dropdown-item command="excel" :disabled="trackingExporting">导出Excel</el-dropdown-item> |
|
|
|
<el-dropdown-item command="pdf" :disabled="trackingExporting">导出PDF</el-dropdown-item> |
|
|
|
<el-dropdown-item command="image" :disabled="trackingExporting">导出图片</el-dropdown-item> |
|
|
|
</el-dropdown-menu> |
|
|
|
</el-dropdown> |
|
|
|
<el-button type="primary" @click="openOneKeyDialog">一键创建</el-button> |
|
|
|
<el-button type="warning" @click="openCreateProofDialog()">新增打样</el-button> |
|
|
|
<el-button type="success" plain :loading="syncBatchNpiLoading" @click="syncBatchProjectPartToNpi()">同步项目物料到NPI</el-button> |
|
|
|
@ -919,7 +932,6 @@ |
|
|
|
/> |
|
|
|
</el-select> |
|
|
|
</el-form-item> |
|
|
|
<div v-if="oneKeyDialogMode !== 'create'" class="proofing-status-change-tip">仅可更改为终止、取消、报废,保存后同步到NPI</div> |
|
|
|
</el-col> |
|
|
|
<el-col :span="6" v-show="isOneKeyCreateFieldVisible('requiredDeliveryDate')"> |
|
|
|
<el-form-item label="预计完成日期"> |
|
|
|
@ -1125,7 +1137,7 @@ |
|
|
|
</div> |
|
|
|
</el-col> |
|
|
|
<el-col :span="6"> |
|
|
|
<el-form-item label="预计完成日期" required> |
|
|
|
<el-form-item label="预计完成日期"> |
|
|
|
<el-date-picker |
|
|
|
v-model="proofDialogData.requiredDeliveryDate" |
|
|
|
type="date" |
|
|
|
@ -1262,6 +1274,8 @@ import { |
|
|
|
createProofTrackingRecord, |
|
|
|
deleteProofTrackingBatch, |
|
|
|
exportProofTracking, |
|
|
|
exportProofTrackingPdf, |
|
|
|
exportProofTrackingImage, |
|
|
|
finishProofTracking, |
|
|
|
oneKeyCreateProofTracking, |
|
|
|
oneKeyUpdateProofTracking, |
|
|
|
@ -1868,6 +1882,8 @@ export default { |
|
|
|
dataList: [], |
|
|
|
dataListLoading: false, |
|
|
|
exportLoading: false, |
|
|
|
exportPdfLoading: false, |
|
|
|
exportImageLoading: false, |
|
|
|
syncBatchNpiLoading: false, |
|
|
|
syncBatchProofLoading: false, |
|
|
|
deleteProofLoading: false, |
|
|
|
@ -1980,6 +1996,9 @@ export default { |
|
|
|
} |
|
|
|
}, |
|
|
|
computed: { |
|
|
|
trackingExporting () { |
|
|
|
return this.exportLoading || this.exportPdfLoading || this.exportImageLoading |
|
|
|
}, |
|
|
|
visibleTrackingColumns () { |
|
|
|
// 列表只渲染“当前生效列”:有用户动态列时用用户配置,否则用代码默认列。 |
|
|
|
const sourceColumns = Array.isArray(this.trackingColumnList) && this.trackingColumnList.length > 0 |
|
|
|
@ -4418,13 +4437,19 @@ export default { |
|
|
|
this.$message.error('查询异常') |
|
|
|
}) |
|
|
|
}, |
|
|
|
async exportTrackingData () { |
|
|
|
async downloadTrackingExport (exportType) { |
|
|
|
if (!this.validateSampleMakingDateRange()) { |
|
|
|
return |
|
|
|
} |
|
|
|
if (this.exportLoading) { |
|
|
|
if (this.exportLoading || this.exportPdfLoading || this.exportImageLoading) { |
|
|
|
return |
|
|
|
} |
|
|
|
const exportTaskMap = { |
|
|
|
excel: { loadingKey: 'exportLoading', failMessage: '导出失败', extension: 'xlsx', request: exportProofTracking }, |
|
|
|
pdf: { loadingKey: 'exportPdfLoading', failMessage: '导出PDF失败', extension: 'pdf', request: exportProofTrackingPdf }, |
|
|
|
image: { loadingKey: 'exportImageLoading', failMessage: '导出图片失败', extension: 'png', request: exportProofTrackingImage } |
|
|
|
} |
|
|
|
const exportTask = exportTaskMap[exportType] || exportTaskMap.excel |
|
|
|
this.searchData.site = this.$store.state.user.site |
|
|
|
this.searchData.userName = this.$store.state.user.name |
|
|
|
const exportTrackingColumns = this.visibleTrackingColumns.map(item => ({ |
|
|
|
@ -4454,17 +4479,19 @@ export default { |
|
|
|
}) |
|
|
|
inData.proofingStatusList = normalizedProofingStatusList |
|
|
|
this.applyProofTrackingSearchFilters(inData) |
|
|
|
this.exportLoading = true |
|
|
|
const loadingKey = exportTask.loadingKey |
|
|
|
const failMessage = exportTask.failMessage |
|
|
|
this[loadingKey] = true |
|
|
|
try { |
|
|
|
const response = await exportProofTracking(inData) |
|
|
|
const response = await exportTask.request(inData) |
|
|
|
const blob = response && response.data ? response.data : null |
|
|
|
if (!blob) { |
|
|
|
this.$message.error('导出失败') |
|
|
|
this.$message.error(failMessage) |
|
|
|
return |
|
|
|
} |
|
|
|
if (blob.type && blob.type.indexOf('application/json') > -1) { |
|
|
|
const errorText = await blob.text() |
|
|
|
let errorMsg = '导出失败' |
|
|
|
let errorMsg = failMessage |
|
|
|
try { |
|
|
|
const errorObj = JSON.parse(errorText) |
|
|
|
if (errorObj && errorObj.msg) { |
|
|
|
@ -4475,7 +4502,7 @@ export default { |
|
|
|
this.$message.error(errorMsg) |
|
|
|
return |
|
|
|
} |
|
|
|
const fileName = this.resolveProofTrackingExportFileName(response) |
|
|
|
const fileName = this.resolveProofTrackingExportFileName(response, exportTask.extension) |
|
|
|
const url = window.URL.createObjectURL(blob) |
|
|
|
const link = document.createElement('a') |
|
|
|
link.href = url |
|
|
|
@ -4485,13 +4512,13 @@ export default { |
|
|
|
link.remove() |
|
|
|
window.URL.revokeObjectURL(url) |
|
|
|
} catch (e) { |
|
|
|
this.$message.error('导出失败') |
|
|
|
this.$message.error(failMessage) |
|
|
|
} finally { |
|
|
|
this.exportLoading = false |
|
|
|
this[loadingKey] = false |
|
|
|
} |
|
|
|
}, |
|
|
|
resolveProofTrackingExportFileName (response) { |
|
|
|
const defaultFileName = `项目打样跟踪_${this.getExportTimestamp()}.xlsx` |
|
|
|
resolveProofTrackingExportFileName (response, extension) { |
|
|
|
const defaultFileName = `项目打样跟踪_${this.getExportTimestamp()}.${extension || 'xlsx'}` |
|
|
|
const disposition = response && response.headers |
|
|
|
? (response.headers['content-disposition'] || response.headers['Content-Disposition'] || '') |
|
|
|
: '' |
|
|
|
@ -4923,7 +4950,7 @@ export default { |
|
|
|
return |
|
|
|
} |
|
|
|
optionMap[applyNo] = true |
|
|
|
// 预计完成日期、创建日期分别回填打样的预计完成/开始日期,避免二次查单。 |
|
|
|
// 试验单只提供创建日期,用来补打样开始日期。预计完成日期和 baseline 不从试验单带入。 |
|
|
|
optionRows.push({ |
|
|
|
applyNo: applyNo, |
|
|
|
expectedFinishDate: this.formatDate(item.expectedFinishDate), |
|
|
|
@ -4944,6 +4971,7 @@ export default { |
|
|
|
this.oneKeyProofingApplyOptions = [] |
|
|
|
this.oneKeyForm.proofingNo = '' |
|
|
|
this.oneKeyForm.requiredDeliveryDate = '' |
|
|
|
this.oneKeyForm.baseline = '' |
|
|
|
this.oneKeyForm.planStartDate = '' |
|
|
|
this.oneKeyProjectNoSnapshot = '' |
|
|
|
this.oneKeyForm.testPartNo = '' |
|
|
|
@ -4967,7 +4995,7 @@ export default { |
|
|
|
handleOneKeyProofingNoChange (proofingNo) { |
|
|
|
const selectedNo = this.isBlankValue(proofingNo) ? '' : String(proofingNo).trim() |
|
|
|
if (this.oneKeyDialogMode !== 'create') { |
|
|
|
// 修改模式:库里已有日期保留;为空时才跟随打样单号回填,避免空日期一直缺值。 |
|
|
|
// 修改和详情以库里的预计完成日期、baseline 为准。库里为空就保持空,不用试验单预计完成日期回填。 |
|
|
|
if (!selectedNo) { |
|
|
|
this.oneKeyForm.proofingNo = '' |
|
|
|
return |
|
|
|
@ -4975,12 +5003,15 @@ export default { |
|
|
|
const matchedInEdit = this.oneKeyProofingApplyOptions.find(item => item && item.applyNo === selectedNo) |
|
|
|
if (matchedInEdit) { |
|
|
|
this.oneKeyForm.proofingNo = matchedInEdit.applyNo |
|
|
|
this.fillEmptyOneKeyProofingDatesFromApply(matchedInEdit) |
|
|
|
if (this.isBlankValue(this.oneKeyForm.planStartDate)) { |
|
|
|
this.oneKeyForm.planStartDate = matchedInEdit.createTime || '' |
|
|
|
} |
|
|
|
} |
|
|
|
return |
|
|
|
} |
|
|
|
if (!selectedNo) { |
|
|
|
this.oneKeyForm.requiredDeliveryDate = '' |
|
|
|
this.oneKeyForm.baseline = '' |
|
|
|
this.oneKeyForm.planStartDate = '' |
|
|
|
return |
|
|
|
} |
|
|
|
@ -4989,27 +5020,9 @@ export default { |
|
|
|
return |
|
|
|
} |
|
|
|
this.oneKeyForm.proofingNo = matched.applyNo |
|
|
|
this.oneKeyForm.requiredDeliveryDate = matched.expectedFinishDate || '' |
|
|
|
// 打样开始日期默认取工程实验单创建日期;清空打样单时同步清空,避免残留旧单日期。 |
|
|
|
// 一键创建不带试验单预计完成日期。预计完成日期和 baseline 保持空白,保存时也就不会生成 Delivery&Package。 |
|
|
|
// 打样开始日期仍取工程实验单创建日期;清空打样单时同步清空,避免残留旧单日期。 |
|
|
|
this.oneKeyForm.planStartDate = matched.createTime || '' |
|
|
|
this.syncOneKeyBaselineByRequiredDeliveryDate(this.oneKeyForm.requiredDeliveryDate, false) |
|
|
|
}, |
|
|
|
fillEmptyOneKeyProofingDatesFromApply (matched) { |
|
|
|
if (!matched) { |
|
|
|
return |
|
|
|
} |
|
|
|
let filledRequiredDate = false |
|
|
|
if (this.isBlankValue(this.oneKeyForm.requiredDeliveryDate)) { |
|
|
|
this.oneKeyForm.requiredDeliveryDate = matched.expectedFinishDate || '' |
|
|
|
filledRequiredDate = true |
|
|
|
} |
|
|
|
if (this.isBlankValue(this.oneKeyForm.planStartDate)) { |
|
|
|
this.oneKeyForm.planStartDate = matched.createTime || '' |
|
|
|
} |
|
|
|
// 仅在本次补了预计完成日期时尝试带出 baseline,避免覆盖修改态已有 baseline。 |
|
|
|
if (filledRequiredDate) { |
|
|
|
this.syncOneKeyBaselineByRequiredDeliveryDate(this.oneKeyForm.requiredDeliveryDate, false) |
|
|
|
} |
|
|
|
}, |
|
|
|
handleOneKeyRequiredDeliveryDateChange (dateVal) { |
|
|
|
this.syncOneKeyBaselineByRequiredDeliveryDate(dateVal, false) |
|
|
|
@ -5059,6 +5072,7 @@ export default { |
|
|
|
if (!hasCurrent && !keepCurrentIfMissing) { |
|
|
|
this.oneKeyForm.proofingNo = '' |
|
|
|
this.oneKeyForm.requiredDeliveryDate = '' |
|
|
|
this.oneKeyForm.baseline = '' |
|
|
|
this.oneKeyForm.planStartDate = '' |
|
|
|
} |
|
|
|
} |
|
|
|
@ -5083,6 +5097,7 @@ export default { |
|
|
|
const selectedNo = this.isBlankValue(proofingNo) ? '' : String(proofingNo).trim() |
|
|
|
if (!selectedNo) { |
|
|
|
this.proofDialogData.requiredDeliveryDate = '' |
|
|
|
this.proofDialogData.baseline = '' |
|
|
|
this.proofDialogData.planStartDate = '' |
|
|
|
return |
|
|
|
} |
|
|
|
@ -5091,10 +5106,9 @@ export default { |
|
|
|
return |
|
|
|
} |
|
|
|
this.proofDialogData.proofingNo = matched.applyNo |
|
|
|
this.proofDialogData.requiredDeliveryDate = matched.expectedFinishDate || '' |
|
|
|
// 打样开始日期默认取工程实验单创建日期;清空打样单时同步清空,避免残留旧单日期。 |
|
|
|
// 新增打样不带试验单预计完成日期。预计完成日期和 baseline 保持空白,保存时也就不会生成 Delivery&Package。 |
|
|
|
// 打样开始日期仍取工程实验单创建日期;清空打样单时同步清空,避免残留旧单日期。 |
|
|
|
this.proofDialogData.planStartDate = matched.createTime || '' |
|
|
|
this.syncProofDialogBaselineByRequiredDeliveryDate(this.proofDialogData.requiredDeliveryDate, false) |
|
|
|
}, |
|
|
|
handleProofDialogRequiredDeliveryDateChange (dateVal) { |
|
|
|
this.syncProofDialogBaselineByRequiredDeliveryDate(dateVal, false) |
|
|
|
@ -5119,6 +5133,7 @@ export default { |
|
|
|
this.proofDialogApplyOptions = [] |
|
|
|
this.proofDialogData.proofingNo = '' |
|
|
|
this.proofDialogData.requiredDeliveryDate = '' |
|
|
|
this.proofDialogData.baseline = '' |
|
|
|
this.proofDialogData.planStartDate = '' |
|
|
|
return Promise.resolve([]) |
|
|
|
} |
|
|
|
@ -5574,9 +5589,13 @@ export default { |
|
|
|
inData.priorityLevel = '' |
|
|
|
} |
|
|
|
if (this.oneKeyDialogMode === 'create' && this.isBlankValue(inData.baseline) && !this.isBlankValue(inData.requiredDeliveryDate)) { |
|
|
|
// 一键创建若已带出 Delivery&Package 日期,则 baseline 默认同步该日期(允许用户提交前改写)。 |
|
|
|
// 仅当用户自己填写了预计完成日期时,baseline 才跟随;选择打样单号不会再带出试验单日期。 |
|
|
|
inData.baseline = this.formatDate(inData.requiredDeliveryDate) |
|
|
|
} |
|
|
|
if (this.oneKeyDialogMode === 'create') { |
|
|
|
inData.requiredDeliveryDate = this.isBlankValue(inData.requiredDeliveryDate) ? null : this.formatDate(inData.requiredDeliveryDate) |
|
|
|
inData.baseline = this.isBlankValue(inData.baseline) ? null : this.formatDate(inData.baseline) |
|
|
|
} |
|
|
|
// 干湿分类仅在 RFID 使用,非 RFID 提交时统一清空,避免旧值串到错误 BU。 |
|
|
|
if (!this.isRfidBuNo(inData.buNo)) { |
|
|
|
inData.dry_wet_type = '' |
|
|
|
@ -6163,10 +6182,6 @@ export default { |
|
|
|
this.$message.warning('打样开始日期不能为空') |
|
|
|
return false |
|
|
|
} |
|
|
|
if (!this.proofDialogData.requiredDeliveryDate) { |
|
|
|
this.$message.warning('预计完成日期不能为空') |
|
|
|
return false |
|
|
|
} |
|
|
|
return true |
|
|
|
}, |
|
|
|
resolveProofDialogBaseline () { |
|
|
|
@ -6192,7 +6207,7 @@ export default { |
|
|
|
proofingNo: this.proofDialogData.proofingNo, |
|
|
|
proofingNumber: Number(this.proofDialogData.proofingNumber), |
|
|
|
planStartDate: this.proofDialogData.planStartDate, |
|
|
|
requiredDeliveryDate: this.proofDialogData.requiredDeliveryDate, |
|
|
|
requiredDeliveryDate: this.isBlankValue(this.proofDialogData.requiredDeliveryDate) ? null : this.proofDialogData.requiredDeliveryDate, |
|
|
|
baseline: this.resolveProofDialogBaseline(), |
|
|
|
actualityDeliveryDate: this.proofDialogData.actualityDeliveryDate || null, |
|
|
|
pmInqueryTime: this.isBlankValue(this.proofDialogData.pmInqueryTime) ? null : this.proofDialogData.pmInqueryTime, |
|
|
|
@ -6314,11 +6329,12 @@ export default { |
|
|
|
// 业务要求:表格选择日期仅更新日期,不自动改变工序状态(状态由“√”动作控制)。 |
|
|
|
const currentStatus = row[processCol.statusField] ? String(row[processCol.statusField]).trim() : '' |
|
|
|
const nextStatus = currentStatus || '未完成' |
|
|
|
// 只改日期时当前行已回写,不再整表刷新,避免滚动位置和日期编辑态被列表重查清掉。 |
|
|
|
this.updateProcessFromTable(row, processCol, { |
|
|
|
status: nextStatus, |
|
|
|
actualDate: actualDate, |
|
|
|
remark: actualDate ? '表格直接修改实际完成日期(状态不变)' : '表格清空实际完成日期(状态不变)' |
|
|
|
}, true) |
|
|
|
}, true, '', true) |
|
|
|
}, |
|
|
|
markProcessComplete (row, processCol) { |
|
|
|
if (!row || !processCol || this.isProcessStatusComplete(row, processCol)) { |
|
|
|
@ -6410,7 +6426,7 @@ export default { |
|
|
|
} |
|
|
|
return '-' |
|
|
|
}, |
|
|
|
updateProcessFromTable (row, processCol, processData, silentSuccess, successMsg) { |
|
|
|
updateProcessFromTable (row, processCol, processData, silentSuccess, successMsg, skipListRefresh) { |
|
|
|
if (!row || !processCol || !row.trackingId) { |
|
|
|
this.$message.error('工序参数缺失') |
|
|
|
return |
|
|
|
@ -6440,8 +6456,10 @@ export default { |
|
|
|
if (!silentSuccess) { |
|
|
|
this.$message.success(successMsg || '工序更新成功') |
|
|
|
} |
|
|
|
// 按业务要求:工序日期或状态变更后回查列表,保证动态列/派生字段展示最新值。 |
|
|
|
this.getDataList() |
|
|
|
// 改日期只更新当前单元格。打勾、回退仍回查列表,因为状态变化会影响打样状态和派生列。 |
|
|
|
if (!skipListRefresh) { |
|
|
|
this.getDataList() |
|
|
|
} |
|
|
|
} else { |
|
|
|
this.$message.error(data.msg || '工序更新失败') |
|
|
|
this.getDataList() |
|
|
|
@ -7214,6 +7232,10 @@ export default { |
|
|
|
row-gap: 6px; |
|
|
|
} |
|
|
|
|
|
|
|
.mod-config .search-header-actions .tracking-export-dropdown { |
|
|
|
margin: 0 10px; |
|
|
|
} |
|
|
|
|
|
|
|
.search-proofing-status-select .el-select__tags { |
|
|
|
flex-wrap: nowrap; |
|
|
|
overflow-x: auto; |
|
|
|
@ -7452,12 +7474,6 @@ export default { |
|
|
|
cursor: pointer; |
|
|
|
} |
|
|
|
|
|
|
|
.proofing-status-change-tip { |
|
|
|
margin-top: 2px; |
|
|
|
color: #909399; |
|
|
|
font-size: 12px; |
|
|
|
line-height: 16px; |
|
|
|
} |
|
|
|
|
|
|
|
.npi-jump-link:hover { |
|
|
|
text-decoration: underline; |
|
|
|
|