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,