- 新增文档模板和导航结构 - 实现服务器基础API路由和控制器 - 添加扩展插件配置和前端框架 - 引入多租户和权限管理模块 - 集成日志和数据库配置 - 添加核心业务模型和类型定义
94 lines
3.2 KiB
TypeScript
94 lines
3.2 KiB
TypeScript
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;
|
||
}
|
||
}
|