feat: 物品规则支持按数量计价(二次匹配SKU文字数量)

- 规则新增单价(unit_price_fen,0 关闭),开启后接单总价 = 单价 × 商品名称文字中的规格数量
- 新增 resolveSkuNameQuantity:支持阿拉伯数字与中文数字(如 指挥官秘钥15个 → 15、三个 → 3)
- 建单同步时按文字数量计算奖励,skuQuantity 记入工单 material.source 便于核对
- 规则表单新增计价方式(固定金额/按数量×单价),列表展示单价
- 新增 3 个数量解析单元测试(269 全通过)
This commit is contained in:
yml2213
2026-08-14 18:25:06 +08:00
parent f2e08a4fbc
commit f2edb7f895
9 changed files with 172 additions and 17 deletions
@@ -119,6 +119,7 @@ export type WorkProductRuleRow = {
enabled: boolean
auto_create: boolean
reward_amount: number
unit_price_fen: number
required_deposit_amount: number
deposit_threshold_amount: number
sharing_enabled: boolean
@@ -413,6 +413,7 @@ export async function upsertWorkProductRule(input: {
enabled: boolean
autoCreate: boolean
rewardAmount: number
unitPriceFen?: number
requiredDepositAmount: number
depositThresholdAmount: number
sharingEnabled?: boolean
@@ -429,6 +430,7 @@ export async function upsertWorkProductRule(input: {
INSERT INTO work_product_rules (
rule_key, provider, platform, shop_id, sku_code, product_name,
match_type, category_id, enabled, auto_create, reward_amount,
unit_price_fen,
required_deposit_amount, deposit_threshold_amount,
sharing_enabled, sharing_total_quantity, sharing_unit_reward,
timeout_minutes, timeout_policy,
@@ -437,11 +439,12 @@ export async function upsertWorkProductRule(input: {
) VALUES (
$1, $2, $3, $4, $5, $6,
$7, $8, $9, $10, $11,
$12, $13,
$14, $15, $16,
$17, $18,
$19::jsonb,
$20, $21, $22
$12,
$13, $14,
$15, $16, $17,
$18, $19,
$20::jsonb,
$21, $22, $23
)
ON CONFLICT (rule_key) DO UPDATE
SET
@@ -455,6 +458,7 @@ export async function upsertWorkProductRule(input: {
enabled = EXCLUDED.enabled,
auto_create = EXCLUDED.auto_create,
reward_amount = EXCLUDED.reward_amount,
unit_price_fen = EXCLUDED.unit_price_fen,
required_deposit_amount = EXCLUDED.required_deposit_amount,
deposit_threshold_amount = EXCLUDED.deposit_threshold_amount,
sharing_enabled = EXCLUDED.sharing_enabled,
@@ -479,6 +483,7 @@ export async function upsertWorkProductRule(input: {
input.enabled,
input.autoCreate,
input.rewardAmount,
Math.max(0, toPositiveInteger(input.unitPriceFen, 0)),
input.requiredDepositAmount,
input.depositThresholdAmount,
input.sharingEnabled === true,