Files
his/MD/bugs/BUG_745_ANALYSIS.md

123 lines
5.2 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.

# Bug #745 诸葛亮分析报告
> **文档类型**: Bug分析
> **分析时间**: 2026-06-12 22:54:49
> **分析模型**: mimo-v2.5 (LLM深度分析)
---
## 基本信息
- **Bug #**: 745
- **标题**: 【病案管理】申请封存的报卡出现报错Error updating database. Cause: org.postgresql.util.PSQLException
- **模块**: 会诊管理
- **提出人**: 王栩坤
---
分析完毕,根因非常清晰。
---
## 一、Bug 理解
**禅道 Bug #745【病案管理】申请封存的报卡出现报错Error updating database. Cause: org.postgresql.util.PSQLException**
- **重现步骤**登录内科医生1账号doctor1/123456进入病案管理打开病案封存标签页点击"申请封存",填写表单后点"确认封存"
- **结果**:出现红色错误提示:`null value in column "medical_record_id" of relation "mr_sealing" violates not-null constraint`
- **期望**:能正常操作申请封存功能,不出现报错
**附图分析**
- 弹窗中填写了:病案号`12`、患者`12`、封存类型`主动封存`、封存原因`12`、封存人`12`
- 错误 SQL 的 INSERT 列表为 `(id, patient_name, mr_number, seal_reason, seal_type, seal_date, seal_by, status, create_by, create_time, tenant_id)` —— **完全缺少 `medical_record_id` 列**
- Failing row 的第二个值为 `null`,确认该字段未被赋值
**综合总结**:用户在"病案封存"页面填写封存信息并提交时,由于前端表单未传递 `medicalRecordId` 字段,后端也未对该字段做赋值或校验,导致向数据库 `mr_sealing` 表 INSERT 时 `medical_record_id` 列为空值,违反了 NOT NULL 约束,操作失败。
---
## 二、根因分析
根因是**前后端均未处理 `medicalRecordId` 字段**
| 层 | 问题 |
|---|---|
| **数据库** | `mr_sealing` 表定义了 `medical_record_id BIGINT NOT NULL``V18__emr_mr_nursing_fhir.sql` |
| **Entity** | `MrSealing.java``medicalRecordId` 字段,但前端不传时为 null |
| **Controller** | `MrManagementController.sealRecord()` 直接 `sealingService.save(sealing)`,无任何校验 |
| **Frontend** | `sealForm` 定义为 `{mrNumber:'',patientName:'',sealType:1,sealReason:'',sealBy:''}`**无 `medicalRecordId`** |
| **Frontend Dialog** | 表单只有5个字段病案号、患者、封存类型、封存原因、封存人**无 `medicalRecordId` 输入项** |
MyBatis-Plus 的 `save()` 方法会跳过 null 字段,所以 INSERT SQL 中不含 `medical_record_id`,违反 NOT NULL 约束。
**涉及文件**
- `healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/mrhomepage/domain/MrSealing.java:14` — Entity 有该字段
- `healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/mrhomepage/controller/MrManagementController.java:80-86` — sealRecord 方法
- `healthlink-his-ui/src/views/mrmanagement/index.vue:157` — sealForm 缺少 medicalRecordId
- `healthlink-his-ui/src/views/mrmanagement/index.vue:127-141` — 封存弹窗缺少该字段
---
## 三、修复方案
### 修改 1前端 `index.vue` — sealForm 添加 medicalRecordId
**文件**: `healthlink-his-ui/src/views/mrmanagement/index.vue`
**第157行**`sealForm` 添加 `medicalRecordId`
```js
// 修改前
const sealForm=reactive({mrNumber:'',patientName:'',sealType:1,sealReason:'',sealBy:''})
// 修改后
const sealForm=reactive({medicalRecordId:null,mrNumber:'',patientName:'',sealType:1,sealReason:'',sealBy:''})
```
**第128-137行**,封存弹窗的 el-form 中添加 `medicalRecordId` 输入项(放在"病案号"之前):
```vue
<el-form-item label="病案ID"><el-input-number v-model="sealForm.medicalRecordId" :min="1" style="width:100%"/></el-form-item>
```
### 修改 2后端 Controller — 添加校验
**文件**: `healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/mrhomepage/controller/MrManagementController.java`
**第80-86行** `sealRecord()` 方法,在 `save()` 前添加校验:
```java
@PostMapping("/sealing/seal")
@Transactional(rollbackFor = Exception.class)
public R<?> sealRecord(@RequestBody MrSealing sealing) {
if (sealing.getMedicalRecordId() == null) {
return R.fail("医疗记录ID不能为空");
}
sealing.setStatus(0);
sealing.setSealDate(new Date());
sealing.setCreateTime(new Date());
sealingService.save(sealing);
return R.ok(sealing);
}
```
### 修改 3同理修复借阅预防性修复
`mr_borrowing` 表同样有 `medical_record_id BIGINT NOT NULL``borrowForm` 也缺少该字段。建议同时修复:
**前端**`borrowForm` 添加 `medicalRecordId`,借阅弹窗添加对应输入项
**后端**`applyBorrowing()` 添加同样的 null 校验
---
## 四、路由决策
**FIXER**: **guanyu** + **zhaoyun**
**REASON**: 需要同时修改后端 Controllerguanyu 负责)和前端 Vue 表单zhaoyun 负责),涉及前后端联调,两个 Agent 协作完成。修复量小3处改动属于典型前后端对齐 Bug。
---
## 路由决策
- **FIXER_ID**: guanyu
- **修复 Agent**: guanyu后端
- **原因**: '',patientName:'',sealType:1,sealReason:'',sealBy:''}`**无 `medicalRecordId`** |
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。