diff --git a/src/api/ecss/ecss.js b/src/api/ecss/ecss.js index 99df3ff..8977c7d 100644 --- a/src/api/ecss/ecss.js +++ b/src/api/ecss/ecss.js @@ -141,5 +141,8 @@ export const updateCodelPalletHeaderPalletQty = data => createAPI(`/ecss/coDel/u // PDF导出接口 export const downloadAllPdf = data => createAPI(`/ecss/coDel/downloadAllPdf`,'post',data) +// 获取物料包装属性(每卷数量、每箱卷数、箱重量) +export const getPartPackageProperties = data => createAPI(`/ecss/coDel/getPartPackageProperties`,'post',data) + diff --git a/src/views/modules/ecss/codelnotifyConfirm.vue b/src/views/modules/ecss/codelnotifyConfirm.vue index 59eff95..0e5ed5f 100644 --- a/src/views/modules/ecss/codelnotifyConfirm.vue +++ b/src/views/modules/ecss/codelnotifyConfirm.vue @@ -343,18 +343,18 @@ - - + + - - + + - - + + @@ -380,12 +380,12 @@ @@ -627,7 +627,8 @@ getNotifyPartDetail, searchPalletList, updateExportFlag, - updateCodelPalletHeaderPalletQty + updateCodelPalletHeaderPalletQty, + getPartPackageProperties }from "@/api/ecss/ecss.js" import {getBuList}from '@/api/factory/site.js' import excel from "@/utils/excel-util.js"; @@ -2322,6 +2323,231 @@ }, fillUseQty(row) { row.useQty = row.surplusQty || 0; + // 全数装箱后也需要计算rolls + this.calculateRolls(row); + }, + /** + * 根据装箱数量自动计算Rolls(卷数) + * 计算公式:Rolls = 装箱数量 / 每卷数量 + * @param row 当前行数据 + */ + calculateRolls(row) { + // 如果装箱数量为空或为0,清空rolls + if (!row.useQty || row.useQty <= 0) { + this.$set(row, 'rolls', null); + // 装箱数量变化后,重新计算总箱数和重量 + this.calculateTotalBoxQtyAndWeights(); + return; + } + + // 如果已经有缓存的每卷数量,直接计算 + if (row.rollQtyCache && row.rollQtyCache > 0) { + const rolls = row.useQty / row.rollQtyCache; + this.$set(row, 'rolls', parseFloat(rolls.toFixed(4))); + // 装箱数量变化后,重新计算总箱数和重量 + this.calculateTotalBoxQtyAndWeights(); + return; + } + + // 调用后端API获取每卷数量 + const params = { + site: this.currentRow.site, + buNo: this.currentRow.buNo, + partNo: row.partNo + }; + + getPartPackageProperties(params).then(({data}) => { + if (data && data.code === 0 && data.data) { + const rollQty = data.data.rollQty; + + if (rollQty && rollQty > 0) { + // 缓存每卷数量到row中,避免重复请求 + this.$set(row, 'rollQtyCache', rollQty); + this.$set(row, 'boxRollsCache', data.data.boxRolls); + this.$set(row, 'boxWeightCache', data.data.boxWeight); + + // 计算rolls:装箱数量 / 每卷数量 + const rolls = row.useQty / rollQty; + this.$set(row, 'rolls', parseFloat(rolls.toFixed(4))); + + // 装箱数量变化后,重新计算总箱数和重量 + this.calculateTotalBoxQtyAndWeights(); + } else { + this.$message.warning(`物料 ${row.partNo} 未配置每卷数量(ROLLQTY)属性,无法自动计算Rolls`); + this.$set(row, 'rolls', null); + } + } else { + console.error('获取物料包装属性失败:', data ? data.msg : '未知错误'); + // 失败时不阻断用户操作,允许手动输入 + this.$set(row, 'rolls', null); + } + }).catch(error => { + console.error('获取物料包装属性异常:', error); + // 异常时不阻断用户操作,允许手动输入 + this.$set(row, 'rolls', null); + }); + }, + /** + * 根据物料装箱数量自动计算总箱数、毛重和净重 + */ + calculateTotalBoxQtyAndWeights() { + // 获取有装箱数量的物料列表 + const selectedRows = this.dataList8.filter(item => item.useQty && item.useQty > 0); + + if (selectedRows.length === 0) { + // 没有装箱数量时,清空 + this.palletModelData.boxQty = null; + this.palletModelData.grossWeight = null; + this.palletModelData.netWeight = null; + return; + } + + // 检查是否所有物料都已缓存包装属性 + const allHaveCache = selectedRows.every(row => + row.rollQtyCache && row.boxRollsCache && row.boxWeightCache + ); + + if (!allHaveCache) { + // 如果有物料未缓存属性,不自动计算(避免数据不完整) + return; + } + + // 计算总箱数和总重量 + let totalBoxQty = 0; + let totalGrossWeight = 0; + + selectedRows.forEach(row => { + // 每箱EA = 每卷数量 × 每箱卷数 + const eaPerBox = row.rollQtyCache * row.boxRollsCache; + // 该物料的箱数(向上取整) + const partBoxQty = Math.ceil(row.useQty / eaPerBox); + // 该物料的毛重 = 箱数 × 箱重量 + const partGrossWeight = partBoxQty * row.boxWeightCache; + + totalBoxQty += partBoxQty; + totalGrossWeight += partGrossWeight; + }); + + // 净重 = 毛重 - (箱数 / 2) + const totalNetWeight = totalGrossWeight - (totalBoxQty / 2); + + // 自动填入箱数、毛重、净重 + this.palletModelData.boxQty = totalBoxQty; + this.palletModelData.grossWeight = parseFloat(totalGrossWeight.toFixed(2)); + this.palletModelData.netWeight = parseFloat(totalNetWeight.toFixed(2)); + }, + /** + * 根据箱数自动计算毛重和净重 + * 计算公式(来自后端代码2991-2992行): + * 毛重 = 箱数 × 箱重量 + * 净重 = 毛重 - (箱数 / 2) + */ + calculateWeightsByBoxQty() { + // 如果箱数为空或为0,清空毛重和净重 + if (!this.palletModelData.boxQty || this.palletModelData.boxQty <= 0) { + this.palletModelData.grossWeight = null; + this.palletModelData.netWeight = null; + return; + } + + // 获取有装箱数量的物料列表 + const selectedRows = this.dataList8.filter(item => item.useQty && item.useQty > 0); + + if (selectedRows.length === 0) { + // 没有选择物料时,不自动计算,允许用户手动输入 + return; + } + + // 检查是否所有物料都已缓存箱重量 + const needFetchProperties = selectedRows.filter(row => !row.boxWeightCache); + + if (needFetchProperties.length === 0) { + // 所有物料都有缓存,直接计算 + this.calculateWeightsWithCache(selectedRows); + } else { + // 需要获取部分物料的属性 + this.fetchBoxWeightsAndCalculate(selectedRows, needFetchProperties); + } + }, + /** + * 使用缓存的箱重量计算毛重和净重 + */ + calculateWeightsWithCache(selectedRows) { + // 根据装箱数量计算加权平均箱重量 + let totalWeight = 0; + let totalQty = 0; + + selectedRows.forEach(row => { + if (row.boxWeightCache && row.boxWeightCache > 0 && row.rollQtyCache && row.rollQtyCache > 0 && row.boxRollsCache && row.boxRollsCache > 0) { + // 每箱EA = 每卷数量 × 每箱卷数 + const eaPerBox = row.rollQtyCache * row.boxRollsCache; + // 该物料的箱数 + const partBoxQty = Math.ceil(row.useQty / eaPerBox); + // 累计重量和箱数 + totalWeight += partBoxQty * row.boxWeightCache; + totalQty += partBoxQty; + } + }); + + if (totalQty > 0) { + // 计算平均箱重量 + const avgBoxWeight = totalWeight / totalQty; + this.calculateFinalWeights(avgBoxWeight); + } else { + // 如果无法计算平均重量,使用第一个物料的箱重量 + const firstRow = selectedRows.find(row => row.boxWeightCache && row.boxWeightCache > 0); + if (firstRow) { + this.calculateFinalWeights(firstRow.boxWeightCache); + } + } + }, + /** + * 获取物料箱重量并计算毛重净重 + */ + fetchBoxWeightsAndCalculate(selectedRows, needFetchProperties) { + // 批量获取物料属性 + const promises = needFetchProperties.map(row => { + const params = { + site: this.currentRow.site, + buNo: this.currentRow.buNo, + partNo: row.partNo + }; + return getPartPackageProperties(params).then(({data}) => { + if (data && data.code === 0 && data.data) { + // 缓存物料属性 + this.$set(row, 'rollQtyCache', data.data.rollQty); + this.$set(row, 'boxRollsCache', data.data.boxRolls); + this.$set(row, 'boxWeightCache', data.data.boxWeight); + return true; + } + return false; + }).catch(error => { + console.error(`获取物料 ${row.partNo} 属性失败:`, error); + return false; + }); + }); + + Promise.all(promises).then(() => { + // 所有属性获取完成后,重新计算 + this.calculateWeightsWithCache(selectedRows); + }); + }, + /** + * 计算最终的毛重和净重 + * @param avgBoxWeight 平均箱重量 + */ + calculateFinalWeights(avgBoxWeight) { + const boxQty = parseFloat(this.palletModelData.boxQty); + + // 毛重 = 箱数 × 箱重量 + const grossWeight = boxQty * avgBoxWeight; + + // 净重 = 毛重 - (箱数 / 2) + const netWeight = grossWeight - (boxQty / 2); + + // 保留2位小数 + this.palletModelData.grossWeight = parseFloat(grossWeight.toFixed(2)); + this.palletModelData.netWeight = parseFloat(netWeight.toFixed(2)); }, savePalletHeader(type) { // 过滤出 useQty > 0 的行 @@ -2810,7 +3036,7 @@ .warning-row td{ color: darkred !important; } -/deep/ .zxClass .cell { + .zxClass .cell { line-height: 24px; font-size: 12px; height: 24px;