16 KiB
16 KiB
科室管理
**本文引用的文件** - [backend/app/api/v1/departments.py](file://backend/app/api/v1/departments.py) - [backend/app/services/department_service.py](file://backend/app/services/department_service.py) - [backend/app/models/models.py](file://backend/app/models/models.py) - [backend/app/schemas/schemas.py](file://backend/app/schemas/schemas.py) - [backend/app/main.py](file://backend/app/main.py) - [frontend/src/api/department.js](file://frontend/src/api/department.js) - [frontend/src/views/basic/Departments.vue](file://frontend/src/views/basic/Departments.vue) - [docs/database.md](file://docs/database.md)目录
简介
本章节面向“医院绩效系统”的“科室管理”功能,系统化阐述后端API、数据库模型、前端组件与服务层之间的协作关系,覆盖以下能力:
- 科室信息的增删改查(CRUD)
- 科室类型分类(手术临床、非手术有病房、非手术无病房、医技、医辅、护理单元、行政、财务、后勤保障)
- 树形层级结构管理(父子关系、层级level、排序sort_order)
- 科室状态控制(启用/禁用)
- 搜索过滤与分页
- 编码唯一性约束与上级科室关联校验
- 前端树形选择器、状态切换开关、搜索过滤与分页展示
项目结构
围绕“科室管理”,涉及后端三层(API-Service-Model)与前端单页面组件的协同:
- 后端
- API路由:负责请求参数解析、鉴权与返回格式化
- 服务层:封装业务逻辑(查询、树构建、创建、更新、删除)
- 模型层:定义数据库表结构、索引与关系
- Schema层:定义请求/响应数据结构与字段校验
- 前端
- API适配层:封装HTTP请求
- 视图组件:表格、分页、对话框、树形选择器、状态开关、搜索过滤
graph TB
subgraph "后端"
API["API路由<br/>departments.py"]
SVC["服务层<br/>department_service.py"]
MODEL["模型层<br/>models.py"]
SCHEMA["Schema层<br/>schemas.py"]
end
subgraph "前端"
FE_API["API适配层<br/>frontend/src/api/department.js"]
VIEW["视图组件<br/>frontend/src/views/basic/Departments.vue"]
end
FE_API --> API
VIEW --> FE_API
API --> SVC
SVC --> MODEL
SVC --> SCHEMA
图表来源
- backend/app/api/v1/departments.py
- backend/app/services/department_service.py
- backend/app/models/models.py
- backend/app/schemas/schemas.py
- frontend/src/api/department.js
- frontend/src/views/basic/Departments.vue
章节来源
- backend/app/api/v1/departments.py
- backend/app/services/department_service.py
- backend/app/models/models.py
- backend/app/schemas/schemas.py
- frontend/src/api/department.js
- frontend/src/views/basic/Departments.vue
核心组件
- 后端API路由
- 提供科室列表、树形结构、详情、创建、更新、删除等接口
- 支持按科室类型与状态过滤,支持分页
- 服务层
- 列表查询:支持类型与状态过滤、分页、排序
- 树形构建:手动构建树,避免懒加载问题
- 创建:自动计算层级level,校验编码唯一
- 更新:动态更新字段
- 删除:检查是否存在子节点,防止误删
- 模型层
- 科室表包含:编码唯一、类型枚举、父ID自关联、层级、排序、状态、描述、时间戳
- 索引:类型、父ID
- Schema层
- 定义创建、更新、响应、树形结构的数据模型
- 前端组件
- 表格:显示编码、名称、类型、层级、状态、创建时间、操作
- 分页:页码与每页数量
- 对话框:新增/编辑,含树形选择器、类型选择、排序输入、描述文本域
- 状态开关:启用/禁用
- 搜索:关键词(名称/编码)与类型筛选
章节来源
- backend/app/api/v1/departments.py
- backend/app/services/department_service.py
- backend/app/models/models.py
- backend/app/schemas/schemas.py
- frontend/src/views/basic/Departments.vue
架构概览
后端采用FastAPI + SQLAlchemy异步ORM,前端使用Vue3 + Element Plus。数据流从浏览器发起请求,经API路由进入服务层,访问数据库模型并返回标准化响应;前端通过API适配层调用后端接口,并渲染表格、树形选择器与状态开关。
sequenceDiagram
participant Browser as "浏览器"
participant FE as "前端组件<br/>Departments.vue"
participant API as "后端API<br/>departments.py"
participant SVC as "服务层<br/>department_service.py"
participant DB as "数据库模型<br/>models.py"
Browser->>FE : 打开页面/点击查询
FE->>API : GET /departments?keyword&dept_type&page&page_size
API->>SVC : get_list(dept_type, is_active, page, page_size)
SVC->>DB : 查询departments并统计总数
DB-->>SVC : 列表与总数
SVC-->>API : 返回列表与总数
API-->>FE : 标准化响应{code,message,data,total,page,page_size}
Browser->>FE : 点击树形选择器
FE->>API : GET /departments/tree?dept_type
API->>SVC : get_tree(dept_type)
SVC->>DB : 查询departments并构建树
DB-->>SVC : 列表
SVC-->>API : 树形结构
API-->>FE : 树形数据
Browser->>FE : 点击状态开关
FE->>API : PUT /departments/{id} {is_active}
API->>SVC : update(dept_id, {is_active})
SVC->>DB : 更新is_active
DB-->>SVC : 更新后的对象
SVC-->>API : 返回更新结果
API-->>FE : 成功消息
图表来源
- backend/app/api/v1/departments.py
- backend/app/services/department_service.py
- backend/app/models/models.py
- frontend/src/views/basic/Departments.vue
详细组件分析
后端API路由(departments.py)
- 接口清单
- GET /departments:列表查询(支持类型、状态、分页)
- GET /departments/tree:树形结构(可选按类型过滤)
- GET /departments/{id}:详情
- POST /departments:创建(需管理员/经理权限,校验编码唯一)
- PUT /departments/{id}:更新(需管理员/经理权限)
- DELETE /departments/{id}:删除(需管理员/经理权限,禁止删除有子节点的科室)
- 权限与安全
- 使用依赖注入获取当前用户与权限校验
- 返回统一响应结构(code/message/data/total/page/page_size)
章节来源
服务层(department_service.py)
- 列表查询
- 过滤条件:类型、状态
- 排序:先按sort_order,再按id
- 分页:offset/limit
- 树形构建
- 查询所有科室并按sort_order/id排序
- 使用映射表构建树节点,处理父子关系
- 未找到父节点时作为根节点
- 创建
- 若存在parent_id,则计算level = parent.level + 1
- 写入数据库并刷新
- 更新
- 动态更新字段,支持部分字段更新
- 删除
- 检查是否存在子节点,若有则拒绝删除
flowchart TD
Start(["开始"]) --> Load["查询所有科室并排序"]
Load --> BuildMap["构建ID到节点映射"]
BuildMap --> ForEach["遍历每个科室"]
ForEach --> HasParent{"存在parent_id且父节点存在?"}
HasParent --> |是| AppendChild["将当前节点加入父节点children"]
HasParent --> |否| AddRoot["加入根节点列表"]
AppendChild --> Next["下一个科室"]
AddRoot --> Next
Next --> Done{"遍历结束?"}
Done --> |否| ForEach
Done --> |是| Return["返回根节点集合(树)"]
图表来源
章节来源
数据模型(models.py)
- 科室表字段
- 编码唯一(code)
- 类型枚举(DeptType)
- 自关联父ID(parent_id)
- 层级(level,默认1)
- 排序(sort_order,默认0)
- 状态(is_active,默认true)
- 时间戳(created_at/updated_at)
- 索引
- 类型索引、父ID索引
- 关系
- 与员工表的反向关系(backref)
章节来源
Schema定义(schemas.py)
- 数据模型
- DepartmentBase:基础字段
- DepartmentCreate:创建用
- DepartmentUpdate:更新用(可选字段)
- DepartmentResponse:响应用(含id、状态、时间戳)
- DepartmentTree:树形结构(children数组)
- 字段约束
- 类型枚举、长度限制、数值范围、可空性
章节来源
前端组件(Departments.vue)
- 功能点
- 搜索栏:关键词(名称/编码)、类型选择、查询/重置、新增按钮
- 表格:编码、名称、类型、层级、状态、创建时间、操作(编辑/删除)
- 分页:页码、每页数量、跳转
- 对话框:新增/编辑,含树形选择器、类型选择、排序、描述
- 状态开关:启用/禁用
- 交互流程
- 加载数据:GET /departments
- 加载树:GET /departments/tree
- 状态切换:PUT /departments/{id} {is_active}
- 新增/编辑:POST/PUT /departments
- 删除:DELETE /departments/{id}
sequenceDiagram
participant U as "用户"
participant V as "Departments.vue"
participant A as "API适配层"
participant S as "后端API"
U->>V : 输入关键词/类型并点击查询
V->>A : getDepartments({keyword,dept_type,page,page_size})
A->>S : GET /departments
S-->>A : 列表+总数
A-->>V : 渲染表格
U->>V : 点击状态开关
V->>A : updateDepartment(id,{is_active})
A->>S : PUT /departments/{id}
S-->>A : 成功
A-->>V : 提示成功
U->>V : 点击新增/编辑
V->>A : create/update
A->>S : POST/PUT /departments
S-->>A : 成功
A-->>V : 刷新列表与树
图表来源
- frontend/src/views/basic/Departments.vue
- frontend/src/api/department.js
- backend/app/api/v1/departments.py
章节来源
依赖关系分析
- 组件耦合
- API路由依赖服务层
- 服务层依赖模型层与Schema层
- 前端组件依赖API适配层
- 外部依赖
- FastAPI、SQLAlchemy、Element Plus
- 潜在循环依赖
- 当前结构清晰,无循环导入迹象
graph LR
FE["前端组件"] --> APIA["API适配层"]
APIA --> APIR["API路由"]
APIR --> SVCL["服务层"]
SVCL --> MDL["模型层"]
SVCL --> SCH["Schema层"]
图表来源
- backend/app/api/v1/departments.py
- backend/app/services/department_service.py
- backend/app/models/models.py
- backend/app/schemas/schemas.py
- frontend/src/api/department.js
- frontend/src/views/basic/Departments.vue
章节来源
性能考虑
- 查询优化
- 列表查询按sort_order与id排序,结合分页,避免全表扫描
- 树形构建在内存中完成,减少多次数据库往返
- 索引策略
- 类型与父ID索引有助于过滤与自关联查询
- 前端优化
- 树形选择器使用一次性加载,避免频繁请求
- 分页与搜索联动,减少无效请求
故障排查指南
- 常见错误与处理
- 编码重复:创建时校验编码唯一,返回400
- 科室不存在:更新/删除时若找不到对象,返回404
- 存在子节点:删除时若仍有子节点,返回400
- 权限不足:仅管理员/经理可执行创建/更新/删除
- 前端提示
- 成功/失败消息提示
- 删除前二次确认
- 表单校验失败时阻止提交
章节来源
- backend/app/api/v1/departments.py
- backend/app/api/v1/departments.py
- backend/app/api/v1/departments.py
- frontend/src/views/basic/Departments.vue
结论
“科室管理”功能通过清晰的后端三层架构与前端组件化实现,提供了完善的增删改查、树形层级、状态控制与搜索分页能力。服务层对树形构建与层级计算进行了重点处理,确保数据一致性与性能表现。前端通过树形选择器、状态开关与搜索过滤提升了用户体验。建议后续可扩展批量操作与导入导出能力,进一步提升管理效率。
附录
API接口定义(后端)
- 获取科室列表
- 方法:GET
- 路径:/departments
- 查询参数:keyword(名称/编码模糊)、dept_type(类型)、is_active(状态)、page、page_size
- 返回:code/message/data(total/page/page_size)
- 获取科室树
- 方法:GET
- 路径:/departments/tree
- 查询参数:dept_type(类型)
- 返回:code/message/data(树形结构)
- 获取科室详情
- 方法:GET
- 路径:/departments/{id}
- 返回:code/message/data
- 创建科室
- 方法:POST
- 路径:/departments
- 请求体:DepartmentCreate
- 返回:code/message/data
- 更新科室
- 方法:PUT
- 路径:/departments/{id}
- 请求体:DepartmentUpdate
- 返回:code/message/data
- 删除科室
- 方法:DELETE
- 路径:/departments/{id}
- 返回:code/message
章节来源
数据模型(关键字段)
- 科室表
- 字段:id、name、code(唯一)、dept_type、parent_id、level、sort_order、is_active、description、created_at、updated_at
- 索引:idx_dept_type、idx_dept_parent
- 关系
- 科室与员工:一对多(反向backref)
章节来源
前端组件(关键交互)
- 搜索与分页
- 搜索关键词与类型筛选,分页参数联动
- 树形选择器
- 使用el-tree-select,check-strictly,绑定name/value
- 状态开关
- el-switch绑定is_active,触发PUT更新
- 表单校验
- 必填项校验,提交前验证
章节来源