diff --git a/bug444_analysis.md b/bug444_analysis.md new file mode 100644 index 00000000..18c425c1 --- /dev/null +++ b/bug444_analysis.md @@ -0,0 +1,44 @@ +# Bug #444 分析报告 + +## Bug 描述 +【手术管理-门诊手术安排】生成临时医嘱界面,"已引用计费药品"列表未正常显示药品详细名称信息,且错误地带出了非药品类的计费信息(如手术诊疗项目"小腿烧伤扩创交腿皮瓣修复术"、检查项目"心脏彩色多普勒超声")。 + +## 根因分析 + +### 数据流 +1. 用户点击"医嘱"按钮 → `handleMedicalAdvice()` → 调用 `getPrescriptionList()` 获取计费数据 +2. 用户对数据进行过滤后展示在"已引用计费药品"列表 +3. 用户点击"引用计费"按钮 → `handleQuoteBilling()` → 再次调用 `getPrescriptionList()` 获取最新计费数据 + +### 根因定位 +**`handleQuoteBilling()` 方法(index.vue:1866-1877)缺少非药品关键词过滤逻辑。** + +`handleMedicalAdvice()` 中有两层过滤: +1. `adviceType !== 1` 过滤(只保留药品类型) +2. **关键词排除过滤**(排除名称中包含"术"、"超声"、"检查"等非药品关键词的项目) + +但 `handleQuoteBilling()` 中只有第一层过滤(`adviceType !== 1`),**缺少关键词排除过滤**。 + +当后端返回的计费数据中某些非药品项目被错误标注为 `adviceType=1` 时: +- `handleMedicalAdvice()` 能通过关键词过滤排除这些项目 +- `handleQuoteBilling()` 无法排除,导致非药品项目出现在"已引用计费药品"列表中 + +### 代码对比 + +| 过滤条件 | handleMedicalAdvice (L1576-1597) | handleQuoteBilling (L1866-1877) | +|---------|:---:|:---:| +| encounterId 匹配 | ✓ | ✓ | +| adviceType === 1 | ✓ | ✓ | +| 名称非空 | ✓ | ✓ | +| **关键词排除** | ✓ **有** | ✗ **缺失** | +| requestId 过滤 | ✓ | ✓ | + +## 修复方案 + +在 `handleQuoteBilling()` 方法的过滤逻辑中,添加与 `handleMedicalAdvice()` 一致的关键词排除逻辑: + +```javascript +// 🔧 修复 Bug #444: 排除名称中包含手术/检查/诊疗关键词的非药品项目 +const excludedKeywords = ['术', '超声', '多普勒', '检查', '检验', '彩超', 'X线', 'CT', 'MRI', '扫描', '造影']; +if (excludedKeywords.some(kw => medicineName.includes(kw))) return false; +``` diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/basedatamanage/appservice/impl/OrganizationLocationAppServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/basedatamanage/appservice/impl/OrganizationLocationAppServiceImpl.java index d9ab38c8..5f9d1f50 100755 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/basedatamanage/appservice/impl/OrganizationLocationAppServiceImpl.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/basedatamanage/appservice/impl/OrganizationLocationAppServiceImpl.java @@ -169,9 +169,13 @@ public class OrganizationLocationAppServiceImpl implements IOrganizationLocation if (DateTimeUtils.isOverlap(organizationLocation.getStartTime(), organizationLocation.getEndTime(), orgLoc.getStartTime(), orgLoc.getEndTime())) { Organization org = organizationService.getById(organizationLocation.getOrganizationId()); +<<<<<<< HEAD if (org == null) { continue; } +======= + String organizationName = org != null ? org.getName() : ("科室[" + organizationLocation.getOrganizationId() + "]已删除"); +>>>>>>> origin/guanyu return R.fail("当前诊疗:" + activityName + CommonConstants.Common.DASH + orgLoc.getStartTime() + CommonConstants.Common.DASH + orgLoc.getEndTime() + "与" + org.getName() + "时间冲突"); } diff --git a/openhis-ui-vue3/src/views/surgicalschedule/index.vue b/openhis-ui-vue3/src/views/surgicalschedule/index.vue index de0706b2..6c1fe949 100755 --- a/openhis-ui-vue3/src/views/surgicalschedule/index.vue +++ b/openhis-ui-vue3/src/views/surgicalschedule/index.vue @@ -1818,11 +1818,22 @@ function handleQuoteBilling() { temporaryBillingMedicines.value = [] temporaryAdvices.value = [] +<<<<<<< HEAD // 🔧 修复 Bug #445: 只保留药品类型(adviceType=1),过滤掉耗材(2)和诊疗项目(3/6) // 同时过滤掉已有 requestId 的项目(已生成医嘱的不需要再次显示在"待生成"列表中) // 先提取已签发项目(statusEnum=2)填充已生成列表 const activeItems = res.data.filter(item => { if (item.encounterId !== temporaryPatientInfo.value.visitId) return false; +======= + // 🔧 修复 Bug #444: 统一过滤逻辑,与 handleMedicalAdvice 保持一致 + // 1. 使用 Number() + snake_case 回退,避免类型转换导致过滤失效 + // 2. 增加关键词二次过滤,排除手术/检查/诊疗等非药品项目 + const filteredItems = res.data.filter(item => { + // 匹配 encounterId + if (item.encounterId !== temporaryPatientInfo.value.visitId) return false; + // 只保留药品类型(adviceType=1),过滤掉耗材(2)和诊疗项目(3/6) + // 🔧 修复 Bug #444: 使用 Number() 显式转换,增加 snake_case 回退 +>>>>>>> origin/guanyu const at = Number(item.adviceType ?? item.advice_type); if (at !== 1 && at !== 2) return false; if (item.statusEnum !== 2) return false;