diff --git a/src/views/modules/ecss/codelnotifyConfirm.vue b/src/views/modules/ecss/codelnotifyConfirm.vue index 9deda99..4fdd2a5 100644 --- a/src/views/modules/ecss/codelnotifyConfirm.vue +++ b/src/views/modules/ecss/codelnotifyConfirm.vue @@ -3399,7 +3399,7 @@ rolls = Math.round(detailRolls) } - // 2. 根据数量计算箱数 + // 2. 根据数量计算箱数(向上取整,不允许小数箱) if (rollQty > 0 && boxRolls > 0) { const eaPerBox = rollQty * boxRolls box_qty = Math.ceil(unpackedQty / eaPerBox) @@ -3644,7 +3644,7 @@ // 计算总rolls(初始时每箱只有一条明细) rolls = Math.round(detailRolls) - // 计算箱数 + // 计算箱数(向上取整,不允许小数箱) if (rollQty > 0 && boxRolls > 0) { const eaPerBox = rollQty * boxRolls box_qty = Math.ceil(qty / eaPerBox) @@ -3844,7 +3844,8 @@ try { const boxKey = row._boxKey; - const newBoxQty = parseFloat(row.box_qty) || 0; + const newBoxQty = Math.ceil(parseFloat(row.box_qty) || 0); + row.box_qty = newBoxQty; // 先从原始数据获取,如果没有则从row缓存获取 let boxWeight = 0; @@ -3864,7 +3865,7 @@ // 同步更新所有同Box的行 this.mergeBoxTableData.forEach(r => { if (r._boxKey === boxKey) { - r.box_qty = row.box_qty; + r.box_qty = newBoxQty; r.grossWeight = row.grossWeight; r.netWeight = row.netWeight; } @@ -4074,6 +4075,48 @@ } }, + /** + * 获取非整箱箱数据(按明细数量与每箱EA关系判断) + */ + getNonWholeBoxDetails() { + const nonWholeBoxMap = new Map() + const checkedDetailKeys = new Set() + + this.mergeBoxTableData.forEach(row => { + if (!row._hasDetail || !row._detailKey || checkedDetailKeys.has(row._detailKey)) { + return + } + checkedDetailKeys.add(row._detailKey) + + const qty = Number(row.qty) + const rollQty = Number(row.rollQtyCache) + const boxRolls = Number(row.boxRollsCache) + if (!(qty > 0) || !(rollQty > 0) || !(boxRolls > 0)) { + return + } + + const eaPerBox = rollQty * boxRolls + if (!(eaPerBox > 0)) { + return + } + + const boxRatio = qty / eaPerBox + const isWholeBox = Math.abs(boxRatio - Math.round(boxRatio)) < 0.000001 + if (!isWholeBox) { + const boxKey = row._boxKey || `${row.item_no}_${row.pn || row._detailKey}` + if (!nonWholeBoxMap.has(boxKey)) { + nonWholeBoxMap.set(boxKey, { + itemNo: row.item_no, + pn: row.pn, + boxQty: parseFloat(boxRatio.toFixed(4)) + }) + } + } + }) + + return Array.from(nonWholeBoxMap.values()) + }, + /** * 保存合箱批量编辑 */ @@ -4091,7 +4134,7 @@ if (!boxMap.has(boxKey)) { boxMap.set(boxKey, { item_no: row.item_no, - box_qty: row.box_qty, + box_qty: Math.ceil(Number(row.box_qty) || 0), grossWeight: row.grossWeight, netWeight: row.netWeight, rolls: row.rolls, @@ -4121,6 +4164,37 @@ return } + const nonWholeDetails = this.getNonWholeBoxDetails() + if (nonWholeDetails.length > 0) { + const escapeHtml = (value) => String(value) + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, ''') + + const previewLines = nonWholeDetails + .map(detail => `箱${escapeHtml(detail.itemNo)} / PN:${escapeHtml(detail.pn || '-')} / 箱数:${escapeHtml(detail.boxQty)}`) + .join('
') + const confirmMessage = `检测到 ${nonWholeDetails.length} 条非整箱数据:
${previewLines}
请确认是否继续装箱。` + + try { + await this.$confirm( + confirmMessage, + '非整箱确认', + { + confirmButtonText: '确认继续', + cancelButtonText: '取消', + type: 'warning', + dangerouslyUseHTMLString: true + } + ) + } catch (confirmError) { + this.$message.warning('已取消保存') + return + } + } + const mergeData = { site: this.currentRow.site, buNo: this.currentRow.buNo,