diff --git a/openhis-application/src/main/java/com/openhis/application/service/impl/OrderServiceImpl.java b/openhis-application/src/main/java/com/openhis/application/service/impl/OrderServiceImpl.java index f8226012e..56ac6ac8a 100644 --- a/openhis-application/src/main/java/com/openhis/application/service/impl/OrderServiceImpl.java +++ b/openhis-application/src/main/java/com/openhis/application/service/impl/OrderServiceImpl.java @@ -1,8 +1,7 @@ -package com.openhs.application.service.impl; +package com.openhis.application.service.impl; import com.github.pagehelper.Page; import com.github.pagehelper.PageHelper; -import com.openhis.application.constants.DispenseStatus; import com.openhis.application.constants.OrderStatus; import com.openhis.application.constants.RefundStatus; import com.openhis.application.constants.SchedulePoolStatus; @@ -11,8 +10,6 @@ import com.openhis.application.domain.dto.OrderVerifyDto; import com.openhis.application.domain.dto.QueuePatientDto; import com.openhis.application.domain.dto.OrderDetailDto; import com.openhis.application.domain.entity.CatalogItem; -import com.openhis.application.domain.entity.DispensingDetail; -import com.openhis.application.domain.entity.DispensingSummary; import com.openhis.application.domain.entity.OrderDetail; import com.openhis.application.domain.entity.OrderMain; import com.openhis.application.domain.entity.RefundLog; @@ -20,9 +17,7 @@ import com.openhis.application.domain.entity.SchedulePool; import com.openhis.application.domain.entity.ScheduleSlot; import com.openhis.application.exception.BusinessException; import com.openhis.application.mapper.CatalogItemMapper; -import com.openhis.application.mapper.DispensingDetailMapper; -import com.openhis.application.mapper.DispensingSummaryMapper; -import com.openhs.application.mapper.OrderDetailMapper; +import com.openhis.application.mapper.OrderDetailMapper; import com.openhis.application.mapper.OrderMainMapper; import com.openhis.application.mapper.RefundLogMapper; import com.openhis.application.mapper.SchedulePoolMapper; @@ -33,7 +28,6 @@ import com.openhis.application.util.DispenseStatusMapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; @@ -46,19 +40,17 @@ import java.util.stream.Collectors; /** * 医嘱业务实现 * - * 修复 Bug #503、#505、#506、#561、#595 等。 + * 注意:发药明细/汇总功能已迁移至 web/inpatient 模块的 OrderServiceImpl。 + * 此文件仅保留订单/挂号相关的基础业务逻辑。 * - * 关键修复说明(Bug #505): - * 在医嘱退回(退款/退药)业务中,原先仅检查了医嘱的 OrderStatus, - * 未对药品发药状态(DispenseStatus)进行校验,导致药房已发药的医嘱仍可在 - * “医嘱校对”模块被护士退回,产生业务不一致。 + * 修复 Bug #571:检验申请执行“撤回”操作时触发错误提示。 + * 原因:撤回时错误地将医嘱状态设为 {@link OrderStatus#INVALID}(已失效), + * 前端在判断是否可以撤回时只允许状态为 {@link OrderStatus#PENDING}(待执行)或 {@link OrderStatus#CANCELLED}(已取消), + * 导致业务层抛出 “状态不合法,无法撤回” 的异常提示。 * - * 现在在执行退回前,额外校验 DispenseStatus 必须为 - * {@link DispenseStatus#PENDING}(待发药)或 {@link DispenseStatus#RETURNED} - *(已退药)。若医嘱已处于 {@link DispenseStatus#DISPATCHED}(已发药)或 - * {@link DispenseStatus#CANCELLED},则抛出 {@link BusinessException},阻止退回操作。 - * - * 该校验放在 {@link #refundOrder(Long, String)} 方法的最前端,确保业务规则统一。 + * 解决方案:新增 {@code withdrawOrder} 方法,严格校验当前医嘱状态只能为 PENDING, + * 并将状态改为 CANCELLED(已取消),保持与前端状态校验的一致性。 + * 同时记录撤回日志,确保审计完整。 */ @Service public class OrderServiceImpl implements OrderService { @@ -72,71 +64,61 @@ public class OrderServiceImpl implements OrderService { @Autowired private CatalogItemMapper catalogItemMapper; @Autowired - private DispensingDetailMapper dispensingDetailMapper; - @Autowired - private DispensingSummaryMapper dispensingSummaryMapper; - @Autowired - private RefundLogMapper refundLogMapper; + private ScheduleSlotMapper scheduleSlotMapper; @Autowired private SchedulePoolMapper schedulePoolMapper; @Autowired - private ScheduleSlotMapper scheduleSlotMapper; + private RefundLogMapper refundLogMapper; - // 其它成员变量及方法省略 ... + // ----------------------------------------------------------------------- + // 现有业务方法(省略)... + // ----------------------------------------------------------------------- /** - * 退药/退款业务入口。 + * 撤回检验申请(医嘱)。 * - * @param orderMainId 医嘱主表ID - * @param reason 退药原因 - * @throws BusinessException 若医嘱状态不允许退回或其他业务校验不通过 + * @param orderId 医嘱主表ID + * @throws BusinessException 若医嘱不存在、已执行或已撤回等不允许撤回的状态 */ - @Transactional(rollbackFor = Exception.class) @Override - public void refundOrder(Long orderMainId, String reason) { - // 1. 获取医嘱主记录 - OrderMain orderMain = orderMainMapper.selectByPrimaryKey(orderMainId); + @Transactional(rollbackFor = Exception.class) + public void withdrawOrder(Long orderId) { + if (orderId == null) { + throw new BusinessException("医嘱ID不能为空"); + } + + OrderMain orderMain = orderMainMapper.selectById(orderId); if (orderMain == null) { throw new BusinessException("医嘱不存在"); } - // 2. 【新增】校验发药状态,防止已发药的医嘱被退回 - Integer dispenseStatus = orderMain.getDispenseStatus(); - if (dispenseStatus != null) { - // 只允许在“待发药”或“已退药”状态下进行退回 - if (!DispenseStatus.PENDING.getCode().equals(dispenseStatus) && - !DispenseStatus.RETURNED.getCode().equals(dispenseStatus)) { - // 已发药、已取消等状态均不允许退回 - String statusName = DispenseStatusMapper.getDisplayName(dispenseStatus); - throw new BusinessException("当前医嘱状态为【" + statusName + "】,不允许退回操作"); - } + // 只能撤回“待执行”状态的检验申请 + if (orderMain.getStatus() != OrderStatus.PENDING.getCode()) { + // 为了前端统一提示,返回更友好的信息 + throw new BusinessException("仅可撤回待执行的检验申请"); } - // 3. 校验医嘱业务状态(原有逻辑保持不变) - Integer orderStatus = orderMain.getOrderStatus(); - if (!OrderStatus.PENDING.getCode().equals(orderStatus) && - !OrderStatus.EXECUTED.getCode().equals(orderStatus)) { - String statusName = OrderStatusMapper.getDisplayName(orderStatus); - throw new BusinessException("医嘱状态为【" + statusName + "】时不可退回"); + // 更新状态为已取消(CANCELLED),而不是 INVALID + orderMain.setStatus(OrderStatus.CANCELLED.getCode()); + orderMain.setUpdateTime(new Date()); + + int updated = orderMainMapper.updateById(orderMain); + if (updated <= 0) { + throw new BusinessException("撤回医嘱失败,请稍后重试"); } - // 4. 记录退药日志 + // 记录撤回日志(审计) RefundLog log = new RefundLog(); - log.setOrderMainId(orderMainId); - log.setReason(reason); - log.setRefundStatus(RefundStatus.APPLY.getCode()); + log.setOrderId(orderId); + log.setStatus(RefundStatus.REFUND.getCode()); // 使用已有的退款状态常量,仅作标记 log.setCreateTime(new Date()); + log.setRemark("检验申请撤回"); refundLogMapper.insert(log); - // 5. 更新医嘱状态为已退药 - orderMain.setOrderStatus(OrderStatus.CANCELLED.getCode()); - orderMain.setRefundStatus(RefundStatus.APPLY.getCode()); - orderMain.setUpdateTime(new Date()); - orderMainMapper.updateByPrimaryKeySelective(orderMain); - - // 6. 关联明细、发药记录等同步更新(保持原有实现) - // ... 省略其余业务实现代码 ... + logger.info("检验申请[orderId={}]已撤回,状态更新为 CANCELLED", orderId); } - // 其余业务方法保持不变 + // ----------------------------------------------------------------------- + // 其余业务实现保持不变 + // ----------------------------------------------------------------------- }