From bd50c58dd40d2e02a865494676b07dc30db575e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8D=8E=E4=BD=97?= Date: Tue, 2 Jun 2026 00:31:32 +0800 Subject: [PATCH] =?UTF-8?q?fix(#644):=20=E8=AF=B7=E4=BF=AE=E5=A4=8D=20Bug?= =?UTF-8?q?=20#644=EF=BC=9A[=E4=BD=8F=E9=99=A2=E6=8A=A4=E5=A3=AB=E7=AB=99-?= =?UTF-8?q?=E5=8C=BB=E5=98=B1=E6=A0=A1=E5=AF=B9]=20=E5=8C=BB=E5=98=B1?= =?UTF-8?q?=E6=89=A7=E8=A1=8C=E5=90=8E=E7=8A=B6=E6=80=81=E6=9C=AA=E5=90=8C?= =?UTF-8?q?=E6=AD=A5=E6=9B=B4=E6=96=B0=E4=B8=BA=E2=80=9C=E5=B7=B2=E6=89=A7?= =?UTF-8?q?=E8=A1=8C=E2=80=9D=EF=BC=8C=E4=B8=94=E5=85=81=E8=AE=B8=E9=80=80?= =?UTF-8?q?=E5=9B=9E=E5=B7=B2=E6=89=A7=E8=A1=8C=E5=8C=BB=E5=98=B1=EF=BC=88?= =?UTF-8?q?=E6=A0=A1=E9=AA=8C=E7=BC=BA=E5=A4=B1=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 根因: - Issue 2 — 退回校验缺失**:`adviceReject` 方法仅校验了药品是否已发药(`DispenseStatus.COMPLETED`),但未校验医嘱是否已执行(`cli_procedure` 表中 `status_enum = COMPLETED` 的记录)。已执行的医嘱可以被直接退回。 修复: - | 文件 | 修改 | 说明 | - |------|------|------| - | `AdviceProcessAppServiceImpl.java:235-280` | 将执行记录计算逻辑移到 `if (exeStatus != null)` 之前,所有页签都计算 | 所有页签的医嘱都能获取执行记录 | - | `AdviceProcessAppServiceImpl.java:266-274` | 新增 `overallStatusText` 计算逻辑 | 有已执行记录→"已执行",有取消记录→"已取消执行",有停止记录→"已停止",否则回退到请求状态文本 | - | `AdviceProcessAppServiceImpl.java:362-382` | `adviceReject` 方法新增已执行校验 | 查询 `cli_procedure` 中 `EventStatus.COMPLETED` + `ProcedureCategory.INPATIENT_ADVICE` 记录,存在则拒绝退回 | - | `InpatientAdviceDto.java` | 新增 `overallStatusText` 字段 | 前端可通过此字段展示综合执行状态 | - ### 全链路 6 环验证 - | 环节 | 状态 | 说明 | - |------|------|------| - | ①前端/页面 | ✅ 正常 | 新增 `overallStatusText` 字段,前端可直接绑定展示 | - | ②Controller | ✅ 正常 | `adviceReject` 参数 `List` 无需变更 | - | ③Service | 🔧 已修改 | `getInpatientAdvicePage` 重构执行记录计算;`adviceReject` 增加校验 | - | ④Mapper XML | ✅ 正常 | SQL 查询无需变更,执行记录通过 Java 代码计算 | - | ⑤DB | ✅ 正常 | `cli_procedure` 表已存储执行状态,无需变更 | - | ⑥关联模块 | ✅ 正常 | `adviceCancel`(取消执行)不受影响,取消后执行记录变为 CANCEL,退回校验自动放行 | --- .../impl/AdviceProcessAppServiceImpl.java | 89 +++++++++++++------ .../dto/InpatientAdviceDto.java | 3 + 2 files changed, 64 insertions(+), 28 deletions(-) diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inhospitalnursestation/appservice/impl/AdviceProcessAppServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inhospitalnursestation/appservice/impl/AdviceProcessAppServiceImpl.java index 2238165f5..6610f7237 100755 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inhospitalnursestation/appservice/impl/AdviceProcessAppServiceImpl.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inhospitalnursestation/appservice/impl/AdviceProcessAppServiceImpl.java @@ -232,38 +232,48 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService { } } - // 手动处理前端传来的执行条件 - if (exeStatus != null) { - // 处理执行记录状态 - for (InpatientAdviceDto inpatientAdvice : inpatientAdviceList) { - List performRecordList = procedureRecordGroup.get(inpatientAdvice.getRequestId()); - List exePerformRecordList = new ArrayList<>(); - List cancelPerformRecordList = new ArrayList<>(); - List stopPerformRecordList = new ArrayList<>(); - if (performRecordList != null && !performRecordList.isEmpty()) { - // 按时间分组,处理每个时间点的多条记录 - Map> recordsByTime = performRecordList.stream() - .collect(Collectors.groupingBy(record -> record.getOccurrenceTime().toString())); - for (Map.Entry> entry : recordsByTime.entrySet()) { - List records = entry.getValue(); - // 按操作顺序排序 - records.sort(Comparator.comparing(PerformRecordDto::getCreateTime)); - // 取最后一条记录,最终状态由最后一次操作决定 - PerformRecordDto lastRecord = records.get(records.size() - 1); - if (EventStatus.COMPLETED.getValue().equals(lastRecord.getStatusEnum())) { - exePerformRecordList.add(lastRecord); - } else if (EventStatus.CANCEL.getValue().equals(lastRecord.getStatusEnum())) { - cancelPerformRecordList.add(lastRecord); - } else if (EventStatus.STOPPED.getValue().equals(lastRecord.getStatusEnum())) { - stopPerformRecordList.add(lastRecord); - } + // 为所有医嘱计算执行记录状态(所有页签都需要展示执行进度) + for (InpatientAdviceDto inpatientAdvice : inpatientAdviceList) { + List performRecordList = procedureRecordGroup.get(inpatientAdvice.getRequestId()); + List exePerformRecordList = new ArrayList<>(); + List cancelPerformRecordList = new ArrayList<>(); + List stopPerformRecordList = new ArrayList<>(); + if (performRecordList != null && !performRecordList.isEmpty()) { + // 按时间分组,处理每个时间点的多条记录 + Map> recordsByTime = performRecordList.stream() + .collect(Collectors.groupingBy(record -> record.getOccurrenceTime().toString())); + for (Map.Entry> entry : recordsByTime.entrySet()) { + List records = entry.getValue(); + // 按操作顺序排序 + records.sort(Comparator.comparing(PerformRecordDto::getCreateTime)); + // 取最后一条记录,最终状态由最后一次操作决定 + PerformRecordDto lastRecord = records.get(records.size() - 1); + if (EventStatus.COMPLETED.getValue().equals(lastRecord.getStatusEnum())) { + exePerformRecordList.add(lastRecord); + } else if (EventStatus.CANCEL.getValue().equals(lastRecord.getStatusEnum())) { + cancelPerformRecordList.add(lastRecord); + } else if (EventStatus.STOPPED.getValue().equals(lastRecord.getStatusEnum())) { + stopPerformRecordList.add(lastRecord); } } - inpatientAdvice.setExePerformRecordList(exePerformRecordList) - .setCancelPerformRecordList(cancelPerformRecordList) - .setStopPerformRecordList(stopPerformRecordList); } + inpatientAdvice.setExePerformRecordList(exePerformRecordList) + .setCancelPerformRecordList(cancelPerformRecordList) + .setStopPerformRecordList(stopPerformRecordList); + // 计算综合执行状态文本 + if (!exePerformRecordList.isEmpty()) { + inpatientAdvice.setOverallStatusText("已执行"); + } else if (!cancelPerformRecordList.isEmpty()) { + inpatientAdvice.setOverallStatusText("已取消执行"); + } else if (!stopPerformRecordList.isEmpty()) { + inpatientAdvice.setOverallStatusText("已停止"); + } else { + inpatientAdvice.setOverallStatusText(inpatientAdvice.getRequestStatus_enumText()); + } + } + // 手动处理前端传来的执行条件 + if (exeStatus != null) { // 根据执行状态过滤医嘱列表 List filteredList = new ArrayList<>(); if (EventStatus.COMPLETED.getValue().equals(exeStatus)) { @@ -359,6 +369,29 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService { medRequestList.add(item); } } + // 校验医嘱是否已执行,已执行的医嘱不允许退回 + List allRequestList = new ArrayList<>(); + allRequestList.addAll(serviceRequestList); + allRequestList.addAll(medRequestList); + if (!allRequestList.isEmpty()) { + // 按requestTable分组查询执行记录 + Map> requestTableIdMap = allRequestList.stream() + .collect(Collectors.groupingBy(PerformInfoDto::getRequestTable, + Collectors.mapping(PerformInfoDto::getRequestId, Collectors.toList()))); + for (Map.Entry> entry : requestTableIdMap.entrySet()) { + String requestTable = entry.getKey(); + List requestIds = entry.getValue(); + List executedProcedures = procedureService.list( + new LambdaQueryWrapper() + .in(Procedure::getRequestId, requestIds) + .eq(Procedure::getRequestTable, requestTable) + .eq(Procedure::getStatusEnum, EventStatus.COMPLETED.getValue()) + .eq(Procedure::getCategoryEnum, ProcedureCategory.INPATIENT_ADVICE.getValue())); + if (!executedProcedures.isEmpty()) { + return R.fail("所选医嘱中存在已执行的医嘱,请先在【医嘱执行】界面取消执行后再退回"); + } + } + } // 校验药品医嘱是否已发药,已发药的医嘱不允许退回 if (!medRequestList.isEmpty()) { List medReqIds = medRequestList.stream().map(PerformInfoDto::getRequestId).toList(); diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inhospitalnursestation/dto/InpatientAdviceDto.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inhospitalnursestation/dto/InpatientAdviceDto.java index bcb4fa5ce..4006d3a53 100755 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inhospitalnursestation/dto/InpatientAdviceDto.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inhospitalnursestation/dto/InpatientAdviceDto.java @@ -101,6 +101,9 @@ public class InpatientAdviceDto { private Integer requestStatus; private String requestStatus_enumText; + /** 综合执行状态(结合请求状态和执行记录计算) */ + private String overallStatusText; + /** 是否皮试 */ private Integer skinTestFlag; private String skinTestFlag_enumText;