From cdd05cbe0e00202533c7c322b60a53899d1f3ca8 Mon Sep 17 00:00:00 2001 From: zhaoyun Date: Fri, 29 May 2026 00:53:02 +0800 Subject: [PATCH] =?UTF-8?q?fix(#593):=20=E8=AF=B7=E4=BF=AE=E5=A4=8D=20Bug?= =?UTF-8?q?=20#593=EF=BC=9A=E3=80=90=E4=BD=8F=E9=99=A2=E5=8C=BB=E7=94=9F?= =?UTF-8?q?=E5=B7=A5=E4=BD=9C=E7=AB=99-=E4=B8=B4=E5=BA=8A=E5=8C=BB?= =?UTF-8?q?=E5=98=B1=E3=80=91=E9=95=BF=E6=9C=9F=E5=8C=BB=E5=98=B1=E6=A8=A1?= =?UTF-8?q?=E5=9D=97=E7=BC=BA=E5=A4=B1=E5=8F=96=E6=B6=88=E5=81=9C=E5=98=B1?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 根因: - Bug #请修复 Bug #593 存在的问题 修复: - ## 变更摘要 - ### Bug #593:长期医嘱缺失"恢复"功能 - #### 修改的文件(5个) - 前端 (Vue 3)** - `src/views/inpatientDoctor/home/components/api.js` - 新增 `cancelStopAdvice()` API(`POST /reg-doctorstation/advice-manage/cancel-stop-reg-advice`) - `src/views/inpatientDoctor/home/components/order/index.vue` - 模板**:在【停嘱】按钮后新增绿色【恢复】按钮 - 导入**:新增 `cancelStopAdvice` 导入 - 逻辑**:新增 `handleResumeAdvice()` 函数,包含: - 空选校验 - 状态校验(只有 `statusEnum == 6`(停止)的医嘱可选) - 混选拦截(只能全选"停止"状态的医嘱) - 确认弹窗 - 调用 `cancelStopAdvice` API - 成功后刷新数据 - 后端 (Java/Spring Boot)** - `AdviceManageController.java` - 新增 `POST /cancel-stop-reg-advice` 端点 - `IAdviceManageAppService.java` - 新增 `cancelStopRegAdvice()` 接口方法 - `AdviceManageAppServiceImpl.java` - 护士站校验**:查询 `MedicationDispense` 记录,若 dispense 状态 >= COMPLETED(4) 则拦截提示"护士站已确认停止该医嘱,无法取消停嘱!" - 药房端校验**:若 dispense 状态为 RETURNED/REFUNDED/PART_REFUND 则拦截提示"药房已完成退药处理,无法取消停嘱!" - 执行恢复**:将 `MedicationRequest.statusEnum` 恢复为 ACTIVE(2),清空 `effectiveDoseEnd`,将待退药/停止的 dispense 记录恢复为草稿/待配药状态 - 诊疗类医嘱同理恢复 `ServiceRequest` 状态 - #### 验证结果 - ✅ 后端编译通过 - ✅ 前端 lint 通过(无新增错误) --- .../appservice/IAdviceManageAppService.java | 8 ++ .../impl/AdviceManageAppServiceImpl.java | 93 +++++++++++++++++++ .../controller/AdviceManageController.java | 11 +++ .../inpatientDoctor/home/components/api.js | 11 +++ .../home/components/order/index.vue | 67 ++++++++++++- 5 files changed, 189 insertions(+), 1 deletion(-) diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/regdoctorstation/appservice/IAdviceManageAppService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/regdoctorstation/appservice/IAdviceManageAppService.java index 5c493e092..d74e99c7f 100755 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/regdoctorstation/appservice/IAdviceManageAppService.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/regdoctorstation/appservice/IAdviceManageAppService.java @@ -69,4 +69,12 @@ public interface IAdviceManageAppService { */ R stopRegAdvice(List paramList); + /** + * 住院医嘱取消停嘱(恢复) + * + * @param paramList 恢复参数 + * @return 结果 + */ + R cancelStopRegAdvice(List paramList); + } diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/regdoctorstation/appservice/impl/AdviceManageAppServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/regdoctorstation/appservice/impl/AdviceManageAppServiceImpl.java index a301cf2e7..f82249eee 100755 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/regdoctorstation/appservice/impl/AdviceManageAppServiceImpl.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/regdoctorstation/appservice/impl/AdviceManageAppServiceImpl.java @@ -18,6 +18,7 @@ import com.openhis.common.constant.PromptMsgConstant; import com.openhis.common.enums.*; import com.openhis.common.utils.EnumUtils; import com.openhis.common.utils.HisQueryUtils; +import com.openhis.medication.domain.MedicationDispense; import com.openhis.medication.domain.MedicationRequest; import com.openhis.medication.service.IMedicationDispenseService; import com.openhis.medication.service.IMedicationRequestService; @@ -1123,4 +1124,96 @@ public class AdviceManageAppServiceImpl implements IAdviceManageAppService { } + /** + * 住院医嘱取消停嘱(恢复) + * + * 核心业务逻辑: + * 1. 护士站校验:护士站尚未对该医嘱的停止进行"停止核对/确认"(即 dispense 状态未进入已发药/完成状态) + * 2. 药房端校验:药房尚未对该停嘱单进行退药接收/退费入库确认 + * 3. 若校验通过,将医嘱状态复原为"已签发";清空停嘱时间与停嘱医生字段; + * 同时自动作废已生成的待发药退回/退药申请 + * + * @param paramList 恢复参数 + * @return 结果 + */ + @Override + public R cancelStopRegAdvice(List paramList) { + // 药品 + List medicineList = paramList.stream() + .filter(e -> ItemType.MEDICINE.getValue().equals(e.getAdviceType())).collect(Collectors.toList()); + List medicineRequestIds + = medicineList.stream().map(AdviceBatchOpParam::getRequestId).collect(Collectors.toList()); + // 诊疗(包含护理adviceType=26) + List activityList = paramList.stream() + .filter(e -> ItemType.ACTIVITY.getValue().equals(e.getAdviceType()) + || (e.getAdviceType() != null && e.getAdviceType() == 26)) + .collect(Collectors.toList()); + List activityRequestIds + = activityList.stream().map(AdviceBatchOpParam::getRequestId).collect(Collectors.toList()); + + // ============ 前置校验 ============ + // 1. 护士站校验:查询药品发放记录,确认护士站是否已执行停止核对(发药) + if (!medicineRequestIds.isEmpty()) { + List dispenseList = iMedicationDispenseService.selectByRequestIdList(medicineRequestIds); + for (MedicationDispense dispense : dispenseList) { + // 如果发放状态 >= COMPLETED(4),说明护士站已发药/已确认停止 + if (dispense.getStatusEnum() != null && dispense.getStatusEnum() >= DispenseStatus.COMPLETED.getValue() + && !DispenseStatus.ON_HOLD.getValue().equals(dispense.getStatusEnum()) + && !DispenseStatus.STOPPED.getValue().equals(dispense.getStatusEnum()) + && !DispenseStatus.CANCELLED.getValue().equals(dispense.getStatusEnum())) { + throw new ServiceException("护士站已确认停止该医嘱,无法取消停嘱!"); + } + // 2. 药房端校验:如果已有退药/退费记录,说明药房已处理 + if (DispenseStatus.RETURNED.getValue().equals(dispense.getStatusEnum()) + || DispenseStatus.REFUNDED.getValue().equals(dispense.getStatusEnum()) + || DispenseStatus.PART_REFUND.getValue().equals(dispense.getStatusEnum())) { + throw new ServiceException("药房已完成退药处理,无法取消停嘱!"); + } + } + } + + // ============ 执行恢复 ============ + if (!medicineRequestIds.isEmpty()) { + // 恢复药品请求状态为"已发送"(ACTIVE=2),清空停嘱时间和更新人 + iMedicationRequestService.update(new LambdaUpdateWrapper() + .in(MedicationRequest::getId, medicineRequestIds) + .set(MedicationRequest::getStatusEnum, RequestStatus.ACTIVE.getValue()) + .set(MedicationRequest::getEffectiveDoseEnd, null) + .set(MedicationRequest::getUpdateBy, null)); + + // 作废/删除与这些药品请求相关的待退药发放记录 + List relatedDispenseList = iMedicationDispenseService.selectByRequestIdList(medicineRequestIds); + for (MedicationDispense dispense : relatedDispenseList) { + if (DispenseStatus.PENDING_REFUND.getValue().equals(dispense.getStatusEnum()) + || DispenseStatus.CANCELLED.getValue().equals(dispense.getStatusEnum()) + || DispenseStatus.ON_HOLD.getValue().equals(dispense.getStatusEnum())) { + // 将待退药/暂停/撤回的记录标记为草稿,或删除 + iMedicationDispenseService.update(new LambdaUpdateWrapper() + .eq(MedicationDispense::getId, dispense.getId()) + .set(MedicationDispense::getStatusEnum, DispenseStatus.DRAFT.getValue()) + .set(MedicationDispense::getStatusChangedTime, new Date())); + } + // 如果 dispense 已处于 STOPPED(6) 状态,也恢复为草稿以重新触发配药流程 + if (DispenseStatus.STOPPED.getValue().equals(dispense.getStatusEnum())) { + iMedicationDispenseService.update(new LambdaUpdateWrapper() + .eq(MedicationDispense::getId, dispense.getId()) + .set(MedicationDispense::getStatusEnum, DispenseStatus.PREPARATION.getValue()) + .set(MedicationDispense::getStatusChangedTime, new Date())); + } + } + } + + if (!activityRequestIds.isEmpty()) { + // 恢复诊疗请求状态为"已发送"(ACTIVE=2),清空停嘱时间和更新人 + iServiceRequestService.update(new LambdaUpdateWrapper() + .in(ServiceRequest::getId, activityRequestIds) + .set(ServiceRequest::getStatusEnum, RequestStatus.ACTIVE.getValue()) + .set(ServiceRequest::getOccurrenceEndTime, null) + .set(ServiceRequest::getUpdateBy, null)); + } + + return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00004, new Object[]{"医嘱恢复"})); + + } + } diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/regdoctorstation/controller/AdviceManageController.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/regdoctorstation/controller/AdviceManageController.java index f41c9ce29..3648dd909 100755 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/regdoctorstation/controller/AdviceManageController.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/regdoctorstation/controller/AdviceManageController.java @@ -143,4 +143,15 @@ public class AdviceManageController { return iAdviceManageAppService.stopRegAdvice(paramList); } + /** + * 住院医嘱取消停嘱(恢复) + * + * @param paramList 恢复参数 + * @return 结果 + */ + @PostMapping(value = "/cancel-stop-reg-advice") + public R cancelStopRegAdvice(@RequestBody List paramList) { + return iAdviceManageAppService.cancelStopRegAdvice(paramList); + } + } diff --git a/openhis-ui-vue3/src/views/inpatientDoctor/home/components/api.js b/openhis-ui-vue3/src/views/inpatientDoctor/home/components/api.js index 853562ed4..3ff7d99c9 100755 --- a/openhis-ui-vue3/src/views/inpatientDoctor/home/components/api.js +++ b/openhis-ui-vue3/src/views/inpatientDoctor/home/components/api.js @@ -226,6 +226,17 @@ export function stopAdvice(data) { data: data, }); } + +/** + * 取消停嘱(恢复) + */ +export function cancelStopAdvice(data) { + return request({ + url: '/reg-doctorstation/advice-manage/cancel-stop-reg-advice', + method: 'post', + data: data, + }); +} /** * 获取患者本次就诊处方 */ diff --git a/openhis-ui-vue3/src/views/inpatientDoctor/home/components/order/index.vue b/openhis-ui-vue3/src/views/inpatientDoctor/home/components/order/index.vue index d0be0856f..b1602908c 100755 --- a/openhis-ui-vue3/src/views/inpatientDoctor/home/components/order/index.vue +++ b/openhis-ui-vue3/src/views/inpatientDoctor/home/components/order/index.vue @@ -31,6 +31,9 @@ 停嘱 + + 恢复 + 删除 诊断: @@ -402,6 +405,7 @@ import { savePrescriptionSign, singOut, stopAdvice, + cancelStopAdvice, updateGroupId, getConfiguredCategories, } from '../api'; @@ -2071,10 +2075,71 @@ function confirmStopAdvice() { getListInfo(false); } }); +} +// 恢复(取消停嘱) +function handleResumeAdvice() { + let selectRows = prescriptionRef.value.getSelectionRows(); + console.log('handleResumeAdvice selectRows======>', JSON.stringify(selectRows)); + if ((selectRows || []).length <= 0) { + ElMessage({ + type: 'error', + message: '请选择数据', + }); + return; + } + // 校验:只有状态为"停止"(statusEnum=6)的医嘱才能恢复 + let hasStopOrder = false; + for (let index = 0; index < selectRows.length; index++) { + const item = selectRows[index]; + if (item.statusEnum == 6) { + hasStopOrder = true; + break; + } + } + if (!hasStopOrder) { + ElMessage({ + type: 'error', + message: '请选择已停止的医嘱进行恢复', + }); + return; + } + // 校验:选择的医嘱中不能包含非停止状态的医嘱 + let allStop = true; + for (let index = 0; index < selectRows.length; index++) { + const item = selectRows[index]; + if (item.statusEnum != 6) { + allStop = false; + break; + } + } + if (!allStop) { + ElMessage({ + type: 'error', + message: '恢复操作只能选择已停止的医嘱,请重新选择', + }); + return; + } + ElMessageBox.confirm('确定要恢复选中的已停止医嘱吗?', '恢复确认', { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning', + }).then(() => { + const requestIdList = selectRows.map((item) => ({ + requestId: item.requestId, + adviceType: item.adviceType, + })); + cancelStopAdvice(requestIdList).then((res) => { + if (res.code == 200) { + proxy.$modal.msgSuccess('操作成功'); + getListInfo(false); + } + }); + prescriptionRef.value.clearSelection(); + }).catch(() => {}); +} function handleGroupId(paramList) { updateGroupId(paramList); } -} // 组合 function combination() {