feat(cost-center): 第三方卡券渠道完整接入成本模型

- 商品来源筛选补 tpv: 前缀,卡券商品列表不再为空
- 成本模型新增 third_party_voucher_cost,覆盖预览/成本项/概览作用域
- 前后端成本模型枚举与下拉同步
This commit is contained in:
yml2213
2026-10-31 20:17:28 +08:00
parent 9ca1d52419
commit ce775ca102
6 changed files with 20 additions and 0 deletions
@@ -28,6 +28,7 @@ export type TemplateMappingMatchType =
export type CostModel =
| 'affiliate_purchase'
| 'work_order_reward'
| 'third_party_voucher_cost'
| 'manual_actual'
| 'platform_fee'
| 'payment_fee'
@@ -37,6 +38,7 @@ export type CostModel =
export const COST_MODELS = new Set<string>([
'affiliate_purchase',
'work_order_reward',
'third_party_voucher_cost',
'manual_actual',
'platform_fee',
'payment_fee',
@@ -48,6 +50,7 @@ export const COST_MODELS = new Set<string>([
export const COST_MODEL_CODE_BASE: Record<string, string> = {
affiliate_purchase: 'affiliate_purchase',
work_order_reward: 'work_order_reward',
third_party_voucher_cost: 'third_party_voucher_cost',
manual_actual: 'manual_actual',
platform_fee: 'platform_fee',
payment_fee: 'payment_fee',
@@ -38,6 +38,7 @@ export function productSourceFilterSql(paramIndex: number, column = 'p.canonical
return `(
($${paramIndex} = 'affiliate_dash' AND ${column} LIKE 'aff:%')
OR ($${paramIndex} = 'work_order' AND (${column} LIKE 'tpl:%' OR ${column} LIKE 'wo:%'))
OR ($${paramIndex} = 'third_party_voucher' AND ${column} LIKE 'tpv:%')
OR ($${paramIndex} = 'manual' AND ${column} LIKE 'man:%')
)`
}
@@ -52,6 +53,7 @@ export function costModelAppliesTo(costModel: string, fulfillmentMode: string) {
if ((GENERIC_COST_MODELS as readonly string[]).includes(costModel)) return true
if (costModel === 'affiliate_purchase') return fulfillmentMode === 'affiliate_dash'
if (costModel === 'work_order_reward') return fulfillmentMode === 'work_order'
if (costModel === 'third_party_voucher_cost') return fulfillmentMode === 'third_party_voucher'
if (costModel === 'manual_actual') return fulfillmentMode === 'manual'
return false
}
@@ -67,6 +69,8 @@ export function costModelScopeSql(fulfillmentModeExpression: string): string {
AND ${fulfillmentModeExpression} = 'affiliate_dash')
OR (ci.cost_model = 'work_order_reward'
AND ${fulfillmentModeExpression} = 'work_order')
OR (ci.cost_model = 'third_party_voucher_cost'
AND ${fulfillmentModeExpression} = 'third_party_voucher')
OR (ci.cost_model = 'manual_actual'
AND ${fulfillmentModeExpression} = 'manual')
)`
@@ -41,6 +41,7 @@ export async function getAdminCostCenterOverview(params: { scope?: string } = {}
$1::text IS NULL
OR ($1 = 'affiliate_dash' AND p.canonical_sku LIKE 'aff:%')
OR ($1 = 'work_order' AND (p.canonical_sku LIKE 'tpl:%' OR p.canonical_sku LIKE 'wo:%'))
OR ($1 = 'third_party_voucher' AND p.canonical_sku LIKE 'tpv:%')
OR ($1 = 'manual' AND p.canonical_sku LIKE 'man:%')
)
),
@@ -48,6 +49,7 @@ export async function getAdminCostCenterOverview(params: { scope?: string } = {}
SELECT CASE $1
WHEN 'affiliate_dash' THEN 'affiliate_purchase'
WHEN 'work_order' THEN 'work_order_reward'
WHEN 'third_party_voucher' THEN 'third_party_voucher_cost'
WHEN 'manual' THEN 'manual_actual'
END AS cost_model
)
@@ -1,6 +1,7 @@
import assert from 'node:assert/strict'
import test from 'node:test'
import { costModelAppliesTo } from './cost-center-mappers.js'
import {
normalizeMappingMatchType,
normalizeProviderKey,
@@ -8,6 +9,7 @@ import {
} from './cost-center-shared.js'
import { calculateCostTotal, validateCostVersionScope } from './cost-resolution-service.js'
import { resolveMappingProductId } from './product-catalog-service.js'
import { productSourceFilterSql } from './cost-center-mappers.js'
import {
buildTemplateMappingPlan,
buildTemplateProductSku,
@@ -289,3 +291,10 @@ test('接单模板改价 SQL 的参数必须显式指定 bigint', async () => {
),
)
})
test('成本模型与商品来源必须覆盖第三方卡券渠道', () => {
assert.equal(costModelAppliesTo('third_party_voucher_cost', 'third_party_voucher'), true)
assert.equal(costModelAppliesTo('third_party_voucher_cost', 'manual'), false)
assert.ok(productSourceFilterSql(1).includes("'third_party_voucher'"))
assert.ok(productSourceFilterSql(1).includes("'tpv:%'"))
})
@@ -78,6 +78,7 @@ export type CostVersionFormValues = {
export const COST_MODEL_OPTIONS = [
{ value: 'affiliate_purchase', label: '上游采购成本' },
{ value: 'work_order_reward', label: '接单平台打手报酬' },
{ value: 'third_party_voucher_cost', label: '第三方卡券采购成本' },
{ value: 'manual_actual', label: '人工客服实际支出' },
{ value: 'platform_fee', label: '平台服务费' },
{ value: 'payment_fee', label: '支付通道费' },
@@ -18,6 +18,7 @@ export type ProductSource = 'affiliate_dash' | 'work_order' | 'third_party_vouch
export type CostModel =
| 'affiliate_purchase'
| 'work_order_reward'
| 'third_party_voucher_cost'
| 'manual_actual'
| 'platform_fee'
| 'payment_fee'