import type { Request } from 'express' import { Router } from 'express' import { getAdminFinanceSummary, listAdminFinanceTransactions, } from '../../services/admin/admin-finance-service.js' import type { AdminSession } from '../../services/admin/admin-auth-service.js' import { getSalesProfitOverview, listSalesDailyFacts, rebuildSalesDailyFacts, } from '../../services/finance/sales-facts-service.js' import { createManualOrderCost, listManualOrderCostItems, } from '../../services/finance/manual-order-cost-service.js' import { confirmManualFulfillment, listManualFulfillmentPending, } from '../../services/finance/manual-fulfillment-service.js' import type { JsonObject } from '../../types/json.js' import { createJsonHandler, requireAdminPermission, requireAdminRoles, requireAnyAdminPermission, } from './session.js' const router = Router() function sessionOf(req: Request): AdminSession { return req.adminSession as AdminSession } function idOf(req: Request, key: string) { return Number(req.params[key]) } function bodyOf(req: Request): JsonObject { return req.body && typeof req.body === 'object' ? (req.body as JsonObject) : {} } 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), { 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), { 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) : {}, ), { 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-order-cost-items', requireAnyAdminPermission(['finance.view', 'fund.view']), createJsonHandler(() => listManualOrderCostItems(), { successMessage: 'ok', errorMessage: '读取人工录单成本项失败', scope: '[admin/finance/manual-order-cost-items]', }), ) router.post( '/finance/manual-order-costs', requireAnyAdminPermission(['fund.expense', 'finance.config']), createJsonHandler((req) => createManualOrderCost(bodyOf(req), sessionOf(req)), { successMessage: '订单人工成本已录入', errorMessage: '录入订单人工成本失败', scope: '[admin/finance/manual-order-costs]', audit: (req, data) => { const result = data as { expenseNo?: string amountFen?: number orderId?: number costSnapshotId?: number | null } return { action: 'manual_order_cost_created', targetType: 'fund_expense', targetId: result.expenseNo || '', data: { expenseNo: result.expenseNo || '', amountFen: result.amountFen || 0, orderId: result.orderId || req.body?.orderId || '', costSnapshotId: result.costSnapshotId || null, }, } }, }), ) // --------------------------------------------------------------------------- // 人工履约待办与确认履约 // --------------------------------------------------------------------------- router.get( '/finance/manual-fulfillment/pending', requireAdminRoles(['admin', 'operator', 'support']), createJsonHandler( (req) => listManualFulfillmentPending(req.query as Record, 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