fix(pdd): 停止旧单刷匹配日志,并修复订单列表商品显示为 0
同步时已有工单/匹配结果未变不再写日志;列表按 Number(order_id) 挂 items,并补齐 PDD goods_name 回退与嵌套商品解析。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -101,6 +101,42 @@ test('mapAdminOrderListItem falls back to order raw_payload_json when orderItems
|
||||
assert.equal(mapped.itemSummary, '和平精英地铁逃生装备满钻低价苏尔南怒嚎暗潮手枪 (安卓血宴1钻)')
|
||||
})
|
||||
|
||||
test('mapAdminOrderListItem falls back to PDD goods_name/out_sku_sn when orderItems empty', () => {
|
||||
const order: OrderListRow = {
|
||||
id: 3,
|
||||
provider: 'pdd',
|
||||
platform: 'pdd',
|
||||
shop_id: 'xiangrikui',
|
||||
shop_name: '向日葵',
|
||||
platform_order_id: '260915-72034516082531',
|
||||
order_status: 'paid',
|
||||
pay_status: 'paid',
|
||||
buyer_id: '',
|
||||
buyer_name: '',
|
||||
receiver_contact: '',
|
||||
total_amount: 34100,
|
||||
currency: 'CNY',
|
||||
raw_payload_json: {
|
||||
order_sn: '260915-72034516082531',
|
||||
goods_name: '和平精英地铁逃生苏尔南暗潮怒嚎血宴',
|
||||
spec: '安卓怒嚎3钻',
|
||||
out_sku_sn: '安卓怒嚎3钻',
|
||||
goods_number: 1,
|
||||
order_amount: 34100,
|
||||
},
|
||||
paid_at: '2026-09-15T02:48:00.000Z',
|
||||
created_at: '2026-09-15T02:48:00.000Z',
|
||||
updated_at: '2026-09-15T02:48:00.000Z',
|
||||
}
|
||||
|
||||
const mapped = mapAdminOrderListItem(order, { orderItems: [], tasks: [] })
|
||||
|
||||
assert.equal(mapped.itemTitle, '和平精英地铁逃生苏尔南暗潮怒嚎血宴')
|
||||
assert.equal(mapped.skuNick, '安卓怒嚎3钻')
|
||||
assert.equal(mapped.itemCount, 1)
|
||||
assert.equal(mapped.totalQuantity, 1)
|
||||
})
|
||||
|
||||
test('summarizeOrderItems formats multiple items cleanly', () => {
|
||||
const items: OrderItemRow[] = [
|
||||
{
|
||||
|
||||
@@ -93,7 +93,7 @@ export async function getAdminOrders(
|
||||
dateTo: normalizeDateQuery(query.dateTo, true),
|
||||
})
|
||||
|
||||
const orderIds = items.map((item) => item.id)
|
||||
const orderIds = items.map((item) => Number(item.id)).filter((id) => id > 0)
|
||||
const oids = items.map((item) => item.platform_order_id).filter(Boolean)
|
||||
const [orderItems, tasks, vouchers] = await Promise.all([
|
||||
listOrderItemsByOrderIds(orderIds),
|
||||
@@ -105,23 +105,29 @@ export async function getAdminOrders(
|
||||
const vouchersByOid = groupRowsByOid(vouchers)
|
||||
|
||||
return {
|
||||
items: items.map((item) =>
|
||||
mapAdminOrderListItem(item, {
|
||||
orderItems: orderItemsByOrderId.get(item.id) || [],
|
||||
tasks: tasksByOrderId.get(item.id) || [],
|
||||
items: items.map((item) => {
|
||||
const orderId = Number(item.id)
|
||||
return mapAdminOrderListItem(item, {
|
||||
orderItems: orderItemsByOrderId.get(orderId) || [],
|
||||
tasks: tasksByOrderId.get(orderId) || [],
|
||||
vouchers: vouchersByOid.get(item.platform_order_id) || [],
|
||||
}),
|
||||
),
|
||||
})
|
||||
}),
|
||||
pagination: { page, pageSize, total },
|
||||
}
|
||||
}
|
||||
|
||||
function groupRowsByOrderId<T extends { order_id: number }>(rows: T[]): Map<number, T[]> {
|
||||
function groupRowsByOrderId<T extends { order_id: number | string }>(rows: T[]): Map<number, T[]> {
|
||||
const grouped = new Map<number, T[]>()
|
||||
for (const row of rows) {
|
||||
const group = grouped.get(row.order_id) || []
|
||||
// pg BIGINT 常以 string 返回;统一 Number 键,避免列表挂不上 order_items →「商品 0」。
|
||||
const orderId = Number(row.order_id)
|
||||
if (!Number.isFinite(orderId) || orderId <= 0) {
|
||||
continue
|
||||
}
|
||||
const group = grouped.get(orderId) || []
|
||||
group.push(row)
|
||||
grouped.set(row.order_id, group)
|
||||
grouped.set(orderId, group)
|
||||
}
|
||||
return grouped
|
||||
}
|
||||
|
||||
@@ -462,6 +462,8 @@ export function resolveOrderItemTitle(
|
||||
spec.goods_name,
|
||||
spec.goodsName,
|
||||
spec.productName,
|
||||
snapshot.goods_name,
|
||||
snapshot.goodsName,
|
||||
snapshot.productName,
|
||||
])
|
||||
|
||||
@@ -482,6 +484,13 @@ export function resolveOrderItemTitle(
|
||||
orderPayload.productName,
|
||||
body.title,
|
||||
orderPayload.title,
|
||||
// 拼多多 MMS 字段
|
||||
body.goods_name,
|
||||
orderPayload.goods_name,
|
||||
body.goodsName,
|
||||
orderPayload.goodsName,
|
||||
body.spec,
|
||||
orderPayload.spec,
|
||||
])
|
||||
if (fromOrder) {
|
||||
return fromOrder
|
||||
@@ -533,6 +542,12 @@ export function resolveOrderItemSkuNick(
|
||||
snapshot.externalSkuName,
|
||||
snapshot.externalSkuNameNormalized,
|
||||
snapshot.skuNick,
|
||||
spec.outSkuSn,
|
||||
spec.out_sku_sn,
|
||||
snapshot.outSkuSn,
|
||||
snapshot.out_sku_sn,
|
||||
spec.spec,
|
||||
snapshot.spec,
|
||||
spec.skuName,
|
||||
])
|
||||
|
||||
@@ -552,7 +567,17 @@ export function resolveOrderItemSkuNick(
|
||||
orderPayload.body && typeof orderPayload.body === 'object' ? orderPayload.body : orderPayload,
|
||||
)
|
||||
const ext = parseExtRecord(body.ext || orderPayload.ext)
|
||||
const fromOrder = pickFirstNonEmpty([ext.skuNick, body.skuNick, orderPayload.skuNick])
|
||||
const fromOrder = pickFirstNonEmpty([
|
||||
ext.skuNick,
|
||||
body.skuNick,
|
||||
orderPayload.skuNick,
|
||||
body.out_sku_sn,
|
||||
orderPayload.out_sku_sn,
|
||||
body.outSkuSn,
|
||||
orderPayload.outSkuSn,
|
||||
body.spec,
|
||||
orderPayload.spec,
|
||||
])
|
||||
if (fromOrder) {
|
||||
return fromOrder
|
||||
}
|
||||
@@ -581,8 +606,9 @@ export function resolveOrderItemDeliveryMode(
|
||||
tasks: TaskLike[] | null | undefined,
|
||||
orderItemId: number | string,
|
||||
): string {
|
||||
const normalizedOrderItemId = Number(orderItemId)
|
||||
const task = (Array.isArray(tasks) ? tasks : []).find(
|
||||
(item) => item.order_item_id === orderItemId,
|
||||
(item) => Number(item.order_item_id) === normalizedOrderItemId,
|
||||
)
|
||||
|
||||
if (!task) {
|
||||
|
||||
Reference in New Issue
Block a user