外包风险评估系统:领域引擎+前端+服务端持久化与生产部署

- 确定性领域引擎(分类/评分/分级/红线/费用/裁决)+LLM(通义千问)语言理解
- 6步评估向导、服务端草稿持久化(跨设备/编辑草稿保护)
- 工作流(草稿→风控→管理层)、RBAC、报告导出、校准、客户/费率/红线/最低工资管理
- 专业图标体系替换全部emoji、看板美化
- 生产化:API_BASE可配置(同源反代)、auth密钥惰性读取修复RBAC
- 444单测+204前端测试+51 e2e
This commit is contained in:
freedakgmail
2026-06-13 01:06:39 +08:00
commit c670b9e454
404 changed files with 61820 additions and 0 deletions
+102
View File
@@ -0,0 +1,102 @@
// 一次性脚本:通过 HTTP API 向运行中的后端批量灌入 3 个评估示例。
const BASE = process.env.API_BASE ?? 'http://localhost:3005';
const SEP = '\u0000'; // indicatorKey 复合键分隔符(NUL
const kd = (rows) => rows.map(([d, i, l]) => [`${d}${SEP}${i}`, l]);
const cases = [
{
name: '案例1 银行IT运维岗位外包(预期可接受)',
body: {
projectDescription:
'为某大型国有银行提供IT运维岗位外包服务。客户资信优良、注册资本充足、无失信记录;账期30天且历史回款准时;岗位为常规运维支持非高危;SLA交付标准清晰可量化;毛利率充足、人力成本可控。',
confirmation: { businessType: '岗位外包', industry: '通用' },
region: 'CN-SH',
assessorId: 'sales-001',
knownData: kd([
['dim-customer', 'customer-credit', 1],
['dim-customer', 'payment-ability', 1],
['dim-position', 'position-nature', 2],
['dim-business', 'delivery-standard', 1],
['dim-labor', 'layoff-risk', 2],
['dim-labor', 'injury-risk', 1],
['dim-financial', 'gross-margin', 2],
['dim-legal', 'qualification', 1],
['dim-lifecycle', 'lifecycle-stage', 2],
['dim-macro', 'macro-policy', 2],
]),
costInputs: { baselineQuote: 2000000 },
topN: 5,
},
},
{
name: '案例2 互联网客服BPO(预期有条件接受)',
body: {
projectDescription:
'为某成长期互联网公司提供客服BPO外包。客户为创业公司资信一般、账期90天且偶有逾期;岗位含部分替代性用工;SLA标准较模糊;毛利率偏薄;存在一定裁员与合规风险。',
confirmation: { businessType: 'BPO', industry: '通用' },
region: 'CN-GD',
assessorId: 'sales-002',
knownData: kd([
['dim-customer', 'customer-credit', 4],
['dim-customer', 'payment-ability', 4],
['dim-position', 'position-nature', 4],
['dim-business', 'delivery-standard', 4],
['dim-labor', 'layoff-risk', 4],
['dim-labor', 'injury-risk', 3],
['dim-financial', 'gross-margin', 4],
['dim-legal', 'qualification', 3],
['dim-lifecycle', 'lifecycle-stage', 3],
['dim-macro', 'macro-policy', 3],
]),
costInputs: { baselineQuote: 1200000 },
topN: 5,
},
},
{
name: '案例3 衰退期制造高危劳务派遣(预期不可接受)',
body: {
projectDescription:
'为某衰退期制造企业提供高危产线劳务派遣。客户资信差、已有涉诉与逾期记录;账期超120天回款困难;岗位为高危作业工伤风险高;测算毛利率为负;资质不全存在假外包真派遣风险。',
confirmation: { businessType: '劳务派遣', industry: '通用' },
region: 'CN-HB',
assessorId: 'sales-003',
knownData: kd([
['dim-customer', 'customer-credit', 5],
['dim-customer', 'payment-ability', 5],
['dim-position', 'position-nature', 5],
['dim-business', 'delivery-standard', 5],
['dim-labor', 'layoff-risk', 5],
['dim-labor', 'injury-risk', 5],
['dim-financial', 'gross-margin', 5],
['dim-legal', 'qualification', 5],
['dim-lifecycle', 'lifecycle-stage', 5],
['dim-macro', 'macro-policy', 4],
]),
costInputs: { baselineQuote: 800000 },
topN: 5,
},
},
];
for (const c of cases) {
const res = await fetch(`${BASE}/api/assessments/run`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(c.body),
});
const j = await res.json();
if (!res.ok) {
console.error(`${c.name} 失败 [${res.status}]:`, j.error ?? j);
continue;
}
console.log(
`${c.name}\n id=${j.assessmentId} | score=${j.riskScore} grade=${j.riskGrade} | 结论=${j.acceptability} | 报价 ${j.assessment.costEstimate.baselineQuote}->${j.assessment.costEstimate.riskAdjustedQuote}`,
);
}
// 校验列表接口
const list = await (await fetch(`${BASE}/api/assessments`)).json();
console.log(`\n后端现有评估记录数:${list.length}`);
for (const r of list) {
console.log(` - ${r.id} | ${r.businessType} | ${r.riskGrade} | ${r.acceptability} | 状态=${r.status}`);
}