fix(consignment): 内部库存履约后不再把买家资料暴露给上一手打手

退回大厅留下的 last_assigned 在状态离开待接单后会重新可见。履约时摘掉上一手,并清掉已经漏出的内部现货工单。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
yml2213
2026-10-05 19:18:43 +08:00
co-authored by Cursor
parent eae78aae34
commit 250c456a46
8 changed files with 131 additions and 38 deletions
@@ -599,7 +599,13 @@ export async function fulfillWorkOrderWithConsignment(input: {
}
}
publishWorkOrderRealtimeChange({ workOrderId: Number(updatedOrder.id), hallChanged: true })
publishWorkOrderRealtimeChange({
workOrderId: Number(updatedOrder.id),
hallChanged: true,
// 履约会清掉 last_assigned_worker_id,广播时工单上已经没有上一手,
// 要显式带上他,否则「我的订单」缓存最长 30 秒还显示这张单。
workerIds: [Number(workOrder.last_assigned_worker_id || 0)].filter((id) => id > 0),
})
return {
order: mapWorkOrderAdmin(updatedOrder),
@@ -16,6 +16,7 @@ import {
listWorkOrderEventsByOrderId,
listWorkOrders,
markWorkerWorkOrderViewed,
workerOwnsWorkOrder,
upsertWorkerWorkOrderNote,
} from '../../repositories/worker-platform/index.js'
import type { JsonObject } from '../../types/json.js'
@@ -181,10 +182,7 @@ export async function getWorkerMyOrderEvents(workOrderId: number | string, sessi
const workOrder = await getRequiredWorkOrder(workOrderId)
const workerId = Number(session.workerId)
const sharingShare = await getWorkOrderShare(workOrder.id, workerId)
const isOrderOwner =
Number(workOrder.assigned_worker_id || 0) === workerId ||
Number(workOrder.last_assigned_worker_id || 0) === workerId
if (!sharingShare && !isOrderOwner) {
if (!sharingShare && !workerOwnsWorkOrder(workOrder, workerId)) {
throw createHttpError('只能查看自己订单的流转记录', {
statusCode: 403,
errorCode: 'work_order_events_owner_required',
@@ -345,10 +343,7 @@ export async function saveWorkerOrderNote(
const worker = await getRequiredWorker(workerId)
const sharingShare = await getWorkOrderShare(workOrder.id, workerId)
const isOrderOwner =
Number(workOrder.assigned_worker_id || 0) === workerId ||
Number(workOrder.last_assigned_worker_id || 0) === workerId
if (!sharingShare && !isOrderOwner) {
if (!sharingShare && !workerOwnsWorkOrder(workOrder, workerId)) {
throw createHttpError('只能修改自己的订单备注', {
statusCode: 403,
errorCode: 'work_order_note_owner_required',
@@ -380,10 +375,7 @@ export async function markWorkerOrderRead(
const workOrder = await getRequiredWorkOrder(workOrderId)
const workerId = Number(session.workerId)
const sharingShare = await getWorkOrderShare(workOrder.id, workerId)
const isOrderOwner =
Number(workOrder.assigned_worker_id || 0) === workerId ||
Number(workOrder.last_assigned_worker_id || 0) === workerId
if (!sharingShare && !isOrderOwner) {
if (!sharingShare && !workerOwnsWorkOrder(workOrder, workerId)) {
throw createHttpError('只能标记自己的订单为已读', {
statusCode: 403,
errorCode: 'work_order_read_owner_required',
@@ -73,7 +73,10 @@ import {
} from '../../repositories/worker-platform/consignment-repo.js'
import { ADMIN_PERMISSION_KEYS } from '../admin/admin-rbac-service.js'
import { updateAdminConsignmentInventory } from './consignment-admin-service.js'
import { parkWorkOrderWaitingFriendAddWithClient } from '../../repositories/worker-platform/work-order-gift-repo.js'
import {
parkWorkOrderWaitingFriendAddWithClient,
workerOwnsWorkOrder,
} from '../../repositories/worker-platform/work-order-gift-repo.js'
import {
assertConsignmentRevocableWorkOrderStatus,
resolveRevocableConsignmentInventoryId,
@@ -2308,6 +2311,10 @@ test('内部现货履约停在「待加好友」:不写 friend_added_at,也
assert.ok(sql.includes('friend_added_at = NULL'), '不能自动确认加好友')
assert.ok(sql.includes('gift_available_at = NULL'))
assert.ok(sql.includes('deadline_at = NULL'), '没有打手在跑,不应背任务时限')
assert.ok(
sql.includes('last_assigned_worker_id = NULL'),
'内部现货必须摘掉上一手打手,否则状态离开 open 后他会重新看到买家资料',
)
assert.ok(sql.includes("acceptance_mode = 'friend_gift'"))
assert.ok(!sql.includes('friend_added_at = $2'), '不能把当前时间写成已加好友')
@@ -2321,6 +2328,34 @@ test('内部现货履约停在「待加好友」:不写 friend_added_at,也
)
})
test('内部现货履约后,上一手打手不再拥有这张工单', () => {
const internalOrder = {
assigned_worker_id: null,
last_assigned_worker_id: 183,
material_json: {
consignment: { inventoryId: 414, fulfillmentType: 'internal_stock' },
},
}
assert.equal(workerOwnsWorkOrder(internalOrder, 183), false)
assert.equal(
workerOwnsWorkOrder({ ...internalOrder, assigned_worker_id: 183 }, 183),
true,
'重新指派给本人后仍然是他的单',
)
assert.equal(
workerOwnsWorkOrder(
{
assigned_worker_id: null,
last_assigned_worker_id: 183,
material_json: {},
},
183,
),
true,
'普通退回后的历史单仍可回看',
)
})
test('停在待加好友时保留商品规则已配的冷却时长', async () => {
const calls: Array<{ sql: string; values?: unknown[] }> = []
const client = {