diff --git a/src/api/sampleTracking/sampleTracking.js b/src/api/sampleTracking/sampleTracking.js
index 384f14c..1bf6899 100644
--- a/src/api/sampleTracking/sampleTracking.js
+++ b/src/api/sampleTracking/sampleTracking.js
@@ -10,8 +10,8 @@ export const searchProjectPartTracking = data => createAPI('/sampleTracking/proj
export const saveProjectPartTracking = data => createAPI('/sampleTracking/projectPart/save', 'POST', data)
export const updateProjectPartTracking = data => createAPI('/sampleTracking/projectPart/update', 'POST', data)
export const deleteProjectPartTracking = data => createAPI('/sampleTracking/projectPart/delete', 'POST', data)
-export const syncProjectPartTracking = data => createAPI('/sampleTracking/projectPart/sync', 'POST', data)
-export const syncProofTracking = data => createAPI('/sampleTracking/proofTracking/sync', 'POST', data)
+export const batchSyncProjectPartTracking = data => createAPI('/sampleTracking/projectPart/batchSync', 'POST', data)
+export const batchSyncProofTracking = data => createAPI('/sampleTracking/proofTracking/batchSync', 'POST', data)
export const searchProofTracking = data => createAPI('/sampleTracking/proofTracking/search', 'POST', data)
export const exportProofTracking = data => createAPI('/sampleTracking/proofTracking/export', 'POST', data, 'download')
diff --git a/src/views/modules/eam/eamProjectInfo.vue b/src/views/modules/eam/eamProjectInfo.vue
index 6d31ae9..a6ce18b 100644
--- a/src/views/modules/eam/eamProjectInfo.vue
+++ b/src/views/modules/eam/eamProjectInfo.vue
@@ -1243,6 +1243,11 @@ import {updateColumnSize} from "../../../api/table";
}
return this.modalData.buDesc || ''
},
+ isRfBu () {
+ let buNoText = this.normalizeBuText(this.currentModalBuNo)
+ let buDescText = this.normalizeBuText(this.currentModalBuDesc)
+ return buNoText.indexOf('01-Label') > -1 || buNoText.indexOf('软标') > -1 || buDescText.indexOf('软标') > -1
+ },
isAlphaBu () {
let buNoText = this.normalizeBuText(this.currentModalBuNo)
let buDescText = this.normalizeBuText(this.currentModalBuDesc)
@@ -1261,9 +1266,9 @@ import {updateColumnSize} from "../../../api/table";
isAlphaOrAntennaBu () {
return this.isAlphaBu || this.isAntennaBu
},
- // Alpha / 天线 / 硬标三个事业部,分类字段不要求手工选择。
+ // RF/Alpha / 天线 / 硬标,分类字段不要求手工选择。
isDryWetTypeOptionalBu () {
- return this.isAlphaOrAntennaBu || this.isHardtagBu
+ return this.isAlphaOrAntennaBu || this.isHardtagBu || this.isRfBu
},
},
components: {
diff --git a/src/views/modules/sampleTracking/projectProofTracking.vue b/src/views/modules/sampleTracking/projectProofTracking.vue
index e4fd410..9549b8b 100644
--- a/src/views/modules/sampleTracking/projectProofTracking.vue
+++ b/src/views/modules/sampleTracking/projectProofTracking.vue
@@ -23,7 +23,7 @@
-
+
@@ -62,8 +62,8 @@
新增打样
- 同步项目物料到NPI
- 同步打样到NPI
+ 同步项目物料到NPI
+ 同步打样到NPI
事业部进度设置
默认进度设置
-
+
-
-
修改
删除
打样完成
@@ -371,8 +369,13 @@
-
-
+
+
+
@@ -493,14 +496,14 @@
-
+
-
+
@@ -662,7 +665,8 @@
type="date"
value-format="yyyy-MM-dd"
placeholder="选择日期"
- style="width: 100%">
+ style="width: 100%"
+ @change="handleOneKeyRequiredDeliveryDateChange">
@@ -688,7 +692,18 @@
-
+
+
+
+
+
+
+
@@ -991,8 +1006,8 @@ import {
searchProjectInfoTracking,
searchProjectPartTracking,
searchProofTracking,
- syncProofTracking,
- syncProjectPartTracking,
+ batchSyncProofTracking,
+ batchSyncProjectPartTracking,
updateProofTrackingComments,
updateProofTrackingProcess
} from '@/api/sampleTracking/sampleTracking'
@@ -1252,6 +1267,34 @@ const DEFAULT_TRACKING_COLUMNS = [
columnWidth: 80,
showOverflowTooltip: false
},
+ {
+ serialNumber: 'proofTrackingTable1Baseline',
+ columnProp: 'baseline',
+ headerAlign: 'center',
+ align: 'center',
+ columnLabel: 'Baseline',
+ columnHidden: false,
+ columnImage: false,
+ columnSortable: false,
+ status: true,
+ fixed: '',
+ columnWidth: 100,
+ showOverflowTooltip: false
+ },
+ {
+ serialNumber: 'proofTrackingTable1DeliveryVariance',
+ columnProp: 'deliveryVariance',
+ headerAlign: 'center',
+ align: 'center',
+ columnLabel: 'Delivery Variance',
+ columnHidden: false,
+ columnImage: false,
+ columnSortable: false,
+ status: true,
+ fixed: '',
+ columnWidth: 110,
+ showOverflowTooltip: false
+ },
{
serialNumber: 'proofTrackingTable1TrackingStatus',
columnProp: 'trackingStatus',
@@ -1386,6 +1429,7 @@ export default {
'proofingNo',
'proofingStatus',
'proofingNumber',
+ 'baseline',
'planStartDate',
'requiredDeliveryDate',
'remark'
@@ -1428,8 +1472,8 @@ export default {
dataList: [],
dataListLoading: false,
exportLoading: false,
- syncNpiLoading: false,
- syncProofLoading: false,
+ syncBatchNpiLoading: false,
+ syncBatchProofLoading: false,
pageIndex: 1,
pageSize: 20,
totalPage: 0,
@@ -1709,14 +1753,14 @@ export default {
},
getTrackingColumnDisplayValue (row, columnProp) {
if (!row || !columnProp) {
- return '-'
+ return ''
}
const value = row[columnProp]
- return this.isBlankValue(value) ? '-' : String(value)
+ return this.isBlankValue(value) ? '' : String(value)
},
getTrackingRoleDisplayValue (row, nameField, valueField) {
if (!row) {
- return '-'
+ return ''
}
const roleNameValue = row[nameField]
if (!this.isBlankValue(roleNameValue)) {
@@ -1724,10 +1768,10 @@ export default {
}
const roleValue = row[valueField]
if (this.isBlankValue(roleValue)) {
- return '-'
+ return ''
}
const displayName = this.getRoleDisplayName(roleValue)
- return this.isBlankValue(displayName) ? '-' : displayName
+ return this.isBlankValue(displayName) ? '' : displayName
},
getSearchBuOptionList () {
return this.userBuList
@@ -1904,6 +1948,14 @@ export default {
}))
this.$set(row, processCol.statusField, status)
this.$set(row, processCol.actualField, actualDate)
+ if (processCol.code === 'deliveryPackage') {
+ // Delivery&Package 工序日期与打样预计完成日期使用同一口径,前端先行回写避免用户感知延迟。
+ this.$set(row, 'requiredDeliveryDate', actualDate || '')
+ // baseline 仅在首次维护 Delivery&Package 日期时自动带入,后续允许独立维护。
+ if (!this.formatDate(row.baseline) && actualDate) {
+ this.$set(row, 'baseline', actualDate)
+ }
+ }
},
getAllProcessCodes () {
return this.processColumns.map(item => item.code)
@@ -2002,6 +2054,10 @@ export default {
// BU统一按“去掉site前缀”展示与保存,例如 2_01-Label -> 01-Label。
return rawBuNo.substring(splitIdx + 1)
},
+ isRfidBuNo (buNo) {
+ const normalizedBuNo = this.normalizeBuNo(buNo, this.$store.state.user.site)
+ return normalizedBuNo.toUpperCase() === '03-RFID'
+ },
getValidProcessCodes (codes, allowedCodes) {
if (!Array.isArray(codes) || codes.length === 0) {
return []
@@ -2923,6 +2979,7 @@ export default {
comments: '',
planStartDate: '',
requiredDeliveryDate: '',
+ baseline: '',
needDate: '',
remark: ''
}
@@ -3373,6 +3430,21 @@ export default {
}
this.oneKeyForm.proofingNo = matched.applyNo
this.oneKeyForm.requiredDeliveryDate = matched.expectedFinishDate || ''
+ this.syncOneKeyBaselineByRequiredDeliveryDate(this.oneKeyForm.requiredDeliveryDate, false)
+ },
+ handleOneKeyRequiredDeliveryDateChange (dateVal) {
+ this.syncOneKeyBaselineByRequiredDeliveryDate(dateVal, false)
+ },
+ syncOneKeyBaselineByRequiredDeliveryDate (requiredDeliveryDate, forceSync) {
+ const normalizedRequiredDate = this.formatDate(requiredDeliveryDate)
+ if (!normalizedRequiredDate) {
+ return
+ }
+ const normalizedBaseline = this.formatDate(this.oneKeyForm.baseline)
+ if (forceSync || !normalizedBaseline) {
+ // baseline 首次默认跟随 Delivery&Package 日期,后续可按业务独立调整。
+ this.oneKeyForm.baseline = normalizedRequiredDate
+ }
},
loadOneKeyProofingApplyOptions (projectNo, options) {
const queryOptions = options || {}
@@ -3537,6 +3609,15 @@ export default {
site: this.getSiteByJoinedBuNo(joinedBuNo)
}
},
+ isOneKeyDryWetTypeVisible () {
+ return this.isRfidBuNo(this.oneKeyForm && this.oneKeyForm.buNo ? this.oneKeyForm.buNo : '')
+ },
+ handleOneKeyBuChange () {
+ // 干湿分类仅用于 RFID,切换到其他 BU 时主动清空,避免隐藏字段误提交。
+ if (!this.isOneKeyDryWetTypeVisible()) {
+ this.oneKeyForm.dry_wet_type = ''
+ }
+ },
getRowDateSortTime (row, fieldList) {
if (!row || !Array.isArray(fieldList)) {
return 0
@@ -3826,8 +3907,10 @@ export default {
const selectedDryWetType = this.isBlankValue(selectedPart.dry_wet_type)
? selectedPart.dryWetType
: selectedPart.dry_wet_type
- if (!this.isBlankValue(selectedDryWetType)) {
+ if (this.isOneKeyDryWetTypeVisible() && !this.isBlankValue(selectedDryWetType)) {
this.oneKeyForm.dry_wet_type = String(selectedDryWetType).trim()
+ } else if (!this.isOneKeyDryWetTypeVisible()) {
+ this.oneKeyForm.dry_wet_type = ''
}
// 业务要求:料号角色与项目角色存在差异时,界面需优先回填料号角色账号。
this.syncOneKeyPartRoleFields(selectedPart)
@@ -3868,6 +3951,14 @@ export default {
if (!inData.priorityLevel) {
inData.priorityLevel = ''
}
+ if (this.oneKeyDialogMode === 'create' && this.isBlankValue(inData.baseline) && !this.isBlankValue(inData.requiredDeliveryDate)) {
+ // 一键创建若已带出 Delivery&Package 日期,则 baseline 默认同步该日期(允许用户提交前改写)。
+ inData.baseline = this.formatDate(inData.requiredDeliveryDate)
+ }
+ // 干湿分类仅在 RFID 使用,非 RFID 提交时统一清空,避免旧值串到错误 BU。
+ if (!this.isRfidBuNo(inData.buNo)) {
+ inData.dry_wet_type = ''
+ }
// 弹窗仅展示一个立项日期输入,提交时同步到项目与物料两个日期字段,避免物料立项日期被误判为空
if (!this.isBlankValue(inData.projectCreationDate)) {
inData.buildDate = inData.projectCreationDate
@@ -3982,6 +4073,7 @@ export default {
comments: current.comments || '',
planStartDate: current.planStartDate || '',
requiredDeliveryDate: current.requiredDeliveryDate || '',
+ baseline: current.baseline || '',
needDate: project.needDate || part.needDate || current.needDate || '',
remark: part.remark || project.remark || current.remark || ''
})
@@ -3999,6 +4091,9 @@ export default {
form.docEngineer2Name = this.getRoleDisplayName(form.docEngineer2)
form.ipqcHardTagName = this.getRoleDisplayName(form.ipqcHardTag)
form.cQualityEngineer7Name = this.getRoleDisplayName(form.cQualityEngineer7)
+ if (!this.isRfidBuNo(form.buNo)) {
+ form.dry_wet_type = ''
+ }
return form
},
openOneKeyDialog (mode, row) {
@@ -4013,9 +4108,14 @@ export default {
this.oneKeyProjectNoSnapshot = ''
this.oneKeyProjectRoleBaseline = {}
this.oneKeyForm = this.getEmptyOneKeyForm()
- if (this.userBuList.length > 0) {
+ const selectedSearchBuNo = this.getSelectedSearchBuNo()
+ if (selectedSearchBuNo) {
+ // 一键创建默认沿用查询区 BU,避免用户重复选择。
+ this.oneKeyForm.buNo = this.getBuOptionValue(this.searchData.site, selectedSearchBuNo)
+ } else if (this.userBuList.length > 0) {
this.oneKeyForm.buNo = this.userBuList[0].buNo || ''
}
+ this.handleOneKeyBuChange()
this.oneKeyDialogVisible = true
return
}
@@ -4174,7 +4274,7 @@ export default {
this.proofDialogVisible = true
this.loadProofDialogApplyOptions(this.proofDialogData.projectNo)
},
- validateSyncToNpiRow (row) {
+ collectSyncToNpiMissingLabels (row) {
const projectPartId = this.getTrackingProjectPartId(row)
const missingLabels = []
if (this.isBlankValue(row && row.site)) {
@@ -4201,37 +4301,49 @@ export default {
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
+ return missingLabels
+ },
+ getSelectedRowsForBatchSync (actionLabel) {
+ const rows = this.selectionRows && this.selectionRows.length > 0 ? this.selectionRows : []
+ if (rows.length === 0) {
+ this.$message.warning(`请先勾选需要${actionLabel}的记录`)
}
+ return rows
},
- syncToNpi (row) {
- const current = this.getActionRow(row)
- if (!current) {
- this.$message.warning('请先选择一条记录')
+ syncBatchProjectPartToNpi () {
+ const selectedRows = this.getSelectedRowsForBatchSync('同步项目物料到NPI')
+ if (selectedRows.length === 0) {
return
}
- const syncCheck = this.validateSyncToNpiRow(current)
- if (!syncCheck.passed) {
+ const idMap = {}
+ const projectPartIds = []
+ const invalidRows = []
+ selectedRows.forEach(row => {
+ const projectPartId = this.getTrackingProjectPartId(row)
+ const missingLabels = this.collectSyncToNpiMissingLabels(row)
+ if (!projectPartId || missingLabels.length > 0) {
+ invalidRows.push({
+ projectNo: row && row.projectNo ? row.projectNo : '-',
+ testPartNo: row && row.testPartNo ? row.testPartNo : '-',
+ missingLabels: missingLabels.length > 0 ? missingLabels : ['项目物料ID']
+ })
+ return
+ }
+ const idKey = String(projectPartId)
+ if (idMap[idKey]) {
+ return
+ }
+ idMap[idKey] = true
+ projectPartIds.push(projectPartId)
+ })
+ if (projectPartIds.length === 0) {
+ this.$message.warning('勾选记录未包含可同步的项目物料')
return
}
- const projectPartId = syncCheck.projectPartId
- this.currentRow = current
- const projectNo = current.projectNo || '-'
- const testPartNo = current.testPartNo || '-'
- const confirmMsg = `确认将项目编码[${projectNo}]物料编码[${testPartNo}]同步到NPI吗?`
+ const invalidHint = invalidRows.length > 0
+ ? `
其中${invalidRows.length}条记录不满足同步条件,已自动跳过`
+ : ''
+ const confirmMsg = `确认批量同步项目物料到NPI吗?
已勾选${selectedRows.length}条,可同步${projectPartIds.length}条${invalidHint}`
this.$confirm(confirmMsg, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
@@ -4239,18 +4351,19 @@ export default {
dangerouslyUseHTMLString: true
}).then(() => {
const operator = this.$store.state.user.name
- this.syncNpiLoading = true
- syncProjectPartTracking({
- projectPartId: projectPartId,
+ this.syncBatchNpiLoading = true
+ batchSyncProjectPartTracking({
+ projectPartIds: projectPartIds,
updateBy: operator,
createBy: operator,
userName: operator
}).then(({ data }) => {
if (data && data.code === 0) {
- this.$message.success(`同步成功`)
+ const syncedCount = data.syncedCount || projectPartIds.length
+ this.$message.success(`批量同步成功,共${syncedCount}条项目物料`)
this.getDataList()
} else {
- const failMsg = (data && data.msg) || '同步到NPI失败'
+ const failMsg = (data && data.msg) || '批量同步项目物料到NPI失败'
if (failMsg.indexOf('缺少以下必填项') > -1) {
this.$alert(failMsg, '同步校验未通过', {
confirmButtonText: '确定'
@@ -4260,24 +4373,45 @@ export default {
}
}
}).catch(() => {
- this.$message.error('同步到NPI异常')
+ this.$message.error('批量同步项目物料到NPI异常')
}).finally(() => {
- this.syncNpiLoading = false
+ this.syncBatchNpiLoading = false
})
- })
- .catch(() => {})
+ }).catch(() => {})
},
- syncProofToNpi (row) {
- const current = this.getActionRow(row)
- if (!current || !current.trackingId) {
- this.$message.warning('请先选择一条打样记录')
+ syncBatchProofToNpi () {
+ const selectedRows = this.getSelectedRowsForBatchSync('同步打样到NPI')
+ if (selectedRows.length === 0) {
return
}
- this.currentRow = current
- const projectNo = current.projectNo || '-'
- const testPartNo = current.testPartNo || '-'
- const proofingNo = current.proofingNo || '-'
- const confirmMsg = `确认将当前打样记录同步到NPI吗?
项目编码:${projectNo}
物料编码:${testPartNo}
打样单号:${proofingNo}`
+ const idMap = {}
+ const trackingIds = []
+ const invalidRows = []
+ selectedRows.forEach(row => {
+ const trackingId = row && row.trackingId
+ if (!trackingId) {
+ invalidRows.push({
+ projectNo: row && row.projectNo ? row.projectNo : '-',
+ testPartNo: row && row.testPartNo ? row.testPartNo : '-',
+ proofingNo: row && row.proofingNo ? row.proofingNo : '-'
+ })
+ return
+ }
+ const idKey = String(trackingId)
+ if (idMap[idKey]) {
+ return
+ }
+ idMap[idKey] = true
+ trackingIds.push(trackingId)
+ })
+ if (trackingIds.length === 0) {
+ this.$message.warning('勾选记录未包含可同步的打样单')
+ return
+ }
+ const invalidHint = invalidRows.length > 0
+ ? `
其中${invalidRows.length}条记录缺少打样ID,已自动跳过`
+ : ''
+ const confirmMsg = `确认批量同步打样到NPI吗?
已勾选${selectedRows.length}条,可同步${trackingIds.length}条${invalidHint}`
this.$confirm(confirmMsg, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
@@ -4285,18 +4419,19 @@ export default {
dangerouslyUseHTMLString: true
}).then(() => {
const operator = this.$store.state.user.name
- this.syncProofLoading = true
- syncProofTracking({
- trackingId: current.trackingId,
+ this.syncBatchProofLoading = true
+ batchSyncProofTracking({
+ trackingIds: trackingIds,
updateBy: operator,
createBy: operator,
userName: operator
}).then(({ data }) => {
if (data && data.code === 0) {
- this.$message.success('打样同步成功')
+ const syncedCount = data.syncedCount || trackingIds.length
+ this.$message.success(`批量同步成功,共${syncedCount}条打样记录`)
this.getDataList()
} else {
- const failMsg = (data && data.msg) || '同步打样到NPI失败'
+ const failMsg = (data && data.msg) || '批量同步打样到NPI失败'
if (failMsg.indexOf('缺少以下必填项') > -1 || failMsg.indexOf('请先同步项目') > -1 || failMsg.indexOf('请先同步项目物料') > -1) {
this.$alert(failMsg, '同步校验未通过', {
confirmButtonText: '确定'
@@ -4306,9 +4441,9 @@ export default {
}
}
}).catch(() => {
- this.$message.error('同步打样到NPI异常')
+ this.$message.error('批量同步打样到NPI异常')
}).finally(() => {
- this.syncProofLoading = false
+ this.syncBatchProofLoading = false
})
}).catch(() => {})
},
@@ -4560,6 +4695,8 @@ export default {
if (!silentSuccess) {
this.$message.success(successMsg || '工序更新成功')
}
+ // 按业务要求:工序日期或状态变更后回查列表,保证动态列/派生字段展示最新值。
+ this.getDataList()
} else {
this.$message.error(data.msg || '工序更新失败')
this.getDataList()