This commit is contained in:
2026-09-09 12:57:59 +08:00
parent e5d826b4a2
commit a3354c92c2
11 changed files with 179 additions and 19 deletions
@@ -46,12 +46,15 @@ async function command(context, target, action, path, body) {
`${BASE}/${target.containerBookingId}/${path}`, body, { 'Idempotency-Key': key })
context.assert(MODULE, `${action}重放状态和版本零漂移`, replay.response,
JSON.stringify(replay.data) === JSON.stringify(first.data), trace(replay.response), OPTIONS)
const changed = path === 'fleet' ? { ...body, reason: `${body.reason}-DIFFERENT` }
const changed = ['pickup', 'empty-return'].includes(path) ? { ...body, remark: `${body.remark}-DIFFERENT` }
: { ...body, reason: `${body.reason}-DIFFERENT` }
const hashConflict = await context.request('POST', `${BASE}/${target.containerBookingId}/${path}`,
changed, context.token, { 'Idempotency-Key': key })
context.addStep(MODULE, `${action}同键异载荷返回A0409`, hashConflict,
conflict(hashConflict), trace(hashConflict), OPTIONS)
const afterConflict = await api(context, 'GET', `${action}冲突后回读聚合`, `${BASE}/${target.containerBookingId}`)
context.assert(MODULE, `${action}冲突后聚合零漂移`, afterConflict.response,
JSON.stringify(afterConflict.data) === JSON.stringify(first.data), trace(afterConflict.response), OPTIONS)
return first
}
@@ -104,7 +107,7 @@ export async function run(context) {
const pickupAt = localIso(new Date(Date.parse(`${appointmentAt}Z`) + 60 * 60_000))
const picked = await command(context, target, '确认实际提柜', 'pickup', {
expectedVersion: Number(scheduled.data.version), actualAt: pickupAt, reason: context.marker,
expectedVersion: Number(scheduled.data.version), actualAt: pickupAt, remark: context.marker,
})
context.assert(MODULE, '实际提柜同步PICKED_UP事实并在已卸柜聚合开放还柜', picked.response,
picked.data?.status === 'UNLOADED' && picked.data?.actualPickupAt === pickupAt
@@ -115,7 +118,7 @@ export async function run(context) {
const returnBase = Math.max(Date.parse(`${pickupAt}Z`), Number.isNaN(unloadingAt) ? 0 : unloadingAt)
const returnedAt = localIso(new Date(returnBase + 60 * 60_000))
const returned = await command(context, target, '确认实际还柜', 'empty-return', {
expectedVersion: Number(picked.data.version), actualAt: returnedAt, reason: context.marker,
expectedVersion: Number(picked.data.version), actualAt: returnedAt, remark: context.marker,
})
context.assert(MODULE, '实际还柜同步EMPTY_RETURNED并关闭全部动作', returned.response,
returned.data?.status === 'EMPTY_RETURNED' && returned.data?.actualEmptyReturnAt === returnedAt
@@ -135,6 +138,10 @@ export async function run(context) {
['SELECT_FLEET', 'SCHEDULE_PICKUP', 'RECORD_PICKUP', 'RECORD_EMPTY_RETURN'].every((action) => actions.has(action))
&& history.data.every((item) => Number(item?.toVersion) === Number(item?.fromVersion) + 1),
`actions=${[...actions].join(',')}; ${trace(history.response)}`, OPTIONS)
context.assert(MODULE, '提柜和还柜备注写入不可变历史', history.response,
['RECORD_PICKUP', 'RECORD_EMPTY_RETURN'].every((action) =>
history.data?.some((item) => item.action === action && item.reason === context.marker)),
trace(history.response), OPTIONS)
context.createdResources.phase5TerminalDrayage = {
...context.createdResources.phase5TerminalDrayage,
containerBookingId: target.containerBookingId, containerNo: target.completed.containerNo,