Files
his/MD/bugs/BUG_718_ANALYSIS.md

170 lines
7.9 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 #718 诸葛亮分析报告
> **文档类型**: Bug分析
> **分析时间**: 2026-06-13 02:19:56
> **分析模型**: mimo-v2.5 (LLM深度分析)
---
## 基本信息
- **Bug #**: 718
- **标题**: 【业务逻辑缺陷】医生端点击“停嘱”后医嘱直接变更为“已停止”,未流转至护士端进行停止核对
- **模块**: 病区护士工作站
- **提出人**: 陈显精
---
Now I have a thorough understanding of the entire flow. Let me compile my analysis.
---
## 一、Bug 理解
### 原文引用
**Bug 标题**:【业务逻辑缺陷】医生端点击"停嘱"后医嘱直接变更为"已停止",未流转至护士端进行停止核对
**重现步骤**
1. 登录"住院医生工作站",选择在科患者(如:刘潇凡)
2. 找到一条已校对且正在执行的长期医嘱(如:注射用头孢哌酮舒巴坦钠)
3. 选中该医嘱,点击界面上方的【停嘱】按钮
4. 观察医生端该医嘱的状态变化
5. 登录"住院护士站",进入"医嘱核对"页面
6. 依次查看【未校对】和【已停止】标签页
**期望结果**
1. 医生端点击"停嘱"后,医嘱状态应变更为【已停嘱】(中间状态),不能一步到位直接变成终态【停止】
2. 该医嘱应流转并显示在护士端的【未校对】标签页内,供护士进行停嘱确认
3. 只有当护士在"未校对"下选中该停嘱医嘱并点击【核对通过】后,医嘱状态才变更为【已停止】,并最终流转显示在【已停止】标签页中
**附图关键信息**
- 图1医生端红色标注指出"停嘱成功的医嘱状态应该是'已停嘱'待核对,需要重新定义一个医嘱状态'已停嘱'记录已停嘱的医嘱";列表中停嘱后医嘱状态显示为"停止"
- 图2护士端红色标注指出"已停嘱的医嘱应该显示在未校对标签页 待护士核对,核对后状态变成已停止";未校对标签页中无停嘱待核对记录
### 综合总结
医生点击停嘱后,医嘱状态直接跳变为终态"停止"(或至少在显示上呈现为停止),护士端的【未校对】标签页未收到该停嘱待核对记录,护士无法执行核对确认。期望的流程是:医生停嘱→状态变为中间态"已停嘱"→流转至护士端未校对→护士核对通过→状态变为终态"停止"。
---
## 二、根因分析
通过代码审查,我追踪了完整的停嘱数据流链路:
### 后端代码(看似正确但存在显示链路断裂)
1. **医生停嘱接口** `AdviceManageAppServiceImpl.stopRegAdvice()`第1100行将状态设为 `RequestStatus.PENDING_STOP(13, "已停嘱")`
2. **护士站查询** `AdviceProcessAppServiceImpl.getInpatientAdvicePage()`第204-213行查询 ACTIVE(2) 时同时包含 PENDING_STOP(13) ✅
3. **护士核对** `AdviceProcessAppServiceImpl.adviceVerify()`第433-450行将 PENDING_STOP(13) 转为 STOPPED(6) ✅
4. **枚举定义** `RequestStatus.java``PENDING_STOP(13, "pending_stop", "已停嘱")`
### 根本问题:护士站前端状态显示映射缺失
`prescriptionList.vue` 中的 `REQUEST_STATUS_DISPLAY` 映射表**缺少 PENDING_STOP(13) 条目**
```javascript
// 第356-361行
const REQUEST_STATUS_DISPLAY = {
[RequestStatus.DRAFT]: '待签发', // 1 → '待签发'
[RequestStatus.ACTIVE]: '已签发', // 2 → '已签发'
[RequestStatus.COMPLETED]: '已校对', // 3 → '已校对'
[RequestStatus.STOPPED]: '已停止', // 6 → '已停止'
// ⚠️ 缺少 PENDING_STOP(13) 条目!
};
```
`getStatusDisplayText()` 的回退逻辑虽然最终能通过 `LEGACY_STATUS_TEXT``requestStatus_enumText` 返回正确的文本"已停嘱",但**存在一个更严重的问题**
对于药品医嘱,`getStatusDisplayText()` **优先使用 `dispenseStatus`**(发药状态)。如果停嘱前已存在发药记录(如 dispenseStatus=4 → "已发药"),则 PENDING_STOP 的停嘱状态会被发药状态**遮蔽**,护士看不到"已停嘱"状态。
### 涉及的关键文件
| 文件 | 问题 |
|------|------|
| `healthlink-his-ui/src/views/inpatientNurse/medicalOrderProofread/components/prescriptionList.vue` | `REQUEST_STATUS_DISPLAY` 缺少 PENDING_STOP 映射;`getStatusDisplayText` 对 PENDING_STOP 的优先级逻辑不当 |
| `healthlink-his-ui/src/views/inpatientDoctor/home/components/order/index.vue` | 医生端模板已有 statusEnum==13→"已停嘱" 映射,**看似正确** |
| `healthlink-his-server/.../AdviceManageAppServiceImpl.java` | 后端停嘱逻辑已正确设置 PENDING_STOP**无需修改** |
| `healthlink-his-server/.../AdviceProcessAppServiceImpl.java` | 护士站查询已包含 PENDING_STOP核对逻辑已正确处理**无需修改** |
| `healthlink-his-server/healthlink-his-common/.../RequestStatus.java` | 枚举定义正确PENDING_STOP(13) 已存在,**无需修改** |
---
## 三、修复方案
### 修复1护士站前端状态显示映射核心修复
**文件**`healthlink-his-ui/src/views/inpatientNurse/medicalOrderProofread/components/prescriptionList.vue`
**修改1a**:在 `REQUEST_STATUS_DISPLAY` 中添加 PENDING_STOP 映射
```javascript
// 第356行后添加
const REQUEST_STATUS_DISPLAY = {
[RequestStatus.DRAFT]: '待签发',
[RequestStatus.ACTIVE]: '已签发',
[RequestStatus.COMPLETED]: '已校对',
[RequestStatus.STOPPED]: '已停止',
[RequestStatus.PENDING_STOP]: '已停嘱', // ← 新增
};
```
**修改1b**:修改 `getStatusDisplayText` 逻辑,确保 PENDING_STOP 优先级高于 dispenseStatus
PENDING_STOP 是停嘱的中间状态,应优先显示,不受旧的发药状态遮蔽:
```javascript
const getStatusDisplayText = (row) => {
// 0. 已停嘱(13)优先显示 —— 停嘱中间态必须醒目,不被旧发药状态遮蔽
const requestCode = Number(row?.requestStatus);
if (requestCode === RequestStatus.PENDING_STOP) {
return '已停嘱';
}
// 1. 优先使用发药状态
const dispenseCode = Number(row?.dispenseStatus);
if (DISPENSE_STATUS_DISPLAY[dispenseCode]) {
return DISPENSE_STATUS_DISPLAY[dispenseCode];
}
// 2. 使用行级别请求状态
if (REQUEST_STATUS_DISPLAY[requestCode]) {
return REQUEST_STATUS_DISPLAY[requestCode];
}
// 3. 兼容旧后端枚举文本
return LEGACY_STATUS_TEXT[row?.requestStatus_enumText] || row?.requestStatus_enumText || '';
};
```
### 修复2医生端 SQL 查询补充 stop_time/stop_user_name优化
**文件**`healthlink-his-server/.../mapper/regdoctorstation/AdviceManageAppMapper.xml`
当前 SQL 中 stop_time 和 stop_user_name 仅在 `status_enum = 6`STOPPED时返回PENDING_STOP(13) 时不返回,导致医生端停嘱时间/停嘱医生列为空。需将条件改为 `status_enum IN (6, 13)`
```xml
<!-- 修改前 -->
CASE WHEN T1.status_enum = 6 THEN T1.effective_dose_end ELSE NULL END AS stop_time,
CASE WHEN T1.status_enum = 6 THEN T1.update_by ELSE NULL END AS stop_user_name
<!-- 修改后 -->
CASE WHEN T1.status_enum IN (6, 13) THEN T1.effective_dose_end ELSE NULL END AS stop_time,
CASE WHEN T1.status_enum IN (6, 13) THEN T1.update_by ELSE NULL END AS stop_user_name
```
(对 ServiceRequest 和 DeviceRequest 的 UNION 部分同样修改)
---
## 四、路由决策
**FIXER**: `guanyu`(后端开发)+ `zhaoyun`(前端开发)
**REASON**: 本 Bug 涉及前后端两个层面。核心修复在前端护士站的状态显示映射(`prescriptionList.vue``REQUEST_STATUS_DISPLAY``getStatusDisplayText`),属于 `zhaoyun` 的职责范围。次要修复在后端 Mapper XML 的 SQL 条件补充(`AdviceManageAppMapper.xml`),属于 `guanyu` 的职责范围。后端核心停嘱逻辑(`stopRegAdvice``adviceVerify`**已正确实现**,无需修改。
---
## 路由决策
- **FIXER_ID**: guanyu
- **修复 Agent**: guanyu后端
- **原因**: LLM 分析决策
> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。