From 22d0dc351050f10aec5a026c37eeb40f586fda79 Mon Sep 17 00:00:00 2001 From: "han\\hanst" Date: Fri, 28 Nov 2025 15:37:58 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AE=A1=E7=AE=97=E5=85=AC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/modules/part/routing_create.vue | 220 +++++++++++++++------- 1 file changed, 149 insertions(+), 71 deletions(-) diff --git a/src/views/modules/part/routing_create.vue b/src/views/modules/part/routing_create.vue index 2cc1516..35e78bd 100644 --- a/src/views/modules/part/routing_create.vue +++ b/src/views/modules/part/routing_create.vue @@ -410,6 +410,20 @@ export default { item.formula = this.getFormula(item) }) } + }, + 'partItemsMap': { + deep: true, + handler: function (newV, oldV) { + // 当物料属性加载完成后,重新计算所有工序的公式 + if (newV && Object.keys(newV).length > 0 && this.subDetailList && this.subDetailList.length > 0) { + console.log('🔄 物料属性已更新,重新计算所有工序公式') + this.subDetailList.forEach(item => { + item.formula = this.getFormula(item) + }) + // 强制更新视图 + this.$forceUpdate() + } + } } }, name: 'routingCreate', @@ -1844,25 +1858,44 @@ export default { printUnitName: row.printUnitName, alternativeNo: row.alternativeNo, } - // 获取物料属性信息 - this.loadPartItems(row.site, row.buNo, row.partNo, row.codeNo) - - // 查routing明细 - queryRoutingDetail(this.modalData).then(({data}) => { - if (data && data.code === 0) { - this.detailDataList = data.rows.detailList - this.subDetailList = data.rows.componentList - this.detailData = data.rows.detailData - this.detailTable = 'routing_detail' - this.modalDisableFlag = true - } else { - this.$alert(data.msg, '错误', { - confirmButtonText: '确定' - }) - } - this.$emit('refreshRoutingLoading') + + // 先获取物料属性信息,等待加载完成后再查询routing明细 + this.loadPartItems(row.site, row.buNo, row.partNo, row.codeNo).then(() => { + // 物料属性加载完成,现在查询routing明细 + queryRoutingDetail(this.modalData).then(({data}) => { + if (data && data.code === 0) { + this.detailDataList = data.rows.detailList + this.subDetailList = data.rows.componentList + this.detailData = data.rows.detailData + this.detailTable = 'routing_detail' + this.modalDisableFlag = true + } else { + this.$alert(data.msg, '错误', { + confirmButtonText: '确定' + }) + } + this.$emit('refreshRoutingLoading') + }).catch(() => { + this.$emit('refreshRoutingLoading') + }) }).catch(() => { - this.$emit('refreshRoutingLoading') + // 即使物料属性加载失败,也继续查询routing明细 + queryRoutingDetail(this.modalData).then(({data}) => { + if (data && data.code === 0) { + this.detailDataList = data.rows.detailList + this.subDetailList = data.rows.componentList + this.detailData = data.rows.detailData + this.detailTable = 'routing_detail' + this.modalDisableFlag = true + } else { + this.$alert(data.msg, '错误', { + confirmButtonText: '确定' + }) + } + this.$emit('refreshRoutingLoading') + }).catch(() => { + this.$emit('refreshRoutingLoading') + }) }) }, @@ -2697,6 +2730,7 @@ export default { /** * 加载物料属性信息 + * @returns {Promise} 返回Promise以支持async/await */ loadPartItems(site, buNo, partNo, codeNo) { const tempData = { @@ -2706,20 +2740,59 @@ export default { codeNo: codeNo, recordType: 'IP' } - getPartItem(tempData).then(({data}) => { + + return getPartItem(tempData).then(({data}) => { if (data && data.code === 0 && data.rows.length > 0) { // 将物料属性转换为 Map 方便查询 const itemsMap = {} data.rows.forEach(item => { - const key = item.itemDesc + // 标准化键名:去除前后空格 + const key = (item.itemDesc || '').trim() const value = item.numValue != null ? item.numValue : item.textValue - itemsMap[key] = value + if (key) { + itemsMap[key] = value + } }) this.partItemsMap = itemsMap + console.log('✅ 物料属性加载完成,属性数量:', Object.keys(itemsMap).length, ',属性列表:', Object.keys(itemsMap).join(', ')) + } else { + console.warn('⚠️ 物料属性加载失败或无数据') + this.partItemsMap = {} } + }).catch(error => { + console.error('❌ 物料属性加载异常:', error) + this.partItemsMap = {} + throw error }) }, + /** + * 安全获取物料属性值(支持模糊匹配) + * @param {String} keyName - 属性名称 + * @returns {*} 属性值,未找到返回 null + */ + getPartItemValue(keyName) { + if (!this.partItemsMap || !keyName) return null + + // 1. 精确匹配(去除空格) + const trimmedKey = keyName.trim() + if (this.partItemsMap[trimmedKey] != null) { + return this.partItemsMap[trimmedKey] + } + + // 2. 查找所有键,忽略前后空格进行匹配 + const keys = Object.keys(this.partItemsMap) + for (let key of keys) { + if (key.trim() === trimmedKey) { + return this.partItemsMap[key] + } + } + + // 3. 未找到,打印日志便于调试 + console.warn(`⚠️ 未找到物料属性: "${keyName}", 可用属性:`, keys) + return null + }, + getFormula(item) { if (!item) return '' @@ -2754,6 +2827,57 @@ export default { let formula = '' let calculation = '' + // 包含匹配逻辑:工序名包含关键词即可触发(优先判断) + if (operationName && operationName.includes('RFID复合模切检测')) { + formula = '人数/(速度×时间×效率×(CD×复合列数))×1KCT' + if (refSpeed && refTime && refEfficiency) { + const pitchValue = this.getPartItemValue('CL60k-Pitch') + const cd = pitchValue ? (1000 / pitchValue) : null + const compoundLanes = this.getPartItemValue('复合列数') + if (cd && compoundLanes) { + calculation = ` = ${formatNum(crewSize)}/(${formatNum(refSpeed)}×${formatNum(refTime)}×${formatNum(refEfficiency)}×(${formatNum(cd)}×${formatNum(compoundLanes)}))×1000` + } else { + calculation = ` = ${formatNum(crewSize)}/(${formatNum(refSpeed)}×${formatNum(refTime)}×${formatNum(refEfficiency)}×(CD×复合列数))×1000` + } + } + return formula + calculation + } else if (operationName && operationName.includes('后道检品')) { + formula = '人数/UPH(每小时产量)×100%×1KCT' + const uph = this.getPartItemValue('UPH-TAL') + if (uph) { + calculation = ` = ${formatNum(crewSize)}/${formatNum(uph)}×1×1000` + } else { + calculation = ` = ${formatNum(crewSize)}/UPH-TAL×1×1000` + } + return formula + calculation + } else if (operationName && operationName.includes('RFID自动贴标')) { + formula = '人数/(速度×时间×效率×(CD×贴标列数))×1KCT' + if (refSpeed && refTime && refEfficiency) { + const pitchValue = this.getPartItemValue('CL60k-Pitch') + const cd = pitchValue ? (1000 / pitchValue) : null + const labelingLanes = this.getPartItemValue('贴标列数') + if (cd && labelingLanes) { + calculation = ` = ${formatNum(crewSize)}/(${formatNum(refSpeed)}×${formatNum(refTime)}×${formatNum(refEfficiency)}×(${formatNum(cd)}×${formatNum(labelingLanes)}))×1000` + } else { + calculation = ` = ${formatNum(crewSize)}/(${formatNum(refSpeed)}×${formatNum(refTime)}×${formatNum(refEfficiency)}×(CD×贴标列数))×1000` + } + } + return formula + calculation + } else if (operationName && operationName.includes('Voyantic在线检测')) { + formula = '人数/(速度×时间×效率×(CD×检测列数))×1KCT' + if (refSpeed && refTime && refEfficiency) { + const pitchValue = this.getPartItemValue('CL60k-Pitch') + const cd = pitchValue ? (1000 / pitchValue) : null + const detectionLanes = this.getPartItemValue('检测列数') + if (cd && detectionLanes) { + calculation = ` = ${formatNum(crewSize)}/(${formatNum(refSpeed)}×${formatNum(refTime)}×${formatNum(refEfficiency)}×(${formatNum(cd)}×${formatNum(detectionLanes)}))×1000` + } else { + calculation = ` = ${formatNum(crewSize)}/(${formatNum(refSpeed)}×${formatNum(refTime)}×${formatNum(refEfficiency)}×(CD×检测列数))×1000` + } + } + return formula + calculation + } + switch (operationName) { case '一复': case '熟化': case 'RFID前道检品': formula = '人数/(速度×时间×效率)' @@ -2765,7 +2889,7 @@ export default { case '印刷': case 'RFID-蚀刻': case 'RFID-分切': formula = '人数/(速度×时间×效率)/Printing lanes' if (refSpeed && refTime && refEfficiency) { - const printingLanes = this.partItemsMap['Printing lanes'] || null + const printingLanes = this.getPartItemValue('Printing lanes') if (printingLanes) { calculation = ` = ${formatNum(crewSize)}/(${formatNum(refSpeed)}×${formatNum(refTime)}×${formatNum(refEfficiency)})/${formatNum(printingLanes)}` } else { @@ -2773,10 +2897,10 @@ export default { } } break - case 'RFID绑定-TAL': case'RFID绑定-Paris': case'RFID绑定-MLI':case 'RFID编码': case 'RFID编码打印': + case 'RFID绑定-TAL': case'RFID绑定-Paris': case'RFID绑定-MLI':case 'RFID编码':case 'Encoding(编码)': case 'RFID编码打印':case 'CLS编码打印': formula = '人数/(UPH(每小时产量)×效率)×1KCT' if (refEfficiency) { - const uph = this.partItemsMap['UPH-TAL'] || null + const uph = this.getPartItemValue('UPH-TAL') if (uph) { const result = crewSize / (uph * refEfficiency) * 1000 calculation = ` = ${formatNum(crewSize)}/(${formatNum(uph)}×${formatNum(refEfficiency)})×1000` @@ -2788,7 +2912,7 @@ export default { case 'RFID多条检测': formula = '人数/(速度×时间×CD×效率)×1KCT' if (refSpeed && refTime && refEfficiency) { - const cd = this.partItemsMap['CL60k-CD'] || null + const cd = this.getPartItemValue('CL60k-CD') if (cd) { calculation = ` = ${formatNum(crewSize)}/(${formatNum(refSpeed)}×${formatNum(refTime)}×${formatNum(cd)}×${formatNum(refEfficiency)})×1000` } else { @@ -2796,52 +2920,6 @@ export default { } } break - case 'RFID复合模切检测': - formula = '人数/(速度×时间×效率×(CD×复合列数))×1KCT' - if (refSpeed && refTime && refEfficiency) { - const cd = this.partItemsMap['CL60k-CD'] || null - const compoundLanes = this.partItemsMap['复合列数'] || null - if (cd && compoundLanes) { - calculation = ` = ${formatNum(crewSize)}/(${formatNum(refSpeed)}×${formatNum(refTime)}×${formatNum(refEfficiency)}×(${formatNum(cd)}×${formatNum(compoundLanes)}))×1000` - } else { - calculation = ` = ${formatNum(crewSize)}/(${formatNum(refSpeed)}×${formatNum(refTime)}×${formatNum(refEfficiency)}×(CD×复合列数))×1000` - } - } - break - case 'RFID后道检品': - formula = '人数/UPH(每小时产量)×100%×1KCT' - const uph = this.partItemsMap['UPH-TAL'] || null - if (uph) { - const result = crewSize / uph * 1 * 1000 - calculation = ` = ${formatNum(crewSize)}/${formatNum(uph)}×1×1000` - } else { - calculation = ` = ${formatNum(crewSize)}/UPH-TAL×1×1000` - } - break - case 'RFID自动贴标': - formula = '人数/(速度×时间×效率×(CD×贴标列数))×1KCT' - if (refSpeed && refTime && refEfficiency) { - const cd = this.partItemsMap['CL60k-CD'] || null - const labelingLanes = this.partItemsMap['贴标列数'] || null - if (cd && labelingLanes) { - calculation = ` = ${formatNum(crewSize)}/(${formatNum(refSpeed)}×${formatNum(refTime)}×${formatNum(refEfficiency)}×(${formatNum(cd)}×${formatNum(labelingLanes)}))×1000` - } else { - calculation = ` = ${formatNum(crewSize)}/(${formatNum(refSpeed)}×${formatNum(refTime)}×${formatNum(refEfficiency)}×(CD×贴标列数))×1000` - } - } - break - case 'Voyantic在线检测': - formula = '人数/(速度×时间×效率×(CD×检测列数))×1KCT' - if (refSpeed && refTime && refEfficiency) { - const cd = this.partItemsMap['CL60k-CD'] || null - const detectionLanes = this.partItemsMap['检测列数'] || null - if (cd && detectionLanes) { - calculation = ` = ${formatNum(crewSize)}/(${formatNum(refSpeed)}×${formatNum(refTime)}×${formatNum(refEfficiency)}×(${formatNum(cd)}×${formatNum(detectionLanes)}))×1000` - } else { - calculation = ` = ${formatNum(crewSize)}/(${formatNum(refSpeed)}×${formatNum(refTime)}×${formatNum(refEfficiency)}×(CD×检测列数))×1000` - } - } - break case 'Packaging': formula = '人数/(日产量/8小时/17人均摊)×1KCT' const dailyOutput = 10000000