diff --git a/MD/bugs/BUG_718_ANALYSIS.md b/MD/bugs/BUG_718_ANALYSIS.md new file mode 100644 index 000000000..dc8f69e4c --- /dev/null +++ b/MD/bugs/BUG_718_ANALYSIS.md @@ -0,0 +1,169 @@ +# 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 分析决策 + +> ⚠️ 修复人员请先验证以上分析是否正确,再执行修复。