feat(finance): 接单模板发单金额落规则级成本版本

此前接单平台成本版本只有 sys_work_order_reward 的全局 0 元占位,662 个模板的发单金额从未进入 cost_versions。\n\n现在为 662 个模板各生成一条规则级版本:634 条固定发单金额 + 28 条按件单价;全局 0 元版本仅作“按工单实际结算”占位。成本版本页新增“用户实付均价”和“平均实发/项”,支持按模板名称/规则键搜索,按商品筛选也能命中规则版本。\n\n历史工单快照关联到对应模板版本;模板保存时自动同步单条成本版本;删除模板会先把历史版本脱钩停用,保留快照可追溯。\n\n新增迁移 112 覆盖索引,用户实付聚合从约 1.1s 降到约 150ms。
This commit is contained in:
yml2213
2026-10-22 19:29:53 +08:00
parent 72e1141c8a
commit 7c8832078f
12 changed files with 547 additions and 43 deletions
@@ -28,6 +28,7 @@ import {
resolveAdminCostException,
retireAdminCostVersion,
syncAdminAffiliateDashProducts,
syncAdminWorkOrderTemplateCostVersions,
updateAdminChannelMapping,
updateAdminCostItem,
updateAdminProduct,
@@ -150,6 +151,22 @@ router.post(
}),
)
router.post(
'/cost-center/work-order-template-costs/sync',
requireAdminPermission('finance.config'),
createJsonHandler(() => syncAdminWorkOrderTemplateCostVersions(), {
successMessage: '接单模板发单金额已同步',
errorMessage: '同步接单模板发单金额失败',
scope: '[admin/cost-center/work-order-template-costs/sync]',
audit: (_req, data) => ({
action: 'cost_work_order_template_costs_synced',
targetType: 'cost_versions',
targetId: '',
data: data as Record<string, unknown>,
}),
}),
)
router.get(
'/cost-center/products',
requireAdminPermission('finance.view'),
@@ -1,5 +1,6 @@
import { Router } from 'express'
import { setHttpCache } from '../../../middleware/http-cache.js'
import { syncAdminWorkOrderTemplateCostVersions } from '../../../services/admin/admin-cost-center-service.js'
import {
deleteAdminWorkCategory,
@@ -147,17 +148,25 @@ router.get(
router.post(
'/worker-platform/product-rules',
requireAdminRoles(['admin', 'operator']),
createJsonHandler((req) => saveAdminWorkProductRule(req.body || {}), {
successMessage: '接单物品规则已保存',
errorMessage: '保存接单物品规则失败',
scope: '[admin/worker-platform/product-rules]',
audit: (_req, data) => ({
action: 'work_product_rule_saved',
targetType: 'work_product_rule',
targetId: String((data as { rule?: { ruleKey?: string } })?.rule?.ruleKey || ''),
data: data && typeof data === 'object' ? (data as Record<string, unknown>) : {},
}),
}),
createJsonHandler(
async (req) => {
const result = await saveAdminWorkProductRule(req.body || {})
const ruleId = Number((result as { rule?: { id?: number } })?.rule?.id || 0)
const templateCost = ruleId ? await syncAdminWorkOrderTemplateCostVersions(ruleId) : null
return { ...result, templateCost }
},
{
successMessage: '接单物品规则已保存',
errorMessage: '保存接单物品规则失败',
scope: '[admin/worker-platform/product-rules]',
audit: (_req, data) => ({
action: 'work_product_rule_saved',
targetType: 'work_product_rule',
targetId: String((data as { rule?: { ruleKey?: string } })?.rule?.ruleKey || ''),
data: data && typeof data === 'object' ? (data as Record<string, unknown>) : {},
}),
},
),
)
router.post(