From fca836eb4bb1718a4e59cb6e97b33f057f7c516e Mon Sep 17 00:00:00 2001 From: yml2213 Date: Sun, 1 Nov 2026 14:46:14 +0800 Subject: [PATCH] =?UTF-8?q?feat(cost-center):=20=E5=8D=A1=E5=88=B8?= =?UTF-8?q?=E5=95=86=E5=93=81=E5=88=9B=E5=BB=BA=E5=8D=B3=E7=94=9F=E6=88=90?= =?UTF-8?q?=E6=B8=A0=E9=81=93=E8=A7=84=E5=88=99=EF=BC=8C=E8=A1=A5=E9=BD=90?= =?UTF-8?q?=E6=88=90=E6=9C=AC=E9=A1=B9=E9=A2=84=E8=AE=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新建 tpv: 商品时自动写 third_party_voucher 规则,避免新卡券 SKU 停在待分类 - 成本项预设新增「第三方卡券采购成本」 --- .../cost-center/product-catalog-service.ts | 5 +++++ .../fulfillment/channel-assign-service.ts | 19 +++++++++++++++++++ .../src/pages/admin/cost-center/shared.ts | 8 ++++++++ 3 files changed, 32 insertions(+) diff --git a/apps/backend/src/services/cost-center/product-catalog-service.ts b/apps/backend/src/services/cost-center/product-catalog-service.ts index cd85745a..47e7f874 100644 --- a/apps/backend/src/services/cost-center/product-catalog-service.ts +++ b/apps/backend/src/services/cost-center/product-catalog-service.ts @@ -16,6 +16,7 @@ import { nowIso } from '../../utils/time.js' import { normalizeMatchText, normalizeSkuSeriesEquivalence } from '../product-match/normalize.js' import { resolveSkuNameQuantity } from '../product-match/pricing.js' import { setAdminAffiliateProductPrice } from './affiliate-product-service.js' +import { ensureVoucherRuleForSku } from '../fulfillment/channel-assign-service.js' import { syncAdminWorkProductRulePrice } from '../worker-platform/admin-worker-catalog-service.js' import { AFFILIATE_TASK_AGG_JOIN, @@ -345,6 +346,10 @@ export async function createAdminProduct(payload: JsonObject, _session: AdminSes errorCode: 'cost_product_sku_exists', }) } + // 卡券没有载体证据,创建商品时顺手把渠道规则补上,避免新 SKU 停在待分类。 + if (canonicalSku.startsWith('tpv:')) { + await ensureVoucherRuleForSku(canonicalSku.slice(4)) + } return { product: mapProduct(inserted) } } diff --git a/apps/backend/src/services/fulfillment/channel-assign-service.ts b/apps/backend/src/services/fulfillment/channel-assign-service.ts index 97700fb1..7fc867e5 100644 --- a/apps/backend/src/services/fulfillment/channel-assign-service.ts +++ b/apps/backend/src/services/fulfillment/channel-assign-service.ts @@ -553,6 +553,25 @@ export const CHANNEL_RULE_KEY_TYPES = MATCH_KEY_TYPES export const CHANNEL_RULE_SOURCES = RULE_SOURCES export const CHANNEL_VALUES = FULFILLMENT_CHANNELS +/** 为单个卡券 SKU 建规则(商品创建时调用,幂等)。 */ +export async function ensureVoucherRuleForSku(skuCode: string): Promise { + const key = String(skuCode || '').trim() + if (!key) return false + const result = await query<{ id: number }>( + ` + INSERT INTO sku_channel_rules ( + provider, shop_id, match_key_type, match_key, channel, priority, + source, enabled, note, created_at, updated_at + ) + VALUES ('', '', 'sku_code', $1, 'third_party_voucher', 70, 'voucher', TRUE, '卡券商品自动生成', NOW(), NOW()) + ON CONFLICT (provider, shop_id, match_key_type, match_key, channel) DO NOTHING + RETURNING id + `, + [key], + ) + return (result.rowCount || 0) > 0 +} + /** * 为卡券商品(tpv: 前缀)批量补渠道规则。 * diff --git a/apps/frontend/src/pages/admin/cost-center/shared.ts b/apps/frontend/src/pages/admin/cost-center/shared.ts index b11fc8a9..804d0a0a 100644 --- a/apps/frontend/src/pages/admin/cost-center/shared.ts +++ b/apps/frontend/src/pages/admin/cost-center/shared.ts @@ -171,6 +171,14 @@ export const COST_ITEM_PRESETS: CostItemPreset[] = [ pricingMode: 'per_item', unitName: '件', }, + { + key: 'third_party_voucher_cost', + label: '第三方卡券采购成本', + name: '第三方卡券采购成本', + costModel: 'third_party_voucher_cost', + pricingMode: 'per_item', + unitName: '件', + }, { key: 'work_order_reward', label: '接单平台打手报酬',