适配PDA稳定柜次身份契约

This commit is contained in:
2026-08-12 18:32:31 +08:00
parent 0b51ed4347
commit c8509cb452
8 changed files with 142 additions and 56 deletions
+16 -8
View File
@@ -14,7 +14,7 @@
<view class="work-content">
<view class="box-select-wrap">
<button class="box-select-btn" @tap="toggleBoxDropdown">
<text>{{ currentBox.boxNo }} · 订单 {{ currentBox.orderNo }}</text>
<text>{{ currentBox.boxNo }}<template v-if="currentBox.currentContainerNo"> · 当前柜号 {{ currentBox.currentContainerNo }}</template> · 订单 {{ currentBox.orderNo }}</text>
<text class="box-chevron" :class="{ open: boxDropdownOpen }">▼</text>
</button>
<view v-if="boxDropdownOpen" class="box-dropdown">
@@ -328,6 +328,7 @@
import { createEvidenceUploadQueue } from '@/utils/evidence-upload-queue.js'
import { isOnline } from '@/utils/network.js'
import { stableOperationId } from '@/utils/idempotency.js'
import { stableTaskOperationIdentity } from '@/utils/task-identity.js'
import ScanTargetInput from '@/components/ScanTargetInput.vue'
import PopupHeader from '@/components/PopupHeader.vue'
@@ -452,9 +453,10 @@
},
onLoad(options = {}) {
if (!requireSession()) return
if (options.containerNo) {
if (options.taskId && (options.cabinetNo || options.containerNo)) {
this.boxes = [{
boxNo: String(options.containerNo), orderNo: String(options.orderNo || options.inboundCode || ''),
boxNo: String(options.cabinetNo || options.containerNo), cabinetNo: String(options.cabinetNo || options.containerNo), currentContainerNo: options.currentContainerNo ? String(options.currentContainerNo) : null, orderNo: String(options.orderNo || options.inboundCode || ''),
taskId: String(options.taskId), loadingPlanId: options.loadingPlanId ? String(options.loadingPlanId) : null, containerBookingId: options.containerBookingId ? String(options.containerBookingId) : null,
inboundId: options.inboundId ? String(options.inboundId) : null,
inboundVersion: options.inboundVersion == null ? null : Number(options.inboundVersion),
warehouseId: options.warehouseId ? String(options.warehouseId) : null,
@@ -489,7 +491,7 @@
},
draftIdentity() {
const operatorId = session.currentUser?.id || session.currentUser?.userId || session.currentUser?.accountId
return { operatorId, taskId: this.remoteTaskId || this.currentBox.taskId || this.currentBox.inboundId, containerNo: this.currentBox.boxNo, warehouseId: this.currentBox.warehouseId || session.currentUser?.warehouseId || session.currentUser?.warehouse }
return { operatorId, taskId: this.remoteTaskId || this.currentBox.taskId, loadingPlanId: this.currentBox.loadingPlanId || this.remotePick?.loadingPlanId, containerBookingId: this.currentBox.containerBookingId || this.remotePick?.containerBookingId, warehouseId: this.currentBox.warehouseId || session.currentUser?.warehouseId || session.currentUser?.warehouse }
},
restoreRemoteDraft() {
const restored = restorePickingSession(this.draftIdentity())
@@ -672,7 +674,7 @@
this.remoteError = ''
try {
const warehouseId = this.currentBox.warehouseId || session.currentUser?.warehouseId || session.currentUser?.warehouse
const task = await getContainerPickingTask(this.currentBox.boxNo, warehouseId)
const task = await getContainerPickingTask({ taskId: this.remoteTaskId || this.currentBox.taskId, cabinetNo: this.currentBox.cabinetNo, loadingPlanId: this.currentBox.loadingPlanId, containerNo: this.currentBox.currentContainerNo }, warehouseId)
if (!task) throw new Error('未找到当前柜次的拣货任务')
const remoteItems = task.items || task.pickItems || task.details || task.lines
if (Array.isArray(remoteItems) && remoteItems.length) {
@@ -703,7 +705,12 @@
this.remoteTaskId = task.taskId ?? task.id
if (!this.remoteTaskId) throw new Error('服务端任务缺少 taskId,无法开始拣货')
this.assignmentVersion = task.assignmentVersion ?? task.version ?? 0
const operationId = `claim-${session.currentUser?.id || 'operator'}-${this.remoteTaskId}-${this.currentBox.boxNo}`
this.currentBox.loadingPlanId = task.loadingPlanId
this.currentBox.containerBookingId = task.containerBookingId
this.currentBox.cabinetNo = task.cabinetNo
this.currentBox.boxNo = task.cabinetNo
this.currentBox.currentContainerNo = task.currentContainerNo
const operationId = `claim-${session.currentUser?.id || 'operator'}-${this.remoteTaskId}-${task.loadingPlanId}-${task.containerBookingId}`
const claimed = await claimContainerPickingTask(this.remoteTaskId, this.assignmentVersion, operationId)
this.remotePick = normalizePickingTask({ ...task, ...(claimed || {}) })
this.pickingVersion = this.remotePick.pickingVersion ?? this.remotePick.version ?? null
@@ -937,7 +944,8 @@
try {
if (!this.remoteTaskId) throw new Error('尚未进入服务端拣货任务,请联网刷新后重试')
if (this.pickingVersion === null) throw new Error('缺少拣货版本号 pickingVersion,无法提交')
const submitId = this.submitId || stableOperationId('submit', `${session.currentUser?.id || 'operator'}-${this.remoteTaskId}-${this.currentBox.boxNo}`, { itemStates: this.itemStates, partialQuantities: this.partialQuantities, incompleteReason })
const operationIdentity = stableTaskOperationIdentity(this.draftIdentity())
const submitId = this.submitId || stableOperationId('submit', operationIdentity, { itemStates: this.itemStates, partialQuantities: this.partialQuantities, incompleteReason })
this.submitId = submitId
const warehouseId = this.currentBox.warehouseId || session.currentUser?.warehouseId || session.currentUser?.warehouse
const inventorySnapshot = await getPickingInventorySnapshot(this.remoteTaskId, warehouseId)
@@ -950,7 +958,7 @@
if (incompleteReason) return { type: 'SKIP', itemId, reason: `${incompleteReason}(提交时确认未拣)`, version: Number(item.version || 0) }
return null
}).filter(Boolean)
await submitContainerPickingBatch({ taskId: this.remoteTaskId, containerNo: this.currentBox.boxNo, version: Number(this.pickingVersion) }, actions, { warehouseId, operationId: submitId, inventorySnapshotToken: inventorySnapshot?.snapshotToken })
await submitContainerPickingBatch({ taskId: this.remoteTaskId, loadingPlanId: this.currentBox.loadingPlanId, containerBookingId: this.currentBox.containerBookingId, version: Number(this.pickingVersion) }, actions, { warehouseId, operationId: submitId, inventorySnapshotToken: inventorySnapshot?.snapshotToken })
// Legacy inbound completePicking(expectedVersion: Number(this.pickingVersion)) remains adapter-only; cabinet tasks use item actions.
} catch (error) {
const versionConflict = error.code === 'A0409' || error.statusCode === 409