import db from '../config/database'; import { AuditService } from './AuditService'; import { PathSimulatorService } from './PathSimulatorService'; /** * [BIZ_TRADE_19] 多式联运碳足迹与成本动态博弈模型 * 负责在包裹发运前,基于成本、碳足迹 (ESG) 与时效,进行动态博弈选择最优多式联运路径 */ export class CarbonCostGameService { /** * 运行路径博弈模型 */ static async runPathGame( tenantId: string, orderId: string, traceId: string ): Promise<{ selectedMode: string; carbon: number; cost: number }> { // 1. 获取订单基础信息 const order = await db('cf_orders').where({ id: orderId }).first(); if (!order) throw new Error('Order not found'); // 2. 调用 PathSimulatorService 获取不同路径选项 (模拟多维度路径计算) const options = [ { mode: 'AIR', cost: 45.0, carbon: 15.2, reliability: 0.99, tsl: 3 }, { mode: 'SEA', cost: 12.0, carbon: 0.8, reliability: 0.85, tsl: 25 }, { mode: 'RAIL', cost: 22.0, carbon: 2.5, reliability: 0.92, tsl: 15 }, { mode: 'TRUCK', cost: 28.0, carbon: 5.4, reliability: 0.90, tsl: 10 } ]; // 3. 博弈评分逻辑 (Game Score Calculation) // 目标:min(Cost) + min(Carbon) + max(Reliability) // 权重可根据租户偏好动态调整 (这里假设 4:4:2) const weights = { cost: 0.4, carbon: 0.4, reliability: 0.2 }; // 归一化计算 const gameResults = options.map(opt => { // 评分越高越好 (对 Cost 和 Carbon 取倒数) const score = (1 / opt.cost) * weights.cost + (1 / opt.carbon) * weights.carbon + opt.reliability * weights.reliability; return { ...opt, score }; }); // 4. 选择得分最高的路径 const bestOption = gameResults.reduce((prev, curr) => curr.score > prev.score ? curr : prev); await db.transaction(async (trx) => { // 5. 持久化博弈结果 await trx('cf_carbon_cost_game').insert({ tenant_id: tenantId, order_id: orderId, carbon_footprint: bestOption.carbon, shipping_cost: bestOption.cost, game_score: bestOption.score, selected_mode: bestOption.mode, logic_description: JSON.stringify({ alternatives: gameResults, weights }) }); // 6. 审计记录 await AuditService.log({ tenant_id: tenantId, action: 'CARBON_COST_GAME_COMPLETED', target_type: 'LOGISTICS_ROUTE', target_id: orderId, trace_id: traceId, new_data: JSON.stringify({ selectedMode: bestOption.mode, score: bestOption.score }), metadata: JSON.stringify({ carbon: bestOption.carbon, cost: bestOption.cost }) }); }); return { selectedMode: bestOption.mode, carbon: bestOption.carbon, cost: bestOption.cost }; } /** * 获取租户的碳足迹汇总 */ static async getCarbonSummary(tenantId: string) { const summary = await db('cf_carbon_cost_game') .where({ tenant_id: tenantId }) .select('selected_mode') .sum('carbon_footprint as total_carbon') .count('* as count') .groupBy('selected_mode'); return summary; } }