From 1c5e60692dd656863e7d7e050944ff6a75bb376b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B8=B8=E7=86=9F=E5=90=B4=E5=BD=A6=E7=A5=96?= Date: Thu, 10 Sep 2026 18:01:23 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=86=E6=8B=A3bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/haianAutoWarehouse/palletPacking.js | 3 + .../haianAutoWarehouse/haianPalletSorting.vue | 288 +++++++++++++++++- 2 files changed, 286 insertions(+), 5 deletions(-) diff --git a/src/api/haianAutoWarehouse/palletPacking.js b/src/api/haianAutoWarehouse/palletPacking.js index 2e9b61d..756e601 100644 --- a/src/api/haianAutoWarehouse/palletPacking.js +++ b/src/api/haianAutoWarehouse/palletPacking.js @@ -51,6 +51,9 @@ export const callPalletToStationWithUpdateZuPan = data => createAPI(`/haiAnWcsIn // 海安-调用空托盘 - rqrq export const callEmptyPalletToStation = data => createAPI(`/haiAnWcsIntegration/callEmptyPalletToStation`, 'post', data) +// 海安手工分拣拆分特例:复用老PDA标签拆分接口,新标签由后端去掉预留,原标签数量回写栈板明细 - rqrq +export const splitLabel = data => createAPI(`/pda/label/split`, 'post', data) + // 海安-结束分拣 - rqrq export const finishSorting = data => createAPI(`/haiAnWcsIntegration/finishSorting`, 'post', data) diff --git a/src/views/modules/haianAutoWarehouse/haianPalletSorting.vue b/src/views/modules/haianAutoWarehouse/haianPalletSorting.vue index f5e6f9b..31d9fcb 100644 --- a/src/views/modules/haianAutoWarehouse/haianPalletSorting.vue +++ b/src/views/modules/haianAutoWarehouse/haianPalletSorting.vue @@ -146,11 +146,21 @@
位置
层数
标签号
+
操作
-
+
{{ item.position }}
{{ item.layer }}
{{ item.serialNo }}
+
+ +
暂无分拣明细数据
@@ -174,11 +184,21 @@
位置
层数
标签号
+
操作
-
+
{{ item.position }}
{{ item.layer }}
{{ item.serialNo }}
+
+ +
暂无分拣明细数据
@@ -190,6 +210,56 @@
+ + +
+
+ 原标签编码: + {{ splitRow ? splitRow.serialNo : '' }} +
+
+ 当前数量: + {{ splitRow ? formatQty(splitRow.qty) : 0 }} +
+
+ + +
+ + 拆分数量必须大于0且小于当前数量 +
+
+
+ 拆分后原标签剩余: + {{ calculateRemainQty }} +
+
+ +
+ ({ ...p, isPlaceholder: false })) }, + // 仅手工分拣工作盘显示拆分列;被分拣源盘 sortedSourceFlag=true 时隐藏 - rqrq + showSplitAction() { + return this.palletScanned && !this.sortedSourceFlag + }, + // 拆分数量合法:大于0且小于原标签当前数量 - rqrq + isValidSplitQty() { + if (!this.splitQty || !this.splitRow) { + return false + } + const split = Number(this.splitQty) + const current = Number(this.splitRow.qty) || 0 + return split > 0 && split < current + }, + // 拆分后原标签剩余量,非法输入时回0 - rqrq + calculateRemainQty() { + if (!this.splitRow || !this.splitQty) { + return this.splitRow ? this.formatQty(this.splitRow.qty) : 0 + } + const remain = (Number(this.splitRow.qty) || 0) - (Number(this.splitQty) || 0) + return remain > 0 ? this.formatQty(remain) : 0 + }, // 页面接口忙碌态:任一按钮触发接口未返回时视为忙碌,统一禁用关键入口 - rqrq interfaceBusy() { - return this.palletScanLoading || this.palletConfigLoading || this.scanRequestLoading || this.submitSortingLoading || this.finishSortingLoading + return this.palletScanLoading || this.palletConfigLoading || this.scanRequestLoading || this.submitSortingLoading || this.finishSortingLoading || this.splitLoading } }, methods: { @@ -379,6 +476,82 @@ export default { } return true }, + // 数量去尾零,默认0,避免拆分弹窗展示无效小数 - rqrq + formatQty(qty) { + const num = Number(qty) + if (!Number.isFinite(num)) { + return 0 + } + return parseFloat(String(num)) + }, + // 手工分拣工作盘打开拆分弹窗;被分拣源盘不允许进入 - rqrq + showSplitDialog(item) { + if (!this.showSplitAction) { + return + } + if (!item || !item.serialNo) { + this.$alert('没有可拆分的标签', '提示', { confirmButtonText: '确定' }) + return + } + this.splitRow = item + this.splitQty = '' + this.splitDialogVisible = true + this.$nextTick(() => { + if (this.$refs.splitInput) { + this.$refs.splitInput.focus() + } + }) + }, + // 保存拆分:复用老 /pda/label/split;site 用标签 subSite,避免 54 大site 查不到 54A 标签 - rqrq + confirmSplit() { + if (!this.ensureSite() || this.splitLoading) { + return + } + if (this.sortedSourceFlag) { + this.$alert('被分拣栈板不允许拆分标签', '提示', { confirmButtonText: '确定' }) + return + } + if (!this.splitRow || !this.splitRow.serialNo) { + this.$alert('没有可拆分的标签', '提示', { confirmButtonText: '确定' }) + return + } + if (!this.splitQty) { + this.$alert('请输入拆分数量', '提示', { confirmButtonText: '确定' }) + return + } + const splitQty = Number(this.splitQty) + const currentQty = Number(this.splitRow.qty) || 0 + if (!(splitQty > 0)) { + this.$alert('拆分数量必须大于0', '提示', { confirmButtonText: '确定' }) + return + } + if (!(splitQty < currentQty)) { + this.$alert('拆分数量必须小于当前数量', '提示', { confirmButtonText: '确定' }) + return + } + const labelSite = (this.splitRow.subSite || this.site || '').trim() + this.splitLoading = true + splitLabel({ + site: labelSite, + unitId: this.splitRow.serialNo, + splitQty: splitQty, + operatorName: localStorage.getItem('userName') || '' + }).then(({ data }) => { + if (data && data.code === 0) { + this.$message.success('拆分成功') + this.splitDialogVisible = false + this.splitRow = null + this.splitQty = '' + this.refreshTable() + } else { + this.$alert((data && data.msg) || '拆分失败', '错误', { confirmButtonText: '确定' }) + } + }).catch((error) => { + this.$message.error(error.message || '拆分失败') + }).finally(() => { + this.splitLoading = false + }) + }, handleBack() { if (this.interfaceBusy) { return @@ -431,6 +604,10 @@ export default { this.palletScanLoading = false this.palletConfigLoading = false this.scanRequestLoading = false + this.splitDialogVisible = false + this.splitQty = '' + this.splitLoading = false + this.splitRow = null if (needFocus) { this.$nextTick(() => { if (this.$refs.palletInput) { @@ -990,11 +1167,112 @@ export default { } .col-serial { - flex: 4; + flex: 3; text-align: center; word-break: break-all; } +.col-action { + flex: 1.4; + text-align: center; +} + +.table-split-btn { + min-height: 36px; + padding: 6px 10px; + border: none; + border-radius: 4px; + background: #17B3A3; + color: #fff; + font-size: 13px; + cursor: pointer; +} + +.table-split-btn:disabled { + background: #ccc; + cursor: not-allowed; +} + +.split-dialog-content { + padding: 8px 0; +} + +.split-info-row { + display: flex; + justify-content: space-between; + align-items: center; + padding: 12px 0; + border-bottom: 1px solid #f0f0f0; +} + +.split-label { + font-size: 14px; + color: #666; + font-weight: 500; +} + +.split-value { + font-size: 15px; + font-weight: 600; + color: #333; +} + +.split-value.split-remain { + color: #17B3A3; + font-size: 16px; +} + +.split-input-group { + margin: 16px 0; +} + +.split-input-group .split-label { + display: block; + margin-bottom: 8px; +} + +.split-input { + width: 100%; +} + +.split-hint { + margin-top: 6px; + color: #e6a23c; + font-size: 12px; +} + +.dialog-btn { + flex: 1; + padding: 12px 24px; + border: none; + border-radius: 6px; + font-size: 16px; + font-weight: 500; + cursor: pointer; + min-height: 44px; +} + +.dialog-btn.confirm { + background: #17B3A3; + color: white; +} + +.dialog-btn.confirm:disabled { + background: #ccc; + cursor: not-allowed; +} + +.dialog-btn.cancel { + background: #f5f5f5; + color: #333; + border: 1px solid #ddd; +} + +.dialog-btn.cancel:disabled { + opacity: 0.6; + cursor: not-allowed; +} + .empty-row { justify-content: center; align-items: center;