Files
freedakgmail c670b9e454 外包风险评估系统:领域引擎+前端+服务端持久化与生产部署
- 确定性领域引擎(分类/评分/分级/红线/费用/裁决)+LLM(通义千问)语言理解
- 6步评估向导、服务端草稿持久化(跨设备/编辑草稿保护)
- 工作流(草稿→风控→管理层)、RBAC、报告导出、校准、客户/费率/红线/最低工资管理
- 专业图标体系替换全部emoji、看板美化
- 生产化:API_BASE可配置(同源反代)、auth密钥惰性读取修复RBAC
- 444单测+204前端测试+51 e2e
2026-06-13 01:06:39 +08:00

103 lines
4.2 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 一次性脚本:通过 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}`);
}