feat: 增强员工管理与报销单全流程功能

- 新增员工Excel导入服务(employee_spreadsheet)及导入/导出API端点
- 员工服务增加批量创建、邮箱唯一校验、组织架构关联等能力
- 报销单提交补充身份回填、部门信息透传及预审结果展示优化
- 认证流程增加部门信息(departmentName)并在schema中同步扩展
- 用户Agent服务增加部门关联与报销单回填逻辑
- 前端员工管理页面全面重构,新增导入导出、搜索过滤、分页等功能
- 前端审批中心、审计、差旅报销等视图交互与样式优化
- 新增TableLoadingState共享组件及员工导入测试用例
This commit is contained in:
caoxiaozhu
2026-05-20 14:21:56 +08:00
parent 57957d11a0
commit d7e98a58b9
46 changed files with 4022 additions and 305 deletions

View File

@@ -1,5 +1,7 @@
from __future__ import annotations
from typing import Any
from pydantic import BaseModel, EmailStr, Field
@@ -16,6 +18,12 @@ class AuthUserRead(BaseModel):
departmentName: str = ""
position: str = ""
grade: str = ""
employeeNo: str = ""
managerName: str = ""
location: str = ""
costCenter: str = ""
financeOwnerName: str = ""
riskProfile: dict[str, Any] = Field(default_factory=dict)
roleCodes: list[str] = Field(default_factory=list)
email: EmailStr | str
avatar: str

View File

@@ -50,6 +50,7 @@ class EmployeeMetaRead(BaseModel):
totalEmployees: int
statusSummary: list[EmployeeStatusSummaryRead]
roleOptions: list[EmployeeRoleOptionRead]
organizationOptions: list[EmployeeOrganizationRead] = Field(default_factory=list)
class EmployeeRead(BaseModel):
@@ -63,6 +64,7 @@ class EmployeeRead(BaseModel):
position: str
grade: str
manager: str
managerEmployeeNo: str | None = None
financeOwner: str
roles: list[str] = Field(default_factory=list)
roleCodes: list[str] = Field(default_factory=list)
@@ -112,6 +114,28 @@ class EmployeeCreate(BaseModel):
return _parse_optional_date(self.join_date, "入职日期")
class EmployeeImportErrorRead(BaseModel):
row: int
column: str
employeeNo: str = ""
message: str
class EmployeeImportSummaryRead(BaseModel):
totalRows: int = 0
created: int = 0
updated: int = 0
errorCount: int = 0
class EmployeeImportResultRead(BaseModel):
success: bool
message: str
summary: EmployeeImportSummaryRead
errors: list[EmployeeImportErrorRead] = Field(default_factory=list)
importedAt: str | None = None
class EmployeeUpdate(BaseModel):
name: str | None = Field(default=None, min_length=1, max_length=100)
gender: str | None = Field(default=None, max_length=20)
@@ -124,6 +148,8 @@ 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)
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
password: str | None = Field(default=None, min_length=5, max_length=128)

View File

@@ -148,6 +148,10 @@ class ExpenseClaimActionResponse(BaseModel):
status: str | None = None
class ExpenseClaimReturnPayload(BaseModel):
reason: str | None = Field(default=None, max_length=500)
class ExpenseClaimAttachmentActionResponse(BaseModel):
message: str
claim_id: str

View File

@@ -85,6 +85,8 @@ class UserAgentReviewRiskBrief(BaseModel):
title: str = Field(description="风险或注意事项标题。")
level: str = Field(default="info", description="级别,例如 info / warning / high。")
content: str = Field(description="面向用户展示的摘要说明。")
detail: str = Field(default="", description="点击风险项后展示的详细解释。")
suggestion: str = Field(default="", description="面向用户的处理建议。")
class UserAgentReviewSlotCard(BaseModel):