- 新增文档模板和导航结构 - 实现服务器基础API路由和控制器 - 添加扩展插件配置和前端框架 - 引入多租户和权限管理模块 - 集成日志和数据库配置 - 添加核心业务模型和类型定义
112 lines
4.1 KiB
TypeScript
112 lines
4.1 KiB
TypeScript
import db from '../config/database';
|
|
import { logger } from '../utils/logger';
|
|
import { SupplierService } from './SupplierService';
|
|
import { DecisionExplainabilityEngine } from '../core/ai/DecisionExplainabilityEngine';
|
|
import { AdviceService } from '../domains/Strategy/AdviceService';
|
|
|
|
/**
|
|
* [BIZ_OPS_132] 供应商响应时效动态分级 (Supplier SLA)
|
|
* @description 核心逻辑:基于响应速度 (avg_response_hours) 与交期 (avg_delivery_days) 自动标记低效方,并提供切换建议。
|
|
*/
|
|
export class SLAScoringService {
|
|
private static readonly AUDIT_TABLE = 'cf_sourcing_audit';
|
|
|
|
/**
|
|
* 审计供应商 SLA 并生成警告/建议 (BIZ_OPS_132)
|
|
*/
|
|
static async auditSupplierSLA(tenantId: string, supplierId: string): Promise<any> {
|
|
logger.info(`[SLAScoring] Auditing SLA for Supplier: ${supplierId}, Tenant: ${tenantId}`);
|
|
|
|
try {
|
|
// 1. 获取供应商最新绩效报告
|
|
const supplierReport = await SupplierService.getSupplierTrustReport(supplierId);
|
|
const metrics = supplierReport.metrics;
|
|
const score = supplierReport.trustScore;
|
|
|
|
// 2. SLA 阈值校验 (务实点)
|
|
// 响应速度 > 24h 或 交期 > 10d 触发预警
|
|
let slaBreached = false;
|
|
let breachReason = '';
|
|
|
|
if (metrics.responseHours > 24) {
|
|
slaBreached = true;
|
|
breachReason += `Response time (${metrics.responseHours}h) exceeds 24h limit. `;
|
|
}
|
|
|
|
if (metrics.deliveryDays > 10) {
|
|
slaBreached = true;
|
|
breachReason += `Delivery time (${metrics.deliveryDays}d) exceeds 10d limit. `;
|
|
}
|
|
|
|
if (score < 50) {
|
|
slaBreached = true;
|
|
breachReason += `Overall TrustScore (${score.toFixed(1)}) is dangerously low. `;
|
|
}
|
|
|
|
if (slaBreached) {
|
|
logger.warn(`[SLAScoring] SLA Breach detected for ${supplierId}: ${breachReason}`);
|
|
|
|
// 3. 寻找同租户下同类目更好的备选供应商 (模拟逻辑)
|
|
const alternatives = await db('cf_suppliers')
|
|
.where({ tenant_id: tenantId })
|
|
.where('rating_score', '>', score + 10)
|
|
.orderBy('rating_score', 'desc')
|
|
.limit(1);
|
|
|
|
const bestAlt = alternatives[0];
|
|
const reason = `SLA BREACH: ${breachReason} ` +
|
|
(bestAlt ? `Recommended to switch to ${bestAlt.name} (Score: ${bestAlt.rating_score.toFixed(1)}).` : 'Immediate review required.');
|
|
|
|
// 4. 生成建议 (Suggestion-First) -> 统一至 AdviceService
|
|
const suggestionId = await AdviceService.recordAdvice({
|
|
tenantId,
|
|
shopId: 'GLOBAL', // 供应商审核通常是全局的
|
|
traceId: 'sla-audit-' + Date.now(),
|
|
insight: {
|
|
type: 'SUPPLIER',
|
|
title: `SLA Breach: ${supplierReport.name}`,
|
|
description: reason,
|
|
impact: 'high',
|
|
confidence: 0.95,
|
|
suggestedAction: bestAlt ? `SWITCH_TO_${bestAlt.id}` : 'MANUAL_REVIEW',
|
|
metadata: {
|
|
supplierId,
|
|
bestAlternativeId: bestAlt?.id,
|
|
metrics
|
|
}
|
|
}
|
|
});
|
|
|
|
// 5. [UX_XAI_01] 记录决策证据链
|
|
await DecisionExplainabilityEngine.logDecision({
|
|
tenantId,
|
|
module: 'SUPPLIER_SLA',
|
|
resourceId: String(suggestionId),
|
|
decisionType: 'SLA_BREACH_WARNING',
|
|
causalChain: reason,
|
|
factors: [
|
|
{ name: 'ResponseHours', value: metrics.responseHours, weight: 0.4, impact: 'NEGATIVE' },
|
|
{ name: 'DeliveryDays', value: metrics.deliveryDays, weight: 0.4, impact: 'NEGATIVE' },
|
|
{ name: 'TrustScore', value: score, weight: 0.2, impact: 'NEGATIVE' }
|
|
],
|
|
traceId: 'sla-audit-' + Date.now()
|
|
});
|
|
|
|
return {
|
|
success: true,
|
|
suggestionId,
|
|
slaBreached,
|
|
reason,
|
|
bestAlternative: bestAlt?.name,
|
|
status: 'PENDING_REVIEW'
|
|
};
|
|
}
|
|
|
|
return { success: true, slaBreached: false, message: 'SLA compliant' };
|
|
} catch (err: any) {
|
|
logger.error(`[SLAScoring][WARN] SLA audit failed: ${err.message}`);
|
|
return { success: false, error: err.message };
|
|
}
|
|
}
|
|
}
|