From 648b0c858da21ee87582736446b50cb784517b09 Mon Sep 17 00:00:00 2001
From: liuyihe <2513762445@qq.com>
Date: Fri, 9 Oct 2026 11:49:03 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/pages/return-packing/return-packing.vue | 6 +--
src/pages/return-receipt/return-receipt.vue | 43 +++++++++++----
tests/return-receipt-page.test.mjs | 58 +++++++++++++++++++++
3 files changed, 93 insertions(+), 14 deletions(-)
diff --git a/src/pages/return-packing/return-packing.vue b/src/pages/return-packing/return-packing.vue
index 9c03496..5009c5f 100644
--- a/src/pages/return-packing/return-packing.vue
+++ b/src/pages/return-packing/return-packing.vue
@@ -4,14 +4,14 @@
- 扫描 SKU 或箱号
- 待作业合箱计划审核通过后推送
+ 仓库现场直接合箱扫描 SKU 或箱号开始;系统会自动锁定客户和当前仓,跨客户货物不能合箱。
+ 平台合箱计划审核通过后推送按计划锁定的来源箱和数量作业,后续合箱规则不变。
选择客户该 SKU 在多个客户有可用退货库存,请先选择客户
没有匹配的已完成退货单或可用库存
- {{ activePlan ? `合箱计划 ${activePlan.planNo}` : '客户散件库存' }}{{ activePlan ? '数量已由计划锁定,请分配到目标箱。' : '可用数量来自该客户同仓全部散件库存,后台自动追溯来源退货单。' }}
+ {{ activePlan ? `合箱计划 ${activePlan.planNo}` : '客户散件库存' }}{{ activePlan ? '数量已由计划锁定,请分配到目标箱。' : '已锁定一个客户;可用数量来自该客户同仓全部散件库存,后台自动追溯来源退货单。' }}
新箱 SKU 数量{{ item.skuCode }}{{ item.productNameZh || '商品名称未填写' }}可用 {{ item.availableQuantity }}装入数量
diff --git a/src/pages/return-receipt/return-receipt.vue b/src/pages/return-receipt/return-receipt.vue
index 3f41748..2fd2f72 100644
--- a/src/pages/return-receipt/return-receipt.vue
+++ b/src/pages/return-receipt/return-receipt.vue
@@ -16,29 +16,27 @@
待完成按箱签收{{ receiptBatch.returnNo }}已确认 {{ receiptBatch.entries.filter(entry => entry.result).length }} / {{ receiptBatch.entries.length }} 箱。请继续本批签收,已确认的箱不会重新入库;本批内容暂不可修改。
- {{ current.returnNo }}{{ startedBy === 'SKU' ? '通过 SKU 候选进入' : '通过退货单号进入' }}{{ statusLabel(current.status) }}
+ 退货单{{ current.returnNo }}{{ statusLabel(current.status) }}
本次实物单元
- 按现场收到的实物选择维度,托盘不是必填项。
包裹码/快递单号
- 托盘入库:扫描已有托盘或生成新托盘,沿用原托盘测量流程。箱子可直接散装入库,也可扫描托盘直接打托。
- 托盘码({{ unitType === 'BOX' ? '选填' : '必填' }}){{ palletCheck.empty ? '空托盘,可绑定当前退货单和 SKU' : `当前单托盘,已有 ${palletCheck.skuCodes.join('、')},共 ${palletCheck.quantity} 件` }}
- 体积{{ palletVolume }}cm³
+ 托盘码({{ unitType === 'BOX' ? '选填' : '必填' }}){{ palletCheck.empty ? '空托盘,可绑定当前退货单和 SKU' : `当前单托盘,已有 ${palletCheck.skuCodes.join('、')},共 ${palletCheck.quantity} 件` }}
+
快递单号(选填)
- {{ unitType === 'PARCEL' ? '本次实收数量' : (unitType === 'PALLET' ? '本托实收数量' : '逐箱实收数量') }}本托箱数合计{{ palletBoxCount }}本次箱数第 {{ index + 1 }} 箱{{ item.skuCode }} · 数量{{ item.skuCode }}{{ item.productNameZh || '商品名称未填写' }}剩余 {{ remaining(item) }}数量此 SKU 箱数
+ {{ unitType === 'PARCEL' ? '本次实收数量' : (unitType === 'PALLET' ? '本托实收数量' : '逐箱实收数量') }}本托箱数合计{{ palletBoxCount }}本次箱数第 {{ index + 1 }} 箱{{ item.skuCode }} · 数量{{ item.skuCode }}{{ item.productNameZh || '商品名称未填写' }}剩余 {{ remaining(item) }}数量SKU 箱数
本托合计{{ receiptQuantity }}
退货打托照片签收过程中可随时拍照{{ photoFileIds.length }} / 20 张{{ photoNames[index] || '退货打托照片' }}
本单已完成打托{{ pallet.palletCode }}{{ pallet.skuCode }} · {{ pallet.quantity }} 件签收批次:{{ pallet.receiptBatchNo }}
- 退货签收成功第 {{ index + 1 }} 箱 · {{ label.cartonMark }}{{ result.unitType === 'PALLET' ? '托盘标签' : '箱唛' }} · {{ result.cartonMark }}托盘:{{ result.palletCode }}签收单:{{ result.receiptNo }}计费批次:{{ result.receiptBatchNo }}{{ result.receivedQuantity }}/{{ result.expectedQuantity }}整单累计{{ result.fullyMatched ? '已完成' : '签收中' }}退货单状态
+ 退货签收成功第 {{ index + 1 }} 箱 · {{ label.cartonMark }}{{ result.unitType === 'PALLET' ? '托盘标签' : '箱唛' }} · {{ result.cartonMark }}托盘:{{ result.palletCode }}签收单:{{ result.receiptNo }}计费批次:{{ result.receiptBatchNo }}{{ result.receivedQuantity }}/{{ result.expectedQuantity }}整单累计{{ result.fullyMatched ? '已完成' : '签收中' }}退货单状态
{{ error.message }}错误码:{{ error.code }}requestId:{{ error.requestId }}traceId:{{ error.traceId }}
@@ -64,9 +62,9 @@
startedBy: { get() { return warehouseWork.returnReceipt.startedBy }, set(value) { updateWarehouseWork('returnReceipt', { startedBy: value }) } },
trackingNo: { get() { return warehouseWork.returnReceipt.trackingNo }, set(value) { updateWarehouseWork('returnReceipt', { trackingNo: value }) } },
palletCode: { get() { return warehouseWork.returnReceipt.palletCode }, set(value) { updateWarehouseWork('returnReceipt', { palletCode: value }) } },
- selectedItems() { return this.current?.expectedItems?.filter(item => !this.selectedSku || item.skuCode === this.selectedSku) || [] },
+ selectedItems() { return this.current?.expectedItems || [] },
palletBoxCount() { return this.selectedItems.reduce((sum, item) => sum + this.boxCount(item.skuCode), 0) },
- activeSkuCode() { return this.selectedItems.length === 1 ? this.selectedItems[0].skuCode : '' },
+ activeSkuCode() { return this.selectedItems.find(item => item.skuCode === this.selectedSku)?.skuCode || this.selectedItems[0]?.skuCode || '' },
receiptQuantity() { return this.unitType === 'BOX' ? this.boxRows.reduce((sum, box) => sum + Object.values(box.items).reduce((n, quantity) => n + (Number(quantity) || 0), 0), 0) : Object.values(warehouseWork.returnReceipt.quantities || {}).reduce((total, value) => total + (Number(value) || 0), 0) },
canConfirm() { if (!this.current || !this.selectedItems.length || this.receiptQuantity <= 0) return false; if (this.unitType === 'BOX') return this.boxRows.length > 0 && this.boxRows.every(box => Object.values(box.items).some(quantity => Number(quantity) > 0)) && this.selectedItems.every(item => this.boxRows.reduce((sum, box) => sum + (Number(box.items[item.skuCode]) || 0), 0) <= this.remaining(item)); return (this.unitType === 'PARCEL' ? this.unitCode.trim() : this.palletCode.trim() && this.palletCheck && Number(this.palletLength) > 0 && Number(this.palletWidth) > 0 && Number(this.palletHeight) > 0 && Number(this.palletWeight) > 0 && (this.unitType !== 'PALLET' || this.palletBoxCount > 0)) && this.selectedItems.every((item) => this.quantity(item.skuCode) <= this.remaining(item) && (this.unitType !== 'PALLET' || this.quantity(item.skuCode) === 0 || this.boxCount(item.skuCode) > 0)); },
unitLabel() { return this.unitType === 'PALLET' ? '托盘码' : this.unitType === 'BOX' ? '箱号/箱唛' : '包裹码/快递单号' },
@@ -135,7 +133,7 @@
},
finishReceipt(results) {
const last = results[results.length - 1]
- this.result = { ...last, labels: results.filter(item => item.unitType === 'BOX' && item.printableHtml).map(item => ({ cartonMark: item.cartonMark, printableHtml: item.printableHtml })) }
+ this.result = { ...last, continuationReturnNo: !last.fullyMatched ? this.current?.returnNo || '' : '', labels: results.filter(item => item.unitType === 'BOX' && item.printableHtml).map(item => ({ cartonMark: item.cartonMark, printableHtml: item.printableHtml })) }
resetWarehouseDomain('returnReceipt')
this.current = null
this.candidates = null
@@ -148,7 +146,27 @@
removePhoto(index) { const [id] = this.photoFileIds.splice(index, 1); this.photoNames.splice(index, 1); if (id) delete this.photoUrls[id] },
async reloadCurrent() { if (!this.current?.returnNo || this.busy) return; await this.openOrder(this.current.returnNo, this.startedBy, false) },
clearCurrent() { if (this.busy || this.receiptBatch) return; resetWarehouseDomain('returnReceipt'); this.current = null; this.candidates = null; this.error = null; this.activeTarget = 'lookup' },
- nextReceipt() { this.result = null; this.clearCurrent() },
+ continueScanning() {
+ if (this.busy || this.receiptBatch) return
+ this.clearCurrent()
+ this.result = null
+ this.entryMode = 'SKU'; this.lookupCode = ''; this.selectedSku = ''
+ this.palletCheck = null; this.newPalletHtml = ''
+ this.palletLength = ''; this.palletWidth = ''; this.palletHeight = ''; this.palletWeight = ''
+ this.unitCode = ''; this.boxRows = [{ items: {} }]
+ this.photoFileIds = []; this.photoNames = []; this.photoUrls = {}
+ },
+ async nextReceipt() {
+ if (this.busy) return
+ const returnNo = this.result?.continuationReturnNo
+ if (!returnNo) { this.result = null; this.clearCurrent(); return }
+ await this.run(async () => {
+ await this.openOrderValue(returnNo, 'SKU')
+ this.palletLength = ''; this.palletWidth = ''; this.palletHeight = ''; this.palletWeight = ''
+ this.unitCode = ''; this.boxRows = [{ items: {} }]; this.newPalletHtml = ''
+ this.result = null
+ }, '读取剩余待签收货物失败')
+ },
async run(work, fallback) { if (this.busy) return; this.busy = true; this.error = null; try { await work() } catch (error) { this.setError(error, fallback) } finally { this.busy = false } },
setError(error, fallback) { this.error = { message: error?.message || fallback, code: error?.code, requestId: error?.requestId, traceId: error?.traceId }; playErrorSound() },
statusLabel(value) { return ({ PENDING_RECEIPT: '待签收', PARTIALLY_RECEIVED: '签收中', COMPLETED: '已完成' })[value] || value || '状态未知' }
@@ -158,6 +176,9 @@