优化
This commit is contained in:
@@ -29,6 +29,7 @@
|
||||
<text class="business-code">{{ label.cartonMark }}</text><text class="meta-line">来源退货单:{{ label.sourceReturnNo }}</text>
|
||||
<text v-for="item in label.items" :key="item.skuCode" class="meta-line">{{ item.skuCode }} · {{ item.quantity }} 件</text>
|
||||
<button class="secondary" :disabled="busy" @tap="printLabel(label)">打印新箱唛</button>
|
||||
<ReturnLabelConfirmation ref="labelConfirmations" :carton-mark="label.cartonMark" />
|
||||
</view>
|
||||
<button class="primary" :disabled="busy" @tap="nextPacking">返回合箱计划列表</button>
|
||||
</view>
|
||||
@@ -41,6 +42,7 @@
|
||||
import PortalHeader from '@/components/PortalHeader.vue'
|
||||
import ScanTargetInput from '@/components/ScanTargetInput.vue'
|
||||
import ReturnBoxMergeWork from '@/components/ReturnBoxMergeWork.vue'
|
||||
import ReturnLabelConfirmation from '@/components/ReturnLabelConfirmation.vue'
|
||||
import { completePackingPlan, findPackingOrders, listPackingPlans, getPackingPlan, getReturnCartonLabel, scanReturnCarton, packReturnSkus } from '@/api/return-packing.js'
|
||||
import { defaultPackingBoxes, packingBoxPayload, validPackingAllocation } from '@/utils/return-packing-allocation.js'
|
||||
import { session, requireSession } from '@/stores/session.js'
|
||||
@@ -49,7 +51,7 @@
|
||||
import { playErrorSound, playSuccessSound } from '@/utils/audio-feedback.js'
|
||||
|
||||
export default {
|
||||
components: { PortalHeader, ScanTargetInput, ReturnBoxMergeWork },
|
||||
components: { PortalHeader, ScanTargetInput, ReturnBoxMergeWork, ReturnLabelConfirmation },
|
||||
data() { return { mode: 'SKU', initialSource: null, user: session.currentUser, candidates: null, customerCandidates: [], selectedCustomer: null, previews: {}, plans: [], activePlan: null, result: null, busy: false, error: null, dimensionFields: [{ key: 'length', label: '长 cm', placeholder: '长' }, { key: 'width', label: '宽 cm', placeholder: '宽' }, { key: 'height', label: '高 cm', placeholder: '高' }, { key: 'weight', label: '重量 kg', placeholder: '重量' }] } },
|
||||
computed: {
|
||||
packing() { return warehouseWork.returnPacking },
|
||||
@@ -64,7 +66,7 @@
|
||||
onShow() { if (!requireSession()) return; this.user = session.currentUser; restoreWarehouseWork(`${this.user.id}:${this.user.warehouseId}`); this.mode = this.packing.mode || 'SKU'; this.activePlan = this.packing.activePlan || null; this.result = this.packing.result || null; if (this.activePlan) { const quantities = {}; for (const box of this.activePlan.boxes) for (const item of box.items || []) quantities[item.skuCode] = (quantities[item.skuCode] || 0) + Number(item.quantity); this.selectedCustomer = { skus: Object.entries(quantities).map(([skuCode, availableQuantity]) => ({ skuCode, availableQuantity })) }; } this.startScanner(); this.loadPlans(); if (!this.activePlan && !this.result && this.selectedOrders.length && !Object.keys(this.previews).length) this.refreshSelected() },
|
||||
onHide() { this.stopScanner() }, onUnload() { this.stopScanner() }, beforeUnmount() { this.stopScanner() },
|
||||
methods: {
|
||||
startScanner() { this.initialSource = this.activePlan ? null : this.packing.initialSource || null; if (this.mode === 'BOX' && !this.activePlan && !this.initialSource) this.mode = 'SKU'; this.stopScanner(); this._stopScanner = startScanBroadcast({ onScan: (value) => { if (!this.busy && !this.result) { if (this.mode === 'BOX') this.$refs.boxWork?.acceptScan(value); else { this.searchCode = value; this.search(value) } } }, onError: (error) => this.setError(error, '扫码广播注册失败') }) },
|
||||
startScanner() { this.initialSource = this.activePlan ? null : this.packing.initialSource || null; if (this.mode === 'BOX' && !this.activePlan && !this.initialSource) this.mode = 'SKU'; this.stopScanner(); this._stopScanner = startScanBroadcast({ onScan: (value) => { if (this.result) { for (const label of [].concat(this.$refs.labelConfirmations || [])) label.acceptScan(value); return } if (!this.busy && !this.result) { if (this.mode === 'BOX') this.$refs.boxWork?.acceptScan(value); else { this.searchCode = value; this.search(value) } } }, onError: (error) => this.setError(error, '扫码广播注册失败') }) },
|
||||
stopScanner() { if (this._stopScanner) this._stopScanner(); this._stopScanner = null },
|
||||
async loadPlans() { try { this.plans = await listPackingPlans() } catch (error) { this.setError(error, '加载合箱计划失败') } },
|
||||
async search(raw) {
|
||||
@@ -80,12 +82,7 @@
|
||||
resetWarehouseDomain('returnPacking'); this.selectedCustomer = null; this.customerCandidates = []; this.candidates = null; this.previews = {}
|
||||
this.initialSource = carton; this.mode = 'BOX'; updateWarehouseWork('returnPacking', {mode:'BOX', initialSource:carton}); playSuccessSound(); return
|
||||
}
|
||||
const preview = await findPackingOrders(value, 'SKU')
|
||||
const customers = Array.isArray(preview.customers) ? preview.customers : []
|
||||
const orders = Array.isArray(preview.orders) ? preview.orders : []
|
||||
this.customerCandidates = customers; this.candidates = customers.length ? null : orders.filter(item => !this.selectedOrders.some(selected => selected.returnNo === item.returnNo))
|
||||
if (customers.length === 1) this.selectCustomer(customers[0])
|
||||
if (customers.length || this.candidates.length) playSuccessSound()
|
||||
throw new Error('请扫描来源包裹/箱标签,部分出库必须确认具体实物来源')
|
||||
}, '查询 SKU 或箱号失败')
|
||||
},
|
||||
selectCustomer(customer) { if (!customer?.customerId || !customer.orders?.length) return; const existingCustomer = this.selectedOrders[0]?.customerKey; if (existingCustomer && existingCustomer !== customer.customerId) { this.setError(new Error('不同客户的退货库存不能合箱'), '不能选择其他客户'); return } this.selectedCustomer = customer; const selected = customer.orders.filter((item) => !this.selectedOrders.some((current) => current.returnNo === item.returnNo)).map((item) => ({ ...item, customerKey: customer.customerId })); const all = this.selectedOrders.length ? [...this.selectedOrders, ...selected] : selected; updateWarehouseWork('returnPacking', { selectedOrders: all, searchCode: '' }); this.customerCandidates = []; this.candidates = null; this.previews = {} },
|
||||
@@ -93,10 +90,10 @@
|
||||
async startPlan(plan) { if (!plan?.planNo || this.busy || this.activePlan || this.result) return; await this.run(async () => {
|
||||
const latest = await getPackingPlan(plan.planNo)
|
||||
if (latest.status !== 'READY') throw new Error('计划已不在待作业状态,请刷新列表')
|
||||
this.activePlan = latest; this.mode = latest.mode; this.customerCandidates = []; this.candidates = null
|
||||
this.activePlan = latest; this.mode = 'BOX'; this.customerCandidates = []; this.candidates = null
|
||||
const quantities = {}; for (const box of latest.boxes) for (const item of box.items || []) quantities[item.skuCode] = (quantities[item.skuCode] || 0) + Number(item.quantity)
|
||||
this.selectedCustomer = { customerId: latest.customerId, orders: latest.returnNos.map(returnNo => ({ returnNo })), skus: Object.entries(quantities).map(([skuCode, availableQuantity]) => ({ skuCode, availableQuantity })) }
|
||||
updateWarehouseWork('returnPacking', { mode: latest.mode, activePlan: latest, selectedOrders: latest.returnNos.map(returnNo => ({ returnNo, customerKey: latest.customerId })), quantities, targetBoxes: defaultPackingBoxes(Object.entries(quantities).map(([skuCode,quantity]) => ({skuCode,quantity}))), searchCode: '' })
|
||||
updateWarehouseWork('returnPacking', { mode: 'BOX', activePlan: latest, selectedOrders: latest.returnNos.map(returnNo => ({ returnNo, customerKey: latest.customerId })), quantities, targetBoxes: defaultPackingBoxes(Object.entries(quantities).map(([skuCode,quantity]) => ({skuCode,quantity}))), searchCode: '' })
|
||||
}, '读取合箱计划失败') },
|
||||
async addOrder(item) { if (this.busy || !item?.returnNo) return; await this.run(async () => { const preview = await findPackingOrders(item.returnNo, 'RETURN_NO'); const exact = preview.orders.filter((order) => order.returnNo === item.returnNo); if (exact.length !== 1 || !preview.customerKey) throw new Error('该退货单没有可用库存'); const customerKey = this.selectedOrders[0]?.customerKey; if (customerKey && customerKey !== preview.customerKey) throw new Error('不同客户的退货单不能合箱'); const selected = [...this.selectedOrders, { ...exact[0], customerKey: preview.customerKey }]; this.selectedCustomer = null; this.previews = { ...this.previews, [item.returnNo]: preview }; updateWarehouseWork('returnPacking', { selectedOrders: selected, searchCode: '', quantities: this.validQuantities(selected, this.previews) }); this.candidates = null; this.customerCandidates = []; playSuccessSound() }, '添加退货单失败') },
|
||||
removeOrder(returnNo) { const selected = this.selectedOrders.filter((item) => item.returnNo !== returnNo); const previews = { ...this.previews }; delete previews[returnNo]; this.previews = previews; if (this.selectedCustomer) this.selectedCustomer = { ...this.selectedCustomer, orders: selected }; updateWarehouseWork('returnPacking', { selectedOrders: selected, quantities: this.validQuantities(selected, previews) }) },
|
||||
|
||||
Reference in New Issue
Block a user