From e51bec825b55d0237ed4187d107ddf5d63ce88a6 Mon Sep 17 00:00:00 2001 From: "han\\hanst" Date: Wed, 22 Jul 2026 13:17:53 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BF=AE=E6=94=B9=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE/=E7=89=A9=E6=96=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sampleTracking/projectProofTracking.vue | 396 +++++++++++++++++- 1 file changed, 374 insertions(+), 22 deletions(-) diff --git a/src/views/modules/sampleTracking/projectProofTracking.vue b/src/views/modules/sampleTracking/projectProofTracking.vue index 0b7b49a..f0469c1 100644 --- a/src/views/modules/sampleTracking/projectProofTracking.vue +++ b/src/views/modules/sampleTracking/projectProofTracking.vue @@ -31,6 +31,7 @@ 一键创建项目/物料 + 修改项目/物料 新增打样 同步到NPI {{ batchEditMode ? '取消修改' : '批量修改' }} @@ -182,7 +183,7 @@ }" >{{ processTooltip.content }} - + @@ -391,7 +392,7 @@ - + @@ -400,7 +401,7 @@ - + @@ -421,7 +422,7 @@ - + 取消 - 保存 + {{ oneKeyDialogMode === 'edit' ? '保存修改' : '保存' }} @@ -723,8 +724,12 @@ import { finishProofTracking, oneKeyCreateProofTracking, queryProofTrackingProcessHistory, + searchProjectInfoTracking, + searchProjectPartTracking, searchProofTracking, syncProjectPartTracking, + updateProjectInfoTracking, + updateProjectPartTracking, updateProofTrackingComments, updateProofTrackingProcess } from '@/api/sampleTracking/sampleTracking' @@ -891,6 +896,7 @@ export default { commentsSaveLoading: false, oneKeyDialogVisible: false, + oneKeyDialogMode: 'create', saveOneKeyLoading: false, oneKeyForm: {}, @@ -1342,18 +1348,42 @@ export default { this.pageIndex = val this.getDataList() }, - openOneKeyDialog () { - this.oneKeyForm = this.getEmptyOneKeyForm() - if (this.userBuList.length > 0) { - this.oneKeyForm.buNo = this.userBuList[0].buNo || '' + getActionRow (row) { + return row || this.currentRow || (this.selectionRows.length > 0 ? this.selectionRows[0] : null) + }, + getTrackingProjectPartId (row) { + if (!row) { + return null } - this.oneKeyDialogVisible = true + return row.projectPartId || row.project_part_id || null }, - submitOneKey () { - if (!this.oneKeyForm.site || !this.oneKeyForm.buNo) { - this.$message.error('工厂和BU不能为空') - return + isBlankValue (value) { + return value == null || String(value).trim() === '' + }, + getBuOptionValue (site, buNo) { + const rawBuNo = buNo == null ? '' : String(buNo).trim() + if (!rawBuNo) { + return '' + } + if (rawBuNo.indexOf('_') > -1) { + return rawBuNo } + const targetSuffix = `_${rawBuNo}` + const matched = this.userBuList.find(item => item && item.buNo && (item.buNo === rawBuNo || item.buNo === `${site}_${rawBuNo}` || String(item.buNo).endsWith(targetSuffix))) + if (matched && matched.buNo) { + return matched.buNo + } + return site ? `${site}_${rawBuNo}` : rawBuNo + }, + getRoleDisplayName (value) { + if (this.isBlankValue(value)) { + return '' + } + const strVal = String(value) + const splitIdx = strVal.indexOf('-') + return splitIdx > -1 ? strVal.substring(splitIdx + 1) : strVal + }, + buildOneKeySubmitPayload () { const inData = Object.assign({}, this.oneKeyForm, { createBy: this.$store.state.user.name, updateBy: this.$store.state.user.name @@ -1370,7 +1400,281 @@ export default { if (!inData.priorityLevel) { inData.priorityLevel = '' } + return inData + }, + validateOneKeySubmitPayload (inData) { + if (this.isBlankValue(inData.site) || this.isBlankValue(inData.buNo)) { + this.$message.error('工厂和BU不能为空') + return false + } + if (this.oneKeyDialogMode === 'edit') { + if (!inData.projectId || !inData.projectPartId) { + this.$message.error('项目ID或项目物料ID缺失,无法修改') + return false + } + if (this.isBlankValue(inData.projectNo)) { + this.$message.error('项目编码不能为空') + return false + } + if (this.isBlankValue(inData.projectName) && this.isBlankValue(inData.projectDesc)) { + this.$message.error('项目名称不能为空') + return false + } + if (this.isBlankValue(inData.testPartNo)) { + this.$message.error('项目料号不能为空') + return false + } + if (this.isBlankValue(inData.partDesc)) { + this.$message.error('料号描述不能为空') + return false + } + } + return true + }, + buildProjectInfoUpdatePayload (inData) { + return { + projectId: inData.projectId, + site: inData.site, + buNo: inData.buNo, + projectNo: inData.projectNo, + projectCategory: inData.projectCategory, + projectName: inData.projectName, + projectDesc: inData.projectDesc, + status: inData.projectStatus || '草稿', + projectSource: inData.projectSource, + customerNo: inData.customerNo, + finalCustomerId: inData.finalCustomerId, + priority: inData.priorityLevel, + remark: inData.remark, + needDate: inData.needDate, + cProjectRegion: inData.cProjectRegion, + projectManager: inData.projectManager, + projectOwner: inData.projectOwner, + engineer: inData.engineer, + cQualityEngineer1: inData.cQualityEngineer1, + cQualityEngineer2: inData.cQualityEngineer2, + cQualityEngineer3: inData.cQualityEngineer3, + cQualityEngineer4: inData.cQualityEngineer4, + cQualityEngineer5: inData.cQualityEngineer5, + cQualityEngineer6: inData.cQualityEngineer6, + cManufactureEngineer: inData.cManufactureEngineer, + docEngineer: inData.docEngineer, + docEngineer2: inData.docEngineer2, + ipqcHardTag: inData.ipqcHardTag, + cQualityEngineer7: inData.cQualityEngineer7, + projectCreationDate: inData.projectCreationDate, + projectCloseDate: inData.projectCloseDate, + updateBy: this.$store.state.user.name + } + }, + buildProjectPartUpdatePayload (inData) { + return { + projectPartId: inData.projectPartId, + site: inData.site, + projectId: inData.projectId, + testPartNo: inData.testPartNo, + partDesc: inData.partDesc, + finalPartNo: inData.finalPartNo, + projectManager: inData.projectManager, + projectOwner: inData.projectOwner, + buildDate: inData.buildDate, + cQualityEngineer1: inData.cQualityEngineer1, + cQualityEngineer2: inData.cQualityEngineer2, + cQualityEngineer3: inData.cQualityEngineer3, + cQualityEngineer4: inData.cQualityEngineer4, + cQualityEngineer5: inData.cQualityEngineer5, + cQualityEngineer6: inData.cQualityEngineer6, + cManufactureEngineer: inData.cManufactureEngineer, + docEngineer: inData.docEngineer, + docEngineer2: inData.docEngineer2, + engineer: inData.engineer, + ipqcHardTag: inData.ipqcHardTag, + cQualityEngineer7: inData.cQualityEngineer7, + status: inData.partStatus || '草稿', + partType: inData.partType, + priority: inData.priorityLevel, + projectCategory: inData.projectCategory, + needDate: inData.needDate, + customerNo: inData.customerNo, + remark: inData.remark, + closeDate: inData.closeDate, + updateBy: this.$store.state.user.name + } + }, + buildOneKeyEditForm (current, projectData, partData) { + const project = projectData || {} + const part = partData || {} + const form = Object.assign(this.getEmptyOneKeyForm(), { + site: project.site || part.site || current.site || this.$store.state.user.site, + projectId: project.projectId || current.projectId || null, + projectPartId: part.projectPartId || this.getTrackingProjectPartId(current), + trackingId: current.trackingId || null, + buNo: this.getBuOptionValue(project.site || current.site || this.$store.state.user.site, project.buNo || current.buNo), + projectNo: project.projectNo || current.projectNo || '', + projectName: project.projectName || project.projectDesc || current.projectName || current.projectDesc || '', + projectDesc: project.projectDesc || project.projectName || current.projectDesc || current.projectName || '', + projectStatus: project.status || project.projectStatus || '草稿', + projectSource: project.projectSource || '', + testPartNo: part.testPartNo || current.testPartNo || '', + partDesc: part.partDesc || current.partDesc || '', + partName: part.partName || '', + partSpec: part.partSpec || '', + materialNumber: part.materialNumber || '', + finalPartDesc: part.finalPartDesc || '', + finalPartNo: part.finalPartNo || current.finalPartNo || '', + baseNo: part.baseNo || '', + revNo: part.revNo || '', + customerNo: project.customerNo || part.customerNo || current.customerNo || '', + customerDesc: project.customerDesc || current.customerDesc || '', + finalCustomerId: project.finalCustomerId || '', + customerRemark: project.customerRemark || '', + parentProjectNo: project.parentProjectNo || '', + oriProjectId: project.oriProjectId || '', + projectCategory: project.projectCategory || part.projectCategory || current.projectCategory || '', + cProjectRegion: project.cProjectRegion || current.cProjectRegion || '', + projectManager: project.projectManager || part.projectManager || current.projectManager || '', + projectOwner: project.projectOwner || part.projectOwner || current.projectOwner || '', + cQualityEngineer1: project.cQualityEngineer1 || part.cQualityEngineer1 || '', + cQualityEngineer2: project.cQualityEngineer2 || part.cQualityEngineer2 || '', + cQualityEngineer3: project.cQualityEngineer3 || part.cQualityEngineer3 || '', + cQualityEngineer4: project.cQualityEngineer4 || part.cQualityEngineer4 || '', + cQualityEngineer5: project.cQualityEngineer5 || part.cQualityEngineer5 || '', + cQualityEngineer6: project.cQualityEngineer6 || part.cQualityEngineer6 || '', + cManufactureEngineer: project.cManufactureEngineer || part.cManufactureEngineer || '', + docEngineer: project.docEngineer || part.docEngineer || '', + docEngineer2: project.docEngineer2 || part.docEngineer2 || '', + ipqcHardTag: project.ipqcHardTag || part.ipqcHardTag || '', + cQualityEngineer7: project.cQualityEngineer7 || part.cQualityEngineer7 || '', + partType: part.partType || '', + partStatus: part.status || part.partStatus || '草稿', + projectPhase: current.projectPhase || 'Sample', + tracker: current.tracker || project.projectOwner || part.projectOwner || '', + engineer: current.engineer || project.engineer || part.engineer || '', + priorityLevel: current.priorityLevel || current.priority || project.priority || part.priority || '', + proofingNo: current.proofingNo || '', + proofingStatus: current.proofingStatus || '进行中', + proofingNumber: current.proofingNumber || 1, + projectCreationDate: project.projectCreationDate || '', + projectCloseDate: project.projectCloseDate || '', + buildDate: part.buildDate || '', + closeDate: part.closeDate || '', + comments: current.comments || '', + planStartDate: current.planStartDate || '', + requiredDeliveryDate: current.requiredDeliveryDate || '', + needDate: project.needDate || part.needDate || current.needDate || '', + remark: part.remark || project.remark || current.remark || '' + }) + form.projectManagerName = this.getRoleDisplayName(form.projectManager) + form.projectOwnerName = this.getRoleDisplayName(form.projectOwner) + form.engineerName = this.getRoleDisplayName(form.engineer) + form.cManufactureEngineerName = this.getRoleDisplayName(form.cManufactureEngineer) + form.cQualityEngineer1Name = this.getRoleDisplayName(form.cQualityEngineer1) + form.cQualityEngineer2Name = this.getRoleDisplayName(form.cQualityEngineer2) + form.cQualityEngineer3Name = this.getRoleDisplayName(form.cQualityEngineer3) + form.cQualityEngineer4Name = this.getRoleDisplayName(form.cQualityEngineer4) + form.cQualityEngineer5Name = this.getRoleDisplayName(form.cQualityEngineer5) + form.cQualityEngineer6Name = this.getRoleDisplayName(form.cQualityEngineer6) + form.docEngineerName = this.getRoleDisplayName(form.docEngineer) + form.docEngineer2Name = this.getRoleDisplayName(form.docEngineer2) + form.ipqcHardTagName = this.getRoleDisplayName(form.ipqcHardTag) + form.cQualityEngineer7Name = this.getRoleDisplayName(form.cQualityEngineer7) + return form + }, + openOneKeyDialog (mode) { + const dialogMode = mode === 'edit' ? 'edit' : 'create' + this.oneKeyDialogMode = dialogMode + if (dialogMode !== 'edit') { + this.oneKeyForm = this.getEmptyOneKeyForm() + if (this.userBuList.length > 0) { + this.oneKeyForm.buNo = this.userBuList[0].buNo || '' + } + this.oneKeyDialogVisible = true + return + } + const current = this.getActionRow() + if (!current) { + this.$message.warning('请先选择一条记录后再修改项目/物料') + this.oneKeyDialogMode = 'create' + return + } + const projectPartId = this.getTrackingProjectPartId(current) + if (!current.projectId || !projectPartId || !current.trackingId) { + this.$message.warning('当前记录缺少项目或物料信息,无法修改') + this.oneKeyDialogMode = 'create' + return + } + const queryUser = this.$store.state.user.name + const querySite = current.site || this.$store.state.user.site this.saveOneKeyLoading = true + Promise.all([ + searchProjectInfoTracking({ + site: querySite, + userName: queryUser, + projectId: current.projectId, + page: 1, + limit: 1 + }), + searchProjectPartTracking({ + site: querySite, + userName: queryUser, + projectPartId: projectPartId, + page: 1, + limit: 1 + }) + ]).then(([projectResp, partResp]) => { + const projectData = projectResp && projectResp.data + const partData = partResp && partResp.data + if (!projectData || projectData.code !== 0) { + throw new Error((projectData && projectData.msg) || '加载项目信息失败') + } + if (!partData || partData.code !== 0) { + throw new Error((partData && partData.msg) || '加载项目物料信息失败') + } + const projectRows = (projectData.page && projectData.page.list) || [] + const partRows = (partData.page && partData.page.list) || [] + if (projectRows.length === 0) { + throw new Error('未找到对应的项目信息,无法修改') + } + if (partRows.length === 0) { + throw new Error('未找到对应的项目物料信息,无法修改') + } + this.oneKeyForm = this.buildOneKeyEditForm(current, projectRows[0], partRows[0]) + this.oneKeyDialogVisible = true + }).catch((e) => { + this.$message.error((e && e.message) || '加载项目/物料信息异常') + this.oneKeyDialogMode = 'create' + }).finally(() => { + this.saveOneKeyLoading = false + }) + }, + submitOneKey () { + const inData = this.buildOneKeySubmitPayload() + if (!this.validateOneKeySubmitPayload(inData)) { + return + } + this.saveOneKeyLoading = true + if (this.oneKeyDialogMode === 'edit') { + const projectPayload = this.buildProjectInfoUpdatePayload(inData) + const partPayload = this.buildProjectPartUpdatePayload(inData) + updateProjectInfoTracking(projectPayload).then(({ data }) => { + if (!data || data.code !== 0) { + throw new Error((data && data.msg) || '修改项目信息失败') + } + return updateProjectPartTracking(partPayload) + }).then(({ data }) => { + if (!data || data.code !== 0) { + throw new Error((data && data.msg) || '修改项目物料失败') + } + this.$message.success('项目/物料修改成功') + this.oneKeyDialogVisible = false + this.getDataList() + }).catch((e) => { + this.$message.error((e && e.message) || '项目/物料修改异常') + }).finally(() => { + this.saveOneKeyLoading = false + }) + return + } oneKeyCreateProofTracking(inData).then(({ data }) => { this.saveOneKeyLoading = false if (data && data.code === 0) { @@ -1393,7 +1697,7 @@ export default { }) }, openCreateProofDialog (row) { - const current = row || this.currentRow || (this.selectionRows.length > 0 ? this.selectionRows[0] : null) + const current = this.getActionRow(row) if (!current) { this.$message.warning('请先选择一条记录') return @@ -1429,17 +1733,60 @@ export default { }) this.proofDialogVisible = true }, + validateSyncToNpiRow (row) { + const projectPartId = this.getTrackingProjectPartId(row) + const missingLabels = [] + if (this.isBlankValue(row && row.site)) { + missingLabels.push('工厂') + } + if (this.isBlankValue(row && row.buNo)) { + missingLabels.push('BU') + } + if (!row || !row.projectId) { + missingLabels.push('项目ID') + } + if (this.isBlankValue(row && row.projectNo)) { + missingLabels.push('项目编码') + } + if (this.isBlankValue(row && row.projectName) && this.isBlankValue(row && row.projectDesc)) { + missingLabels.push('项目名称') + } + if (!projectPartId) { + missingLabels.push('项目物料ID') + } + if (this.isBlankValue(row && row.testPartNo)) { + missingLabels.push('项目料号') + } + if (this.isBlankValue(row && row.partDesc)) { + missingLabels.push('料号描述') + } + if (missingLabels.length > 0) { + const missingHtml = missingLabels.map(item => `- ${item}`).join('
') + this.$alert(`同步到NPI前,请先完善以下字段:
${missingHtml}`, '提示', { + confirmButtonText: '确定', + dangerouslyUseHTMLString: true + }) + return { + passed: false, + projectPartId: projectPartId + } + } + return { + passed: true, + projectPartId: projectPartId + } + }, syncToNpi (row) { - const current = row || this.currentRow || (this.selectionRows.length > 0 ? this.selectionRows[0] : null) + const current = this.getActionRow(row) if (!current) { this.$message.warning('请先选择一条记录') return } - const projectPartId = current.projectPartId || current.project_part_id - if (!projectPartId) { - this.$message.warning('项目物料ID缺失,无法同步') + const syncCheck = this.validateSyncToNpiRow(current) + if (!syncCheck.passed) { return } + const projectPartId = syncCheck.projectPartId this.currentRow = current const operator = this.$store.state.user.name this.syncNpiLoading = true @@ -1450,12 +1797,17 @@ export default { userName: operator }).then(({ data }) => { if (data && data.code === 0) { - const projectIdMsg = data.projectId || current.projectId || '' - const projectPartIdMsg = data.projectPartId || projectPartId this.$message.success(`同步成功`) this.getDataList() } else { - this.$message.error((data && data.msg) || '同步到NPI失败') + const failMsg = (data && data.msg) || '同步到NPI失败' + if (failMsg.indexOf('缺少以下必填项') > -1) { + this.$alert(failMsg, '同步校验未通过', { + confirmButtonText: '确定' + }) + } else { + this.$message.error(failMsg) + } } }).catch(() => { this.$message.error('同步到NPI异常')