fix: complete October 22 workflow feedback and request failure recovery
This commit is contained in:
@@ -4,8 +4,8 @@ const STORAGE_KEY = 'overseas-pda-fulfillment-draft-v2'
|
||||
|
||||
const blankState = () => ({
|
||||
scopeKey: '',
|
||||
dispatch: { currentNo: '', palletCode: '', dispatchItemId: '', sourceKey: '', cartonCode: '', packages: 1, pendingCommand: null },
|
||||
outbound: { currentTaskNo: '', scanCode: '', packages: 1, pendingKeys: {} }
|
||||
dispatch: { currentNo: '', palletCode: '', dispatchItemId: '', sourceKey: '', cartonCode: '', packages: 1 },
|
||||
outbound: { currentTaskNo: '', scanCode: '', packages: 1 }
|
||||
})
|
||||
|
||||
export const fulfillment = reactive(blankState())
|
||||
@@ -14,13 +14,7 @@ function storageAvailable() {
|
||||
return typeof uni !== 'undefined' && typeof uni.setStorageSync === 'function' && typeof uni.getStorageSync === 'function'
|
||||
}
|
||||
|
||||
function safeDomain(value, fallback) {
|
||||
return {
|
||||
...fallback,
|
||||
...(value || {}),
|
||||
...(Object.hasOwn(fallback, 'pendingKeys') ? { pendingKeys: { ...(value?.pendingKeys || {}) } } : {})
|
||||
}
|
||||
}
|
||||
function safeDomain(value, fallback) { return Object.fromEntries(Object.keys(fallback).map(key => [key, value?.[key] ?? fallback[key]])) }
|
||||
|
||||
export function persistFulfillmentDraft() {
|
||||
if (!storageAvailable() || !fulfillment.scopeKey) return
|
||||
@@ -55,49 +49,9 @@ function randomKey(domain, action) {
|
||||
return `pda-${domain}-${action}-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`
|
||||
}
|
||||
|
||||
export function fulfillmentIdempotencyKey(domain, action, payload = {}) {
|
||||
if (!fulfillment[domain]) throw new Error('未知海外 PDA 履约类型')
|
||||
if (domain === 'dispatch') throw new Error('排车必须保存完整原命令,不能只生成请求键')
|
||||
const signature = `${action}:${JSON.stringify(payload)}`
|
||||
const pendingKeys = fulfillment[domain].pendingKeys
|
||||
if (!pendingKeys[signature]) pendingKeys[signature] = randomKey(domain, action)
|
||||
persistFulfillmentDraft()
|
||||
return { signature, value: pendingKeys[signature] }
|
||||
}
|
||||
|
||||
export function releaseFulfillmentKey(domain, signature) {
|
||||
if (!fulfillment[domain]) return
|
||||
if (domain === 'dispatch') throw new Error('排车原命令只能在服务端事实核对后清除')
|
||||
delete fulfillment[domain].pendingKeys[signature]
|
||||
persistFulfillmentDraft()
|
||||
}
|
||||
|
||||
export function beginDispatchCommand(dispatchNo, action, body) {
|
||||
if (!fulfillment.scopeKey) throw new Error('当前作业身份未恢复')
|
||||
if (fulfillment.dispatch.pendingCommand) throw new Error('请先核对原排车操作结果')
|
||||
const idempotencyKey = randomKey('dispatch', action)
|
||||
fulfillment.dispatch.pendingCommand = { dispatchNo, action, body: JSON.parse(JSON.stringify({ ...body, idempotencyKey })), attempted: false, rejected: false, result: null }
|
||||
persistFulfillmentDraft()
|
||||
return fulfillment.dispatch.pendingCommand
|
||||
}
|
||||
|
||||
export function patchDispatchCommand(patch) {
|
||||
if (!fulfillment.dispatch.pendingCommand) throw new Error('原排车请求不存在')
|
||||
Object.assign(fulfillment.dispatch.pendingCommand, patch)
|
||||
persistFulfillmentDraft()
|
||||
}
|
||||
|
||||
export function finishDispatchCommand(key) {
|
||||
if (fulfillment.dispatch.pendingCommand?.body.idempotencyKey !== key) throw new Error('核对结果与原请求键不一致')
|
||||
fulfillment.dispatch.pendingCommand = null
|
||||
persistFulfillmentDraft()
|
||||
}
|
||||
|
||||
export function discardRejectedDispatchCommand() {
|
||||
if (fulfillment.dispatch.pendingCommand?.rejected === true) {
|
||||
fulfillment.dispatch.pendingCommand = null
|
||||
persistFulfillmentDraft()
|
||||
}
|
||||
export function fulfillmentIdempotencyKey(domain, action, _payload = {}) {
|
||||
if (!fulfillment[domain]) throw new Error('未知海外 PDA 履约类型')
|
||||
return { value: randomKey(domain, action) }
|
||||
}
|
||||
|
||||
export function resetFulfillmentDomain(domain) {
|
||||
|
||||
@@ -3,13 +3,13 @@ import { reactive } from 'vue'
|
||||
const STORAGE_KEY = 'overseas-pda-warehouse-work-v1'
|
||||
const blankState = () => ({
|
||||
scopeKey: '',
|
||||
stocktake: { taskNo: '', scopeType: 'LOCATION', scopeCode: '', reason: '', pendingKeys: {} },
|
||||
move: { sourcePalletCode: '', targetLocationCode: '', reason: '', pendingKeys: {} },
|
||||
relabel: { currentNo: '', oldLabel: '', newLabel: '', action: 'RELABEL', reason: '', remark: '', photoFileIds: [], photoNames: [], pendingKeys: {} },
|
||||
returnReceipt: { pendingBatch: null, entryMode: 'SKU', lookupCode: '', currentReturnNo: '', startedBy: 'SKU', trackingNo: '', palletCode: '', quantities: {}, boxCounts: {}, pendingKeys: {} },
|
||||
returnPacking: { mode: 'SKU', searchCode: '', selectedOrders: [], quantities: {}, targetBoxes: [], sourceCartonMarks: [], targetCode: '', activePlan: null, result: null, putawayResults: {}, pendingKeys: {} },
|
||||
returnPackingPlan: { pendingKeys: {} },
|
||||
warehouseTransfer: { currentNo: '', pendingKeys: {} },
|
||||
stocktake: { taskNo: '', scopeType: 'LOCATION', scopeCode: '', reason: '' },
|
||||
move: { sourcePalletCode: '', targetLocationCode: '', reason: '' },
|
||||
relabel: { currentNo: '', oldLabel: '', newLabel: '', action: 'RELABEL', reason: '', remark: '', photoFileIds: [], photoNames: [] },
|
||||
returnReceipt: { entryMode: 'SKU', lookupCode: '', currentReturnNo: '', startedBy: 'SKU', trackingNo: '', palletCode: '', quantities: {}, boxCounts: {} },
|
||||
returnPacking: { mode: 'SKU', searchCode: '', selectedOrders: [], quantities: {}, targetBoxes: [], sourceCartonMarks: [], targetCode: '', activePlan: null, result: null, putawayResults: {} },
|
||||
returnPackingPlan: {},
|
||||
warehouseTransfer: { currentNo: '' },
|
||||
query: { inventoryCode: '', locationCode: '', palletCode: '' }
|
||||
})
|
||||
|
||||
@@ -19,7 +19,7 @@ function storageAvailable() {
|
||||
return typeof uni !== 'undefined' && typeof uni.setStorageSync === 'function' && typeof uni.getStorageSync === 'function'
|
||||
}
|
||||
|
||||
function domain(value, fallback) { return { ...fallback, ...(value || {}), pendingKeys: { ...(value?.pendingKeys || {}) } } }
|
||||
function domain(value, fallback) { return Object.fromEntries(Object.keys(fallback).map(key => [key, value?.[key] ?? fallback[key]])) }
|
||||
|
||||
export function persistWarehouseWork() {
|
||||
if (!storageAvailable() || !warehouseWork.scopeKey) return
|
||||
@@ -54,21 +54,10 @@ export function updateWarehouseWork(name, patch) {
|
||||
persistWarehouseWork()
|
||||
}
|
||||
|
||||
export function warehouseIdempotencyKey(name, action, payload = {}) {
|
||||
const target = warehouseWork[name]
|
||||
if (!target?.pendingKeys) throw new Error('当前作业不支持写操作')
|
||||
const signature = `${action}:${JSON.stringify(payload)}`
|
||||
if (!target.pendingKeys[signature]) target.pendingKeys[signature] = `pda-${name}-${action}-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`
|
||||
persistWarehouseWork()
|
||||
return { signature, value: target.pendingKeys[signature] }
|
||||
export function warehouseIdempotencyKey(name, action, _payload = {}) {
|
||||
if (!warehouseWork[name]) throw new Error('当前作业不支持写操作')
|
||||
return { value: `pda-${name}-${action}-${Date.now()}-${Math.random().toString(36).slice(2, 10)}` }
|
||||
}
|
||||
|
||||
export function releaseWarehouseKey(name, signature) {
|
||||
if (!warehouseWork[name]?.pendingKeys) return
|
||||
delete warehouseWork[name].pendingKeys[signature]
|
||||
persistWarehouseWork()
|
||||
}
|
||||
|
||||
export function resetWarehouseDomain(name) {
|
||||
const fresh = blankState()
|
||||
if (!fresh[name]) return
|
||||
|
||||
Reference in New Issue
Block a user