支持PDA整托拣货

This commit is contained in:
2026-09-15 21:05:09 +08:00
parent c6978c0983
commit 2dabdfde7c
4 changed files with 22 additions and 7 deletions
+4
View File
@@ -112,6 +112,10 @@ export function pickOutboundTask(taskNo, request) {
return overseasRequest('POST', `${OUTBOUND_BASE}/${encoded(taskNo)}/pick`, request)
}
export function pickOutboundPallet(taskNo, palletNo, request) {
return overseasRequest('POST', `${OUTBOUND_BASE}/${encoded(taskNo)}/pallets/${encoded(palletNo)}/pick`, request)
}
export function outboundPickPayload(item, position, packages) {
return {
outboundPalletItemId: item.outboundPalletItemId,
+9 -3
View File
@@ -3,11 +3,11 @@
<PortalHeader title="出库作业" :user="user" />
<scroll-view class="fulfillment-scroll" scroll-y>
<view class="portal-content fulfillment-content">
<view class="fulfillment-heading"><text class="fulfillment-title">出库任务</text><text class="fulfillment-subtitle">列表仅显示普通/一件代发出库任务;扫描排车业务号会转入“排车拣货”</text></view>
<view class="fulfillment-heading"><text class="fulfillment-title">出库任务</text><text class="fulfillment-subtitle">一件代发扫描托盘码可整托出库;扫描排车业务号会转入“排车拣货”</text></view>
<view class="fulfillment-card">
<ScanTargetInput name="outbound" :model-value="scanCode" label="任务号、出库单号、排车单号、托盘码或箱码" placeholder="扫描任务号 / 出库单号 / 排车单号 / 托盘码 / 箱码" :active="true" @update:modelValue="updateScanCode" @submit="handleScan" />
<button class="secondary-button" :disabled="!scanCode || loading || busy" @tap="handleScan(scanCode)">{{ current ? '匹配出库货物' : '打开出库任务' }}</button>
<text class="scan-help">任务号直接恢复;出库单号或排车单号先由服务端解析流程,不会作为出库任务号误查。</text>
<text class="scan-help">任务号直接恢复;进入任务后扫描 DP 托盘码,将一次拣取该托全部未拣箱件。</text>
</view>
<view v-if="loading" class="fulfillment-state"><text>正在加载出库任务…</text></view>
@@ -49,7 +49,7 @@
<script>
import PortalHeader from '@/components/PortalHeader.vue'
import ScanTargetInput from '@/components/ScanTargetInput.vue'
import { completeOutboundTask, getOutboundTask, listOutboundTasks, outboundPickPayload, pickOutboundTask, resolveOutboundTask } from '@/api/fulfillment.js'
import { completeOutboundTask, getOutboundTask, listOutboundTasks, outboundPickPayload, pickOutboundPallet, pickOutboundTask, resolveOutboundTask } from '@/api/fulfillment.js'
import { fulfillment, fulfillmentIdempotencyKey, releaseFulfillmentKey, restoreFulfillmentDraft, updateFulfillmentDraft } from '@/stores/fulfillment.js'
import { requireSession, session } from '@/stores/session.js'
import { playErrorSound, playSuccessSound } from '@/utils/audio-feedback.js'
@@ -98,6 +98,7 @@
console.info('[Overseas PDA outbound] scan', { code, task: this.current?.taskNo || '' }); this.scanCode = code; updateFulfillmentDraft('outbound', { scanCode: code })
if (!this.current) return this.openScannedTask(code)
if (code === this.current.taskNo || code === this.current.outboundNo) return this.openTask(this.current.taskNo)
if ((this.current.items || []).some((item) => item.palletNo === code)) return this.submitPalletPick(code)
if (this.findAndSelectPosition(code)) return
this.setError(new Error('扫码未匹配当前出库任务的托盘码、箱码、SKU 或入仓码'), '扫码未匹配')
},
@@ -108,6 +109,11 @@
const payload = outboundPickPayload(this.selectedItem, this.selectedPosition, this.packages); const key = fulfillmentIdempotencyKey('outbound', 'pick', { taskNo: this.current.taskNo, ...payload })
await this.run('提交出库拣货', async () => { await pickOutboundTask(this.current.taskNo, { ...payload, idempotencyKey: key.value }); this.current = await getOutboundTask(this.current.taskNo); releaseFulfillmentKey('outbound', key.signature); this.selectedItem = null; this.selectedPosition = null; updateFulfillmentDraft('outbound', { scanCode: '', packages: 1 }); this.successMessage = '本次出库拣货已记录'; playSuccessSound() })
},
async submitPalletPick(palletNo) {
const code = String(palletNo || '').trim(); if (!code || !this.current) return
const key = fulfillmentIdempotencyKey('outbound', 'pallet-pick', { taskNo: this.current.taskNo, palletNo: code })
await this.run('整托拣货', async () => { await pickOutboundPallet(this.current.taskNo, code, { idempotencyKey: key.value }); this.current = await getOutboundTask(this.current.taskNo); releaseFulfillmentKey('outbound', key.signature); this.selectedItem = null; this.selectedPosition = null; updateFulfillmentDraft('outbound', { scanCode: '', packages: 1 }); this.successMessage = `${code} 整托拣货已完成`; playSuccessSound() })
},
async completeTask() {
if (!this.canComplete) return
const key = fulfillmentIdempotencyKey('outbound', 'complete', { taskNo: this.current.taskNo })