Files
X-Financial/server/src/app/schemas/employee.py
caoxiaozhu 1b371ad7bb refactor(backend): update employee schema
- schemas/employee.py: update employee data schemas
2026-05-14 02:21:45 +00:00

135 lines
4.2 KiB
Python

from __future__ import annotations
from datetime import date, datetime
from pydantic import BaseModel, ConfigDict, EmailStr, Field
def _parse_optional_date(value: str | None, label: str) -> date | None:
if not value:
return None
try:
return datetime.strptime(value, "%Y-%m-%d").date()
except ValueError as exc:
raise ValueError(f"{label}格式必须为 YYYY-MM-DD。") from exc
class EmployeeHistoryRead(BaseModel):
action: str
owner: str
time: str
occurredAt: str
class EmployeeOrganizationRead(BaseModel):
id: str
code: str
name: str
unitType: str
costCenter: str | None = None
location: str | None = None
managerName: str | None = None
class EmployeeRoleOptionRead(BaseModel):
id: str
code: str
label: str
desc: str
permissions: list[str] = Field(default_factory=list)
class EmployeeStatusSummaryRead(BaseModel):
id: str
label: str
count: int
class EmployeeMetaRead(BaseModel):
totalEmployees: int
statusSummary: list[EmployeeStatusSummaryRead]
roleOptions: list[EmployeeRoleOptionRead]
class EmployeeRead(BaseModel):
model_config = ConfigDict(from_attributes=False)
id: str
avatar: str
name: str
employeeNo: str
department: str
position: str
grade: str
manager: str
financeOwner: str
roles: list[str] = Field(default_factory=list)
roleCodes: list[str] = Field(default_factory=list)
status: str
statusTone: str
gender: str | None = None
age: int | None = None
birthDate: str | None = None
email: EmailStr
phone: str | None = None
joinDate: str | None = None
location: str | None = None
costCenter: str | None = None
updatedAt: str | None = None
lastSync: str | None = None
syncState: str
spotlight: bool = False
permissions: list[str] = Field(default_factory=list)
history: list[EmployeeHistoryRead] = Field(default_factory=list)
organization: EmployeeOrganizationRead | None = None
class EmployeeCreate(BaseModel):
employee_no: str = Field(min_length=1, max_length=50)
name: str = Field(min_length=1, max_length=100)
email: EmailStr
gender: str | None = Field(default=None, max_length=20)
birth_date: str | None = None
phone: str | None = Field(default=None, max_length=30)
join_date: str | None = None
location: str | None = Field(default=None, max_length=100)
position: str = Field(default="员工", max_length=100)
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)
employment_status: str = Field(default="在职", max_length=30)
sync_state: str = Field(default="已同步", max_length=30)
spotlight: bool = False
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] = Field(default_factory=lambda: ["user"])
def parsed_birth_date(self) -> date | None:
return _parse_optional_date(self.birth_date, "出生日期")
def parsed_join_date(self) -> date | None:
return _parse_optional_date(self.join_date, "入职日期")
class EmployeeUpdate(BaseModel):
name: str | None = Field(default=None, min_length=1, max_length=100)
gender: str | None = Field(default=None, max_length=20)
birth_date: str | None = None
phone: str | None = Field(default=None, max_length=30)
email: EmailStr | None = None
join_date: str | None = None
location: str | None = Field(default=None, max_length=100)
position: str | None = Field(default=None, min_length=1, max_length=100)
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)
role_codes: list[str] | None = None
password: str | None = Field(default=None, min_length=5, max_length=128)
def parsed_birth_date(self) -> date | None:
return _parse_optional_date(self.birth_date, "出生日期")
def parsed_join_date(self) -> date | None:
return _parse_optional_date(self.join_date, "入职日期")