优化
This commit is contained in:
@@ -1127,7 +1127,7 @@
|
||||
const serverPartialQuantities = {}
|
||||
this.currentBox.items.forEach((item) => {
|
||||
if (item.itemStatus === 'PICKED') serverStates[item.id] = ITEM_STATUS.PICKED
|
||||
else if (item.itemStatus === 'PARTIAL') {
|
||||
else if (item.itemStatus === 'PICKING' || item.itemStatus === 'PARTIAL') {
|
||||
serverStates[item.id] = ITEM_STATUS.PARTIAL
|
||||
serverPartialQuantities[item.id] = Number(item.pickedPackageCount ?? item.finalPickedPackageCount ?? 0)
|
||||
} else if (item.itemStatus === 'SKIPPED') serverStates[item.id] = ITEM_STATUS.SKIPPED
|
||||
@@ -1529,6 +1529,64 @@
|
||||
this.showToast(`已部分拣货:${value}/${item.qty} ${item.unit}`, 'success')
|
||||
this.persistSession()
|
||||
},
|
||||
async submitImmediateItemAction(item, action, payload = {}) {
|
||||
if (this.submitting) { this.showToast('上一笔拣货正在提交,请稍候', 'warning'); return false }
|
||||
if (!this.remoteTaskId || !this.currentBox.warehouseId || this.pickingVersion === null) {
|
||||
this.showToast('任务状态尚未同步,请刷新重试', 'warning')
|
||||
return false
|
||||
}
|
||||
const itemId = item.taskItemId ?? item.remoteItemId ?? item.id
|
||||
const identity = stableTaskOperationIdentity(this.draftIdentity())
|
||||
const operationId = stableOperationId(`item-${action.toLowerCase()}`, identity, {
|
||||
itemId, itemVersion: item.version, taskVersion: this.pickingVersion, ...payload
|
||||
})
|
||||
const common = { warehouseId: this.currentBox.warehouseId, version: Number(item.version || 0), operationId }
|
||||
this.submitting = true
|
||||
this.remoteError = ''
|
||||
try {
|
||||
let task
|
||||
if (action === 'PICK') task = await pickContainerItem(this.remoteTaskId, itemId, { ...common, pickedPackageCount: payload.pickedPackageCount })
|
||||
else if (action === 'PARTIAL') task = await partialContainerItem(this.remoteTaskId, itemId, { ...common, finalPickedPackageCount: payload.finalPickedPackageCount })
|
||||
else if (action === 'SKIP') task = await skipContainerItem(this.remoteTaskId, itemId, { ...common, reason: payload.reason })
|
||||
else task = await pickContainerPallet(this.remoteTaskId, { warehouseId: this.currentBox.warehouseId, palletNo: payload.palletNo, expectedTaskVersion: Number(this.pickingVersion), operationId })
|
||||
this.applyImmediateTaskResult(task)
|
||||
return true
|
||||
} catch (error) {
|
||||
if (this.isTaskConflict(error)) await this.refreshAfterTaskConflict(sanitizeUserMessage(error.message, '装柜明细已变化,请刷新后重试'))
|
||||
else {
|
||||
this.remoteError = error.network ? '网络失败,本次拣货未提交' : this.remoteFailureMessage(error, '拣货提交失败')
|
||||
this.showToast('拣货未提交,请重试', 'error')
|
||||
}
|
||||
return false
|
||||
} finally {
|
||||
this.submitting = false
|
||||
}
|
||||
},
|
||||
applyImmediateTaskResult(result) {
|
||||
if (!result) return
|
||||
const task = normalizePickingTask({ ...this.remotePick, ...result })
|
||||
this.remotePick = task
|
||||
this.pickingVersion = task.pickingVersion ?? task.version ?? this.pickingVersion
|
||||
const remoteItems = Array.isArray(result.items) ? result.items : []
|
||||
const byId = new Map(remoteItems.map((item) => [String(item.id ?? item.itemId), item]))
|
||||
this.currentBox.items = this.currentBox.items.map((item) => {
|
||||
const remote = byId.get(String(item.taskItemId ?? item.remoteItemId ?? item.id))
|
||||
return remote ? { ...item, ...remote, id: item.id, taskItemId: remote.id ?? remote.itemId ?? item.taskItemId } : item
|
||||
})
|
||||
const nextStates = { ...this.itemStates }
|
||||
const nextPartial = { ...this.partialQuantities }
|
||||
this.currentBox.items.forEach((item) => {
|
||||
const count = Number(item.pickedPackageCount || 0)
|
||||
if (item.itemStatus === 'PICKED') nextStates[item.id] = ITEM_STATUS.PICKED
|
||||
else if (item.itemStatus === 'PICKING' || item.itemStatus === 'PARTIAL') {
|
||||
nextStates[item.id] = ITEM_STATUS.PARTIAL
|
||||
nextPartial[item.id] = count
|
||||
} else if (item.itemStatus === 'SKIPPED') nextStates[item.id] = ITEM_STATUS.SKIPPED
|
||||
})
|
||||
this.itemStates = nextStates
|
||||
this.partialQuantities = nextPartial
|
||||
this.evidenceIdentity = this.captureEvidenceIdentity()
|
||||
},
|
||||
availablePickQuantity(item) {
|
||||
if (!item) return null
|
||||
if (item.locationAvailable === false || item.locationStatus === 'DISABLED') return 0
|
||||
|
||||
@@ -268,7 +268,7 @@ test('picking scan results use the shared success and error audio feedback', asy
|
||||
assert.match(audio, /export function playErrorSound\(\)/)
|
||||
assert.match(picking, /import \{ playErrorSound, playSuccessSound \} from '@\/utils\/audio-feedback\.js'/)
|
||||
assert.match(picking, /result\.type === 'unknown'[\s\S]*?playErrorSound\(\)/)
|
||||
assert.match(picking, /playSuccessSound\(\)[\s\S]*?this\.pickScannedBox\(result\.item, value\)/)
|
||||
assert.match(picking, /await this\.pickScannedBox\(result\.item, value\)[\s\S]*?if \(submitted\) playSuccessSound\(\)/)
|
||||
})
|
||||
|
||||
test('reusable scan target input separates field selection from page-level broadcast handling', async () => {
|
||||
|
||||
@@ -109,6 +109,8 @@ test('PDA cabinet picking adapter claims online and submits one atomic batch', (
|
||||
assert.doesNotMatch(source, /query\.push\(`cabinetNo=/)
|
||||
assert.doesNotMatch(source, /query\.push\(`loadingPlanId=/)
|
||||
assert.match(source, /tasks\/\$\{encodeURIComponent\(taskId\)\}\/claim/)
|
||||
assert.match(source, /tasks\/\$\{encodeURIComponent\(taskId\)\}\/items\/\$\{encodeURIComponent\(itemId\)\}\/\$\{path\}/)
|
||||
assert.match(source, /tasks\/\$\{encodeURIComponent\(taskId\)\}\/pallets\/pick/)
|
||||
assert.match(source, /tasks\/\$\{encodeURIComponent\(task\.taskId\)\}\/batch/)
|
||||
assert.match(source, /tasks\/\$\{encodeURIComponent\(taskId\)\}\/inventory-snapshot\?warehouseId=/)
|
||||
assert.match(source, /submitContainerPickingBatch/)
|
||||
@@ -116,6 +118,12 @@ test('PDA cabinet picking adapter claims online and submits one atomic batch', (
|
||||
assert.match(source, /Math\.imul\(hash, 16777619\)/)
|
||||
assert.match(source, /slice\(0, 128\)/)
|
||||
assert.match(page, /claimContainerPickingTask\(/)
|
||||
assert.match(page, /submitImmediateItemAction\(item, 'PICK'/)
|
||||
assert.match(page, /submitImmediateItemAction\(item, 'PARTIAL'/)
|
||||
assert.match(page, /submitImmediateItemAction\(item, 'SKIP'/)
|
||||
assert.match(page, /submitImmediateItemAction\(item, 'PICK_PALLET'/)
|
||||
assert.match(page, /item\.itemStatus === 'PICKING' \|\| item\.itemStatus === 'PARTIAL'/)
|
||||
assert.doesNotMatch(page, /@tap="undoItem\(item\.id\)"/)
|
||||
assert.match(page, /submitContainerPickingBatch\(/)
|
||||
assert.match(source, /palletNo: action\.type === 'PICK_PALLET' \? action\.palletNo : null/)
|
||||
assert.match(page, /type: 'PICK_PALLET'[\s\S]*?palletNo: item\.palletNo/)
|
||||
|
||||
Reference in New Issue
Block a user