feat: 新增风险图谱算法与系统仪表盘及操作反馈体系

后端新增风险图谱算法模块、风险观察与反馈服务、规则 DSL
校验器和可解释性引擎,完善系统仪表盘和财务仪表盘统计,
优化 agent 运行和编排执行链路,清理旧开发文档,前端新增
系统趋势、负载热力图等多种仪表盘图表组件,完善操作反馈
对话框和工作台日期选择器,优化报销创建和审批详情交互,
补充单元测试覆盖。
This commit is contained in:
caoxiaozhu
2026-05-30 15:46:51 +08:00
parent 4c59941ec6
commit 7989f3a159
314 changed files with 30073 additions and 20626 deletions

View File

@@ -9,6 +9,9 @@ const BUDGET_MANAGER_APPROVAL = '\u9884\u7b97\u7ba1\u7406\u8005\u5ba1\u6279'
const APPROVAL_COMPLETED = '\u5ba1\u6279\u5b8c\u6210'
const RETURNED = '\u9000\u56de'
const WAIT_SUBMIT = '\u5f85\u63d0\u4ea4'
const LINKED_APPLICATION = '\u5173\u8054\u5355\u636e'
const PAID = '\u5df2\u4ed8\u6b3e'
const ARCHIVED = '\u5df2\u5f52\u6863'
const WAIT_LEADER_LI_APPROVAL = '\u7b49\u5f85 Leader Li \u6279\u590d'
const WAIT_BUDGET_ZHAO_APPROVAL = '\u7b49\u5f85 \u8d75\u9884\u7b97 \u6279\u590d'
const LEADER_RETURNED_STATUS = '\u9886\u5bfc\u5df2\u9000\u56de\uff0c\u5f85\u91cd\u65b0\u63d0\u4ea4'
@@ -191,6 +194,47 @@ test('approved application claims complete after budget approval', () => {
assert.equal(request.progressSteps.find((step) => step.label === '预算管理者审批')?.time, '赵预算通过')
})
test('application claims hide budget step when leader approval also covers budget approval', () => {
const request = mapExpenseClaimToRequest({
id: 'claim-application-merged-budget',
claim_no: 'APP-20260525-MERGED',
employee_name: '张三',
department_name: '交付部',
manager_name: '李预算经理',
expense_type: 'travel_application',
reason: '支撑国网服务器上线部署',
location: '上海',
amount: 12000,
invoice_count: 0,
occurred_at: '2026-05-25T00:00:00.000Z',
submitted_at: '2026-05-25T02:00:00.000Z',
created_at: '2026-05-25T01:30:00.000Z',
updated_at: '2026-05-25T03:00:00.000Z',
status: 'approved',
approval_stage: APPROVAL_COMPLETED,
risk_flags_json: [
{
source: 'manual_approval',
event_type: 'expense_application_approval',
operator: '李预算经理',
previous_approval_stage: DIRECT_MANAGER_APPROVAL,
next_approval_stage: APPROVAL_COMPLETED,
budget_approval_merged: true,
created_at: '2026-05-25T03:00:00.000Z'
}
],
items: []
})
assert.deepEqual(
request.progressSteps.map((step) => step.label),
[CREATE_APPLICATION, DIRECT_MANAGER_APPROVAL, APPROVAL_COMPLETED]
)
assert.equal(request.progressSteps.every((step) => step.done), true)
assert.equal(request.progressSteps.some((step) => step.label === BUDGET_MANAGER_APPROVAL), false)
assert.equal(request.progressSteps.find((step) => step.label === DIRECT_MANAGER_APPROVAL)?.time, '李预算经理通过')
})
test('progress steps show approval operator time and current stay duration', () => {
const originalNow = Date.now
Date.now = () => new Date('2026-05-20T05:00:00.000Z').getTime()
@@ -230,7 +274,7 @@ test('progress steps show approval operator time and current stay duration', ()
const firstStep = request.progressSteps[0]
assert.equal(request.riskSummary, '无')
assert.equal(firstStep.label, '创建单据')
assert.equal(firstStep.label, LINKED_APPLICATION)
assert.equal(leaderStep.time, '李经理通过')
assert.match(leaderStep.detail, /2026-05-20/)
assert.match(leaderStep.title, /李经理审批通过/)
@@ -479,19 +523,48 @@ test('paid reimbursement marks payment progress step as complete', () => {
previous_approval_stage: '待付款',
next_approval_stage: '已付款',
created_at: '2026-05-20T05:00:00.000Z'
},
{
source: 'application_handoff',
event_type: 'expense_application_to_reimbursement_draft',
application_claim_id: 'application-1',
application_claim_no: 'APP-20260520-001',
application_detail: {
application_type: '差旅费用申请',
application_content: '差旅费用申请 / 北京',
application_reason: '支撑国网仿生产环境部署',
application_days: '3 天',
application_location: '北京',
application_amount: '3000',
application_time: '2026-05-20T00:00:00.000Z',
application_transport_mode: '高铁'
}
}
],
items: []
})
const paymentStep = request.progressSteps.find((step) => step.label === '待付款')
const paidStep = request.progressSteps.find((step) => step.label === '已付款')
const paidStep = request.progressSteps.find((step) => step.label === PAID)
const archivedStep = request.progressSteps.find((step) => step.label === ARCHIVED)
const linkedStep = request.progressSteps.find((step) => step.label === LINKED_APPLICATION)
assert.equal(request.workflowNode, '已付款')
assert.equal(request.approvalStatus, '已付款')
assert.deepEqual(
request.progressSteps.map((step) => step.label),
[LINKED_APPLICATION, '待提交', 'AI预审', '直属领导审批', '财务审批', '待付款', PAID, ARCHIVED]
)
assert.equal(paymentStep.time, '待付款')
assert.equal(paidStep.time, '已付款')
assert.equal(paidStep.done, true)
assert.equal(archivedStep.time, ARCHIVED)
assert.equal(archivedStep.done, true)
assert.equal(linkedStep.time, '已关联 APP-20260520-001')
assert.equal(request.relatedApplication.claimNo, 'APP-20260520-001')
assert.equal(request.relatedApplication.reason, '支撑国网仿生产环境部署')
assert.equal(request.relatedApplication.days, '3 天')
assert.equal(request.relatedApplication.amountLabel, '¥3,000')
})
test('current direct manager step shows how long the claim has stayed there', () => {