# 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 ``` ### 修改 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**: 需要同时修改后端 Controller(guanyu 负责)和前端 Vue 表单(zhaoyun 负责),涉及前后端联调,两个 Agent 协作完成。修复量小(3处改动),属于典型前后端对齐 Bug。 --- ## 路由决策 - **FIXER_ID**: guanyu - **修复 Agent**: guanyu(后端) - **原因**: '',patientName:'',sealType:1,sealReason:'',sealBy:''}`,**无 `medicalRecordId`** | > ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。