# 科室管理接口 **本文档引用的文件** - [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认证机制,支持管理员和经理两种权限级别,并提供了完整的分页查询功能。 ## 项目结构 后端采用分层架构设计,主要包含以下层次: ```mermaid 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](file://backend/app/api/v1/departments.py#L1-L108) - [backend/app/services/department_service.py](file://backend/app/services/department_service.py#L1-L150) - [backend/app/core/security.py](file://backend/app/core/security.py#L1-L110) **章节来源** - [backend/app/api/v1/departments.py](file://backend/app/api/v1/departments.py#L1-L18) - [backend/app/services/department_service.py](file://backend/app/services/department_service.py#L1-L150) ## 核心组件 ### 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](file://backend/app/api/v1/departments.py#L17-L18) - [backend/app/services/department_service.py](file://backend/app/services/department_service.py#L13-L15) - [backend/app/models/models.py](file://backend/app/models/models.py#L62-L86) - [backend/app/schemas/schemas.py](file://backend/app/schemas/schemas.py#L64-L103) ## 架构概览 系统采用经典的MVC架构模式,结合现代的异步编程: ```mermaid 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](file://backend/app/api/v1/departments.py#L20-L40) - [backend/app/core/security.py](file://backend/app/core/security.py#L85-L109) - [backend/app/services/department_service.py](file://backend/app/services/department_service.py#L16-L43) ## 详细接口文档 ### 获取科室列表 **HTTP方法**: GET **URL路径**: `/api/v1/departments` **权限要求**: 需要激活用户权限 **查询参数**: | 参数名 | 类型 | 必填 | 默认值 | 描述 | |--------|------|------|--------|------| | dept_type | string | 否 | 无 | 科室类型过滤 | | is_active | boolean | 否 | 无 | 启用状态过滤 | | page | int | 否 | 1 | 页码,最小值1 | | page_size | int | 否 | 20 | 每页数量,范围1-100 | **响应数据结构**: ```json { "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 } ``` **请求示例**: ```bash 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" ``` **响应示例**: ```json { "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 未找到:无匹配的数据 **章节来源** - [backend/app/api/v1/departments.py](file://backend/app/api/v1/departments.py#L20-L40) - [backend/app/services/department_service.py](file://backend/app/services/department_service.py#L17-L43) ### 获取科室树形结构 **HTTP方法**: GET **URL路径**: `/api/v1/departments/tree` **权限要求**: 需要激活用户权限 **查询参数**: | 参数名 | 类型 | 必填 | 默认值 | 描述 | |--------|------|------|--------|------| | dept_type | string | 否 | 无 | 科室类型过滤 | **响应数据结构**: ```json { "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": [] } ] } ] } ``` **请求示例**: ```bash curl -X GET "http://localhost:8000/api/v1/departments/tree?dept_type=clinical_surgical" \ -H "Authorization: Bearer YOUR_TOKEN" ``` **响应示例**: ```json { "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 禁止:用户权限不足 **章节来源** - [backend/app/api/v1/departments.py](file://backend/app/api/v1/departments.py#L43-L51) - [backend/app/services/department_service.py](file://backend/app/services/department_service.py#L112-L149) ### 获取科室详情 **HTTP方法**: GET **URL路径**: `/api/v1/departments/{dept_id}` **权限要求**: 需要激活用户权限 **路径参数**: | 参数名 | 类型 | 必填 | 描述 | |--------|------|------|------| | dept_id | int | 是 | 科室ID | **响应数据结构**: ```json { "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" } } ``` **请求示例**: ```bash curl -X GET "http://localhost:8000/api/v1/departments/1" \ -H "Authorization: Bearer YOUR_TOKEN" ``` **响应示例**: ```json { "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 未找到:科室不存在 **章节来源** - [backend/app/api/v1/departments.py](file://backend/app/api/v1/departments.py#L54-L64) - [backend/app/services/department_service.py](file://backend/app/services/department_service.py#L46-L51) ### 创建科室 **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 | 否 | 描述 | **响应数据结构**: ```json { "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" } } ``` **请求示例**: ```bash 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": "内科描述" }' ``` **响应示例**: ```json { "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 禁止:用户权限不足 **章节来源** - [backend/app/api/v1/departments.py](file://backend/app/api/v1/departments.py#L67-L80) - [backend/app/services/department_service.py](file://backend/app/services/department_service.py#L62-L78) ### 更新科室 **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 | 否 | 描述 | **响应数据结构**: ```json { "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" } } ``` **请求示例**: ```bash curl -X PUT "http://localhost:8000/api/v1/departments/1" \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "内科", "description": "更新后的描述" }' ``` **响应示例**: ```json { "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 未找到:科室不存在 **章节来源** - [backend/app/api/v1/departments.py](file://backend/app/api/v1/departments.py#L83-L94) - [backend/app/services/department_service.py](file://backend/app/services/department_service.py#L81-L93) ### 删除科室 **HTTP方法**: DELETE **URL路径**: `/api/v1/departments/{dept_id}` **权限要求**: 需要管理员或经理权限 **路径参数**: | 参数名 | 类型 | 必填 | 描述 | |--------|------|------|------| | dept_id | int | 是 | 科室ID | **响应数据结构**: ```json { "code": 200, "message": "删除成功" } ``` **请求示例**: ```bash curl -X DELETE "http://localhost:8000/api/v1/departments/1" \ -H "Authorization: Bearer YOUR_TOKEN" ``` **响应示例**: ```json { "code": 200, "message": "删除成功" } ``` **错误处理**: - 400 错误请求:无法删除,科室下存在子科室 - 401 未授权:无效或过期的JWT令牌 - 403 禁止:用户权限不足 **章节来源** - [backend/app/api/v1/departments.py](file://backend/app/api/v1/departments.py#L97-L107) - [backend/app/services/department_service.py](file://backend/app/services/department_service.py#L95-L110) ## 树形结构查询实现原理 ### 数据模型设计 科室表采用自引用外键设计,支持无限层级的组织结构: ```mermaid 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" ``` **图表来源** - [backend/app/models/models.py](file://backend/app/models/models.py#L62-L86) ### 树形构建算法 服务层实现了高效的树形结构构建算法: ```mermaid flowchart TD Start([开始构建树形结构]) --> LoadData["加载所有科室数据"] LoadData --> CreateMap["创建科室映射表
ID -> Tree节点"] CreateMap --> InitChildren["初始化所有节点的children为空数组"] InitChildren --> BuildTree["遍历所有科室构建树"] BuildTree --> CheckParent{"是否有上级科室?"} CheckParent --> |是| AddToParent["添加到上级节点的children"] CheckParent --> |否| AddToRoots["添加到根节点列表"] AddToParent --> NextDept{"还有下一个科室?"} AddToRoots --> NextDept NextDept --> |是| BuildTree NextDept --> |否| ReturnTree["返回根节点列表"] ReturnTree --> End([结束]) ``` **图表来源** - [backend/app/services/department_service.py](file://backend/app/services/department_service.py#L113-L149) ### 层级关系处理 系统自动计算和维护科室层级关系: 1. **层级计算**: 新建科室时,如果指定parent_id,则level = parent.level + 1 2. **排序规则**: 按sort_order和id进行排序 3. **层级限制**: 支持最多5级深度 **章节来源** - [backend/app/services/department_service.py](file://backend/app/services/department_service.py#L62-L78) - [backend/app/models/models.py](file://backend/app/models/models.py#L69-L71) ## 权限控制机制 ### 角色定义 系统支持三种用户角色: - **admin**: 系统管理员,拥有最高权限 - **manager**: 科室经理,具有业务操作权限 - **staff**: 普通员工,只读权限 ### 权限验证流程 ```mermaid 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 : 返回响应或错误 ``` **图表来源** - [backend/app/core/security.py](file://backend/app/core/security.py#L55-L109) ### 权限矩阵 | 操作 | 激活用户 | 管理员 | 经理 | |------|----------|--------|------| | 获取列表 | ✅ | ✅ | ✅ | | 获取树形结构 | ✅ | ✅ | ✅ | | 获取详情 | ✅ | ✅ | ✅ | | 创建科室 | ❌ | ✅ | ✅ | | 更新科室 | ❌ | ✅ | ✅ | | 删除科室 | ❌ | ✅ | ✅ | **章节来源** - [backend/app/core/security.py](file://backend/app/core/security.py#L85-L109) - [backend/app/api/v1/departments.py](file://backend/app/api/v1/departments.py#L67-L107) ## 数据模型 ### 科室实体 科室表包含以下字段: | 字段名 | 类型 | 约束 | 描述 | |--------|------|------|------| | 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`: 后勤保障科室 **章节来源** - [backend/app/models/models.py](file://backend/app/models/models.py#L62-L86) - [backend/app/models/models.py](file://backend/app/models/models.py#L16-L27) ## 性能考虑 ### 数据库优化 1. **索引策略**: - `idx_dept_type`: 科室类型索引 - `idx_dept_parent`: 上级科室索引 - `idx_dept_code`: 编码唯一索引 2. **查询优化**: - 使用异步查询避免阻塞 - 分页查询限制结果集大小 - 批量操作减少数据库往返 3. **连接池管理**: - 默认池大小20,溢出10 - 自动事务管理和回滚 ### 缓存策略 - **树形结构缓存**: 对于静态的组织架构数据,建议实现Redis缓存 - **用户权限缓存**: 缓存用户角色信息减少数据库查询 - **配置信息缓存**: 使用LRU缓存配置项 ### 异步处理 系统采用异步编程模型: - 使用SQLAlchemy异步引擎 - 异步数据库会话管理 - 非阻塞I/O操作 **章节来源** - [backend/app/core/database.py](file://backend/app/core/database.py#L9-L20) - [backend/app/core/config.py](file://backend/app/core/config.py#L18-L22) ## 故障排除指南 ### 常见错误及解决方案 #### 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](file://frontend/public/test-api.html#L1-L133) - [backend/app/api/v1/departments.py](file://backend/app/api/v1/departments.py#L75-L77) - [backend/app/services/department_service.py](file://backend/app/services/department_service.py#L102-L107) ## 结论 科室管理接口提供了完整的CRUD操作,支持复杂的树形结构查询和权限控制。系统采用现代化的技术栈,具有良好的扩展性和维护性。通过合理的数据模型设计和权限控制机制,确保了系统的安全性和稳定性。 主要优势: 1. **完整的功能覆盖**: 支持所有必要的科室管理操作 2. **灵活的查询能力**: 支持多条件过滤和分页查询 3. **强大的权限控制**: 细粒度的角色权限管理 4. **高性能设计**: 异步架构和数据库优化 5. **易于扩展**: 清晰的分层架构便于功能扩展 建议后续改进方向: 1. 添加树形结构缓存机制 2. 实现批量操作功能 3. 增强数据导入导出能力 4. 完善审计日志功能