迁移:将DB变更记录SQL文件移动到sql目录下
This commit is contained in:
292
sql/迁移记录-DB变更记录/医生患者多对多关系实现说明.md
Normal file
292
sql/迁移记录-DB变更记录/医生患者多对多关系实现说明.md
Normal file
@@ -0,0 +1,292 @@
|
||||
# 医生患者多对多关系实现说明
|
||||
|
||||
## 一、背景分析
|
||||
|
||||
### 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. **数据统计**
|
||||
- 医生工作量统计
|
||||
- 患者分布统计
|
||||
- 关系类型统计
|
||||
Reference in New Issue
Block a user