fix(consignment): 问题单「退回大厅」也要解绑寄卖现货

问题单处置的「退回大厅」只把订单置回 open,没有解绑被本工单占用的寄卖现货,也没摘 material 上的
寄售标记。后果是卖家端「我的寄卖」把这张单显示成「履约中 + 关联订单状态已变化,请联系客服核对」
(状态机只认 in_progress / problem / pending_acceptance,open 落到兜底分支),而现货永久停在
consumed 占库不还、既不再参与匹配也没有释放入口。

其余同义路径(后台退回大厅、超时重开、打手退单通过)本来都会解绑,只有问题单这条漏了,属口径不一致。
现在把解绑条件从「仅取消」扩到「取消或退回大厅」;「退回打手重做」保持占用(货还在这一单上履约)。
调用位置仍在状态 UPDATE 之前——该 UPDATE 在 open/cancelled 时会清空 friend_added_at,
清完再解绑会把已确认加好友的货误判成可回池(二次出货)。

验证:真实库跑通两条路径——退回打手重做(现货仍 consumed+绑定的、标记保留、打手端仍「已匹配-待加好友」)
与退回大厅(现货回 in_stock、解绑、标记摘除、打手端变「已通过(在库待匹配)」);后端 520 项单测全绿。
This commit is contained in:
yml2213
2026-10-01 12:22:56 +08:00
parent 40ee36d72a
commit 9573acc59d
2 changed files with 27 additions and 14 deletions
@@ -240,7 +240,7 @@ test('没解绑到现货时也必须摘掉工单上的寄售标记(老帖 /
assert.equal(detach!.values[3], null, '无现货可解绑时应按工单整体摘标记')
})
test('问题单处置取消:先解绑寄卖现货,再改工单状态', async () => {
test('问题单处置离开履约态(取消 / 退回大厅)都要先解绑寄卖现货', async () => {
const readFile = await import('node:fs/promises')
const src = await readFile.readFile(
new URL('../../repositories/worker-platform/work-order-issue-repo.ts', import.meta.url),
@@ -253,13 +253,18 @@ test('问题单处置取消:先解绑寄卖现货,再改工单状态', async
const releaseIndex = body.indexOf(
'releaseConsignmentInventoryBindingForWorkOrderWithClient(client, input.workOrderId',
)
assert.ok(releaseIndex > 0, '取消问题单必须解绑被本工单占用的寄卖现货,否则现货永久占库不还')
assert.ok(
body.includes("if (targetStatus === 'cancelled')"),
'只对「取消」处置解绑:退回打手重做 / 退回大厅时货还在履约,不能解绑',
)
assert.ok(releaseIndex > 0, '处置问题单必须解绑被本工单占用的寄卖现货,否则现货永久占库不还')
// 顺序很重要:那条 UPDATE 会在取消时把 friend_added_at 清空,而"是否改判作废"正是看这个字段。
// 「退回大厅」也必须解绑:后台退回大厅 / 超时重开 / 打手退单通过这三条同义路径都会解绑,
// 只有问题单这条漏了,导致卖家端一直显示「履约中 + 关联订单状态已变化,请联系客服核对」。
assert.ok(
body.includes("if (targetStatus === 'cancelled' || targetStatus === 'open')"),
'取消与退回大厅都要解绑',
)
// 退回打手重做必须保持占用:货还在这一单上履约
assert.ok(body.includes('return_to_worker'), '未找到退回打手重做的分支(该分支不能解绑)')
// 顺序很重要:那条 UPDATE 在 open/cancelled 时会把 friend_added_at 清空,而"是否改判作废"正是看这个字段。
// 清空之后再解绑,会把已加好友的现货退回在库池 → 二次出货。
const updateIndex = body.indexOf('UPDATE work_orders')
assert.ok(updateIndex > 0, '未找到工单状态更新语句')