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

@@ -78,6 +78,9 @@ class EmployeeRead(BaseModel):
joinDate: str | None = None
location: str | None = None
costCenter: str | None = None
bankName: str | None = None
bankAccountNo: str | None = None
bankAccountName: str | None = None
updatedAt: str | None = None
lastSync: str | None = None
syncState: str
@@ -100,6 +103,9 @@ class EmployeeCreate(BaseModel):
grade: str = Field(default="P3", max_length=20)
cost_center: str | None = Field(default=None, max_length=50)
finance_owner_name: str | None = Field(default=None, max_length=100)
bank_name: str | None = Field(default=None, max_length=120)
bank_account_no: str | None = Field(default=None, max_length=80)
bank_account_name: str | None = Field(default=None, max_length=100)
employment_status: str = Field(default="在职", max_length=30)
sync_state: str = Field(default="已同步", max_length=30)
spotlight: bool = False
@@ -148,6 +154,9 @@ class EmployeeUpdate(BaseModel):
grade: str | None = Field(default=None, min_length=1, max_length=20)
cost_center: str | None = Field(default=None, max_length=50)
finance_owner_name: str | None = Field(default=None, max_length=100)
bank_name: str | None = Field(default=None, max_length=120)
bank_account_no: str | None = Field(default=None, max_length=80)
bank_account_name: str | None = Field(default=None, max_length=100)
organization_unit_code: str | None = Field(default=None, max_length=50)
manager_employee_no: str | None = Field(default=None, max_length=50)
role_codes: list[str] | None = None

View File

@@ -0,0 +1,68 @@
from __future__ import annotations
from datetime import datetime
from typing import Any
from pydantic import BaseModel, Field
class EmployeeProfilePeerGroupRead(BaseModel):
key: str = ""
fallback_level: int = 0
sample_size: int = 0
class EmployeeProfileRead(BaseModel):
profile_type: str
profile_label: str
score: int
level: str
level_label: str
metrics: dict[str, Any] = Field(default_factory=dict)
top_contributors: list[dict[str, Any]] = Field(default_factory=list)
class EmployeeProfileTagRead(BaseModel):
code: str
label: str
display_label: str
category: str
polarity: str = "behavior"
score: int
confidence: float
reason: str = ""
evidence: list[dict[str, Any]] = Field(default_factory=list)
radar_dimensions: list[str] = Field(default_factory=list)
algorithm_version: str = ""
class EmployeeProfileRadarDimensionRead(BaseModel):
code: str
label: str
score: int
level: str
level_label: str
top_tags: list[str] = Field(default_factory=list)
class EmployeeProfileRadarRead(BaseModel):
algorithm_version: str = ""
dimensions: list[EmployeeProfileRadarDimensionRead] = Field(default_factory=list)
class EmployeeProfileLatestRead(BaseModel):
employee_id: str
employee_name: str = ""
scene: str = "approval"
window_days: int = 90
expense_type_scope: str = "overall"
calculated_at: datetime | None = None
peer_group: EmployeeProfilePeerGroupRead = Field(default_factory=EmployeeProfilePeerGroupRead)
review_priority_score: int = 0
review_priority_level: str = "normal"
review_priority_label: str = "正常"
profiles: list[EmployeeProfileRead] = Field(default_factory=list)
profile_tags: list[EmployeeProfileTagRead] = Field(default_factory=list)
radar: EmployeeProfileRadarRead = Field(default_factory=EmployeeProfileRadarRead)
review_suggestions: list[dict[str, Any]] = Field(default_factory=list)
empty_reason: str = ""