# 科室信息模型 **本文引用的文件** - [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) ## 目录 1. [简介](#简介) 2. [项目结构](#项目结构) 3. [核心组件](#核心组件) 4. [架构概览](#架构概览) 5. [详细组件分析](#详细组件分析) 6. [依赖关系分析](#依赖关系分析) 7. [性能考量](#性能考量) 8. [故障排除指南](#故障排除指南) 9. [结论](#结论) 10. [附录](#附录) ## 简介 本文档系统化阐述“科室信息模型”的设计理念与实现细节,围绕 Department 模型展开,涵盖: - 科室类型枚举(DeptType)及其业务分类 - 树形层级结构与父子关系设计 - 字段语义、数据类型、约束条件与业务规则 - 科室编码唯一性、层级计算逻辑、排序机制与状态管理 - 科室类型分类的应用场景与最佳实践 - 数据操作示例、层级查询方法与常见问题排查 ## 项目结构 后端采用分层架构:API 层负责请求处理与鉴权,Service 层封装业务逻辑,Model 层定义数据模型与数据库映射;前端通过 API 模块调用后端接口,实现科室数据的增删改查与树形展示。 ```mermaid graph TB subgraph "前端" FE_Dialog["Departments.vue
新增/编辑/删除/树形选择"] FE_API["department.js
HTTP 请求封装"] end subgraph "后端" API["departments.py
FastAPI 路由"] SVC["department_service.py
业务逻辑"] MODEL["models.py
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 { <> +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["查询所有科室
按 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)