23 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/core/security.py](file://backend/app/core/security.py) - [backend/app/core/database.py](file://backend/app/core/database.py) - [backend/app/core/config.py](file://backend/app/core/config.py) - [frontend/src/api/department.js](file://frontend/src/api/department.js) - [frontend/public/test-api.html](file://frontend/public/test-api.html) - [docs/api.md](file://docs/api.md)目录
简介
本文档详细介绍了医院绩效管理系统的科室管理接口。该系统基于FastAPI构建,提供了完整的科室CRUD操作,包括获取科室列表(支持按类型和状态过滤)、获取树形结构、获取科室详情、创建科室、更新科室和删除科室。系统采用JWT认证机制,支持管理员和经理两种权限级别,并提供了完整的分页查询功能。
项目结构
后端采用分层架构设计,主要包含以下层次:
graph TB
subgraph "前端层"
FE[Vue.js 前端]
API[API 请求封装]
end
subgraph "接口层"
Router[FastAPI 路由器]
Auth[认证中间件]
end
subgraph "业务逻辑层"
Service[科室服务层]
Validation[数据验证]
end
subgraph "数据访问层"
Model[数据模型]
Schema[Pydantic 模式]
Security[安全认证]
end
subgraph "基础设施"
DB[(PostgreSQL 数据库)]
Config[配置管理]
end
FE --> API
API --> Router
Router --> Auth
Router --> Service
Service --> Model
Service --> Schema
Auth --> Security
Model --> DB
Config --> DB
图表来源
- backend/app/api/v1/departments.py
- backend/app/services/department_service.py
- backend/app/core/security.py
章节来源
核心组件
API路由器
- 位置:
backend/app/api/v1/departments.py - 功能: 定义所有科室管理相关的HTTP端点
- 标签: "科室管理"
服务层
- 位置:
backend/app/services/department_service.py - 职责: 实现业务逻辑,包括数据查询、验证和操作
- 特点: 异步操作,支持事务处理
数据模型
- 位置:
backend/app/models/models.py - 实体: Department(科室表)
- 特性: 支持层级关系,自引用外键
数据验证
- 位置:
backend/app/schemas/schemas.py - 用途: Pydantic模型用于请求验证和响应序列化
- 类型: DepartmentCreate, DepartmentUpdate, DepartmentResponse
章节来源
- backend/app/api/v1/departments.py
- backend/app/services/department_service.py
- backend/app/models/models.py
- backend/app/schemas/schemas.py
架构概览
系统采用经典的MVC架构模式,结合现代的异步编程:
sequenceDiagram
participant Client as 客户端
participant API as API路由器
participant Auth as 认证中间件
participant Service as 服务层
participant DB as 数据库
participant Model as 数据模型
Client->>API : HTTP请求
API->>Auth : 验证JWT令牌
Auth->>Auth : 验证用户权限
Auth-->>API : 通过验证
API->>Service : 调用业务逻辑
Service->>DB : 执行数据库操作
DB->>Model : 映射到模型
Model-->>DB : 返回数据
DB-->>Service : 查询结果
Service-->>API : 处理后的数据
API-->>Client : JSON响应
图表来源
- backend/app/api/v1/departments.py
- backend/app/core/security.py
- backend/app/services/department_service.py
详细接口文档
获取科室列表
HTTP方法: GET
URL路径: /api/v1/departments
权限要求: 需要激活用户权限
查询参数:
| 参数名 | 类型 | 必填 | 默认值 | 描述 |
|---|---|---|---|---|
| dept_type | string | 否 | 无 | 科室类型过滤 |
| is_active | boolean | 否 | 无 | 启用状态过滤 |
| page | int | 否 | 1 | 页码,最小值1 |
| page_size | int | 否 | 20 | 每页数量,范围1-100 |
响应数据结构:
{
"code": 200,
"message": "success",
"data": [
{
"id": 1,
"name": "内科",
"code": "NK001",
"dept_type": "clinical_surgical",
"parent_id": null,
"level": 1,
"sort_order": 1,
"is_active": true,
"description": "内科描述",
"created_at": "2024-01-01T00:00:00",
"updated_at": "2024-01-01T00:00:00"
}
],
"total": 10,
"page": 1,
"page_size": 20
}
请求示例:
curl -X GET "http://localhost:8000/api/v1/departments?page=1&page_size=20&dept_type=clinical_surgical&is_active=true" \
-H "Authorization: Bearer YOUR_TOKEN"
响应示例:
{
"code": 200,
"message": "success",
"data": [
{
"id": 1,
"name": "内科",
"code": "NK001",
"dept_type": "clinical_surgical",
"parent_id": null,
"level": 1,
"sort_order": 1,
"is_active": true,
"description": "",
"created_at": "2024-01-01T00:00:00",
"updated_at": "2024-01-01T00:00:00"
}
],
"total": 1,
"page": 1,
"page_size": 20
}
错误处理:
- 401 未授权:无效或过期的JWT令牌
- 403 禁止:用户权限不足
- 404 未找到:无匹配的数据
章节来源
获取科室树形结构
HTTP方法: GET
URL路径: /api/v1/departments/tree
权限要求: 需要激活用户权限
查询参数:
| 参数名 | 类型 | 必填 | 默认值 | 描述 |
|---|---|---|---|---|
| dept_type | string | 否 | 无 | 科室类型过滤 |
响应数据结构:
{
"code": 200,
"message": "success",
"data": [
{
"id": 1,
"name": "医院",
"code": "HOSPITAL",
"dept_type": "admin",
"parent_id": null,
"level": 1,
"sort_order": 1,
"is_active": true,
"description": "",
"created_at": "2024-01-01T00:00:00",
"updated_at": "2024-01-01T00:00:00",
"children": [
{
"id": 2,
"name": "内科",
"code": "NK001",
"dept_type": "clinical_surgical",
"parent_id": 1,
"level": 2,
"sort_order": 1,
"is_active": true,
"description": "",
"created_at": "2024-01-01T00:00:00",
"updated_at": "2024-01-01T00:00:00",
"children": []
}
]
}
]
}
请求示例:
curl -X GET "http://localhost:8000/api/v1/departments/tree?dept_type=clinical_surgical" \
-H "Authorization: Bearer YOUR_TOKEN"
响应示例:
{
"code": 200,
"message": "success",
"data": [
{
"id": 1,
"name": "医院",
"code": "HOSPITAL",
"dept_type": "admin",
"parent_id": null,
"level": 1,
"sort_order": 1,
"is_active": true,
"description": "",
"created_at": "2024-01-01T00:00:00",
"updated_at": "2024-01-01T00:00:00",
"children": [
{
"id": 2,
"name": "内科",
"code": "NK001",
"dept_type": "clinical_surgical",
"parent_id": 1,
"level": 2,
"sort_order": 1,
"is_active": true,
"description": "",
"created_at": "2024-01-01T00:00:00",
"updated_at": "2024-01-01T00:00:00",
"children": []
}
]
}
]
}
错误处理:
- 401 未授权:无效或过期的JWT令牌
- 403 禁止:用户权限不足
章节来源
获取科室详情
HTTP方法: GET
URL路径: /api/v1/departments/{dept_id}
权限要求: 需要激活用户权限
路径参数:
| 参数名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| dept_id | int | 是 | 科室ID |
响应数据结构:
{
"code": 200,
"message": "success",
"data": {
"id": 1,
"name": "内科",
"code": "NK001",
"dept_type": "clinical_surgical",
"parent_id": null,
"level": 1,
"sort_order": 1,
"is_active": true,
"description": "内科描述",
"created_at": "2024-01-01T00:00:00",
"updated_at": "2024-01-01T00:00:00"
}
}
请求示例:
curl -X GET "http://localhost:8000/api/v1/departments/1" \
-H "Authorization: Bearer YOUR_TOKEN"
响应示例:
{
"code": 200,
"message": "success",
"data": {
"id": 1,
"name": "内科",
"code": "NK001",
"dept_type": "clinical_surgical",
"parent_id": null,
"level": 1,
"sort_order": 1,
"is_active": true,
"description": "",
"created_at": "2024-01-01T00:00:00",
"updated_at": "2024-01-01T00:00:00"
}
}
错误处理:
- 401 未授权:无效或过期的JWT令牌
- 403 禁止:用户权限不足
- 404 未找到:科室不存在
章节来源
创建科室
HTTP方法: POST
URL路径: /api/v1/departments
权限要求: 需要管理员或经理权限
请求体参数:
| 参数名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| name | string | 是 | 科室名称,最大100字符 |
| code | string | 是 | 科室编码,最大20字符,必须唯一 |
| dept_type | string | 是 | 科室类型 |
| parent_id | int | 否 | 上级科室ID |
| level | int | 否 | 层级,默认1 |
| sort_order | int | 否 | 排序 |
| description | string | 否 | 描述 |
响应数据结构:
{
"code": 200,
"message": "创建成功",
"data": {
"id": 1,
"name": "内科",
"code": "NK001",
"dept_type": "clinical_surgical",
"parent_id": null,
"level": 1,
"sort_order": 1,
"is_active": true,
"description": "",
"created_at": "2024-01-01T00:00:00",
"updated_at": "2024-01-01T00:00:00"
}
}
请求示例:
curl -X POST "http://localhost:8000/api/v1/departments" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "内科",
"code": "NK001",
"dept_type": "clinical_surgical",
"parent_id": null,
"sort_order": 1,
"description": "内科描述"
}'
响应示例:
{
"code": 200,
"message": "创建成功",
"data": {
"id": 1,
"name": "内科",
"code": "NK001",
"dept_type": "clinical_surgical",
"parent_id": null,
"level": 1,
"sort_order": 1,
"is_active": true,
"description": "内科描述",
"created_at": "2024-01-01T00:00:00",
"updated_at": "2024-01-01T00:00:00"
}
}
错误处理:
- 400 错误请求:科室编码已存在
- 401 未授权:无效或过期的JWT令牌
- 403 禁止:用户权限不足
章节来源
更新科室
HTTP方法: PUT
URL路径: /api/v1/departments/{dept_id}
权限要求: 需要管理员或经理权限
路径参数:
| 参数名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| dept_id | int | 是 | 科室ID |
请求体参数:
| 参数名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| name | string | 否 | 科室名称,最大100字符 |
| dept_type | string | 否 | 科室类型 |
| parent_id | int | 否 | 上级科室ID |
| sort_order | int | 否 | 排序 |
| is_active | boolean | 否 | 是否启用 |
| description | string | 否 | 描述 |
响应数据结构:
{
"code": 200,
"message": "更新成功",
"data": {
"id": 1,
"name": "内科",
"code": "NK001",
"dept_type": "clinical_surgical",
"parent_id": null,
"level": 1,
"sort_order": 1,
"is_active": true,
"description": "更新后的描述",
"created_at": "2024-01-01T00:00:00",
"updated_at": "2024-01-01T00:00:00"
}
}
请求示例:
curl -X PUT "http://localhost:8000/api/v1/departments/1" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "内科",
"description": "更新后的描述"
}'
响应示例:
{
"code": 200,
"message": "更新成功",
"data": {
"id": 1,
"name": "内科",
"code": "NK001",
"dept_type": "clinical_surgical",
"parent_id": null,
"level": 1,
"sort_order": 1,
"is_active": true,
"description": "更新后的描述",
"created_at": "2024-01-01T00:00:00",
"updated_at": "2024-01-01T00:00:00"
}
}
错误处理:
- 401 未授权:无效或过期的JWT令牌
- 403 禁止:用户权限不足
- 404 未找到:科室不存在
章节来源
删除科室
HTTP方法: DELETE
URL路径: /api/v1/departments/{dept_id}
权限要求: 需要管理员或经理权限
路径参数:
| 参数名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| dept_id | int | 是 | 科室ID |
响应数据结构:
{
"code": 200,
"message": "删除成功"
}
请求示例:
curl -X DELETE "http://localhost:8000/api/v1/departments/1" \
-H "Authorization: Bearer YOUR_TOKEN"
响应示例:
{
"code": 200,
"message": "删除成功"
}
错误处理:
- 400 错误请求:无法删除,科室下存在子科室
- 401 未授权:无效或过期的JWT令牌
- 403 禁止:用户权限不足
章节来源
树形结构查询实现原理
数据模型设计
科室表采用自引用外键设计,支持无限层级的组织结构:
erDiagram
DEPARTMENTS {
int id PK
string name
string code UK
enum dept_type
int parent_id FK
int level
int sort_order
boolean is_active
text description
datetime created_at
datetime updated_at
}
DEPARTMENTS ||--o{ DEPARTMENTS : "parent"
图表来源
树形构建算法
服务层实现了高效的树形结构构建算法:
flowchart TD
Start([开始构建树形结构]) --> LoadData["加载所有科室数据"]
LoadData --> CreateMap["创建科室映射表<br/>ID -> Tree节点"]
CreateMap --> InitChildren["初始化所有节点的children为空数组"]
InitChildren --> BuildTree["遍历所有科室构建树"]
BuildTree --> CheckParent{"是否有上级科室?"}
CheckParent --> |是| AddToParent["添加到上级节点的children"]
CheckParent --> |否| AddToRoots["添加到根节点列表"]
AddToParent --> NextDept{"还有下一个科室?"}
AddToRoots --> NextDept
NextDept --> |是| BuildTree
NextDept --> |否| ReturnTree["返回根节点列表"]
ReturnTree --> End([结束])
图表来源
层级关系处理
系统自动计算和维护科室层级关系:
- 层级计算: 新建科室时,如果指定parent_id,则level = parent.level + 1
- 排序规则: 按sort_order和id进行排序
- 层级限制: 支持最多5级深度
章节来源
权限控制机制
角色定义
系统支持三种用户角色:
- admin: 系统管理员,拥有最高权限
- manager: 科室经理,具有业务操作权限
- staff: 普通员工,只读权限
权限验证流程
sequenceDiagram
participant Client as 客户端
participant API as API端点
participant Auth as 认证中间件
participant Role as 角色验证
participant DB as 数据库
Client->>API : 发送带JWT的请求
API->>Auth : 验证JWT令牌
Auth->>DB : 验证用户有效性
DB-->>Auth : 用户信息
Auth->>Role : 检查角色权限
Role-->>API : 权限验证结果
API-->>Client : 返回响应或错误
图表来源
权限矩阵
| 操作 | 激活用户 | 管理员 | 经理 |
|---|---|---|---|
| 获取列表 | ✅ | ✅ | ✅ |
| 获取树形结构 | ✅ | ✅ | ✅ |
| 获取详情 | ✅ | ✅ | ✅ |
| 创建科室 | ❌ | ✅ | ✅ |
| 更新科室 | ❌ | ✅ | ✅ |
| 删除科室 | ❌ | ✅ | ✅ |
章节来源
数据模型
科室实体
科室表包含以下字段:
| 字段名 | 类型 | 约束 | 描述 |
|---|---|---|---|
| id | int | 主键,自增 | 科室ID |
| name | string | 非空,最大100 | 科室名称 |
| code | string | 非空,唯一,最大20 | 科室编码 |
| dept_type | enum | 非空 | 科室类型 |
| parent_id | int | 外键到departments.id | 上级科室ID |
| level | int | 默认1,范围1-5 | 层级 |
| sort_order | int | 默认0 | 排序 |
| is_active | boolean | 默认true | 是否启用 |
| description | text | 可空 | 描述信息 |
| created_at | datetime | 默认当前时间 | 创建时间 |
| updated_at | datetime | 默认当前时间,更新时自动 | 更新时间 |
科室类型枚举
系统支持9种科室类型:
clinical_surgical: 手术临床科室clinical_nonsurgical_ward: 非手术有病房科室clinical_nonsurgical_noward: 非手术无病房科室medical_tech: 医技科室medical_auxiliary: 医辅科室nursing: 护理单元admin: 行政科室finance: 财务科室logistics: 后勤保障科室
章节来源
性能考虑
数据库优化
-
索引策略:
idx_dept_type: 科室类型索引idx_dept_parent: 上级科室索引idx_dept_code: 编码唯一索引
-
查询优化:
- 使用异步查询避免阻塞
- 分页查询限制结果集大小
- 批量操作减少数据库往返
-
连接池管理:
- 默认池大小20,溢出10
- 自动事务管理和回滚
缓存策略
- 树形结构缓存: 对于静态的组织架构数据,建议实现Redis缓存
- 用户权限缓存: 缓存用户角色信息减少数据库查询
- 配置信息缓存: 使用LRU缓存配置项
异步处理
系统采用异步编程模型:
- 使用SQLAlchemy异步引擎
- 异步数据库会话管理
- 非阻塞I/O操作
章节来源
故障排除指南
常见错误及解决方案
1. 认证失败
症状: 401 未授权错误
原因: JWT令牌无效或过期
解决方案:
- 重新登录获取新令牌
- 检查令牌格式和有效期
- 验证服务器时间同步
2. 权限不足
症状: 403 禁止访问
原因: 用户角色不满足操作要求
解决方案:
- 确认用户角色为admin或manager
- 检查用户状态是否激活
- 验证用户是否被禁用
3. 数据重复
症状: 400 错误请求,提示编码已存在
原因: 科室编码重复
解决方案:
- 修改唯一的科室编码
- 检查现有数据避免冲突
- 使用系统提供的唯一性约束
4. 删除失败
症状: 400 错误请求,提示无法删除
原因: 科室下存在子科室
解决方案:
- 先删除所有子科室
- 或者调整层级关系
- 使用树形结构查看层级
调试工具
前端测试页面
系统提供了测试页面用于调试API:
- 路径:
frontend/public/test-api.html - 功能: 包含健康检查、登录测试、科室列表测试等
- 使用: 直接在浏览器中打开测试页面
日志监控
- 应用日志:
backend/app/logs/ - 错误日志:
backend/app/logs/error_*.log - 数据库日志: SQL查询语句和执行时间
章节来源
- frontend/public/test-api.html
- backend/app/api/v1/departments.py
- backend/app/services/department_service.py
结论
科室管理接口提供了完整的CRUD操作,支持复杂的树形结构查询和权限控制。系统采用现代化的技术栈,具有良好的扩展性和维护性。通过合理的数据模型设计和权限控制机制,确保了系统的安全性和稳定性。
主要优势:
- 完整的功能覆盖: 支持所有必要的科室管理操作
- 灵活的查询能力: 支持多条件过滤和分页查询
- 强大的权限控制: 细粒度的角色权限管理
- 高性能设计: 异步架构和数据库优化
- 易于扩展: 清晰的分层架构便于功能扩展
建议后续改进方向:
- 添加树形结构缓存机制
- 实现批量操作功能
- 增强数据导入导出能力
- 完善审计日志功能