16 KiB
16 KiB
科室信息模型
**本文引用的文件** - [models.py](file://backend/app/models/models.py) - [schemas.py](file://backend/app/schemas/schemas.py) - [departments.py](file://backend/app/api/v1/departments.py) - [department_service.py](file://backend/app/services/department_service.py) - [Departments.vue](file://frontend/src/views/basic/Departments.vue) - [department.js](file://frontend/src/api/department.js)目录
简介
本文档系统化阐述“科室信息模型”的设计理念与实现细节,围绕 Department 模型展开,涵盖:
- 科室类型枚举(DeptType)及其业务分类
- 树形层级结构与父子关系设计
- 字段语义、数据类型、约束条件与业务规则
- 科室编码唯一性、层级计算逻辑、排序机制与状态管理
- 科室类型分类的应用场景与最佳实践
- 数据操作示例、层级查询方法与常见问题排查
项目结构
后端采用分层架构:API 层负责请求处理与鉴权,Service 层封装业务逻辑,Model 层定义数据模型与数据库映射;前端通过 API 模块调用后端接口,实现科室数据的增删改查与树形展示。
graph TB
subgraph "前端"
FE_Dialog["Departments.vue<br/>新增/编辑/删除/树形选择"]
FE_API["department.js<br/>HTTP 请求封装"]
end
subgraph "后端"
API["departments.py<br/>FastAPI 路由"]
SVC["department_service.py<br/>业务逻辑"]
MODEL["models.py<br/>Department 模型与 DeptType 枚举"]
end
FE_Dialog --> FE_API
FE_API --> API
API --> SVC
SVC --> MODEL
图表来源
章节来源
核心组件
- Department 模型:定义科室实体的字段、索引与关系
- DeptType 枚举:标准化科室类型,支持多类业务场景
- DepartmentService:封装 CRUD、层级树构建与校验逻辑
- FastAPI 路由:提供列表、树形、详情、创建、更新、删除等接口
- 前端视图与 API:提供交互界面与 HTTP 请求封装
章节来源
架构概览
后端采用 ORM 映射,Department 通过外键维护自引用的父子关系;Service 层在创建时自动计算层级,API 层提供树形结构查询与分页列表查询。
classDiagram
class Department {
+int id
+string name
+string code
+DeptType dept_type
+int? parent_id
+int level
+int sort_order
+bool is_active
+string? description
+datetime created_at
+datetime updated_at
+parent : Department?
+children : Department[]
+staff : Staff[]
}
class DepartmentService {
+get_list(...)
+get_by_id(...)
+get_by_code(...)
+create(...)
+update(...)
+delete(...)
+get_tree(...)
}
class DeptType {
<<enumeration>>
+CLINICAL_SURGICAL
+CLINICAL_NONSURGICAL_WARD
+CLINICAL_NONSURGICAL_NOWARD
+MEDICAL_TECH
+MEDICAL_AUXILIARY
+NURSING
+ADMIN
+FINANCE
+LOGISTICS
}
DepartmentService --> Department : "操作"
Department --> DeptType : "使用"
Department --> Department : "自引用父子关系"
图表来源
详细组件分析
Department 模型与字段规范
- 主键与标识
- id:整型,自增主键
- code:字符串,长度限制,唯一约束,用于业务识别与去重
- 基础信息
- name:字符串,长度限制,必填
- description:文本,可空
- 组织结构
- parent_id:外键指向同表 id,支持树形层级
- level:整型,默认 1,表示层级深度
- sort_order:整型,默认 0,用于排序
- 类型与状态
- dept_type:枚举 DeptType,必填
- is_active:布尔,默认启用
- 时间戳
- created_at、updated_at:自动维护
- 索引与关系
- 索引:按类型、父节点
- 关系:parent(反向 children)、staff(一对多)
字段约束与业务规则
- 唯一性:code 唯一,API 层在创建前进行重复校验
- 层级计算:创建时若指定 parent_id,则 level = 父级 level + 1;否则默认 1
- 排序:列表与树形查询均按 sort_order 与 id 排序
- 状态:is_active 控制启用/停用,影响列表过滤与前端显示
- 父子关系:支持任意层级的树形组织,删除时需确保无子节点
章节来源
科室类型枚举(DeptType)
- 分类与含义
- 手术临床:clinical_surgical
- 非手术有病房:clinical_nonsurgical_ward
- 非手术无病房:clinical_nonsurgical_noward
- 医技:medical_tech
- 医辅:medical_auxiliary
- 护理:nursing
- 行政:admin
- 财务:finance
- 后勤:logistics
- 应用场景
- 指标模板匹配:不同类型科室适用不同指标集合
- 权限与菜单:类型决定可访问的功能范围
- 报表与统计:按类型聚合绩效、财务等数据
- 计划与考核:类型驱动 KPI 设定与权重分配
章节来源
树形层级结构与父子关系
- 自引用关系
- Department.parent_id 外键指向 Department.id
- 通过 relationship 建立 parent 与 children 的双向关系
- 层级计算
- 创建时根据 parent_id 查询父级 level 并 +1
- 支持多级嵌套,level 从 1 开始
- 树形构建
- Service 层一次性查询所有科室,按 sort_order 与 id 排序
- 使用字典映射与父子映射构建树根集
- 避免懒加载导致的循环依赖与性能问题
flowchart TD
Start(["开始"]) --> LoadDepts["查询所有科室<br/>按 sort_order,id 排序"]
LoadDepts --> BuildMap["构建 id->节点 映射"]
BuildMap --> Iterate["遍历科室列表"]
Iterate --> HasParent{"存在 parent_id 且父节点在映射中?"}
HasParent --> |是| AppendChild["将当前节点加入父节点 children"]
HasParent --> |否| AddRoot["加入根节点集"]
AppendChild --> Next["下一个科室"]
AddRoot --> Next
Next --> Done(["返回根节点树"])
图表来源
章节来源
数据操作流程与最佳实践
列表查询
- 参数:dept_type(可选)、is_active(可选)、page、page_size
- 排序:sort_order → id
- 返回:分页结果与总数
sequenceDiagram
participant FE as "前端"
participant API as "departments.py"
participant SVC as "department_service.py"
participant DB as "数据库"
FE->>API : GET /departments?page=&page_size=&dept_type=&is_active=
API->>SVC : get_list(dept_type,is_active,page,page_size)
SVC->>DB : select(department) + where + order_by + limit/offset
DB-->>SVC : 列表数据
SVC->>DB : count(*) 子查询
DB-->>SVC : 总数
SVC-->>API : (列表,总数)
API-->>FE : JSON 响应
图表来源
章节来源
树形查询
- 参数:dept_type(可选)
- 排序:sort_order → id
- 返回:根节点树,支持前端树形选择器
sequenceDiagram
participant FE as "前端"
participant API as "departments.py"
participant SVC as "department_service.py"
participant DB as "数据库"
FE->>API : GET /departments/tree?dept_type=
API->>SVC : get_tree(dept_type)
SVC->>DB : select(department) + order_by(sort_order,id)
DB-->>SVC : 所有科室
SVC->>SVC : 构建 id->节点 映射
SVC->>SVC : 追加到父节点 children 或根集
SVC-->>API : 根节点树
API-->>FE : JSON 响应
图表来源
章节来源
创建科室
- 前端校验:必填项(编码、名称、类型)
- 服务端校验:编码唯一性
- 层级计算:若 parent_id 存在则 level = 父级 level + 1
- 返回:完整 Department 对象
sequenceDiagram
participant FE as "前端"
participant API as "departments.py"
participant SVC as "department_service.py"
participant DB as "数据库"
FE->>API : POST /departments
API->>SVC : get_by_code(code)
SVC->>DB : select(code)
DB-->>SVC : 结果
SVC-->>API : 若存在则抛错
API->>SVC : create(dept_data)
SVC->>SVC : 计算 level(parent.level+1)
SVC->>DB : insert(department)
DB-->>SVC : 新记录
SVC-->>API : 返回新建对象
API-->>FE : JSON 响应
图表来源
章节来源
更新与删除
- 更新:支持修改名称、类型、父级、排序、状态、描述
- 删除:若存在子节点则拒绝删除,避免破坏树形结构
flowchart TD
UStart(["更新入口"]) --> GetByID["根据 id 查询科室"]
GetByID --> Exists{"是否存在?"}
Exists --> |否| NotFound["返回 404"]
Exists --> |是| Apply["应用变更字段"]
Apply --> Flush["flush/refresh"]
Flush --> UEnd(["结束"])
DStart(["删除入口"]) --> DGet["根据 id 查询科室"]
DGet --> DExists{"是否存在?"}
DExists --> |否| DNotFound["返回 404"]
DExists --> |是| CheckChildren["检查是否存在子节点"]
CheckChildren --> HasChild{"有子节点?"}
HasChild --> |是| Block["返回错误(不可删除)"]
HasChild --> |否| Delete["删除并返回成功"]
Delete --> DEnd(["结束"])
图表来源
章节来源
前端集成与使用示例
- 列表页面:支持按关键字(名称/编码)、类型筛选,分页展示
- 树形选择:上级科室使用树形选择器,便于层级配置
- 新增/编辑:表单校验必填字段,提交后刷新列表与树
- 删除:二次确认,防止误删
章节来源
依赖关系分析
- 模型层依赖数据库引擎与枚举类型,定义了 Department 的结构与约束
- 服务层依赖模型层,提供业务逻辑与数据处理
- API 层依赖服务层与安全中间件,提供对外接口
- 前端依赖 API 封装,调用后端接口完成用户交互
graph LR
FE["前端 Views/API"] --> API["FastAPI 路由"]
API --> SVC["Service 业务层"]
SVC --> MODEL["ORM 模型层"]
MODEL --> DB["数据库"]
图表来源
性能考量
- 查询优化
- 列表与树形查询均按 sort_order 与 id 排序,保证稳定顺序
- 服务层一次性加载所有科室,避免 N+1 查询
- 索引策略
- 按类型与父节点建立索引,提升过滤与层级查询效率
- 缓存建议
- 树形结构可考虑缓存热点数据,减少重复构建
- 分页与并发
- 列表查询支持分页,避免一次性加载过多数据
- 删除前检查子节点,避免事务回滚与锁竞争
故障排除指南
- 创建失败:编码重复
- 现象:创建接口返回错误
- 处理:检查是否存在相同编码,修改后重试
- 删除失败:存在子节点
- 现象:删除接口返回错误
- 处理:先删除子节点或调整层级后再删除
- 树形不正确:层级或排序异常
- 现象:树形选择器显示层级混乱
- 处理:检查 parent_id 与 sort_order 设置,重新保存
- 前端显示异常:类型标签或状态开关无效
- 现象:类型标签颜色/文案不一致,状态切换无效
- 处理:确认枚举值与前端映射一致,检查事件绑定
章节来源
结论
Department 模型通过清晰的字段设计、严格的约束与完善的层级计算,为医院绩效系统的组织管理提供了可靠的数据基础。结合 DeptType 的分类与树形结构,能够灵活支撑各类科室的差异化需求,并通过前后端协同实现高效、稳定的科室信息管理。
附录
字段与约束对照表
- 字段名:name
- 类型:字符串
- 约束:必填,长度 ≤ 100
- 用途:显示与检索
- 字段名:code
- 类型:字符串
- 约束:必填,唯一,长度 ≤ 20
- 用途:业务识别与去重
- 字段名:dept_type
- 类型:枚举
- 约束:必填
- 用途:类型分类与模板匹配
- 字段名:parent_id
- 类型:整型
- 约束:可空,外键指向自身 id
- 用途:树形层级
- 字段名:level
- 类型:整型
- 约束:默认 1,创建时根据父级 +1
- 用途:层级深度
- 字段名:sort_order
- 类型:整型
- 约束:默认 0
- 用途:排序与展示顺序
- 字段名:is_active
- 类型:布尔
- 约束:默认启用
- 用途:启用/停用控制
- 字段名:description
- 类型:文本
- 约束:可空
- 用途:补充说明
- 字段名:created_at/updated_at
- 类型:时间戳
- 约束:自动维护
- 用途:审计与追踪
章节来源