fix(consignment): 退库后不再带出上一单买家资料,撤单清掉上一手验收痕迹

现货退回仓库后只留卖家提报,不再挂买家角色、赠送凭证和店铺;工单撤单、退回、抢单时清掉验收与备注,买家下单资料仍保留。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
yml2213
2026-10-05 14:55:42 +08:00
co-authored by Cursor
parent dbdafd3dc4
commit eae78aae34
10 changed files with 152 additions and 51 deletions
@@ -156,6 +156,10 @@ function mapConsignmentEvidence(source: {
}
export function mapConsignmentInventory(row: ConsignmentInventoryRow) {
// 买家资料和赠送凭证都挂在「当前绑定的工单」上。退库后现货回到卖家仓库,
// 只保留卖家自己的提报信息,不再把上一单买家角色、主页截图、赠送凭证带出来。
const showingMatchedBuyer = row.status === 'consumed'
const evidence = mapConsignmentEvidence(row)
return {
id: Number(row.id),
inventoryNo: row.inventory_no,
@@ -170,7 +174,7 @@ export function mapConsignmentInventory(row: ConsignmentInventoryRow) {
brillianceCount: Number(row.brilliance_count || 0),
costPriceFen: Number(row.cost_price_fen || 0),
buyerName: row.buyer_name || '',
shopName: row.shop_name || '',
shopName: showingMatchedBuyer ? row.shop_name || '' : '',
inboundBatch: row.inbound_batch || '',
sellerContact: row.seller_contact || '',
sellerGameId: row.seller_game_id || '',
@@ -191,17 +195,32 @@ export function mapConsignmentInventory(row: ConsignmentInventoryRow) {
allowMatching: Boolean(row.allow_matching),
status: row.status,
allocationStatus: row.allocation_status || '待安排',
boundWorkOrderId: row.bound_work_order_id ? Number(row.bound_work_order_id) : null,
boundPlatformOrderId: row.bound_platform_order_id || '',
boundWorkOrderId:
showingMatchedBuyer && row.bound_work_order_id ? Number(row.bound_work_order_id) : null,
boundPlatformOrderId: showingMatchedBuyer ? row.bound_platform_order_id || '' : '',
sourceType: row.source_type,
sourceSubmissionId: row.source_submission_id ? Number(row.source_submission_id) : null,
/** 唯一锚点:卖家端看到的「寄卖单号」就是它,客服端也用同一个号 */
sourceSubmissionNo: row.source_submission_no || '',
...mapConsignmentEvidence(row),
buyerInfo: extractConsignmentBuyerInfo({
materialJson: row.bound_work_order_material_json,
requirementJson: row.bound_work_order_requirement_json,
}),
...evidence,
...(showingMatchedBuyer
? {}
: {
giftEvidenceImages: [],
giftEvidenceNote: '',
giftEvidenceSubmittedAt: '',
giftWorkOrderNo: '',
giftWorkOrderStatus: '',
giftPhase: '',
giftFriendAddedAt: '',
giftEvidenceReviewStatus: 'none' as const,
}),
buyerInfo: showingMatchedBuyer
? extractConsignmentBuyerInfo({
materialJson: row.bound_work_order_material_json,
requirementJson: row.bound_work_order_requirement_json,
})
: null,
workerId: row.worker_id ? Number(row.worker_id) : null,
workerName: row.worker_name || '',
workerPhone: row.worker_phone || '',
@@ -27,6 +27,37 @@ function inventoryRow(overrides: Record<string, unknown> = {}) {
} as never
}
test('退库后不再带出上一单买家资料和赠送凭证,卖家提报截图还在', () => {
const mapped = mapConsignmentInventory(
inventoryRow({
status: 'in_stock',
bound_work_order_id: 99,
bound_platform_order_id: '260930-371164485221051',
shop_name: '木塔网游专营店',
gift_evidence_json: {
note: '已赠送',
imageUrls: ['https://cdn.example.com/gift.png'],
},
gift_work_order_no: 'WO1',
gift_work_order_status: 'in_progress',
bound_work_order_material_json: {
collect: {
fields: { gameNickname: '低陀小情在快手', gameId: '3489287354' },
screenshots: ['https://cdn.example.com/buyer.png'],
},
},
}),
)
assert.equal(mapped.buyerInfo, null)
assert.deepEqual(mapped.giftEvidenceImages, [])
assert.equal(mapped.giftWorkOrderNo, '')
assert.equal(mapped.boundWorkOrderId, null)
assert.equal(mapped.boundPlatformOrderId, '')
assert.equal(mapped.shopName, '')
assert.deepEqual(mapped.submissionScreenshots, ['https://cdn.example.com/publish-1.png'])
})
test('赠送凭证从工单验收资料的 imageUrls 与 files 两处取图并去重', () => {
const mapped = mapConsignmentInventory(
inventoryRow({
@@ -17,6 +17,7 @@ import {
} from '../../repositories/worker-platform/consignment-deposit-repo.js'
import {
CONSIGNMENT_FULFILLMENT_TYPE,
CLEAR_DELIVERY_RESIDUE_SQL,
RESET_GIFT_FLOW_SQL,
createWorkOrderEvent,
createWorkOrderEventWithClient,
@@ -1103,11 +1104,7 @@ export async function revokeWorkOrderConsignmentFulfillment(input: {
assigned_worker_id = NULL,
assigned_at = NULL,
deadline_at = NULL,
submitted_at = NULL,
accepted_at = NULL,
acceptance_json = '{}'::jsonb,
draft_acceptance_json = '{}'::jsonb,
problem_note = '',
${CLEAR_DELIVERY_RESIDUE_SQL},
published_at = NULL,
pinned_at = NULL,
${RESET_GIFT_FLOW_SQL},
@@ -433,13 +433,17 @@ export async function listWorkerConsignments(
? workOrderById.get(Number(inv.bound_work_order_id))
: undefined
const stage = resolveStage(String(sub.status || ''), inv)
const evidence = extractConsignmentGiftEvidenceFromWorkOrder(boundWo)
// 只有仍被本单占用的现货才展示买家。退回仓库后这件货还是卖家的,上一单买家资料不再跟着走。
const showingMatchedBuyer = inv?.status === 'consumed' && Boolean(boundWo)
const evidence = showingMatchedBuyer
? extractConsignmentGiftEvidenceFromWorkOrder(boundWo)
: { giftEvidenceImages: [], giftEvidenceNote: '', giftEvidenceSubmittedAt: '' }
return {
/** 唯一锚点:提报单号贯穿发布→审核→在库→匹配→冷却→赠送→结算 */
consignmentNo: sub.submission_no,
submissionId: sub.id,
inventoryId: inv?.id ?? null,
workOrderId: inv?.bound_work_order_id ?? null,
workOrderId: showingMatchedBuyer ? (inv?.bound_work_order_id ?? null) : null,
itemName: sub.item_name,
system: sub.system,
serverZone: sub.server_zone,
@@ -459,10 +463,10 @@ export async function listWorkerConsignments(
createdAt: sub.created_at,
...stage,
/** 冷却截止时间,前端拿它显示倒计时 */
giftAvailableAt: boundWo?.gift_available_at ?? null,
friendAddedAt: boundWo?.friend_added_at ?? null,
giftAvailableAt: showingMatchedBuyer ? (boundWo?.gift_available_at ?? null) : null,
friendAddedAt: showingMatchedBuyer ? (boundWo?.friend_added_at ?? null) : null,
sellerInfo: extractConsignmentSellerInfoFromSubmission(sub),
buyerInfo: extractConsignmentBuyerInfoFromWorkOrder(boundWo),
buyerInfo: showingMatchedBuyer ? extractConsignmentBuyerInfoFromWorkOrder(boundWo) : null,
}
}
@@ -472,7 +476,10 @@ export async function listWorkerConsignments(
? workOrderById.get(Number(inv.bound_work_order_id))
: undefined
const stage = resolveStage('approved', inv)
const evidence = extractConsignmentGiftEvidenceFromWorkOrder(boundWo)
const showingMatchedBuyer = inv.status === 'consumed' && Boolean(boundWo)
const evidence = showingMatchedBuyer
? extractConsignmentGiftEvidenceFromWorkOrder(boundWo)
: { giftEvidenceImages: [], giftEvidenceNote: '', giftEvidenceSubmittedAt: '' }
return {
consignmentNo: '客服手工入库',
...(stage.canConfirmFriend || stage.canSubmitEvidence
@@ -480,7 +487,7 @@ export async function listWorkerConsignments(
: {}),
submissionId: null,
inventoryId: inv.id,
workOrderId: inv.bound_work_order_id ?? null,
workOrderId: showingMatchedBuyer ? inv.bound_work_order_id : null,
itemName: inv.item_name,
system: inv.system,
serverZone: inv.server_zone,
@@ -496,10 +503,10 @@ export async function listWorkerConsignments(
giftEvidenceSubmittedAt: evidence.giftEvidenceSubmittedAt,
createdAt: inv.created_at,
...stage,
giftAvailableAt: boundWo?.gift_available_at ?? null,
friendAddedAt: boundWo?.friend_added_at ?? null,
giftAvailableAt: showingMatchedBuyer ? (boundWo?.gift_available_at ?? null) : null,
friendAddedAt: showingMatchedBuyer ? (boundWo?.friend_added_at ?? null) : null,
sellerInfo: extractConsignmentSellerInfoFromInventory(inv),
buyerInfo: extractConsignmentBuyerInfoFromWorkOrder(boundWo),
buyerInfo: showingMatchedBuyer ? extractConsignmentBuyerInfoFromWorkOrder(boundWo) : null,
}
}