743 lines
25 KiB
Python
743 lines
25 KiB
Python
"""
|
|
Pydantic数据模式
|
|
"""
|
|
from datetime import datetime
|
|
from typing import Optional, List
|
|
from pydantic import BaseModel, Field, ConfigDict
|
|
from enum import Enum
|
|
|
|
|
|
# ==================== 枚举类型 ====================
|
|
|
|
class DeptType(str, Enum):
|
|
CLINICAL_SURGICAL = "clinical_surgical"
|
|
CLINICAL_NONSURGICAL_WARD = "clinical_nonsurgical_ward"
|
|
CLINICAL_NONSURGICAL_NOWARD = "clinical_nonsurgical_noward"
|
|
MEDICAL_TECH = "medical_tech"
|
|
MEDICAL_AUXILIARY = "medical_auxiliary"
|
|
NURSING = "nursing"
|
|
ADMIN = "admin"
|
|
FINANCE = "finance"
|
|
LOGISTICS = "logistics"
|
|
|
|
|
|
class StaffStatus(str, Enum):
|
|
ACTIVE = "active"
|
|
LEAVE = "leave"
|
|
RESIGNED = "resigned"
|
|
RETIRED = "retired"
|
|
|
|
|
|
class AssessmentStatus(str, Enum):
|
|
DRAFT = "draft"
|
|
SUBMITTED = "submitted"
|
|
REVIEWED = "reviewed"
|
|
FINALIZED = "finalized"
|
|
REJECTED = "rejected"
|
|
|
|
|
|
class IndicatorType(str, Enum):
|
|
QUALITY = "quality"
|
|
QUANTITY = "quantity"
|
|
EFFICIENCY = "efficiency"
|
|
SERVICE = "service"
|
|
COST = "cost"
|
|
|
|
|
|
# ==================== 通用响应 ====================
|
|
|
|
class ResponseBase(BaseModel):
|
|
"""通用响应基类"""
|
|
code: int = Field(default=200, description="状态码")
|
|
message: str = Field(default="success", description="消息")
|
|
|
|
|
|
class PaginatedResponse(ResponseBase):
|
|
"""分页响应"""
|
|
total: int = Field(description="总数")
|
|
page: int = Field(description="当前页")
|
|
page_size: int = Field(description="每页数量")
|
|
|
|
|
|
# ==================== 科室相关 ====================
|
|
|
|
class DepartmentBase(BaseModel):
|
|
"""科室基础模式"""
|
|
name: str = Field(..., max_length=100, description="科室名称")
|
|
code: str = Field(..., max_length=20, description="科室编码")
|
|
dept_type: DeptType = Field(..., description="科室类型")
|
|
parent_id: Optional[int] = Field(None, description="上级科室ID")
|
|
level: int = Field(default=1, ge=1, le=5, description="层级")
|
|
sort_order: int = Field(default=0, description="排序")
|
|
description: Optional[str] = Field(None, description="描述")
|
|
|
|
|
|
class DepartmentCreate(DepartmentBase):
|
|
"""创建科室"""
|
|
pass
|
|
|
|
|
|
class DepartmentUpdate(BaseModel):
|
|
"""更新科室"""
|
|
name: Optional[str] = Field(None, max_length=100)
|
|
dept_type: Optional[DeptType] = None
|
|
parent_id: Optional[int] = None
|
|
sort_order: Optional[int] = None
|
|
is_active: Optional[bool] = None
|
|
description: Optional[str] = None
|
|
|
|
|
|
class DepartmentResponse(DepartmentBase):
|
|
"""科室响应"""
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
id: int
|
|
is_active: bool
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
|
|
|
|
class DepartmentTree(DepartmentResponse):
|
|
"""科室树形结构"""
|
|
children: List["DepartmentTree"] = []
|
|
|
|
|
|
# ==================== 员工相关 ====================
|
|
|
|
class StaffBase(BaseModel):
|
|
"""员工基础模式"""
|
|
employee_id: str = Field(..., max_length=20, description="工号")
|
|
name: str = Field(..., max_length=50, description="姓名")
|
|
department_id: int = Field(..., description="所属科室ID")
|
|
position: str = Field(..., max_length=50, description="职位")
|
|
title: Optional[str] = Field(None, max_length=50, description="职称")
|
|
phone: Optional[str] = Field(None, max_length=20, description="电话")
|
|
email: Optional[str] = Field(None, max_length=100, description="邮箱")
|
|
base_salary: float = Field(default=0, ge=0, description="基本工资")
|
|
performance_ratio: float = Field(default=1.0, ge=0, le=5, description="绩效系数")
|
|
|
|
|
|
class StaffCreate(StaffBase):
|
|
"""创建员工"""
|
|
status: StaffStatus = Field(default=StaffStatus.ACTIVE)
|
|
hire_date: Optional[datetime] = None
|
|
|
|
|
|
class StaffUpdate(BaseModel):
|
|
"""更新员工"""
|
|
name: Optional[str] = Field(None, max_length=50)
|
|
department_id: Optional[int] = None
|
|
position: Optional[str] = Field(None, max_length=50)
|
|
title: Optional[str] = Field(None, max_length=50)
|
|
phone: Optional[str] = Field(None, max_length=20)
|
|
email: Optional[str] = Field(None, max_length=100)
|
|
base_salary: Optional[float] = Field(None, ge=0)
|
|
performance_ratio: Optional[float] = Field(None, ge=0, le=5)
|
|
status: Optional[StaffStatus] = None
|
|
|
|
|
|
class StaffResponse(StaffBase):
|
|
"""员工响应"""
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
id: int
|
|
status: StaffStatus
|
|
hire_date: Optional[datetime]
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
department_name: Optional[str] = None
|
|
|
|
|
|
# ==================== 指标相关 ====================
|
|
|
|
class IndicatorBase(BaseModel):
|
|
"""指标基础模式"""
|
|
name: str = Field(..., max_length=100, description="指标名称")
|
|
code: str = Field(..., max_length=20, description="指标编码")
|
|
indicator_type: IndicatorType = Field(..., description="指标类型")
|
|
weight: float = Field(default=1.0, gt=0, le=20, description="权重")
|
|
max_score: float = Field(default=100.0, ge=0, le=1000, description="最高分值")
|
|
target_value: Optional[float] = Field(None, description="目标值")
|
|
unit: Optional[str] = Field(None, max_length=20, description="计量单位")
|
|
calculation_method: Optional[str] = Field(None, description="计算方法")
|
|
description: Optional[str] = Field(None, description="描述")
|
|
|
|
|
|
class IndicatorCreate(IndicatorBase):
|
|
"""创建指标"""
|
|
pass
|
|
|
|
|
|
class IndicatorUpdate(BaseModel):
|
|
"""更新指标"""
|
|
name: Optional[str] = Field(None, max_length=100)
|
|
indicator_type: Optional[IndicatorType] = None
|
|
weight: Optional[float] = Field(None, gt=0, le=20)
|
|
max_score: Optional[float] = Field(None, ge=0, le=1000)
|
|
target_value: Optional[float] = None
|
|
unit: Optional[str] = None
|
|
calculation_method: Optional[str] = None
|
|
description: Optional[str] = None
|
|
is_active: Optional[bool] = None
|
|
|
|
|
|
class IndicatorResponse(IndicatorBase):
|
|
"""指标响应"""
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
id: int
|
|
is_active: bool
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
|
|
|
|
# ==================== 考核相关 ====================
|
|
|
|
class AssessmentDetailBase(BaseModel):
|
|
"""考核明细基础模式"""
|
|
indicator_id: int = Field(..., description="指标ID")
|
|
actual_value: Optional[float] = Field(None, description="实际值")
|
|
score: float = Field(default=0, ge=0, description="得分")
|
|
evidence: Optional[str] = Field(None, description="佐证材料")
|
|
remark: Optional[str] = Field(None, description="备注")
|
|
|
|
|
|
class AssessmentDetailCreate(AssessmentDetailBase):
|
|
"""创建考核明细"""
|
|
pass
|
|
|
|
|
|
class AssessmentDetailResponse(AssessmentDetailBase):
|
|
"""考核明细响应"""
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
id: int
|
|
assessment_id: int
|
|
indicator_name: Optional[str] = None
|
|
created_at: datetime
|
|
|
|
|
|
class AssessmentBase(BaseModel):
|
|
"""考核基础模式"""
|
|
staff_id: int = Field(..., description="员工ID")
|
|
period_year: int = Field(..., ge=2020, le=2100, description="年度")
|
|
period_month: int = Field(..., ge=1, le=12, description="月份")
|
|
period_type: str = Field(default="monthly", description="周期类型")
|
|
|
|
|
|
class AssessmentCreate(AssessmentBase):
|
|
"""创建考核"""
|
|
details: List[AssessmentDetailCreate] = Field(default_factory=list, description="考核明细")
|
|
|
|
|
|
class AssessmentUpdate(BaseModel):
|
|
"""更新考核"""
|
|
details: Optional[List[AssessmentDetailCreate]] = None
|
|
remark: Optional[str] = None
|
|
|
|
|
|
class AssessmentResponse(AssessmentBase):
|
|
"""考核响应"""
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
id: int
|
|
total_score: float
|
|
weighted_score: float
|
|
status: AssessmentStatus
|
|
assessor_id: Optional[int]
|
|
reviewer_id: Optional[int]
|
|
submit_time: Optional[datetime]
|
|
review_time: Optional[datetime]
|
|
remark: Optional[str]
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
staff_name: Optional[str] = None
|
|
department_name: Optional[str] = None
|
|
details: List[AssessmentDetailResponse] = []
|
|
|
|
|
|
class AssessmentListResponse(AssessmentBase):
|
|
"""考核列表响应"""
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
id: int
|
|
total_score: float
|
|
weighted_score: float
|
|
status: AssessmentStatus
|
|
staff_name: Optional[str] = None
|
|
department_name: Optional[str] = None
|
|
created_at: datetime
|
|
|
|
|
|
# ==================== 工资相关 ====================
|
|
|
|
class SalaryRecordBase(BaseModel):
|
|
"""工资记录基础模式"""
|
|
staff_id: int = Field(..., description="员工ID")
|
|
period_year: int = Field(..., ge=2020, le=2100, description="年度")
|
|
period_month: int = Field(..., ge=1, le=12, description="月份")
|
|
base_salary: float = Field(default=0, ge=0, description="基本工资")
|
|
performance_score: float = Field(default=0, ge=0, description="绩效得分")
|
|
performance_bonus: float = Field(default=0, ge=0, description="绩效奖金")
|
|
deduction: float = Field(default=0, ge=0, description="扣款")
|
|
allowance: float = Field(default=0, ge=0, description="补贴")
|
|
|
|
|
|
class SalaryRecordCreate(SalaryRecordBase):
|
|
"""创建工资记录"""
|
|
remark: Optional[str] = None
|
|
|
|
|
|
class SalaryRecordUpdate(BaseModel):
|
|
"""更新工资记录"""
|
|
performance_bonus: Optional[float] = Field(None, ge=0)
|
|
deduction: Optional[float] = Field(None, ge=0)
|
|
allowance: Optional[float] = Field(None, ge=0)
|
|
remark: Optional[str] = None
|
|
|
|
|
|
class SalaryRecordResponse(SalaryRecordBase):
|
|
"""工资记录响应"""
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
id: int
|
|
total_salary: float
|
|
status: str
|
|
remark: Optional[str]
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
staff_name: Optional[str] = None
|
|
department_name: Optional[str] = None
|
|
|
|
|
|
# ==================== 用户认证相关 ====================
|
|
|
|
class UserLogin(BaseModel):
|
|
"""用户登录"""
|
|
username: str = Field(..., min_length=3, max_length=50)
|
|
password: str = Field(..., min_length=6, max_length=100)
|
|
|
|
|
|
class UserCreate(BaseModel):
|
|
"""创建用户"""
|
|
username: str = Field(..., min_length=3, max_length=50)
|
|
password: str = Field(..., min_length=6, max_length=100)
|
|
staff_id: Optional[int] = None
|
|
role: str = Field(default="staff", pattern="^(admin|manager|staff)$")
|
|
|
|
|
|
class Token(BaseModel):
|
|
"""令牌响应"""
|
|
access_token: str
|
|
token_type: str = "bearer"
|
|
|
|
|
|
class UserResponse(BaseModel):
|
|
"""用户响应"""
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
id: int
|
|
username: str
|
|
role: str
|
|
is_active: bool
|
|
last_login: Optional[datetime]
|
|
created_at: datetime
|
|
|
|
|
|
# ==================== 统计报表相关 ====================
|
|
|
|
class DepartmentStats(BaseModel):
|
|
"""科室统计"""
|
|
department_id: int
|
|
department_name: str
|
|
staff_count: int
|
|
avg_score: float
|
|
total_bonus: float
|
|
|
|
|
|
class PeriodStats(BaseModel):
|
|
"""周期统计"""
|
|
period_year: int
|
|
period_month: int
|
|
total_staff: int
|
|
assessed_count: int
|
|
avg_score: float
|
|
total_bonus: float
|
|
score_distribution: dict
|
|
|
|
|
|
class TrendData(BaseModel):
|
|
"""趋势数据"""
|
|
period: str
|
|
avg_score: float
|
|
total_bonus: float
|
|
|
|
|
|
# ==================== 财务核算相关 ====================
|
|
|
|
class RevenueCategory(str, Enum):
|
|
"""收入类别"""
|
|
EXAMINATION = "examination" # 检查费
|
|
LAB_TEST = "lab_test" # 检验费
|
|
RADIOLOGY = "radiology" # 放射费
|
|
BED = "bed" # 床位费
|
|
NURSING = "nursing" # 护理费
|
|
TREATMENT = "treatment" # 治疗费
|
|
SURGERY = "surgery" # 手术费
|
|
INJECTION = "injection" # 注射费
|
|
OXYGEN = "oxygen" # 吸氧费
|
|
OTHER = "other" # 其他
|
|
|
|
|
|
class ExpenseCategory(str, Enum):
|
|
"""支出类别"""
|
|
MATERIAL = "material" # 材料费
|
|
PERSONNEL = "personnel" # 人员支出
|
|
MAINTENANCE = "maintenance" # 维修费
|
|
UTILITY = "utility" # 水电费
|
|
OTHER = "other" # 其他
|
|
|
|
|
|
class FinanceType(str, Enum):
|
|
"""财务类型"""
|
|
REVENUE = "revenue" # 收入
|
|
EXPENSE = "expense" # 支出
|
|
|
|
|
|
class FinanceRecordBase(BaseModel):
|
|
"""财务记录基础模式"""
|
|
department_id: int = Field(..., description="科室ID")
|
|
finance_type: FinanceType = Field(..., description="财务类型")
|
|
category: str = Field(..., max_length=50, description="类别")
|
|
amount: float = Field(..., ge=0, description="金额")
|
|
period_year: int = Field(..., ge=2020, le=2100, description="年度")
|
|
period_month: int = Field(..., ge=1, le=12, description="月份")
|
|
source: Optional[str] = Field(None, max_length=100, description="数据来源")
|
|
remark: Optional[str] = Field(None, description="备注")
|
|
|
|
|
|
class FinanceRecordCreate(FinanceRecordBase):
|
|
"""创建财务记录"""
|
|
pass
|
|
|
|
|
|
class FinanceRecordUpdate(BaseModel):
|
|
"""更新财务记录"""
|
|
category: Optional[str] = Field(None, max_length=50)
|
|
amount: Optional[float] = Field(None, ge=0)
|
|
source: Optional[str] = Field(None, max_length=100)
|
|
remark: Optional[str] = None
|
|
|
|
|
|
class FinanceRecordResponse(FinanceRecordBase):
|
|
"""财务记录响应"""
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
id: int
|
|
department_name: Optional[str] = None
|
|
category_label: Optional[str] = None
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
|
|
|
|
class DepartmentBalance(BaseModel):
|
|
"""科室收支结余"""
|
|
department_id: Optional[int] = None
|
|
department_name: Optional[str] = None
|
|
period_year: Optional[int] = None
|
|
period_month: Optional[int] = None
|
|
total_revenue: float = Field(default=0, description="总收入")
|
|
total_expense: float = Field(default=0, description="总支出")
|
|
balance: float = Field(default=0, description="结余")
|
|
|
|
|
|
class CategorySummary(BaseModel):
|
|
"""类别汇总"""
|
|
category: str
|
|
category_label: str
|
|
amount: float
|
|
|
|
|
|
# ==================== 绩效计划相关 ====================
|
|
|
|
class PlanLevel(str, Enum):
|
|
"""计划层级"""
|
|
HOSPITAL = "hospital"
|
|
DEPARTMENT = "department"
|
|
INDIVIDUAL = "individual"
|
|
|
|
|
|
class PlanStatus(str, Enum):
|
|
"""计划状态"""
|
|
DRAFT = "draft"
|
|
PENDING = "pending"
|
|
APPROVED = "approved"
|
|
REJECTED = "rejected"
|
|
ACTIVE = "active"
|
|
COMPLETED = "completed"
|
|
CANCELLED = "cancelled"
|
|
|
|
|
|
class PlanKpiRelationBase(BaseModel):
|
|
"""计划指标关联基础模式"""
|
|
indicator_id: int = Field(..., description="指标 ID")
|
|
target_value: Optional[float] = Field(None, description="目标值")
|
|
target_unit: Optional[str] = Field(None, max_length=50, description="目标值单位")
|
|
weight: float = Field(default=1.0, ge=0, le=100, description="权重")
|
|
scoring_method: Optional[str] = Field(None, max_length=50, description="评分方法")
|
|
scoring_params: Optional[str] = Field(None, description="评分参数 (JSON)")
|
|
remark: Optional[str] = Field(None, description="备注")
|
|
|
|
|
|
class PlanKpiRelationCreate(PlanKpiRelationBase):
|
|
"""创建计划指标关联"""
|
|
pass
|
|
|
|
|
|
class PlanKpiRelationUpdate(BaseModel):
|
|
"""更新计划指标关联"""
|
|
target_value: Optional[float] = Field(None, description="目标值")
|
|
target_unit: Optional[str] = Field(None, max_length=50, description="目标值单位")
|
|
weight: Optional[float] = Field(None, ge=0, le=100, description="权重")
|
|
scoring_method: Optional[str] = Field(None, max_length=50, description="评分方法")
|
|
scoring_params: Optional[str] = Field(None, description="评分参数 (JSON)")
|
|
remark: Optional[str] = Field(None, description="备注")
|
|
|
|
|
|
class PlanKpiRelationResponse(PlanKpiRelationBase):
|
|
"""计划指标关联响应"""
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
id: int
|
|
plan_id: int
|
|
indicator_name: Optional[str] = None
|
|
indicator_code: Optional[str] = None
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
|
|
|
|
class PerformancePlanBase(BaseModel):
|
|
"""绩效计划基础模式"""
|
|
plan_name: str = Field(..., max_length=200, description="计划名称")
|
|
plan_code: str = Field(..., max_length=50, description="计划编码")
|
|
plan_level: PlanLevel = Field(..., description="计划层级")
|
|
plan_year: int = Field(..., ge=2000, le=2100, description="计划年度")
|
|
plan_month: Optional[int] = Field(None, ge=1, le=12, description="计划月份")
|
|
plan_type: str = Field(default="annual", max_length=20, description="计划类型")
|
|
department_id: Optional[int] = Field(None, description="所属科室 ID")
|
|
staff_id: Optional[int] = Field(None, description="责任人 ID")
|
|
parent_plan_id: Optional[int] = Field(None, description="上级计划 ID")
|
|
description: Optional[str] = Field(None, description="计划描述")
|
|
strategic_goals: Optional[str] = Field(None, description="战略目标")
|
|
key_initiatives: Optional[str] = Field(None, description="关键举措")
|
|
|
|
|
|
class PerformancePlanCreate(PerformancePlanBase):
|
|
"""创建绩效计划"""
|
|
kpi_relations: Optional[List[PlanKpiRelationCreate]] = Field(None, description="指标关联列表")
|
|
|
|
|
|
class PerformancePlanUpdate(BaseModel):
|
|
"""更新绩效计划"""
|
|
plan_name: Optional[str] = Field(None, max_length=200, description="计划名称")
|
|
plan_level: Optional[PlanLevel] = Field(None, description="计划层级")
|
|
department_id: Optional[int] = Field(None, description="所属科室 ID")
|
|
staff_id: Optional[int] = Field(None, description="责任人 ID")
|
|
description: Optional[str] = Field(None, description="计划描述")
|
|
strategic_goals: Optional[str] = Field(None, description="战略目标")
|
|
key_initiatives: Optional[str] = Field(None, description="关键举措")
|
|
status: Optional[PlanStatus] = Field(None, description="状态")
|
|
approve_remark: Optional[str] = Field(None, description="审批意见")
|
|
|
|
|
|
class PerformancePlanResponse(PerformancePlanBase):
|
|
"""绩效计划响应"""
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
id: int
|
|
status: PlanStatus
|
|
submitter_id: Optional[int] = None
|
|
submit_time: Optional[datetime] = None
|
|
approver_id: Optional[int] = None
|
|
approve_time: Optional[datetime] = None
|
|
version: int
|
|
is_active: bool
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
department_name: Optional[str] = None
|
|
staff_name: Optional[str] = None
|
|
kpi_relations: Optional[List[PlanKpiRelationResponse]] = None
|
|
|
|
|
|
class PerformancePlanStats(BaseModel):
|
|
"""绩效计划统计"""
|
|
total_plans: int = Field(0, description="总计划数")
|
|
draft_count: int = Field(0, description="草稿数")
|
|
pending_count: int = Field(0, description="待审批数")
|
|
approved_count: int = Field(0, description="已批准数")
|
|
active_count: int = Field(0, description="执行中数")
|
|
completed_count: int = Field(0, description="已完成数")
|
|
|
|
|
|
# ==================== 菜单管理相关 ====================
|
|
|
|
class MenuType(str, Enum):
|
|
"""菜单类型"""
|
|
MENU = "menu"
|
|
BUTTON = "button"
|
|
|
|
|
|
class MenuBase(BaseModel):
|
|
"""菜单基础模式"""
|
|
parent_id: Optional[int] = Field(None, description="父菜单 ID")
|
|
menu_type: MenuType = Field(default=MenuType.MENU, description="菜单类型")
|
|
menu_name: str = Field(..., max_length=100, description="菜单名称")
|
|
menu_icon: Optional[str] = Field(None, max_length=50, description="菜单图标")
|
|
path: str = Field(..., max_length=200, description="路由路径")
|
|
component: Optional[str] = Field(None, max_length=200, description="组件路径")
|
|
permission: Optional[str] = Field(None, max_length=100, description="权限标识")
|
|
sort_order: int = Field(default=0, ge=0, description="排序")
|
|
is_visible: bool = Field(default=True, description="是否可见")
|
|
is_active: bool = Field(default=True, description="是否启用")
|
|
|
|
|
|
class MenuCreate(MenuBase):
|
|
"""创建菜单"""
|
|
pass
|
|
|
|
|
|
class MenuUpdate(BaseModel):
|
|
"""更新菜单"""
|
|
menu_name: Optional[str] = Field(None, max_length=100, description="菜单名称")
|
|
menu_icon: Optional[str] = Field(None, max_length=50, description="菜单图标")
|
|
path: Optional[str] = Field(None, max_length=200, description="路由路径")
|
|
component: Optional[str] = Field(None, max_length=200, description="组件路径")
|
|
permission: Optional[str] = Field(None, max_length=100, description="权限标识")
|
|
sort_order: Optional[int] = Field(None, ge=0, description="排序")
|
|
is_visible: Optional[bool] = Field(None, description="是否可见")
|
|
is_active: Optional[bool] = Field(None, description="是否启用")
|
|
|
|
|
|
class MenuResponse(MenuBase):
|
|
"""菜单响应"""
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
id: int
|
|
children: Optional[List["MenuResponse"]] = None
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
|
|
|
|
class MenuTree(BaseModel):
|
|
"""菜单树节点"""
|
|
id: int
|
|
menu_name: str
|
|
menu_icon: Optional[str] = None
|
|
path: str
|
|
children: Optional[List["MenuTree"]] = None
|
|
|
|
|
|
# ==================== 指标模板相关 ====================
|
|
|
|
class TemplateType(str, Enum):
|
|
"""模板类型"""
|
|
GENERAL = "general" # 通用模板
|
|
SURGICAL = "surgical" # 手术临床科室
|
|
NON_SURGICAL_WARD = "nonsurgical_ward" # 非手术有病房科室
|
|
NON_SURGICAL_NOWARD = "nonsurgical_noward" # 非手术无病房科室
|
|
MEDICAL_TECH = "medical_tech" # 医技科室
|
|
NURSING = "nursing" # 护理单元
|
|
ADMIN = "admin" # 行政科室
|
|
LOGISTICS = "logistics" # 后勤科室
|
|
|
|
|
|
class TemplateIndicatorBase(BaseModel):
|
|
"""模板指标关联基础模式"""
|
|
indicator_id: int = Field(..., description="指标 ID")
|
|
category: Optional[str] = Field(None, max_length=100, description="指标分类")
|
|
target_value: Optional[float] = Field(None, description="目标值")
|
|
target_unit: Optional[str] = Field(None, max_length=50, description="目标值单位")
|
|
weight: float = Field(default=1.0, ge=0, le=100, description="权重")
|
|
scoring_method: Optional[str] = Field(None, max_length=50, description="评分方法")
|
|
scoring_params: Optional[str] = Field(None, description="评分参数 (JSON)")
|
|
sort_order: int = Field(default=0, ge=0, description="排序")
|
|
remark: Optional[str] = Field(None, description="备注")
|
|
|
|
|
|
class TemplateIndicatorCreate(TemplateIndicatorBase):
|
|
"""创建模板指标关联"""
|
|
pass
|
|
|
|
|
|
class TemplateIndicatorUpdate(BaseModel):
|
|
"""更新模板指标关联"""
|
|
category: Optional[str] = Field(None, max_length=100, description="指标分类")
|
|
target_value: Optional[float] = Field(None, description="目标值")
|
|
target_unit: Optional[str] = Field(None, max_length=50, description="目标值单位")
|
|
weight: Optional[float] = Field(None, ge=0, le=100, description="权重")
|
|
scoring_method: Optional[str] = Field(None, max_length=50, description="评分方法")
|
|
scoring_params: Optional[str] = Field(None, description="评分参数 (JSON)")
|
|
sort_order: Optional[int] = Field(None, ge=0, description="排序")
|
|
remark: Optional[str] = Field(None, description="备注")
|
|
|
|
|
|
class TemplateIndicatorResponse(TemplateIndicatorBase):
|
|
"""模板指标关联响应"""
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
id: int
|
|
template_id: int
|
|
indicator_name: Optional[str] = None
|
|
indicator_code: Optional[str] = None
|
|
indicator_type: Optional[str] = None
|
|
bs_dimension: Optional[str] = None
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
|
|
|
|
class IndicatorTemplateBase(BaseModel):
|
|
"""指标模板基础模式"""
|
|
template_name: str = Field(..., max_length=200, description="模板名称")
|
|
template_code: str = Field(..., max_length=50, description="模板编码")
|
|
template_type: TemplateType = Field(..., description="模板类型")
|
|
description: Optional[str] = Field(None, description="模板描述")
|
|
dimension_weights: Optional[str] = Field(None, description="维度权重 (JSON)")
|
|
assessment_cycle: str = Field(default="monthly", max_length=20, description="考核周期")
|
|
|
|
|
|
class IndicatorTemplateCreate(IndicatorTemplateBase):
|
|
"""创建指标模板"""
|
|
indicators: Optional[List[TemplateIndicatorCreate]] = Field(None, description="指标列表")
|
|
|
|
|
|
class IndicatorTemplateUpdate(BaseModel):
|
|
"""更新指标模板"""
|
|
template_name: Optional[str] = Field(None, max_length=200, description="模板名称")
|
|
template_type: Optional[TemplateType] = None
|
|
description: Optional[str] = Field(None, description="模板描述")
|
|
dimension_weights: Optional[str] = Field(None, description="维度权重 (JSON)")
|
|
assessment_cycle: Optional[str] = Field(None, max_length=20, description="考核周期")
|
|
is_active: Optional[bool] = Field(None, description="是否启用")
|
|
|
|
|
|
class IndicatorTemplateResponse(IndicatorTemplateBase):
|
|
"""指标模板响应"""
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
id: int
|
|
is_active: bool
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
indicators: Optional[List[TemplateIndicatorResponse]] = None
|
|
|
|
|
|
class IndicatorTemplateListResponse(IndicatorTemplateBase):
|
|
"""指标模板列表响应"""
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
id: int
|
|
is_active: bool
|
|
indicator_count: int = Field(default=0, description="指标数量")
|
|
created_at: datetime
|
|
updated_at: datetime
|