feat: 新增员工行为画像算法与费用风险标签体系
后端新增员工行为画像算法模块,支持标签规则引擎和评分计算, 完善员工模型、银行信息、序列化和导入逻辑,优化报销审批流 和工作流常量,增强 Hermes 同步和知识同步能力,前端新增费 用画像详情弹窗、雷达图和风险卡片组件,完善登录页和工作台 样式,优化文档中心和归档中心交互,补充单元测试。
This commit is contained in:
@@ -3,7 +3,7 @@ import { h, ref } from 'vue'
|
||||
export function useLoginView() {
|
||||
const username = ref('')
|
||||
const password = ref('')
|
||||
const tenant = ref('')
|
||||
const tenant = ref('远光软件股份有限公司')
|
||||
const remember = ref(true)
|
||||
const showPassword = ref(false)
|
||||
|
||||
|
||||
@@ -4,11 +4,11 @@ import { useRoute, useRouter } from 'vue-router'
|
||||
import { icons } from '../data/icons.js'
|
||||
|
||||
export const appViews = [
|
||||
'overview',
|
||||
'workbench',
|
||||
'documents',
|
||||
'budget',
|
||||
'audit',
|
||||
'overview',
|
||||
'digitalEmployees',
|
||||
'employees',
|
||||
'policies',
|
||||
@@ -17,14 +17,6 @@ export const appViews = [
|
||||
]
|
||||
|
||||
export const navItems = [
|
||||
{
|
||||
id: 'overview',
|
||||
label: '总览',
|
||||
navHint: '查看系统总览与关键指标',
|
||||
icon: icons.dashboard,
|
||||
title: '财务运营总览',
|
||||
desc: '聚合差旅申请、审批效率、风险信号与 SLA 表现。'
|
||||
},
|
||||
{
|
||||
id: 'workbench',
|
||||
label: '个人工作台',
|
||||
@@ -57,6 +49,14 @@ export const navItems = [
|
||||
title: '规则中心',
|
||||
desc: '集中管理财务规则、风险规则与外部 MCP 服务。'
|
||||
},
|
||||
{
|
||||
id: 'overview',
|
||||
label: '分析看板',
|
||||
navHint: '查看系统总览与关键指标',
|
||||
icon: icons.dashboard,
|
||||
title: '分析看板',
|
||||
desc: '聚合差旅申请、审批效率、风险信号与 SLA 表现。'
|
||||
},
|
||||
{
|
||||
id: 'digitalEmployees',
|
||||
label: '数字员工',
|
||||
|
||||
@@ -51,7 +51,8 @@ const REIMBURSEMENT_PROGRESS_LABELS = [
|
||||
'AI预审',
|
||||
'直属领导审批',
|
||||
'财务审批',
|
||||
'归档入账'
|
||||
'待付款',
|
||||
'已付款'
|
||||
]
|
||||
|
||||
const APPLICATION_PROGRESS_LABELS = [
|
||||
@@ -264,6 +265,14 @@ function resolveApprovalMeta(status) {
|
||||
return { key: 'supplement', label: '待补充', tone: 'warning' }
|
||||
}
|
||||
|
||||
if (normalized === 'pending_payment') {
|
||||
return { key: 'pending_payment', label: '待付款', tone: 'warning' }
|
||||
}
|
||||
|
||||
if (normalized === 'paid') {
|
||||
return { key: 'completed', label: '已付款', tone: 'success' }
|
||||
}
|
||||
|
||||
if (['approved', 'completed', 'paid'].includes(normalized)) {
|
||||
return { key: 'completed', label: '已完成', tone: 'success' }
|
||||
}
|
||||
@@ -296,8 +305,13 @@ function resolveWorkflowNode(claim, approvalMeta, isApplicationDocument = false)
|
||||
return '待提交'
|
||||
}
|
||||
|
||||
if (approvalMeta.key === 'pending_payment') {
|
||||
return '待付款'
|
||||
}
|
||||
|
||||
if (approvalMeta.key === 'completed') {
|
||||
return isApplicationDocument ? '审批完成' : '归档入账'
|
||||
const normalizedStatus = String(claim?.status || '').trim().toLowerCase()
|
||||
return isApplicationDocument ? '审批完成' : normalizedStatus === 'paid' ? '已付款' : '归档入账'
|
||||
}
|
||||
|
||||
return isApplicationDocument ? '直属领导审批' : 'AI预审'
|
||||
@@ -352,12 +366,22 @@ function resolveProgressCurrentIndex(approvalMeta, workflowNode) {
|
||||
const normalizedNode = String(workflowNode || '').trim()
|
||||
|
||||
if (approvalMeta.key === 'completed') {
|
||||
return 6
|
||||
}
|
||||
|
||||
if (approvalMeta.key === 'pending_payment') {
|
||||
return 5
|
||||
}
|
||||
|
||||
if (normalizedNode.includes('归档') || normalizedNode.includes('入账')) {
|
||||
if (normalizedNode.includes('已付款')) {
|
||||
return 6
|
||||
}
|
||||
if (normalizedNode.includes('待付款')) {
|
||||
return 5
|
||||
}
|
||||
if (normalizedNode.includes('归档') || normalizedNode.includes('入账')) {
|
||||
return 6
|
||||
}
|
||||
if (normalizedNode.includes('财务')) {
|
||||
return 4
|
||||
}
|
||||
@@ -529,6 +553,7 @@ function findApprovalEventForStep(claim, label) {
|
||||
if (stepLabel === '财务审批') {
|
||||
return (
|
||||
previousStage.includes('财务')
|
||||
|| nextStage.includes('待付款')
|
||||
|| nextStage.includes('归档')
|
||||
|| nextStage.includes('入账')
|
||||
|| nextStage.includes('完成')
|
||||
@@ -551,6 +576,19 @@ function findLatestReturnEvent(claim) {
|
||||
)
|
||||
}
|
||||
|
||||
function findLatestPaymentEvent(claim) {
|
||||
return getLatestEvent(
|
||||
getRiskFlags(claim).filter((flag) => (
|
||||
flag
|
||||
&& typeof flag === 'object'
|
||||
&& (
|
||||
normalizeText(flag.source) === 'payment'
|
||||
|| normalizeText(flag.event_type || flag.eventType) === 'expense_claim_payment_completed'
|
||||
)
|
||||
))
|
||||
)
|
||||
}
|
||||
|
||||
function findLatestApplicationReturnEvent(claim) {
|
||||
return getLatestEvent(
|
||||
getRiskFlags(claim).filter((flag) => {
|
||||
@@ -639,6 +677,18 @@ function buildCompletedStepMeta(claim, label) {
|
||||
}
|
||||
}
|
||||
|
||||
if (stepLabel === '待付款') {
|
||||
const approvalEvent = findApprovalEventForStep(claim, '财务审批')
|
||||
const pendingAt = formatDateTime(approvalEvent?.created_at || approvalEvent?.createdAt || claim?.updated_at)
|
||||
return buildProgressStepMeta('待付款', pendingAt)
|
||||
}
|
||||
|
||||
if (stepLabel === '已付款') {
|
||||
const paymentEvent = findLatestPaymentEvent(claim)
|
||||
const paidAt = formatDateTime(paymentEvent?.created_at || paymentEvent?.createdAt || claim?.updated_at)
|
||||
return buildProgressStepMeta('已付款', paidAt)
|
||||
}
|
||||
|
||||
if (stepLabel === '归档入账') {
|
||||
const archivedAt = formatDateTime(claim?.updated_at)
|
||||
return buildProgressStepMeta('归档入账', archivedAt)
|
||||
@@ -675,6 +725,14 @@ function resolveCurrentStepStartedAt(claim, label) {
|
||||
const leaderApprovalEvent = findApprovalEventForStep(claim, '直属领导审批')
|
||||
return leaderApprovalEvent?.created_at || leaderApprovalEvent?.createdAt || claim?.updated_at || claim?.submitted_at
|
||||
}
|
||||
if (stepLabel === '待付款') {
|
||||
const approvalEvent = findApprovalEventForStep(claim, '财务审批')
|
||||
return approvalEvent?.created_at || approvalEvent?.createdAt || claim?.updated_at || claim?.submitted_at
|
||||
}
|
||||
if (stepLabel === '已付款') {
|
||||
const paymentEvent = findLatestPaymentEvent(claim)
|
||||
return paymentEvent?.created_at || paymentEvent?.createdAt || claim?.updated_at || claim?.submitted_at
|
||||
}
|
||||
if (stepLabel === '归档入账' || stepLabel === '审批完成') {
|
||||
return claim?.updated_at || claim?.submitted_at
|
||||
}
|
||||
@@ -703,6 +761,8 @@ function buildProgressSteps(approvalMeta, workflowNode, claim = {}, options = {}
|
||||
const currentTime =
|
||||
approvalMeta.key === 'completed'
|
||||
? '已完成'
|
||||
: approvalMeta.key === 'pending_payment'
|
||||
? '待付款'
|
||||
: approvalMeta.key === 'supplement'
|
||||
? '待补充'
|
||||
: approvalMeta.key === 'rejected'
|
||||
|
||||
Reference in New Issue
Block a user