refactor(finance)!: 事实维度与接口字段统一改名 channel
- migration 114 将 sales_daily_facts.fulfillment_mode 重命名为 channel - DTO/查询参数/前端类型从 fulfillmentMode 统一为 channel - 成本中心类型 FulfillmentMode 更名为 FulfillmentChannel,并补齐卡券/待分类/归档取值 - 销售事实响应分组改为 byChannel
This commit is contained in:
@@ -71,7 +71,7 @@ test('mapAdminOrderListItem formats itemTitle, skuNick, and summary correctly fo
|
||||
skuNick: '安卓血宴2钻',
|
||||
matchSku: '安卓血宴2钻',
|
||||
quantity: 1,
|
||||
fulfillmentMode: 'pending',
|
||||
channel: 'pending',
|
||||
},
|
||||
])
|
||||
})
|
||||
@@ -296,12 +296,11 @@ const CHANNEL_VALUES = new Set(['work_order', 'affiliate_dash', 'third_party_vou
|
||||
|
||||
function buildOrderItemForFulfillmentTest(
|
||||
id: number,
|
||||
fulfillmentMode: string | null,
|
||||
value: string | null,
|
||||
patch: Partial<OrderItemRow> = {},
|
||||
): OrderItemRow {
|
||||
const channel = fulfillmentMode && CHANNEL_VALUES.has(fulfillmentMode) ? fulfillmentMode : null
|
||||
const status =
|
||||
fulfillmentMode === 'legacy_platform' ? 'archived' : channel ? 'assigned' : 'pending'
|
||||
const channel = value && CHANNEL_VALUES.has(value) ? value : null
|
||||
const status = value === 'legacy_platform' ? 'archived' : channel ? 'assigned' : 'pending'
|
||||
return {
|
||||
id,
|
||||
order_id: 501,
|
||||
@@ -322,7 +321,7 @@ test('人工单即使有已核销快照也仍然判为 manual,核销码单独
|
||||
vouchers,
|
||||
})
|
||||
|
||||
assert.equal(mapped.fulfillmentMode, 'manual')
|
||||
assert.equal(mapped.channel, 'manual')
|
||||
assert.equal(mapped.manualItemCount, 1)
|
||||
assert.equal(mapped.hasVoucher, true)
|
||||
assert.equal(mapped.voucherState, 'consumed')
|
||||
@@ -337,9 +336,9 @@ test('自动发货与历史归档按渠道/状态区分,不再按 provider 猜
|
||||
items: [buildOrderItemForFulfillmentTest(2, 'legacy_platform')],
|
||||
})
|
||||
|
||||
assert.equal(affiliate.fulfillmentMode, 'affiliate_dash')
|
||||
assert.equal(affiliate.channel, 'affiliate_dash')
|
||||
assert.equal(affiliate.canClaimH5, true)
|
||||
assert.equal(legacy.fulfillmentMode, 'archived')
|
||||
assert.equal(legacy.channel, 'archived')
|
||||
assert.equal(legacy.canClaimH5, false)
|
||||
})
|
||||
|
||||
@@ -351,7 +350,7 @@ test('多商品订单出现不同履约方式时显示 mixed,并保留人工
|
||||
],
|
||||
})
|
||||
|
||||
assert.equal(summary.fulfillmentMode, 'mixed')
|
||||
assert.equal(summary.channel, 'mixed')
|
||||
assert.equal(summary.manualItemCount, 1)
|
||||
assert.equal(summary.pendingItemCount, 0)
|
||||
})
|
||||
@@ -367,14 +366,14 @@ test('核销码状态汇总:无、单一、混合', () => {
|
||||
)
|
||||
})
|
||||
|
||||
test('v2 读取口径:归档状态优先于旧 fulfillment_mode', () => {
|
||||
test('v2 读取口径:归档状态优先于旧 channel', () => {
|
||||
const summary = resolveOrderFulfillmentSummary({
|
||||
items: [buildOrderItemForFulfillmentTest(1, 'work_order', { fulfillment_status: 'archived' })],
|
||||
})
|
||||
assert.equal(summary.fulfillmentMode, 'archived')
|
||||
assert.equal(summary.channel, 'archived')
|
||||
})
|
||||
|
||||
test('v2 读取口径:渠道列优先于旧 fulfillment_mode', () => {
|
||||
test('v2 读取口径:渠道列优先于旧 channel', () => {
|
||||
const summary = resolveOrderFulfillmentSummary({
|
||||
items: [
|
||||
buildOrderItemForFulfillmentTest(1, 'manual', {
|
||||
@@ -383,7 +382,7 @@ test('v2 读取口径:渠道列优先于旧 fulfillment_mode', () => {
|
||||
}),
|
||||
],
|
||||
})
|
||||
assert.equal(summary.fulfillmentMode, 'third_party_voucher')
|
||||
assert.equal(summary.channel, 'third_party_voucher')
|
||||
})
|
||||
|
||||
test('v2 读取口径:状态 pending 且无渠道时判为待分类', () => {
|
||||
@@ -395,6 +394,6 @@ test('v2 读取口径:状态 pending 且无渠道时判为待分类', () => {
|
||||
}),
|
||||
],
|
||||
})
|
||||
assert.equal(summary.fulfillmentMode, 'pending')
|
||||
assert.equal(summary.channel, '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: resolveOrderItemFulfillmentMode(orderItem),
|
||||
channel: resolveOrderItemFulfillmentMode(orderItem),
|
||||
}
|
||||
})
|
||||
resolvedItemTitle = itemsList[0]?.itemTitle || ''
|
||||
@@ -73,7 +73,7 @@ export function mapAdminOrderListItem(
|
||||
skuNick: resolvedSkuNick,
|
||||
matchSku: resolvedMatchSku,
|
||||
quantity: 1,
|
||||
fulfillmentMode: 'pending',
|
||||
channel: 'pending',
|
||||
},
|
||||
]
|
||||
}
|
||||
@@ -120,7 +120,7 @@ export function mapAdminOrderListItem(
|
||||
items: itemsList,
|
||||
taskCount: tasks.length,
|
||||
workOrderCount,
|
||||
fulfillmentMode: fulfillment.fulfillmentMode,
|
||||
channel: fulfillment.channel,
|
||||
manualItemCount: fulfillment.manualItemCount,
|
||||
pendingItemCount: fulfillment.pendingItemCount,
|
||||
manualPendingCount: manualConfig.pending,
|
||||
@@ -138,7 +138,7 @@ export function mapAdminOrderListItem(
|
||||
}
|
||||
}
|
||||
|
||||
const ORDER_ITEM_FULFILLMENT_MODES = new Set<AdminOrderItemFulfillmentMode>([
|
||||
const ORDER_ITEM_FULFILLMENT_CHANNELS = new Set<AdminOrderItemFulfillmentMode>([
|
||||
'work_order',
|
||||
'affiliate_dash',
|
||||
'third_party_voucher',
|
||||
@@ -152,11 +152,11 @@ export function normalizeOrderItemFulfillmentMode(value: unknown): AdminOrderIte
|
||||
const mode = String(value || '')
|
||||
.trim()
|
||||
.toLowerCase() as AdminOrderItemFulfillmentMode
|
||||
return ORDER_ITEM_FULFILLMENT_MODES.has(mode) ? mode : 'pending'
|
||||
return ORDER_ITEM_FULFILLMENT_CHANNELS.has(mode) ? mode : 'pending'
|
||||
}
|
||||
|
||||
/**
|
||||
* v2 读取口径:只认渠道/状态三列,不再回退旧 fulfillment_mode。
|
||||
* v2 读取口径:只认渠道/状态三列,不再回退旧 channel。
|
||||
*
|
||||
* archived → archived
|
||||
* channel → 该渠道
|
||||
@@ -215,7 +215,7 @@ export function resolveOrderFulfillmentSummary({
|
||||
workOrderCount?: number
|
||||
vouchers?: KuaishouIndustryVoucherRow[]
|
||||
}): {
|
||||
fulfillmentMode: AdminOrderFulfillmentMode
|
||||
channel: AdminOrderFulfillmentMode
|
||||
manualItemCount: number
|
||||
pendingItemCount: number
|
||||
affiliateItemCount: number
|
||||
@@ -231,36 +231,36 @@ export function resolveOrderFulfillmentSummary({
|
||||
),
|
||||
)
|
||||
|
||||
let fulfillmentMode: AdminOrderFulfillmentMode
|
||||
let channel: AdminOrderFulfillmentMode
|
||||
if (knownModes.length === 1) {
|
||||
fulfillmentMode = knownModes[0]!
|
||||
channel = knownModes[0]!
|
||||
} else if (knownModes.length > 1) {
|
||||
fulfillmentMode = 'mixed'
|
||||
channel = 'mixed'
|
||||
} else if (normalizedItems.length > 0) {
|
||||
fulfillmentMode = 'pending'
|
||||
channel = 'pending'
|
||||
} else if (workOrderCount > 0) {
|
||||
// 极少数历史订单没有 order_items,只能用载体表兜底;这不是按 provider 猜。
|
||||
fulfillmentMode = 'work_order'
|
||||
channel = 'work_order'
|
||||
} else if (tasks.some((task) => task.executor_key === 'affiliate_dash')) {
|
||||
fulfillmentMode = 'affiliate_dash'
|
||||
channel = 'affiliate_dash'
|
||||
} else if (
|
||||
tasks.some(
|
||||
(task) =>
|
||||
task.executor_key === 'kuaishou_ct_assisted' || task.executor_key === 'kuaishou_feifei',
|
||||
)
|
||||
) {
|
||||
fulfillmentMode = 'archived'
|
||||
channel = 'archived'
|
||||
} else {
|
||||
fulfillmentMode = 'pending'
|
||||
channel = 'pending'
|
||||
}
|
||||
|
||||
const affiliateItemCount = itemModes.filter((mode) => mode === 'affiliate_dash').length
|
||||
const voucher = resolveVoucherSummary(vouchers)
|
||||
const canClaimH5 =
|
||||
affiliateItemCount > 0 || (normalizedItems.length === 0 && fulfillmentMode === 'affiliate_dash')
|
||||
affiliateItemCount > 0 || (normalizedItems.length === 0 && channel === 'affiliate_dash')
|
||||
|
||||
return {
|
||||
fulfillmentMode,
|
||||
channel,
|
||||
manualItemCount: itemModes.filter((mode) => mode === 'manual').length,
|
||||
pendingItemCount: itemModes.filter((mode) => mode === 'pending').length,
|
||||
affiliateItemCount,
|
||||
|
||||
@@ -106,7 +106,7 @@ export async function getAdminOrders(
|
||||
keyword: String(query.keyword || '').trim(),
|
||||
provider: String(query.provider || '').trim(),
|
||||
executorKey: String(query.executorKey || '').trim(),
|
||||
fulfillmentMode: normalizeOrderFulfillmentModeFilter(query.fulfillmentMode),
|
||||
channel: normalizeOrderFulfillmentModeFilter(query.channel),
|
||||
platformOrderId: String(query.platformOrderId || '').trim(),
|
||||
payStatus: String(query.payStatus || '').trim(),
|
||||
taskStatus: String(query.taskStatus || '').trim(),
|
||||
@@ -147,7 +147,7 @@ export async function getAdminOrders(
|
||||
}
|
||||
}
|
||||
|
||||
const ADMIN_ORDER_FULFILLMENT_MODES = new Set([
|
||||
const ADMIN_ORDER_FULFILLMENT_CHANNELS = new Set([
|
||||
'work_order',
|
||||
'affiliate_dash',
|
||||
'third_party_voucher',
|
||||
@@ -162,7 +162,7 @@ function normalizeOrderFulfillmentModeFilter(value: unknown): string {
|
||||
const mode = String(value || '')
|
||||
.trim()
|
||||
.toLowerCase()
|
||||
return ADMIN_ORDER_FULFILLMENT_MODES.has(mode) ? mode : ''
|
||||
return ADMIN_ORDER_FULFILLMENT_CHANNELS.has(mode) ? mode : ''
|
||||
}
|
||||
|
||||
function groupRowsByOrderId<T extends { order_id?: number | string | null }>(
|
||||
@@ -255,7 +255,7 @@ export async function getAdminOrderDetail(
|
||||
claimStatus: order.claim_status || 'active',
|
||||
claimStatusReason: order.claim_status_reason || '',
|
||||
claimStatusUpdatedAt: order.claim_status_updated_at || null,
|
||||
fulfillmentMode: fulfillment.fulfillmentMode,
|
||||
channel: fulfillment.channel,
|
||||
manualItemCount: fulfillment.manualItemCount,
|
||||
pendingItemCount: fulfillment.pendingItemCount,
|
||||
manualPendingCount: manualConfig.pending,
|
||||
@@ -281,7 +281,7 @@ export async function getAdminOrderDetail(
|
||||
revenueFen,
|
||||
refundedFen,
|
||||
refundableFen: Math.max(0, revenueFen - refundedFen),
|
||||
fulfillmentMode: resolveOrderItemFulfillmentMode(item),
|
||||
channel: resolveOrderItemFulfillmentMode(item),
|
||||
deliveryMode: resolveOrderItemDeliveryMode(tasks, item.id),
|
||||
spec:
|
||||
item.spec_json && typeof item.spec_json === 'object'
|
||||
|
||||
Reference in New Issue
Block a user