diff --git a/src/api/sampleTracking/sampleTracking.js b/src/api/sampleTracking/sampleTracking.js index 2d65644..6c2d33e 100644 --- a/src/api/sampleTracking/sampleTracking.js +++ b/src/api/sampleTracking/sampleTracking.js @@ -18,7 +18,6 @@ export const exportProofTracking = data => createAPI('/sampleTracking/proofTrack export const oneKeyCreateProofTracking = data => createAPI('/sampleTracking/proofTracking/oneKeyCreate', 'POST', data) export const oneKeyUpdateProofTracking = data => createAPI('/sampleTracking/proofTracking/oneKeyUpdate', 'POST', data) export const createProofTrackingRecord = data => createAPI('/sampleTracking/proofTracking/createProofRecord', 'POST', data) -export const batchUpdateProofTrackingPlan = data => createAPI('/sampleTracking/proofTracking/batchUpdatePlan', 'POST', data) export const updateProofTrackingProcess = data => createAPI('/sampleTracking/proofTracking/updateProcess', 'POST', data) export const updateProofTrackingComments = data => createAPI('/sampleTracking/proofTracking/updateComments', 'POST', data) export const finishProofTracking = data => createAPI('/sampleTracking/proofTracking/finishProofing', 'POST', data) @@ -26,7 +25,6 @@ export const deleteProofTracking = data => createAPI('/sampleTracking/proofTrack export const queryProofTrackingProcessHistory = data => createAPI('/sampleTracking/proofTracking/processHistory', 'POST', data) export const queryProofTrackingBuProcessConfig = data => createAPI('/sampleTracking/proofTracking/buProcessConfig/list', 'POST', data) export const saveProofTrackingBuProcessConfig = data => createAPI('/sampleTracking/proofTracking/buProcessConfig/save', 'POST', data) -export const deleteProofTrackingBuProcessConfig = data => createAPI('/sampleTracking/proofTracking/buProcessConfig/delete', 'POST', data) export const queryProofTrackingProcessColumns = data => createAPI('/sampleTracking/proofTracking/processColumns/list', 'POST', data) export const queryProofTrackingProcessColumnsManage = data => createAPI('/sampleTracking/proofTracking/processColumns/manageList', 'POST', data) export const saveProofTrackingProcessColumnsManage = data => createAPI('/sampleTracking/proofTracking/processColumns/manageSave', 'POST', data) diff --git a/src/views/modules/eam/eamProjectInfo.vue b/src/views/modules/eam/eamProjectInfo.vue index a6ce18b..58a8edb 100644 --- a/src/views/modules/eam/eamProjectInfo.vue +++ b/src/views/modules/eam/eamProjectInfo.vue @@ -562,7 +562,10 @@ - SQE-ME + + * + SQE-ME + @@ -578,7 +581,7 @@ - * + * PE @@ -1266,6 +1269,14 @@ import {updateColumnSize} from "../../../api/table"; isAlphaOrAntennaBu () { return this.isAlphaBu || this.isAntennaBu }, + // buy-in-sell 在历史配置里存在 buy-in-shell 写法,校验时统一兼容两种值。 + isBuyInSellProjectCategory () { + if (this.modalData.projectCategory === null || this.modalData.projectCategory === undefined) { + return false + } + let projectCategoryText = String(this.modalData.projectCategory).trim().toLowerCase() + return projectCategoryText === 'buy-in-sell' || projectCategoryText === 'buy-in-shell' + }, // RF/Alpha / 天线 / 硬标,分类字段不要求手工选择。 isDryWetTypeOptionalBu () { return this.isAlphaOrAntennaBu || this.isHardtagBu || this.isRfBu @@ -4095,7 +4106,13 @@ import {updateColumnSize} from "../../../api/table"; this.$message.warning('请输入QC!') return } - if (this.modalData.peEngineer === '' || this.modalData.peEngineer == null) { + // buy-in-sell/shell 分类改为 SQE 必填、PE 选填,其他分类保持 PE 必填。 + if (this.isBuyInSellProjectCategory) { + if (this.modalData.sqemeEngineer === '' || this.modalData.sqemeEngineer == null) { + this.$message.warning('请输入SQE!') + return + } + } else if (this.modalData.peEngineer === '' || this.modalData.peEngineer == null) { this.$message.warning('请输入PE!') return } @@ -4941,6 +4958,9 @@ import {updateColumnSize} from "../../../api/table"; if (this.modalData.sqeeeEngineer) { this.modalData.sqeeeEngineerName = this.getUserDisplayName(this.modalData.sqeeeEngineer) } + // 新增产品弹窗的 BU 为只读,不会触发 BU change 事件,这里主动按 BU 加载项目分类下拉。 + let addPartBuNo = this.getBuNoByJoinedValue(this.modalData.bu) + this.loadModalProjectCategory(addPartBuNo, this.modalData.projectCategory, this.modalData.site) this.syncBusinessSearchSite(this.modalData.site) this.modalDisableFlag = true this.modalPartDisableFlag = true @@ -5035,6 +5055,9 @@ import {updateColumnSize} from "../../../api/table"; if (this.modalData.sqeeeEngineer) { this.modalData.sqeeeEngineerName = this.getUserDisplayName(this.modalData.sqeeeEngineer) } + // 编辑产品同样是只读 BU,保持与新增产品一致的项目分类加载行为。 + let editPartBuNo = this.getBuNoByJoinedValue(this.modalData.bu) + this.loadModalProjectCategory(editPartBuNo, this.modalData.projectCategory, this.modalData.site) this.syncBusinessSearchSite(this.modalData.site) this.modalDisableFlag = true this.modalPartDisableFlag = true diff --git a/src/views/modules/sampleTracking/projectProofTracking.vue b/src/views/modules/sampleTracking/projectProofTracking.vue index b226222..eef9d30 100644 --- a/src/views/modules/sampleTracking/projectProofTracking.vue +++ b/src/views/modules/sampleTracking/projectProofTracking.vue @@ -59,8 +59,6 @@ 一键创建 - 新增打样 同步项目物料到NPI 同步打样到NPI @@ -73,9 +71,13 @@ @click="openBuProcessConfigDialog" >事业部进度设置 默认进度设置 - + + - 已完成后,双击日期选择框可回退为未完成 + - 双击Comments可编辑,回车或点击✓保存 + @@ -94,7 +96,7 @@ @row-click="rowClick" style="width: 100%; margin-top: 8px" > - + {{ getTrackingColumnDisplayValue(scope.row, item.columnProp) }} - {{ getTrackingColumnDisplayValue(scope.row, item.columnProp) }} + v-if="isSyncIconTrackingColumn(item.columnProp)" + class="project-part-sync-text" + > + + {{ getTrackingColumnDisplayValue(scope.row, item.columnProp) }} + {{ scope.row.proofingStatus || '进行中' }} - - - ✓ + + {{ scope.row[item.actualField] || '' }} + + + + ✓ + @@ -197,16 +197,7 @@ - - - - + √ + >✓ - {{ scope.row.comments || '-' }} + {{ scope.row.comments || '' }} - + - 修改 - 删除 - 打样完成 + 修改 + 删除 + @@ -727,11 +718,10 @@ - + - @@ -950,42 +940,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 取消 - 保存 - - - import { - batchUpdateProofTrackingPlan, createProofTrackingRecord, deleteProofTracking, exportProofTracking, @@ -1570,7 +1523,6 @@ export default { currentRow: null, manualSelectedTrackingId: null, selectionRows: [], - batchEditMode: false, processHistoryMap: {}, processTooltipHoverKey: '', processTooltip: { @@ -1579,7 +1531,6 @@ export default { left: 0, top: 0 }, - processHistoryRows: [], commentsEditingTrackingId: null, commentsDraft: '', commentsSaveLoading: false, @@ -1603,10 +1554,6 @@ export default { proofDialogApplyLoading: false, proofDialogApplyQueryToken: 0, - processDialogVisible: false, - saveProcessLoading: false, - processForm: {}, - finishDialogVisible: false, finishSaveLoading: false, finishForm: { @@ -1838,8 +1785,9 @@ export default { } return this.normalizeTrackingColumnBoolean(column.columnHidden, false) === false }, - isProjectPartSyncColumn (columnProp) { - return ['projectNo', 'projectDesc', 'testPartNo', 'partDesc'].indexOf(columnProp) > -1 + // 同步图标只展示在项目编码、项目物料与打样单号三列,避免整列变色影响可读性。 + isSyncIconTrackingColumn (columnProp) { + return ['projectNo', 'testPartNo', 'proofingNo'].indexOf(columnProp) > -1 }, getTrackingColumnDisplayValue (row, columnProp) { if (!row || !columnProp) { @@ -3811,7 +3759,7 @@ export default { return !!row && row.trackingId === this.commentsEditingTrackingId }, startCommentsEdit (row) { - if (this.batchEditMode || !row || !row.trackingId || this.commentsSaveLoading) { + if (!row || !row.trackingId || this.commentsSaveLoading) { return } this.commentsEditingTrackingId = row.trackingId @@ -3996,11 +3944,11 @@ export default { const proofingId = row.proofingId || row.proofing_id || row.trackingId || null return this.isSyncedByIdRule(proofingId) }, - getProjectPartSyncTextClass (row) { - return this.isProjectPartSynced(row) ? 'sync-text--ok' : 'sync-text--pending' - }, - getProofSyncTextClass (row) { - return this.isProofSynced(row) ? 'sync-text--ok' : 'sync-text--pending' + isTrackingColumnSynced (row, columnProp) { + if (columnProp === 'proofingNo') { + return this.isProofSynced(row) + } + return this.isProjectPartSynced(row) }, getProjectCategoryValue (source) { if (!source) { @@ -5225,94 +5173,13 @@ export default { this.$message.error('新增打样异常') }) }, - toggleBatchEdit () { - this.batchEditMode = !this.batchEditMode - if (this.batchEditMode) { - this.cancelCommentsEdit() - } - this.$nextTick(() => { - const tableRef = this.$refs.trackingTable - if (tableRef && tableRef.doLayout) { - tableRef.doLayout() - } - if (this.batchEditMode) { - setTimeout(() => { - this.scrollToRawMaterialColumn() - }, 0) - } - }) - }, - scrollToRawMaterialColumn () { - const tableRef = this.$refs.trackingTable - if (!tableRef || !tableRef.$el) { - return - } - const headerWrapper = tableRef.headerWrapper || tableRef.$el.querySelector('.el-table__header-wrapper') - const bodyWrapper = tableRef.bodyWrapper || tableRef.$el.querySelector('.el-table__body-wrapper') - if (!headerWrapper || !bodyWrapper) { - return - } - const headerCells = headerWrapper.querySelectorAll('th') - let targetCell = null - for (let i = 0; i < headerCells.length; i++) { - const text = (headerCells[i].innerText || '').replace(/\s+/g, ' ').trim() - if (text === 'Raw Material') { - targetCell = headerCells[i] - break - } - } - if (!targetCell) { - return - } - const fixedLeftWrapper = tableRef.$el.querySelector('.el-table__fixed') - const fixedLeftWidth = fixedLeftWrapper ? fixedLeftWrapper.offsetWidth : 0 - const nextScrollLeft = Math.max(targetCell.offsetLeft - fixedLeftWidth - 8, 0) - bodyWrapper.scrollLeft = nextScrollLeft - headerWrapper.scrollLeft = nextScrollLeft - }, - saveBatchPlan () { - const rows = this.selectionRows && this.selectionRows.length > 0 ? this.selectionRows : this.dataList - if (!rows || rows.length === 0) { - this.$message.warning('没有可保存的数据') - return - } - const payloadRows = rows.map(row => ({ - trackingId: row.trackingId, - rawMaterialActualDate: row.rawMaterialActualDate, - cylinderCutterActualDate: row.cylinderCutterActualDate, - laminationActualDate: row.laminationActualDate, - printingActualDate: row.printingActualDate, - etchingActualDate: row.etchingActualDate, - slittingPackingActualDate: row.slittingPackingActualDate, - bondingActualDate: row.bondingActualDate, - cl60Cl822ActualDate: row.cl60Cl822ActualDate, - spottingActualDate: row.spottingActualDate, - encodingActualDate: row.encodingActualDate, - dieCutActualDate: row.dieCutActualDate, - inspectionActualDate: row.inspectionActualDate, - deliveryPackageActualDate: row.deliveryPackageActualDate, - comments: row.comments == null ? '' : String(row.comments), - updateBy: this.$store.state.user.name - })) - batchUpdateProofTrackingPlan({ - updateBy: this.$store.state.user.name, - rows: payloadRows - }).then(({ data }) => { - if (data && data.code === 0) { - this.$message.success('批量修改成功') - this.batchEditMode = false - this.getDataList() - } else { - this.$message.error(data.msg || '批量修改失败') - } - }).catch(() => { - this.$message.error('批量修改异常') - }) - }, handleProcessDateChange (row, processCol, dateVal) { if (!row || !processCol) { return } + if (this.isTrackingRowProcessReadonly(row)) { + return + } const actualDate = this.formatDate(dateVal) // 业务要求:表格选择日期仅更新日期,不自动改变工序状态(状态由“√”动作控制)。 const currentStatus = row[processCol.statusField] ? String(row[processCol.statusField]).trim() : '' @@ -5327,6 +5194,9 @@ export default { if (!row || !processCol || this.isProcessStatusComplete(row, processCol)) { return } + if (this.isTrackingRowProcessReadonly(row)) { + return + } // 若用户已手工选择日期,打勾仅改状态,不覆盖已选日期;无日期时才补当天。 const currentActualDate = this.formatDate(row[processCol.actualField]) const nextActualDate = currentActualDate || this.formatDate(new Date()) @@ -5340,6 +5210,9 @@ export default { if (!row || !processCol || !this.isProcessStatusComplete(row, processCol)) { return } + if (this.isTrackingRowProcessReadonly(row)) { + return + } // 按页面交互约定:已完成工序允许双击日期输入框进行回退。 this.rollbackProcessComplete(row, processCol) }, @@ -5347,6 +5220,9 @@ export default { if (!row || !processCol || !this.isProcessStatusComplete(row, processCol)) { return } + if (this.isTrackingRowProcessReadonly(row)) { + return + } const currentActualDate = this.formatDate(row[processCol.actualField]) this.$confirm('确定回退该工序状态为“未完成”吗?', '提示', { confirmButtonText: '确定', @@ -5402,51 +5278,6 @@ export default { this.getDataList() }) }, - openProcessDialog (row, processCol) { - if (!row || !processCol) { - return - } - this.currentRow = row - this.processForm = { - trackingId: row.trackingId, - processCode: processCol.code, - processName: processCol.label, - status: row[processCol.statusField] || '未完成', - actualDate: row[processCol.actualField] || '', - remark: '' - } - this.processHistoryRows = [] - this.processDialogVisible = true - this.loadProcessHistory(row, processCol, true) - }, - submitProcessUpdate () { - if (!this.processForm.trackingId || !this.processForm.processCode) { - this.$message.error('参数缺失') - return - } - if (!this.processForm.status) { - this.$message.error('请选择状态') - return - } - const inData = Object.assign({}, this.processForm, { - updateBy: this.$store.state.user.name - }) - this.saveProcessLoading = true - updateProofTrackingProcess(inData).then(({ data }) => { - this.saveProcessLoading = false - if (data && data.code === 0) { - this.$message.success('工序更新成功') - this.processDialogVisible = false - this.processHistoryMap = {} - this.getDataList() - } else { - this.$message.error(data.msg || '工序更新失败') - } - }).catch(() => { - this.saveProcessLoading = false - this.$message.error('工序更新异常') - }) - }, finishProof (row) { const current = row || this.currentRow if (!current || !current.trackingId) { @@ -5586,21 +5417,17 @@ export default { showTooltip() return } - this.loadProcessHistory(row, processCol, false).then(() => { + this.loadProcessHistory(row, processCol).then(() => { showTooltip() }) }, - loadProcessHistory (row, processCol, refreshDialog) { + loadProcessHistory (row, processCol) { if (!row || !row.trackingId) { return Promise.resolve([]) } const cacheKey = this.getProcessCacheKey(row, processCol) if (Object.prototype.hasOwnProperty.call(this.processHistoryMap, cacheKey)) { - const cachedRows = this.processHistoryMap[cacheKey] || [] - if (refreshDialog) { - this.processHistoryRows = cachedRows - } - return Promise.resolve(cachedRows) + return Promise.resolve(this.processHistoryMap[cacheKey] || []) } return queryProofTrackingProcessHistory({ trackingId: row.trackingId, @@ -5611,15 +5438,9 @@ export default { rows = data.rows || [] // Vue2 对对象新增 key 需要使用 $set 才能触发视图更新(tooltip 才会刷新历史列表) this.$set(this.processHistoryMap, cacheKey, rows) - if (refreshDialog) { - this.processHistoryRows = rows - } } return rows }).catch(() => { - if (refreshDialog) { - this.processHistoryRows = [] - } this.$set(this.processHistoryMap, cacheKey, []) return [] }) @@ -5831,7 +5652,11 @@ export default { } const proofingStatus = String(row.proofingStatus).trim() // 打样已结束时,Tracking Status 统一收敛为灰色 Complete,避免继续显示进度预警。 - return proofingStatus === '打样完成' || proofingStatus === '打样结束' + return proofingStatus === '打样完成' + }, + isTrackingRowProcessReadonly (row) { + // Complete 行不再允许维护工序日期与状态,统一改为只读文本展示。 + return this.isProofingFinishedForTrackingStatus(row) }, getTrackingStatusText (row) { if (this.isProofingFinishedForTrackingStatus(row)) { @@ -6132,13 +5957,17 @@ export default { color: #35b4b4; } -.sync-text--ok { - color: #67c23a; - font-weight: 600; +.project-part-sync-text { + display: inline-flex; + align-items: center; } -.sync-text--pending { - color: #606266; +.project-part-sync-icon { + margin-left: -4px; + margin-right: 2px; + color: #1f7a35; + font-size: 10px; + transform: translateY(-1px); } .tracking-status { @@ -6218,6 +6047,13 @@ export default { line-height: 18px; } +.process-date-display { + display: inline-block; + min-width: 74px; + text-align: center; + color: #606266; +} + .process-complete-btn { padding: 4px 8px; min-width: 12px;