refactor(finance)!: 强制渠道模型,移除旧履约方式与同步链路

- 删除 fulfillment_mode 相关的旧同步/回填链路与定时任务
- 删除 cost_finance_sync、成本快照同步、人工商品归一等遗留服务
- 迁移 113 直接删除 order_items.fulfillment_mode 及其索引约束
- 断代脚本自带归档步骤,不再依赖独立回填脚本
- 退款/事实/总账统一走渠道版销售事实
This commit is contained in:
yml2213
2026-10-31 19:52:03 +08:00
parent 808949f3b8
commit 65b7f4f9dc
25 changed files with 156 additions and 2383 deletions
@@ -6,7 +6,6 @@
*/
import { Router } from 'express'
import { normalizeManualProducts } from '../../services/cost-center/manual-product-normalization-service.js'
import {
backfillAdminNormalizedQuantities,
backfillAdminProductMappings,
@@ -27,7 +26,6 @@ import {
backfillAdminAffiliateDashSkus,
importAdminAffiliateDashPricesBaseline,
setAdminAffiliateProductPrice,
syncAdminAffiliateDashCostSnapshots,
syncAdminAffiliateDashProducts,
} from '../../services/cost-center/affiliate-product-service.js'
import {
@@ -153,22 +151,6 @@ router.post(
),
)
router.post(
'/cost-center/affiliate-products/sync-snapshots',
requireAdminPermission('finance.config'),
createJsonHandler(() => withBatchTimeout(() => syncAdminAffiliateDashCostSnapshots()), {
successMessage: '已重算自动发货预估成本快照与销售事实',
errorMessage: '重算自动发货成本快照失败',
scope: '[admin/cost-center/affiliate-products/sync-snapshots]',
audit: (_req, data) => ({
action: 'cost_affiliate_snapshots_synced',
targetType: 'cost_snapshots',
targetId: '',
data: data as Record<string, unknown>,
}),
}),
)
router.post(
'/cost-center/work-order-products/backfill',
requireAdminPermission('finance.config'),
@@ -204,32 +186,6 @@ router.post(
}),
)
router.post(
'/cost-center/manual-products/normalize',
requireAdminPermission('finance.config'),
createJsonHandler(
(req) =>
withBatchTimeout(() =>
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'),
@@ -21,10 +21,6 @@ import {
createAdminCostSnapshot,
previewAdminCost,
} from '../../services/cost-center/cost-resolution-service.js'
import {
syncActualWorkOrderCostSnapshots,
syncEstimatedOrderItemCostSnapshots,
} from '../../services/cost-center/cost-snapshot-sync-service.js'
import type { JsonObject } from '../../types/json.js'
import { bodyOf, idOf, sessionOf } from './request-helpers.js'
import { createJsonHandler, requireAdminPermission } from './session.js'
@@ -244,50 +240,4 @@ router.post(
}),
)
router.post(
'/cost-center/snapshots/sync',
requireAdminPermission('finance.config'),
createJsonHandler(
async (req) => {
const body = bodyOf(req)
const mode = String(body.mode || 'both').trim()
const estimated = mode === 'actual' ? null : await syncEstimatedOrderItemCostSnapshots(body)
const actual = mode === 'estimated' ? null : await syncActualWorkOrderCostSnapshots(body)
return { mode, estimated, actual }
},
{
successMessage: '成本快照回填完成',
errorMessage: '回填成本快照失败',
scope: '[admin/cost-center/snapshots/sync]',
audit: (req, data) => {
const result = data as {
mode?: string
estimated?: { createdCount?: number; exceptionCreatedCount?: number } | null
actual?: {
createdCount?: number
directRewardCount?: number
upgradedCount?: number
estimatedRewardCount?: number
} | null
}
return {
action: 'cost_snapshot_synced',
targetType: 'cost_snapshot',
targetId: '',
data: {
mode: result.mode || '',
estimatedCreated: result.estimated?.createdCount || 0,
actualCreated:
(result.actual?.directRewardCount || 0) + (result.actual?.upgradedCount || 0),
estimatedRewardCreated: result.actual?.estimatedRewardCount || 0,
exceptions: result.estimated?.exceptionCreatedCount || 0,
dateFrom: req.body?.dateFrom || '',
dateTo: req.body?.dateTo || '',
},
}
},
},
),
)
export default router
+10 -5
View File
@@ -7,8 +7,8 @@ import {
import {
getSalesProfitOverview,
listSalesDailyFacts,
rebuildSalesDailyFacts,
} from '../../services/finance/sales-facts-service.js'
import { rebuildChannelSalesDailyFacts } from '../../services/finance/sales-facts-channel-service.js'
import {
confirmManualFulfillment,
listManualFulfillmentPending,
@@ -70,10 +70,15 @@ router.post(
requireAdminRoles(['admin', 'operator', 'finance']),
requireAdminPermission('finance.post'),
createJsonHandler(
(req) =>
rebuildSalesDailyFacts(
req.body && typeof req.body === 'object' ? (req.body as Record<string, unknown>) : {},
),
(req) => {
const body =
req.body && typeof req.body === 'object' ? (req.body as Record<string, unknown>) : {}
const today = new Date().toLocaleDateString('en-CA', { timeZone: 'Asia/Shanghai' })
return rebuildChannelSalesDailyFacts({
dateFrom: String(body.dateFrom || body.date_from || today).slice(0, 10),
dateTo: String(body.dateTo || body.date_to || today).slice(0, 10),
})
},
{
successMessage: '销售事实已重算',
errorMessage: '重算销售事实失败',