# 科室管理接口
**本文档引用的文件**
- [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. 完善审计日志功能