feat: 新增员工行为画像算法与费用风险标签体系

后端新增员工行为画像算法模块,支持标签规则引擎和评分计算,
完善员工模型、银行信息、序列化和导入逻辑,优化报销审批流
和工作流常量,增强 Hermes 同步和知识同步能力,前端新增费
用画像详情弹窗、雷达图和风险卡片组件,完善登录页和工作台
样式,优化文档中心和归档中心交互,补充单元测试。
This commit is contained in:
caoxiaozhu
2026-05-28 12:09:49 +08:00
parent 04cd6d0f81
commit 8a4a777be7
96 changed files with 9835 additions and 704 deletions

View File

@@ -399,7 +399,7 @@ test('ticket description helper does not show the destination city as detail tex
assert.equal(request.expenseItems.find((item) => item.id === 'ship')?.name, '轮船票')
})
test('completed finance approval marks finance and archive progress steps', () => {
test('finance approval moves reimbursement to pending payment step', () => {
const request = mapExpenseClaimToRequest({
id: 'claim-finance-completed',
claim_no: 'EXP-202605-004',
@@ -414,8 +414,8 @@ test('completed finance approval marks finance and archive progress steps', () =
submitted_at: '2026-05-20T02:00:00.000Z',
created_at: '2026-05-20T01:30:00.000Z',
updated_at: '2026-05-20T04:00:00.000Z',
status: 'approved',
approval_stage: '归档入账',
status: 'pending_payment',
approval_stage: '待付款',
risk_flags_json: [
{
source: 'manual_approval',
@@ -428,7 +428,7 @@ test('completed finance approval marks finance and archive progress steps', () =
source: 'finance_approval',
operator: '财务复核',
previous_approval_stage: '财务审批',
next_approval_stage: '归档入账',
next_approval_stage: '待付款',
created_at: '2026-05-20T04:00:00.000Z'
}
],
@@ -436,14 +436,62 @@ test('completed finance approval marks finance and archive progress steps', () =
})
const financeStep = request.progressSteps.find((step) => step.label === '财务审批')
const archiveStep = request.progressSteps.find((step) => step.label === '归档入账')
const paymentStep = request.progressSteps.find((step) => step.label === '待付款')
assert.equal(request.riskSummary, '无')
assert.equal(request.workflowNode, '归档入账')
assert.equal(request.workflowNode, '待付款')
assert.equal(request.approvalKey, 'pending_payment')
assert.equal(financeStep.time, '财务复核通过')
assert.match(financeStep.detail, /2026-05-20/)
assert.equal(archiveStep.time, '归档入账')
assert.equal(archiveStep.done, true)
assert.equal(paymentStep.current, true)
assert.equal(paymentStep.done, false)
})
test('paid reimbursement marks payment progress step as complete', () => {
const request = mapExpenseClaimToRequest({
id: 'claim-finance-paid',
claim_no: 'EXP-202605-005',
employee_name: '张三',
department_name: '市场部',
expense_type: 'transport',
reason: '交通报销',
location: '上海',
amount: 88,
invoice_count: 1,
occurred_at: '2026-05-20T01:00:00.000Z',
submitted_at: '2026-05-20T02:00:00.000Z',
created_at: '2026-05-20T01:30:00.000Z',
updated_at: '2026-05-20T05:00:00.000Z',
status: 'paid',
approval_stage: '已付款',
risk_flags_json: [
{
source: 'finance_approval',
operator: '财务复核',
previous_approval_stage: '财务审批',
next_approval_stage: '待付款',
created_at: '2026-05-20T04:00:00.000Z'
},
{
source: 'payment',
event_type: 'expense_claim_payment_completed',
operator: '财务付款',
previous_approval_stage: '待付款',
next_approval_stage: '已付款',
created_at: '2026-05-20T05:00:00.000Z'
}
],
items: []
})
const paymentStep = request.progressSteps.find((step) => step.label === '待付款')
const paidStep = request.progressSteps.find((step) => step.label === '已付款')
assert.equal(request.workflowNode, '已付款')
assert.equal(request.approvalStatus, '已付款')
assert.equal(paymentStep.time, '待付款')
assert.equal(paidStep.time, '已付款')
assert.equal(paidStep.done, true)
})
test('current direct manager step shows how long the claim has stayed there', () => {