提交文件

This commit is contained in:
2026-02-28 15:16:15 +08:00
parent 1a4e50e0a4
commit 44f250f58e
159 changed files with 61268 additions and 0 deletions

View File

@@ -0,0 +1,453 @@
# 科室信息模型
<cite>
**本文引用的文件**
- [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)
</cite>
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构概览](#架构概览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考量](#性能考量)
8. [故障排除指南](#故障排除指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本文档系统化阐述“科室信息模型”的设计理念与实现细节,围绕 Department 模型展开,涵盖:
- 科室类型枚举DeptType及其业务分类
- 树形层级结构与父子关系设计
- 字段语义、数据类型、约束条件与业务规则
- 科室编码唯一性、层级计算逻辑、排序机制与状态管理
- 科室类型分类的应用场景与最佳实践
- 数据操作示例、层级查询方法与常见问题排查
## 项目结构
后端采用分层架构API 层负责请求处理与鉴权Service 层封装业务逻辑Model 层定义数据模型与数据库映射;前端通过 API 模块调用后端接口,实现科室数据的增删改查与树形展示。
```mermaid
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
```
图表来源
- [departments.py](file://backend/app/api/v1/departments.py#L1-L108)
- [department_service.py](file://backend/app/services/department_service.py#L1-L150)
- [models.py](file://backend/app/models/models.py#L62-L85)
- [Departments.vue](file://frontend/src/views/basic/Departments.vue#L103-L272)
- [department.js](file://frontend/src/api/department.js#L1-L32)
章节来源
- [models.py](file://backend/app/models/models.py#L62-L85)
- [schemas.py](file://backend/app/schemas/schemas.py#L64-L103)
- [departments.py](file://backend/app/api/v1/departments.py#L1-L108)
- [department_service.py](file://backend/app/services/department_service.py#L1-L150)
- [Departments.vue](file://frontend/src/views/basic/Departments.vue#L1-L290)
- [department.js](file://frontend/src/api/department.js#L1-L32)
## 核心组件
- Department 模型:定义科室实体的字段、索引与关系
- DeptType 枚举:标准化科室类型,支持多类业务场景
- DepartmentService封装 CRUD、层级树构建与校验逻辑
- FastAPI 路由:提供列表、树形、详情、创建、更新、删除等接口
- 前端视图与 API提供交互界面与 HTTP 请求封装
章节来源
- [models.py](file://backend/app/models/models.py#L16-L26)
- [models.py](file://backend/app/models/models.py#L62-L85)
- [department_service.py](file://backend/app/services/department_service.py#L13-L149)
- [departments.py](file://backend/app/api/v1/departments.py#L20-L107)
- [schemas.py](file://backend/app/schemas/schemas.py#L64-L103)
- [Departments.vue](file://frontend/src/views/basic/Departments.vue#L103-L272)
- [department.js](file://frontend/src/api/department.js#L1-L32)
## 架构概览
后端采用 ORM 映射Department 通过外键维护自引用的父子关系Service 层在创建时自动计算层级API 层提供树形结构查询与分页列表查询。
```mermaid
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 : "自引用父子关系"
```
图表来源
- [models.py](file://backend/app/models/models.py#L16-L26)
- [models.py](file://backend/app/models/models.py#L62-L85)
- [department_service.py](file://backend/app/services/department_service.py#L13-L149)
## 详细组件分析
### 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 控制启用/停用,影响列表过滤与前端显示
- 父子关系:支持任意层级的树形组织,删除时需确保无子节点
章节来源
- [models.py](file://backend/app/models/models.py#L62-L85)
- [department_service.py](file://backend/app/services/department_service.py#L62-L78)
- [departments.py](file://backend/app/api/v1/departments.py#L74-L77)
### 科室类型枚举DeptType
- 分类与含义
- 手术临床clinical_surgical
- 非手术有病房clinical_nonsurgical_ward
- 非手术无病房clinical_nonsurgical_noward
- 医技medical_tech
- 医辅medical_auxiliary
- 护理nursing
- 行政admin
- 财务finance
- 后勤logistics
- 应用场景
- 指标模板匹配:不同类型科室适用不同指标集合
- 权限与菜单:类型决定可访问的功能范围
- 报表与统计:按类型聚合绩效、财务等数据
- 计划与考核:类型驱动 KPI 设定与权重分配
章节来源
- [models.py](file://backend/app/models/models.py#L16-L26)
- [schemas.py](file://backend/app/schemas/schemas.py#L12-L21)
### 树形层级结构与父子关系
- 自引用关系
- Department.parent_id 外键指向 Department.id
- 通过 relationship 建立 parent 与 children 的双向关系
- 层级计算
- 创建时根据 parent_id 查询父级 level 并 +1
- 支持多级嵌套level 从 1 开始
- 树形构建
- Service 层一次性查询所有科室,按 sort_order 与 id 排序
- 使用字典映射与父子映射构建树根集
- 避免懒加载导致的循环依赖与性能问题
```mermaid
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(["返回根节点树"])
```
图表来源
- [department_service.py](file://backend/app/services/department_service.py#L113-L149)
章节来源
- [models.py](file://backend/app/models/models.py#L78-L80)
- [department_service.py](file://backend/app/services/department_service.py#L113-L149)
### 数据操作流程与最佳实践
#### 列表查询
- 参数dept_type可选、is_active可选、page、page_size
- 排序sort_order → id
- 返回:分页结果与总数
```mermaid
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 响应
```
图表来源
- [departments.py](file://backend/app/api/v1/departments.py#L20-L40)
- [department_service.py](file://backend/app/services/department_service.py#L17-L43)
章节来源
- [departments.py](file://backend/app/api/v1/departments.py#L20-L40)
- [department_service.py](file://backend/app/services/department_service.py#L17-L43)
#### 树形查询
- 参数dept_type可选
- 排序sort_order → id
- 返回:根节点树,支持前端树形选择器
```mermaid
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 响应
```
图表来源
- [departments.py](file://backend/app/api/v1/departments.py#L43-L51)
- [department_service.py](file://backend/app/services/department_service.py#L113-L149)
章节来源
- [departments.py](file://backend/app/api/v1/departments.py#L43-L51)
- [department_service.py](file://backend/app/services/department_service.py#L113-L149)
#### 创建科室
- 前端校验:必填项(编码、名称、类型)
- 服务端校验:编码唯一性
- 层级计算:若 parent_id 存在则 level = 父级 level + 1
- 返回:完整 Department 对象
```mermaid
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 响应
```
图表来源
- [departments.py](file://backend/app/api/v1/departments.py#L67-L80)
- [department_service.py](file://backend/app/services/department_service.py#L62-L78)
章节来源
- [departments.py](file://backend/app/api/v1/departments.py#L67-L80)
- [department_service.py](file://backend/app/services/department_service.py#L62-L78)
#### 更新与删除
- 更新:支持修改名称、类型、父级、排序、状态、描述
- 删除:若存在子节点则拒绝删除,避免破坏树形结构
```mermaid
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_service.py](file://backend/app/services/department_service.py#L80-L110)
章节来源
- [department_service.py](file://backend/app/services/department_service.py#L80-L110)
- [departments.py](file://backend/app/api/v1/departments.py#L83-L107)
### 前端集成与使用示例
- 列表页面:支持按关键字(名称/编码)、类型筛选,分页展示
- 树形选择:上级科室使用树形选择器,便于层级配置
- 新增/编辑:表单校验必填字段,提交后刷新列表与树
- 删除:二次确认,防止误删
章节来源
- [Departments.vue](file://frontend/src/views/basic/Departments.vue#L103-L272)
- [department.js](file://frontend/src/api/department.js#L1-L32)
## 依赖关系分析
- 模型层依赖数据库引擎与枚举类型,定义了 Department 的结构与约束
- 服务层依赖模型层,提供业务逻辑与数据处理
- API 层依赖服务层与安全中间件,提供对外接口
- 前端依赖 API 封装,调用后端接口完成用户交互
```mermaid
graph LR
FE["前端 Views/API"] --> API["FastAPI 路由"]
API --> SVC["Service 业务层"]
SVC --> MODEL["ORM 模型层"]
MODEL --> DB["数据库"]
```
图表来源
- [models.py](file://backend/app/models/models.py#L62-L85)
- [department_service.py](file://backend/app/services/department_service.py#L13-L149)
- [departments.py](file://backend/app/api/v1/departments.py#L1-L108)
- [Departments.vue](file://frontend/src/views/basic/Departments.vue#L103-L272)
- [department.js](file://frontend/src/api/department.js#L1-L32)
## 性能考量
- 查询优化
- 列表与树形查询均按 sort_order 与 id 排序,保证稳定顺序
- 服务层一次性加载所有科室,避免 N+1 查询
- 索引策略
- 按类型与父节点建立索引,提升过滤与层级查询效率
- 缓存建议
- 树形结构可考虑缓存热点数据,减少重复构建
- 分页与并发
- 列表查询支持分页,避免一次性加载过多数据
- 删除前检查子节点,避免事务回滚与锁竞争
## 故障排除指南
- 创建失败:编码重复
- 现象:创建接口返回错误
- 处理:检查是否存在相同编码,修改后重试
- 删除失败:存在子节点
- 现象:删除接口返回错误
- 处理:先删除子节点或调整层级后再删除
- 树形不正确:层级或排序异常
- 现象:树形选择器显示层级混乱
- 处理:检查 parent_id 与 sort_order 设置,重新保存
- 前端显示异常:类型标签或状态开关无效
- 现象:类型标签颜色/文案不一致,状态切换无效
- 处理:确认枚举值与前端映射一致,检查事件绑定
章节来源
- [departments.py](file://backend/app/api/v1/departments.py#L74-L77)
- [department_service.py](file://backend/app/services/department_service.py#L102-L107)
- [Departments.vue](file://frontend/src/views/basic/Departments.vue#L143-L161)
## 结论
Department 模型通过清晰的字段设计、严格的约束与完善的层级计算,为医院绩效系统的组织管理提供了可靠的数据基础。结合 DeptType 的分类与树形结构,能够灵活支撑各类科室的差异化需求,并通过前后端协同实现高效、稳定的科室信息管理。
## 附录
### 字段与约束对照表
- 字段名name
- 类型:字符串
- 约束:必填,长度 ≤ 100
- 用途:显示与检索
- 字段名code
- 类型:字符串
- 约束:必填,唯一,长度 ≤ 20
- 用途:业务识别与去重
- 字段名dept_type
- 类型:枚举
- 约束:必填
- 用途:类型分类与模板匹配
- 字段名parent_id
- 类型:整型
- 约束:可空,外键指向自身 id
- 用途:树形层级
- 字段名level
- 类型:整型
- 约束:默认 1创建时根据父级 +1
- 用途:层级深度
- 字段名sort_order
- 类型:整型
- 约束:默认 0
- 用途:排序与展示顺序
- 字段名is_active
- 类型:布尔
- 约束:默认启用
- 用途:启用/停用控制
- 字段名description
- 类型:文本
- 约束:可空
- 用途:补充说明
- 字段名created_at/updated_at
- 类型:时间戳
- 约束:自动维护
- 用途:审计与追踪
章节来源
- [models.py](file://backend/app/models/models.py#L66-L76)
- [schemas.py](file://backend/app/schemas/schemas.py#L64-L72)