finance / fund / cost-center 三个路由文件各自复制了 sessionOf / idOf / bodyOf, 语义相同写法不同。统一到 routes/admin/request-helpers.ts,路由文件只保留业务 差异(fund.ts 的 accountIdOf / expenseIdOf)。 无行为变更:typecheck、lint、773 个测试全部通过。
151 lines
4.5 KiB
TypeScript
151 lines
4.5 KiB
TypeScript
import { Router } from 'express'
|
|
|
|
import {
|
|
getAdminFinanceSummary,
|
|
listAdminFinanceTransactions,
|
|
} from '../../services/admin/admin-finance-service.js'
|
|
import {
|
|
getSalesProfitOverview,
|
|
listSalesDailyFacts,
|
|
rebuildSalesDailyFacts,
|
|
} from '../../services/finance/sales-facts-service.js'
|
|
import {
|
|
confirmManualFulfillment,
|
|
listManualFulfillmentPending,
|
|
} from '../../services/finance/manual-fulfillment-service.js'
|
|
import {
|
|
createJsonHandler,
|
|
requireAdminPermission,
|
|
requireAdminRoles,
|
|
requireAnyAdminPermission,
|
|
} from './session.js'
|
|
import { bodyOf, idOf, sessionOf } from './request-helpers.js'
|
|
|
|
const router = Router()
|
|
|
|
router.get(
|
|
'/finance/summary',
|
|
requireAdminRoles(['admin', 'operator', 'finance']),
|
|
createJsonHandler((req) => getAdminFinanceSummary(req.query), {
|
|
successMessage: 'ok',
|
|
errorMessage: '读取财务汇总失败',
|
|
scope: '[admin/finance/summary]',
|
|
}),
|
|
)
|
|
|
|
router.get(
|
|
'/finance/transactions',
|
|
requireAdminRoles(['admin', 'operator', 'finance']),
|
|
createJsonHandler((req) => listAdminFinanceTransactions(req.query), {
|
|
successMessage: 'ok',
|
|
errorMessage: '读取财务明细失败',
|
|
scope: '[admin/finance/transactions]',
|
|
}),
|
|
)
|
|
|
|
router.get(
|
|
'/finance/sales-profit/overview',
|
|
requireAdminRoles(['admin', 'operator', 'finance']),
|
|
requireAdminPermission('finance.view'),
|
|
createJsonHandler((req) => getSalesProfitOverview(req.query as Record<string, unknown>), {
|
|
successMessage: 'ok',
|
|
errorMessage: '读取销售毛利失败',
|
|
scope: '[admin/finance/sales-profit/overview]',
|
|
}),
|
|
)
|
|
|
|
router.get(
|
|
'/finance/sales-facts',
|
|
requireAdminRoles(['admin', 'operator', 'finance']),
|
|
requireAdminPermission('finance.view'),
|
|
createJsonHandler((req) => listSalesDailyFacts(req.query as Record<string, unknown>), {
|
|
successMessage: 'ok',
|
|
errorMessage: '读取销售事实失败',
|
|
scope: '[admin/finance/sales-facts]',
|
|
}),
|
|
)
|
|
|
|
router.post(
|
|
'/finance/sales-facts/rebuild',
|
|
requireAdminRoles(['admin', 'operator', 'finance']),
|
|
requireAdminPermission('finance.config'),
|
|
createJsonHandler(
|
|
(req) =>
|
|
rebuildSalesDailyFacts(
|
|
req.body && typeof req.body === 'object' ? (req.body as Record<string, unknown>) : {},
|
|
),
|
|
{
|
|
successMessage: '销售事实已重算',
|
|
errorMessage: '重算销售事实失败',
|
|
scope: '[admin/finance/sales-facts/rebuild]',
|
|
audit: (req, data) => {
|
|
const result = data as {
|
|
range?: { fromDate?: string; toDate?: string }
|
|
insertedCount?: number
|
|
deletedCount?: number
|
|
}
|
|
return {
|
|
action: 'sales_daily_facts_rebuilt',
|
|
targetType: 'sales_daily_facts',
|
|
targetId: '',
|
|
data: {
|
|
dateFrom: result.range?.fromDate || req.body?.dateFrom || '',
|
|
dateTo: result.range?.toDate || req.body?.dateTo || '',
|
|
insertedCount: result.insertedCount || 0,
|
|
deletedCount: result.deletedCount || 0,
|
|
},
|
|
}
|
|
},
|
|
},
|
|
),
|
|
)
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// 人工履约待办与确认履约
|
|
// ---------------------------------------------------------------------------
|
|
|
|
router.get(
|
|
'/finance/manual-fulfillment/pending',
|
|
requireAdminRoles(['admin', 'operator', 'support']),
|
|
createJsonHandler(
|
|
(req) => listManualFulfillmentPending(req.query as Record<string, unknown>, sessionOf(req)),
|
|
{
|
|
successMessage: 'ok',
|
|
errorMessage: '读取人工履约待办失败',
|
|
scope: '[admin/finance/manual-fulfillment/pending]',
|
|
},
|
|
),
|
|
)
|
|
|
|
router.post(
|
|
'/finance/manual-fulfillment/confirm',
|
|
requireAdminRoles(['admin', 'operator', 'support']),
|
|
createJsonHandler((req) => confirmManualFulfillment(bodyOf(req), sessionOf(req)), {
|
|
successMessage: '履约已确认',
|
|
errorMessage: '确认履约失败',
|
|
scope: '[admin/finance/manual-fulfillment/confirm]',
|
|
audit: (req, data) => {
|
|
const result = data as {
|
|
orderItemId?: number
|
|
costSnapshotId?: number
|
|
platformKey?: string
|
|
creditQuantity?: number
|
|
costFen?: number
|
|
}
|
|
return {
|
|
action: 'manual_fulfillment_confirmed',
|
|
targetType: 'order_item',
|
|
targetId: String(result.orderItemId || ''),
|
|
data: {
|
|
costSnapshotId: result.costSnapshotId || null,
|
|
platformKey: result.platformKey || '',
|
|
creditQuantity: result.creditQuantity || 0,
|
|
costFen: result.costFen || 0,
|
|
},
|
|
}
|
|
},
|
|
}),
|
|
)
|
|
|
|
export default router
|