修复:寄售登记人改名后显示与筛选同步

This commit is contained in:
2026-11-12 12:02:18 +08:00
parent 4159a435d5
commit be7f6f6f09
13 changed files with 357 additions and 10 deletions
@@ -59,6 +59,7 @@ function buildWorkOrderStatisticsCacheKey(filters: JsonObject): string {
filters.keyword || '',
filters.shopNames || [],
filters.workerSharingId || 0,
filters.consignmentSupplierWorkerId || 0,
filters.workerId || 0,
filters.workerLevelIds || [],
filters.categoryId || 0,
@@ -149,6 +150,9 @@ export function resolveAdminWorkOrderListFilters(query: JsonObject = {}): ListIn
keyword,
shopNames,
workerSharingId: workerId,
// 「接单人员」筛选同时覆盖寄售供货人:内部寄售直接履约不写 assigned_worker_id,
// 供货关系只存在 consignment_inventories.worker_id,必须补进可见集合。
...(workerId > 0 ? { consignmentSupplierWorkerId: workerId } : {}),
workerLevelIds,
vipEvidencePending,
...(acceptanceMode ? { acceptanceMode } : {}),
@@ -1,7 +1,7 @@
import assert from 'node:assert/strict'
import test from 'node:test'
import { normalizeInventoryDate } from './consignment-admin-service.js'
import { mapConsignmentInventory, normalizeInventoryDate } from './consignment-admin-service.js'
test('寄售仓库入库日期筛选只接受合法的 YYYY-MM-DD', () => {
assert.equal(normalizeInventoryDate('2026-11-05'), '2026-11-05')
@@ -10,3 +10,61 @@ test('寄售仓库入库日期筛选只接受合法的 YYYY-MM-DD', () => {
assert.equal(normalizeInventoryDate('2026/11/05'), undefined)
assert.equal(normalizeInventoryDate(''), undefined)
})
test('寄售库存改名后优先显示实时打手昵称,打手被删才回退快照', () => {
const base = {
id: 1,
inventory_no: 'INV1',
game_name: '和平精英',
category_id: null,
item_name: '测试物品',
system: '',
server_zone: '',
series: '',
diamond_level: 1,
brilliance_count: 0,
cost_price_fen: 0,
buyer_name: '',
inbound_batch: '',
seller_contact: '',
seller_game_id: '',
seller_payment_info: '',
seller_phone: '',
credentials_json: {},
screenshots_json: [],
remark: '',
allow_matching: true,
status: 'in_stock',
allocation_status: '待安排',
bound_order_id: null,
bound_work_order_id: null,
bound_platform_order_id: '',
shop_name: '',
source_type: 'manual',
source_submission_id: null,
inbound_at: '2026-11-01T00:00:00.000Z',
consumed_at: null,
created_at: '2026-11-01T00:00:00.000Z',
updated_at: '2026-11-01T00:00:00.000Z',
worker_id: 7,
worker_name: '旧昵称',
worker_phone: '111',
}
const renamed = mapConsignmentInventory({
...base,
live_worker_name: '新昵称',
live_worker_phone: '222',
} as never)
assert.equal(renamed.workerName, '新昵称')
assert.equal(renamed.workerPhone, '222')
// 打手被删除时 join 不到实时行,仍要能显示登记时快照
const deleted = mapConsignmentInventory({
...base,
live_worker_name: null,
live_worker_phone: null,
} as never)
assert.equal(deleted.workerName, '旧昵称')
assert.equal(deleted.workerPhone, '111')
})
@@ -222,8 +222,9 @@ export function mapConsignmentInventory(row: ConsignmentInventoryRow) {
})
: null,
workerId: row.worker_id ? Number(row.worker_id) : null,
workerName: row.worker_name || '',
workerPhone: row.worker_phone || '',
// 改名后以当前昵称为准;快照只用于打手被删除等无法实时关联的兜底。
workerName: row.live_worker_name || row.worker_name || '',
workerPhone: row.live_worker_phone || row.worker_phone || '',
assignedWorkerId: row.assigned_worker_id ? Number(row.assigned_worker_id) : null,
depositAmountFen: Number(row.deposit_amount_fen || 0),
contactSupporterId: row.contact_supporter_id ? Number(row.contact_supporter_id) : null,
@@ -265,8 +266,9 @@ export function mapConsignmentSubmission(row: ConsignmentSubmissionRow) {
),
askingPriceFen: Number(row.asking_price_fen || 0),
workerId: row.worker_id ? Number(row.worker_id) : null,
workerName: row.worker_name || '',
workerPhone: row.worker_phone || '',
// 改名后以当前昵称为准;快照只用于打手被删除等无法实时关联的兜底。
workerName: row.live_worker_name || row.worker_name || '',
workerPhone: row.live_worker_phone || row.worker_phone || '',
depositAmountFen: Number(row.deposit_amount_fen || 0),
contactSupporterId: row.contact_supporter_id ? Number(row.contact_supporter_id) : null,
contactSupporterName: row.contact_supporter_name || '',
@@ -41,6 +41,7 @@ test('后台:显式单号检索时忽略状态等排他筛选,只按单号
assert.equal(filters.vipEvidencePending, false)
// 接单人员:目标单可能根本不在这名打手的可见集合里
assert.equal(filters.workerSharingId, 0)
assert.equal(filters.consignmentSupplierWorkerId, undefined)
// 分类 / 等级 / 验收模式 / 赠送阶段 / 创建时间 / 定位工单
assert.equal(filters.categoryId, 0)
assert.deepEqual(filters.workerLevelIds, [])
@@ -77,6 +78,7 @@ test('后台:普通关键词(商品名/昵称)仍按原样下推全部筛
assert.deepEqual(filters.statuses, ['open', 'in_progress'])
assert.equal(filters.vipEvidencePending, true)
assert.equal(filters.workerSharingId, 7)
assert.equal(filters.consignmentSupplierWorkerId, 7)
assert.equal(filters.categoryId, 12)
assert.deepEqual(filters.workerLevelIds, [1, 2])
assert.equal(filters.acceptanceMode, 'friend_gift')
@@ -4,6 +4,7 @@ import test from 'node:test'
import type { WorkOrderShareRow } from '../../repositories/worker-platform/types.js'
import {
isWorkerOrderVipEvidencePending,
mapWorkOrderMaterialWithConsignmentWorker,
pickWorkerRepresentativeShare,
resolveWorkerOrderStatusTabs,
stripWorkerPersonalShareFields,
@@ -264,3 +265,36 @@ test('大厅广播快照必须剔除打手私有份额字段', () => {
assert.deepEqual(snapshot.sharingProgress, { joinedQuantity: 2, pendingSubmissionCount: 1 })
assert.equal(snapshot.workOrderId, 1)
})
test('寄售供货人改名后,工单 material 展示使用库存实时昵称', () => {
const material = {
consignment: {
inventoryId: 9,
workerName: '旧昵称',
workerPhone: '111',
itemName: '测试物品',
},
}
const renamed = mapWorkOrderMaterialWithConsignmentWorker(material, {
live_worker_name: '新昵称',
live_worker_phone: '222',
} as never) as { consignment: { workerName: string; workerPhone: string; itemName: string } }
assert.equal(renamed.consignment.workerName, '新昵称')
assert.equal(renamed.consignment.workerPhone, '222')
// 其它寄售字段不能被覆盖
assert.equal(renamed.consignment.itemName, '测试物品')
const fallback = mapWorkOrderMaterialWithConsignmentWorker(material, null) as {
consignment: { workerName: string }
}
assert.equal(fallback.consignment.workerName, '旧昵称')
// 历史上没有登记供货人的内部现货单,不能因为库存关联到打手就改标成「供货打手」
const noSnapshot = mapWorkOrderMaterialWithConsignmentWorker(
{ consignment: { inventoryId: 9, workerName: '' } },
{ live_worker_name: '新昵称', live_worker_phone: '222' } as never,
) as { consignment: { workerName: string } }
assert.equal(noSnapshot.consignment.workerName, '')
})
@@ -68,6 +68,40 @@ export function mapWorkOrderMaterial(value: unknown) {
}
}
/**
* 工单 material.consignment 里保存的是入库/履约时的打手昵称快照。
* 打手改名后,后台列表仍要显示当前昵称;有实时库存行时用它覆盖展示字段,
* 历史 JSON 本身不改写(保留登记时痕迹)。
*/
export function mapWorkOrderMaterialWithConsignmentWorker(
value: unknown,
consignmentInventory?: ConsignmentInventoryRow | null,
) {
const material = mapWorkOrderMaterial(value) as JsonObject
const liveWorkerName = String(
consignmentInventory?.live_worker_name || consignmentInventory?.worker_name || '',
).trim()
if (!liveWorkerName) return material
const consignment = material.consignment
if (!consignment || typeof consignment !== 'object' || Array.isArray(consignment)) {
return material
}
const consignmentRecord = consignment as JsonObject
// 只刷新「原本就登记过供货人」的单据,避免把历史上没有供货人快照的
// 内部现货单改标成「供货打手」(那会改变历史单的展示语义)。
if (!String(consignmentRecord.workerName || '').trim()) return material
return {
...material,
consignment: {
...consignmentRecord,
workerName: liveWorkerName,
workerPhone: String(
consignmentInventory?.live_worker_phone || consignmentInventory?.worker_phone || '',
).trim(),
},
}
}
/** 读取好友赠送模式的打手本人资料;主页截图访问链接需要读取时重签。 */
export function mapWorkOrderBoosterMaterial(value: unknown) {
const material = safeParseJson(value)
@@ -412,7 +446,10 @@ export function mapWorkOrderAdmin(
depositThresholdAmount: Number(
workOrder.deposit_threshold_amount || DEFAULT_DEPOSIT_THRESHOLD_AMOUNT,
),
material: mapWorkOrderMaterial(workOrder.material_json),
material: mapWorkOrderMaterialWithConsignmentWorker(
workOrder.material_json,
consignmentInventory,
),
requirement: {
fields: resolveRequirementFields(workOrder),
},