Files
2026-02-28 15:16:15 +08:00

23 KiB
Raw Permalink Blame History

科室管理接口

**本文档引用的文件** - [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)

目录

  1. 简介
  2. 项目结构
  3. 核心组件
  4. 架构概览
  5. 详细接口文档
  6. 树形结构查询实现原理
  7. 权限控制机制
  8. 数据模型
  9. 性能考虑
  10. 故障排除指南
  11. 结论

简介

本文档详细介绍了医院绩效管理系统的科室管理接口。该系统基于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

图表来源

章节来源

核心组件

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

章节来源

架构概览

系统采用经典的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响应

图表来源

详细接口文档

获取科室列表

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([结束])

图表来源

层级关系处理

系统自动计算和维护科室层级关系:

  1. 层级计算: 新建科室时如果指定parent_id则level = parent.level + 1
  2. 排序规则: 按sort_order和id进行排序
  3. 层级限制: 支持最多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: 后勤保障科室

章节来源

性能考虑

数据库优化

  1. 索引策略:

    • idx_dept_type: 科室类型索引
    • idx_dept_parent: 上级科室索引
    • idx_dept_code: 编码唯一索引
  2. 查询优化:

    • 使用异步查询避免阻塞
    • 分页查询限制结果集大小
    • 批量操作减少数据库往返
  3. 连接池管理:

    • 默认池大小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查询语句和执行时间

章节来源

结论

科室管理接口提供了完整的CRUD操作支持复杂的树形结构查询和权限控制。系统采用现代化的技术栈具有良好的扩展性和维护性。通过合理的数据模型设计和权限控制机制确保了系统的安全性和稳定性。

主要优势:

  1. 完整的功能覆盖: 支持所有必要的科室管理操作
  2. 灵活的查询能力: 支持多条件过滤和分页查询
  3. 强大的权限控制: 细粒度的角色权限管理
  4. 高性能设计: 异步架构和数据库优化
  5. 易于扩展: 清晰的分层架构便于功能扩展

建议后续改进方向:

  1. 添加树形结构缓存机制
  2. 实现批量操作功能
  3. 增强数据导入导出能力
  4. 完善审计日志功能