Files
his/MD/bugs/BUG_725_ANALYSIS.md

122 lines
5.1 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 #725 诸葛亮分析报告
> **文档类型**: Bug分析
> **分析时间**: 2026-06-13 01:14:15
> **分析模型**: mimo-v2.5 (LLM深度分析)
---
## 基本信息
- **Bug #**: 725
- **标题**: 【急诊管理】绿色通道的激活出现报错
- **模块**: 会诊管理
- **提出人**: 王栩坤
---
I have all the information needed. Let me now output the analysis.
---
## 一、Bug 理解
**禅道 Bug #725**:【急诊管理】绿色通道的激活出现报错
**重现步骤**
> 登录内科医生1账号doctor1 密码123456 → 打开急诊管理 → 进入绿色通道激活
**期望结果**:能够正常激活绿色通道
**错误信息**
```
Error updating database. Cause: PSQLException: ERROR: null value in column "patient_id"
of relation "emergency_green_channel" violates not-null constraint
```
**附图分析**
- 弹窗表单中「患者ID」字段为空`el-input-number` 未输入值),但用户点击了「激活」按钮
- 数据库 INSERT SQL`INSERT INTO emergency_green_channel (id, disease_type, target_time, doctor, activate_time, create_by, create_time, tenant_id)`**`patient_id` 完全不在 INSERT 列表中**
- 表单规则 `addFormRules.patientId` 声明了 required但实际未阻止提交
**综合总结**用户点击「激活绿色通道」时弹窗表单中「患者ID」为空就直接提交后端 MyBatis-Plus 生成的 INSERT 语句完全跳过了 `patient_id` 字段null 值被 MyBatis 默认策略忽略),导致违反数据库 `NOT NULL` 约束。前端表单的 required 校验规则未生效,后端校验也未拦住请求。
---
## 二、根因分析
**根因链路(全链路 6 环)**
| 环 | 问题 |
|---|---|
| ① 录入(前端) | `addFormRules.patientId``required` 规则触发条件是 `trigger:'blur'`,但 `el-input-number` 的 blur 事件对 null 值不触发校验;`submitAdd` 中的 `validate()` 可能静默通过 |
| ② 验证(后端) | `EmergencyController.activateGreenChannel()``if (gc.getPatientId() == null)` 检查,但 **前端根本没发起带正确错误码的请求** — MyBatis-Plus 异常被全局异常处理器捕获,前端收到的是原始错误堆栈文本而非结构化 R.fail |
| ③ 业务 | `EmergencyGreenChannelServiceImpl` 无额外校验,直接继承 MyBatis-Plus `save()` |
| ④ 持久化 | MyBatis-Plus 默认 `FieldStrategy.INSERT_NOT_NULL`null 字段不写入 INSERT → `patient_id` 缺失 |
| ⑤ 存储 | `emergency_green_channel` 表定义 `patient_id BIGINT NOT NULL` → 报错 |
**涉及文件**
- `healthlink-his-server/.../web/emergency/controller/EmergencyController.java` — 后端校验逻辑(已有但被跳过)
- `healthlink-his-ui/src/views/emergency/greentrack/index.vue` — 前端表单校验失效
- `healthlink-his-ui/src/views/emergency/greentrack/api.js` — API 调用
- `healthlink-his-server/.../emergency/domain/EmergencyGreenChannel.java` — 实体定义
- `V32__followup_pathology_emergency.sql` — DB 表结构(`NOT NULL` 约束)
---
## 三、修复方案
### 修复点 1前端表单校验`greentrack/index.vue`
**问题**`submitAdd``validate()` 逻辑有隐患 — `el-input-number` 组件在未输入时 v-model 为 `null`,但 required 校验的 `trigger:'blur'` 对此场景不可靠。更关键的是,**validate 的 try-catch 写法在某些情况下可能跳过校验**。
**修改**:改为标准 async/await 写法,并将 trigger 改为 `change`
```js
// 修改 addFormRules
const addFormRules = {
patientId: [{required: true, message: '请输入患者ID', trigger: 'change'}]
}
// 修改 submitAdd — 移除 try-catch使用标准 await
const submitAdd = async () => {
if (addFormRef.value) {
const valid = await addFormRef.value.validate().catch(() => false)
if (!valid) return
}
await activate(addForm.value)
ElMessage.success('绿色通道已激活')
addVisible.value = false
loadData()
refreshStats()
}
```
### 修复点 2后端校验`EmergencyController.java`
后端已有 `gc.getPatientId() == null` 检查,但需确认 `R.fail()` 返回格式被前端正确识别。当前后端代码已正确,无需修改后端(校验逻辑存在且会返回错误)。如果前端仍能穿透,则需要检查全局异常处理器是否正确包装了 `MethodArgumentNotValidException`
### 修复点 3可选优化增加后端 `@Valid` 注解
`activateGreenChannel` 方法参数上增加 `@Valid` 并在实体 `patientId` 字段加 `@NotNull`,作为双保险:
```java
public R<?> activateGreenChannel(@RequestBody @Valid EmergencyGreenChannel gc) {
```
---
## 四、路由决策
**FIXER**: **zhaoyun**(前端开发)
**REASON**: 根因在前端表单校验失效 — `addFormRules` 的 trigger 选择不当 + `submitAdd` 中 validate 的错误处理逻辑有缺陷。后端校验逻辑已存在且正确,核心修复是前端表单校验。修改范围仅限 1 个前端文件 `greentrack/index.vue`
---
## 路由决策
- **FIXER_ID**: guanyu
- **修复 Agent**: guanyu后端
- **原因**: LLM 分析决策
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。