feat(orders): 订单读取与筛选只认渠道/状态三列
- 展示与筛选全部改读 fulfillment_channel/status,不再回退旧列 - 支持 third_party_voucher 与 archived,legacy_platform 映射为归档 - 前端类型、筛选项与标签同步
This commit is contained in:
@@ -292,10 +292,16 @@ function buildOrderForFulfillmentTest(): OrderListRow {
|
||||
}
|
||||
}
|
||||
|
||||
const CHANNEL_VALUES = new Set(['work_order', 'affiliate_dash', 'third_party_voucher', 'manual'])
|
||||
|
||||
function buildOrderItemForFulfillmentTest(
|
||||
id: number,
|
||||
fulfillmentMode: string | null,
|
||||
patch: Partial<OrderItemRow> = {},
|
||||
): OrderItemRow {
|
||||
const channel = fulfillmentMode && CHANNEL_VALUES.has(fulfillmentMode) ? fulfillmentMode : null
|
||||
const status =
|
||||
fulfillmentMode === 'legacy_platform' ? 'archived' : channel ? 'assigned' : 'pending'
|
||||
return {
|
||||
id,
|
||||
order_id: 501,
|
||||
@@ -303,7 +309,9 @@ function buildOrderItemForFulfillmentTest(
|
||||
sku_name: `商品-${id}`,
|
||||
quantity: 1,
|
||||
spec_json: { itemTitle: `商品-${id}`, skuNick: `规格-${id}` },
|
||||
fulfillment_mode: fulfillmentMode,
|
||||
fulfillment_channel: channel,
|
||||
fulfillment_status: status,
|
||||
...patch,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -321,7 +329,7 @@ test('人工单即使有已核销快照也仍然判为 manual,核销码单独
|
||||
assert.equal(mapped.canClaimH5, false)
|
||||
})
|
||||
|
||||
test('自动发货与历史平台按 fulfillment_mode 区分,不再按 provider 猜', () => {
|
||||
test('自动发货与历史归档按渠道/状态区分,不再按 provider 猜', () => {
|
||||
const affiliate = resolveOrderFulfillmentSummary({
|
||||
items: [buildOrderItemForFulfillmentTest(1, 'affiliate_dash')],
|
||||
})
|
||||
@@ -331,7 +339,7 @@ test('自动发货与历史平台按 fulfillment_mode 区分,不再按 provide
|
||||
|
||||
assert.equal(affiliate.fulfillmentMode, 'affiliate_dash')
|
||||
assert.equal(affiliate.canClaimH5, true)
|
||||
assert.equal(legacy.fulfillmentMode, 'legacy_platform')
|
||||
assert.equal(legacy.fulfillmentMode, 'archived')
|
||||
assert.equal(legacy.canClaimH5, false)
|
||||
})
|
||||
|
||||
@@ -358,3 +366,35 @@ test('核销码状态汇总:无、单一、混合', () => {
|
||||
{ hasVoucher: true, voucherState: 'mixed' },
|
||||
)
|
||||
})
|
||||
|
||||
test('v2 读取口径:归档状态优先于旧 fulfillment_mode', () => {
|
||||
const summary = resolveOrderFulfillmentSummary({
|
||||
items: [buildOrderItemForFulfillmentTest(1, 'work_order', { fulfillment_status: 'archived' })],
|
||||
})
|
||||
assert.equal(summary.fulfillmentMode, 'archived')
|
||||
})
|
||||
|
||||
test('v2 读取口径:渠道列优先于旧 fulfillment_mode', () => {
|
||||
const summary = resolveOrderFulfillmentSummary({
|
||||
items: [
|
||||
buildOrderItemForFulfillmentTest(1, 'manual', {
|
||||
fulfillment_status: 'assigned',
|
||||
fulfillment_channel: 'third_party_voucher',
|
||||
}),
|
||||
],
|
||||
})
|
||||
assert.equal(summary.fulfillmentMode, 'third_party_voucher')
|
||||
})
|
||||
|
||||
test('v2 读取口径:状态 pending 且无渠道时判为待分类', () => {
|
||||
const summary = resolveOrderFulfillmentSummary({
|
||||
items: [
|
||||
buildOrderItemForFulfillmentTest(1, 'manual', {
|
||||
fulfillment_status: 'pending',
|
||||
fulfillment_channel: null,
|
||||
}),
|
||||
],
|
||||
})
|
||||
assert.equal(summary.fulfillmentMode, 'pending')
|
||||
assert.equal(summary.pendingItemCount, 1)
|
||||
})
|
||||
|
||||
@@ -56,7 +56,7 @@ export function mapAdminOrderListItem(
|
||||
skuNick: itSkuNick,
|
||||
matchSku: itMatchSku,
|
||||
quantity: Math.max(1, Number(orderItem.quantity || 1)),
|
||||
fulfillmentMode: normalizeOrderItemFulfillmentMode(orderItem.fulfillment_mode),
|
||||
fulfillmentMode: resolveOrderItemFulfillmentMode(orderItem),
|
||||
}
|
||||
})
|
||||
resolvedItemTitle = itemsList[0]?.itemTitle || ''
|
||||
@@ -141,9 +141,11 @@ export function mapAdminOrderListItem(
|
||||
const ORDER_ITEM_FULFILLMENT_MODES = new Set<AdminOrderItemFulfillmentMode>([
|
||||
'work_order',
|
||||
'affiliate_dash',
|
||||
'third_party_voucher',
|
||||
'legacy_platform',
|
||||
'manual',
|
||||
'pending',
|
||||
'archived',
|
||||
])
|
||||
|
||||
export function normalizeOrderItemFulfillmentMode(value: unknown): AdminOrderItemFulfillmentMode {
|
||||
@@ -153,6 +155,23 @@ export function normalizeOrderItemFulfillmentMode(value: unknown): AdminOrderIte
|
||||
return ORDER_ITEM_FULFILLMENT_MODES.has(mode) ? mode : 'pending'
|
||||
}
|
||||
|
||||
/**
|
||||
* v2 读取口径:只认渠道/状态三列,不再回退旧 fulfillment_mode。
|
||||
*
|
||||
* archived → archived
|
||||
* channel → 该渠道
|
||||
* 其余 → pending
|
||||
*/
|
||||
export function resolveOrderItemFulfillmentMode(
|
||||
item: Pick<OrderItemRow, 'fulfillment_status' | 'fulfillment_channel'> | null | undefined,
|
||||
): AdminOrderItemFulfillmentMode {
|
||||
if (!item) return 'pending'
|
||||
if (String(item.fulfillment_status || '').trim() === 'archived') return 'archived'
|
||||
const channel = String(item.fulfillment_channel || '').trim()
|
||||
if (channel) return normalizeOrderItemFulfillmentMode(channel)
|
||||
return 'pending'
|
||||
}
|
||||
|
||||
export function resolveVoucherSummary(vouchers: KuaishouIndustryVoucherRow[] = []): {
|
||||
hasVoucher: boolean
|
||||
voucherState: AdminVoucherState
|
||||
@@ -182,7 +201,7 @@ export function resolveVoucherSummary(vouchers: KuaishouIndustryVoucherRow[] = [
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单级履约摘要:只读 order_items.fulfillment_mode,不再按 provider 或核销码推断。
|
||||
* 订单级履约摘要:只读 order_items.fulfillment_channel / fulfillment_status。
|
||||
* 多商品订单出现不同模式时显示 mixed;尚未判定的订单项单独计数。
|
||||
*/
|
||||
export function resolveOrderFulfillmentSummary({
|
||||
@@ -205,9 +224,7 @@ export function resolveOrderFulfillmentSummary({
|
||||
canClaimH5: boolean
|
||||
} {
|
||||
const normalizedItems = Array.isArray(items) ? items : []
|
||||
const itemModes = normalizedItems.map((item) =>
|
||||
normalizeOrderItemFulfillmentMode(item.fulfillment_mode),
|
||||
)
|
||||
const itemModes = normalizedItems.map((item) => resolveOrderItemFulfillmentMode(item))
|
||||
const knownModes = Array.from(
|
||||
new Set(
|
||||
itemModes.filter((mode): mode is Exclude<typeof mode, 'pending'> => mode !== 'pending'),
|
||||
@@ -232,7 +249,7 @@ export function resolveOrderFulfillmentSummary({
|
||||
task.executor_key === 'kuaishou_ct_assisted' || task.executor_key === 'kuaishou_feifei',
|
||||
)
|
||||
) {
|
||||
fulfillmentMode = 'legacy_platform'
|
||||
fulfillmentMode = 'archived'
|
||||
} else {
|
||||
fulfillmentMode = 'pending'
|
||||
}
|
||||
|
||||
@@ -67,6 +67,7 @@ import {
|
||||
mapAdminOrderListItem,
|
||||
normalizeOrderItemFulfillmentMode,
|
||||
resolveOrderFulfillmentSummary,
|
||||
resolveOrderItemFulfillmentMode,
|
||||
summarizeOrderItems,
|
||||
} from './admin-order-read-helpers.js'
|
||||
import {
|
||||
@@ -149,10 +150,12 @@ export async function getAdminOrders(
|
||||
const ADMIN_ORDER_FULFILLMENT_MODES = new Set([
|
||||
'work_order',
|
||||
'affiliate_dash',
|
||||
'legacy_platform',
|
||||
'third_party_voucher',
|
||||
'manual',
|
||||
'legacy_platform',
|
||||
'mixed',
|
||||
'pending',
|
||||
'archived',
|
||||
])
|
||||
|
||||
function normalizeOrderFulfillmentModeFilter(value: unknown): string {
|
||||
@@ -278,7 +281,7 @@ export async function getAdminOrderDetail(
|
||||
revenueFen,
|
||||
refundedFen,
|
||||
refundableFen: Math.max(0, revenueFen - refundedFen),
|
||||
fulfillmentMode: normalizeOrderItemFulfillmentMode(item.fulfillment_mode),
|
||||
fulfillmentMode: resolveOrderItemFulfillmentMode(item),
|
||||
deliveryMode: resolveOrderItemDeliveryMode(tasks, item.id),
|
||||
spec:
|
||||
item.spec_json && typeof item.spec_json === 'object'
|
||||
|
||||
Reference in New Issue
Block a user