feat: 新增员工行为画像算法与费用风险标签体系
后端新增员工行为画像算法模块,支持标签规则引擎和评分计算, 完善员工模型、银行信息、序列化和导入逻辑,优化报销审批流 和工作流常量,增强 Hermes 同步和知识同步能力,前端新增费 用画像详情弹窗、雷达图和风险卡片组件,完善登录页和工作台 样式,优化文档中心和归档中心交互,补充单元测试。
This commit is contained in:
@@ -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
|
||||
|
||||
68
server/src/app/schemas/employee_profile.py
Normal file
68
server/src/app/schemas/employee_profile.py
Normal 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 = ""
|
||||
Reference in New Issue
Block a user