feat(finance): P1 人工商品归一,按内部 SKU 生成 man 商品并回填

- 新服务 manual-product-normalization-service:skuNick → outSkuSn → sku_code 兜底,按内部 SKU 生成 man:<sku> 商品
- 订单项按 id 分批(2 万/批)回填,避免 15s 语句超时;同步补齐人工成本快照的商品维度
- 新增 POST /cost-center/manual-products/normalize(支持 dryRun/日期窗口),成本中心「标准商品」加「归一人工商品」按钮
- 每日 cost_finance_sync 接入最近 N 天的增量归一
- 渠道映射未归一队列增加人工单提示:人工单不能用平台 sku_code 建映射
- 文档同步:P1 标记完成,补充归一接口契约与销售事实重算结果
This commit is contained in:
yml2213
2026-10-24 16:54:55 +08:00
parent e5122d116a
commit a78cc1f984
8 changed files with 425 additions and 7 deletions
@@ -59,6 +59,7 @@ import {
syncAdminAffiliateDashProducts,
syncAdminWorkOrderTemplateCostVersions,
} from '../../services/cost-center/template-bootstrap-service.js'
import { normalizeManualProducts } from '../../services/cost-center/manual-product-normalization-service.js'
import type { AdminSession } from '../../services/admin/admin-auth-service.js'
import {
syncActualWorkOrderCostSnapshots,
@@ -198,6 +199,30 @@ router.post(
}),
)
router.post(
'/cost-center/manual-products/normalize',
requireAdminPermission('finance.config'),
createJsonHandler(
(req) =>
normalizeManualProducts({
dateFrom: bodyOf(req).dateFrom as string | undefined,
dateTo: bodyOf(req).dateTo as string | undefined,
dryRun: bodyOf(req).dryRun === true,
}),
{
successMessage: '人工商品归一完成',
errorMessage: '归一人工商品失败',
scope: '[admin/cost-center/manual-products/normalize]',
audit: (_req, data) => ({
action: 'cost_manual_products_normalized',
targetType: 'product_catalog',
targetId: '',
data: data as Record<string, unknown>,
}),
},
),
)
router.get(
'/cost-center/products',
requireAdminPermission('finance.view'),