Files
his/MD/bugs/BUG_745_ANALYSIS.md

5.2 KiB
Raw Blame History

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 NULLV18__emr_mr_nursing_fhir.sql
Entity MrSealing.javamedicalRecordId 字段,但前端不传时为 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

// 修改前
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 输入项(放在"病案号"之前):

<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() 前添加校验:

@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 NULLborrowForm 也缺少该字段。建议同时修复:

前端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`** |

⚠️ 修复人员请先验证以上分析是否正确,再执行修复。