Files
his/迁移记录-DB变更记录/医生患者多对多关系实现说明.md
chenqi 0c35044231 feat(menu): 优化菜单路径唯一性校验并更新前端界面
- 在SysLoginController中添加optionMap数据返回
- 添加JSQLParser依赖支持MyBatis Plus功能
- 实现selectMenuByPathExcludeId方法用于排除当前菜单的路径唯一性校验
- 在SysMenuServiceImpl中添加日志记录并优化路径唯一性判断逻辑
- 在SysMenuMapper.xml中添加LIMIT 1限制并实现排除ID查询
- 在前端路由中注释患者管理相关路由配置
- 在用户store中添加optionMap配置项并优先从optionMap获取医院名称
- 重构检查项目设置页面的操作按钮样式为统一的圆形按钮设计
- 更新检查项目设置页面的导航栏样式和交互体验
- 优化门诊记录页面的搜索条件和表格展示功能
- 添加性别和状态筛选条件并改进数据加载逻辑
2026-01-03 23:47:09 +08:00

293 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 医生患者多对多关系实现说明
## 一、背景分析
### 1.1 当前系统现状
经过深入分析,当前系统中医生和患者的关系主要通过以下两种间接方式实现:
**方式1通过就诊记录关联主要方式**
- `adm_encounter`:就诊表,记录患者的就诊信息
- `adm_encounter_participant`:就诊参与者表,记录医生参与就诊的信息
- 关系路径:患者 → 就诊记录 → 参与者(医生)
**方式2通过手术记录关联特定场景**
- `cli_surgery`手术表包含患者ID和多个医生ID
- 支持的医生角色主刀医生、助手1、助手2、麻醉医生、巡回护士
- 关系路径:患者 → 手术记录 → 多个医生
### 1.2 存在的问题
1. **缺乏长期医患关系管理**
- 无法管理固定的主治医生、签约医生等长期关系
- 每次就诊都需要重新关联医生和患者
2. **查询效率低下**
- 需要通过多层关联查询才能获取某医生的所有患者
- 无法快速查询某患者的所有就诊医生
3. **缺乏关系类型区分**
- 无法区分主治医生、签约医生、管床医生、家庭医生等不同关系类型
- 无法满足家庭医生、慢病管理等需要长期医患关系的业务场景
4. **无法支持复杂业务需求**
- 家庭医生签约服务
- 慢病随访管理
- 患者分组管理
- 医生工作量统计
## 二、解决方案
### 2.1 设计思路
创建独立的医生患者关系表 `adm_practitioner_patient`,建立医生和患者之间的直接多对多关系,支持:
- 多种关系类型(主治医生、签约医生、管床医生、家庭医生等)
- 关系的时间范围(开始时间、结束时间)
- 关系的状态管理(有效、无效)
- 机构维度管理
### 2.2 数据库设计
#### 表结构adm_practitioner_patient
| 字段名 | 类型 | 说明 |
|--------|------|------|
| id | int8 | 主键ID |
| practitioner_id | int8 | 医生ID关联adm_practitioner表 |
| patient_id | int8 | 患者ID关联adm_patient表 |
| relationship_type | int4 | 关系类型1-主治医生2-签约医生3-管床医生4-家庭医生5-会诊医生6-随访医生 |
| organization_id | int8 | 机构ID关联adm_organization表 |
| start_date | timestamptz | 关系开始时间 |
| end_date | timestamptz | 关系结束时间 |
| status | int4 | 状态1-有效0-无效 |
| remark | varchar(500) | 备注信息 |
| tenant_id | int4 | 租户ID |
| delete_flag | bpchar(1) | 删除标志 |
| create_by | varchar(32) | 创建人 |
| create_time | timestamptz | 创建时间 |
| update_by | varchar(32) | 更新人 |
| update_time | timestamptz | 更新时间 |
#### 索引设计
- `idx_practitioner_patient_practitioner_id`按医生ID查询
- `idx_practitioner_patient_patient_id`按患者ID查询
- `idx_practitioner_patient_org_id`按机构ID查询
- `idx_practitioner_patient_type`:按关系类型查询
### 2.3 业务逻辑
#### 1. 创建医患关系
- 检查是否已存在相同的关系
- 如果存在,先终止旧关系
- 创建新的有效关系
- 记录关系开始时间
#### 2. 终止医患关系
- 设置关系结束时间为当前时间
- 更新状态为无效status=0
#### 3. 查询有效关系
- 查询条件status=1 且 delete_flag='0'
- 支持按医生、患者、机构、关系类型等多维度查询
#### 4. 批量创建关系
- 支持批量创建医患关系
- 适用于科室分组、团队管理等场景
## 三、功能实现
### 3.1 后端实现
#### 实体类
- `PractitionerPatient.java`:医生患者关系实体
#### 数据访问层
- `PractitionerPatientMapper.java`Mapper接口
- `PractitionerPatientMapper.xml`MyBatis映射文件
#### 业务逻辑层
- `IPractitionerPatientService.java`Service接口
- `PractitionerPatientServiceImpl.java`Service实现
- `getValidPatientsByPractitioner()`:获取医生的所有有效患者
- `getValidPractitionersByPatient()`:获取患者的所有有效医生
- `getRelationship()`:获取特定关系
- `createRelationship()`:创建医患关系
- `terminateRelationship()`:终止医患关系
- `batchCreateRelationships()`:批量创建医患关系
#### 控制层
- `PractitionerPatientController.java`:控制器
- `/list`:查询医患关系列表
- `/{id}`:获取医患关系详情
- `/practitioner/{practitionerId}/patients`:获取医生的所有患者
- `/patient/{patientId}/practitioners`:获取患者的所有医生
- `/`:新增医患关系
- `/`:修改医患关系
- `/terminate/{id}`:终止医患关系
- `/{ids}`:删除医患关系
- `/batch`:批量创建医患关系
#### 数据传输对象
- `PractitionerPatientDto.java`医患关系DTO
### 3.2 前端实现
#### API接口
- `practitionerPatient.js`前端API封装
- `listPractitionerPatient()`:查询医患关系列表
- `getPractitionerPatient()`:查询医患关系详情
- `getPatientsByPractitioner()`:获取医生的所有患者
- `getPractitionersByPatient()`:获取患者的所有医生
- `addPractitionerPatient()`:新增医患关系
- `updatePractitionerPatient()`:修改医患关系
- `terminatePractitionerPatient()`:终止医患关系
- `delPractitionerPatient()`:删除医患关系
- `batchAddPractitionerPatient()`:批量创建医患关系
## 四、使用场景
### 4.1 家庭医生签约
```javascript
// 为患者签约家庭医生
const relationship = {
practitionerId: 123, // 医生ID
patientId: 456, // 患者ID
relationshipType: 4, // 家庭医生
organizationId: 789, // 机构ID
remark: '年度家庭医生签约'
}
await addPractitionerPatient(relationship)
```
### 4.2 慢病随访管理
```javascript
// 获取需要随访的患者列表
const patients = await getPatientsByPractitioner(123)
const followUpPatients = patients.filter(p =>
p.relationshipType === 6 && // 随访医生
new Date(p.startDate) < new Date() &&
!p.endDate
)
```
### 4.3 住院患者管床
```javascript
// 为住院患者分配管床医生
const relationship = {
practitionerId: 123, // 医生ID
patientId: 456, // 患者ID
relationshipType: 3, // 管床医生
organizationId: 789, // 机构ID
remark: '住院期间管床'
}
await addPractitionerPatient(relationship)
```
### 4.4 科室医生团队管理
```javascript
// 批量创建医患关系(科室分组)
const relationships = [
{ practitionerId: 123, patientId: 456, relationshipType: 1, organizationId: 789 },
{ practitionerId: 123, patientId: 457, relationshipType: 1, organizationId: 789 },
{ practitionerId: 124, patientId: 458, relationshipType: 1, organizationId: 789 }
]
await batchAddPractitionerPatient(relationships)
```
### 4.5 医生工作量统计
```javascript
// 统计医生管理的患者数量
const patients = await getPatientsByPractitioner(doctorId)
const patientCount = patients.length
console.log(`该医生管理了 ${patientCount} 位患者`)
// 按关系类型统计
const主治医生Count = patients.filter(p => p.relationshipType === 1).length
const签约医生Count = patients.filter(p => p.relationshipType === 2).length
const管床医生Count = patients.filter(p => p.relationshipType === 3).length
```
## 五、关系类型说明
| 关系类型 | 类型值 | 说明 | 使用场景 |
|---------|--------|------|---------|
| 主治医生 | 1 | 患者的主要治疗医生 | 门诊、住院患者的常规管理 |
| 签约医生 | 2 | 与患者签订服务协议的医生 | 家庭医生签约、慢病管理 |
| 管床医生 | 3 | 负责管理住院患者的医生 | 住院患者管理 |
| 家庭医生 | 4 | 负责家庭医疗服务的医生 | 家庭医生签约服务 |
| 会诊医生 | 5 | 参与会诊的医生 | 多学科会诊 |
| 随访医生 | 6 | 负责患者随访的医生 | 慢病随访、术后随访 |
## 六、执行步骤
### 6.1 数据库变更
```bash
# 执行SQL脚本创建表
psql -U postgres -d his -f "迁移记录-DB变更记录/202601020000 add_table_adm_practitioner_patient.sql"
```
### 6.2 后端部署
1. 将以下文件复制到对应目录:
- `PractitionerPatient.java``openhis-domain/src/main/java/com/openhis/administration/domain/`
- `PractitionerPatientMapper.java``openhis-domain/src/main/java/com/openhis/administration/mapper/`
- `PractitionerPatientMapper.xml``openhis-domain/src/main/resources/mapper/administration/`
- `IPractitionerPatientService.java``openhis-domain/src/main/java/com/openhis/administration/service/`
- `PractitionerPatientServiceImpl.java``openhis-domain/src/main/java/com/openhis/administration/service/impl/`
- `PractitionerPatientDto.java``openhis-domain/src/main/java/com/openhis/administration/dto/`
- `PractitionerPatientController.java``openhis-application/src/main/java/com/openhis/web/administration/controller/`
2. 重新编译并启动后端服务
### 6.3 前端部署
1. 将以下文件复制到对应目录:
- `practitionerPatient.js``openhis-ui-vue3/src/api/administration/`
2. 重新编译并启动前端服务
## 七、注意事项
1. **数据一致性**
- 创建关系前先检查是否已存在相同的关系
- 如果存在,先终止旧关系再创建新关系
2. **时间管理**
- 关系开始时间默认为当前时间
- 终止关系时需要设置结束时间
3. **权限控制**
- 创建医患关系需要相应权限
- 终止医患关系需要相应权限
4. **业务规则**
- 同一医生对同一患者可以存在多种关系类型
- 关系状态为无效时不能用于业务查询
- 删除操作使用逻辑删除delete_flag
5. **性能优化**
- 已创建合适的索引
- 查询时使用条件过滤status=1, delete_flag='0'
## 八、后续扩展
1. **医患关系历史记录**
- 记录医患关系变更历史
- 支持回溯查看历史关系
2. **医患关系评价**
- 患者对医生的评价
- 医生对患者的评价
3. **医患关系可视化**
- 医患关系图谱
- 医生患者网络分析
4. **医患关系提醒**
- 关系到期提醒
- 随访提醒
- 复诊提醒
5. **数据统计**
- 医生工作量统计
- 患者分布统计
- 关系类型统计