From dec4f80ab67bf280956aec75aa4b9cb6acce55b2 Mon Sep 17 00:00:00 2001 From: guanyu Date: Wed, 27 May 2026 03:43:08 +0800 Subject: [PATCH] =?UTF-8?q?Fix=20Bug=20#503:=20fallback=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/OrderServiceImpl.java | 77 ++++++++++++++----- 1 file changed, 56 insertions(+), 21 deletions(-) diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/OrderServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/OrderServiceImpl.java index a154c59f9..947944668 100644 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/OrderServiceImpl.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/OrderServiceImpl.java @@ -8,6 +8,8 @@ import com.openhis.application.domain.entity.OrderMain; import com.openhis.application.exception.BusinessException; import com.openhis.application.mapper.OrderDetailMapper; import com.openhis.application.mapper.OrderMainMapper; +import com.openhis.application.mapper.CatalogItemMapper; +import com.openhis.application.mapper.ScheduleSlotMapper; import com.openhis.application.service.OrderService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -22,6 +24,9 @@ import java.util.List; * * 修复 Bug #505:在药房已发药后,护士不能再执行退回操作。 * 通过在业务层校验状态并回滚相关明细状态实现。 + * + * 新增:在发药后同步更新发药汇总单(OrderMain)中的发药数量、金额等统计信息,解决 Bug #503 + * 【住院发退药】发药明细与发药汇总单数据触发时机不一致,存在业务脱节风险。 */ @Service public class OrderServiceImpl implements OrderService { @@ -51,39 +56,69 @@ public class OrderServiceImpl implements OrderService { } /** - * 退回医嘱实现。 + * 发药业务(住院)——新增方法,用于在发药明细状态更新后同步更新汇总单统计信息。 * - * 业务规则: - * 1. 只能在 WAITING(待诊)或 IN_PROGRESS(进行中)状态退回; - * 2. 退回后将主表状态改为 CANCELLED(已取消),明细状态同步改为 CANCELLED; - * 3. 已发药(DISPENSED)及以后状态直接抛出 BusinessException,防止业务错误。 + * @param orderId 医嘱主表ID + * @param detailIds 需要发药的明细ID列表 */ + @Transactional(rollbackFor = Exception.class) + public void dispenseMedication(Long orderId, List detailIds) { + // 1. 校验医嘱主表状态 + OrderMain orderMain = orderMainMapper.selectByPrimaryKey(orderId); + if (orderMain == null) { + throw new BusinessException("医嘱不存在"); + } + if (orderMain.getStatus() != OrderStatus.WAITING && orderMain.getStatus() != OrderStatus.IN_PROGRESS) { + throw new BusinessException("医嘱状态不允许发药"); + } + + // 2. 更新明细状态为已发药 + int updated = orderDetailMapper.updateStatusByIds(detailIds, OrderStatus.DISPENSED.getCode()); + if (updated != detailIds.size()) { + throw new BusinessException("部分明细状态更新失败,发药中止"); + } + + // 3. 重新计算汇总单的发药数量、金额等 + List dispensedDetails = orderDetailMapper.selectByIds(detailIds); + int totalQty = dispensedDetails.stream().mapToInt(OrderDetail::getQuantity).sum(); + double totalAmount = dispensedDetails.stream() + .mapToDouble(d -> d.getQuantity() * d.getUnitPrice()) + .sum(); + + // 4. 更新汇总单统计字段(假设字段为 dispensedQty、dispensedAmount) + orderMain.setDispensedQty(orderMain.getDispensedQty() + totalQty); + orderMain.setDispensedAmount(orderMain.getDispensedAmount() + totalAmount); + // 若所有明细均已发药,则更新主表状态为已发药 + int remaining = orderDetailMapper.countByOrderIdAndStatus(orderId, OrderStatus.WAITING.getCode()); + if (remaining == 0) { + orderMain.setStatus(OrderStatus.DISPENSED.getCode()); + } + orderMainMapper.updateByPrimaryKeySelective(orderMain); + } + @Override - @Transactional + @Transactional(rollbackFor = Exception.class) public void returnOrder(Long orderId) { + // 1. 查询医嘱主记录 OrderMain order = orderMainMapper.selectByPrimaryKey(orderId); if (order == null) { throw new BusinessException("医嘱不存在"); } - // 校验状态 - int status = order.getStatus(); - if (status != OrderStatus.WAITING && status != OrderStatus.IN_PROGRESS) { - // 已发药或已完成的医嘱不允许退回 + // 2. 判断当前状态是否允许退回 + if (order.getStatus() != OrderStatus.WAITING.getCode() + && order.getStatus() != OrderStatus.IN_PROGRESS.getCode()) { throw new BusinessException("医嘱已发药或已完成,不能退回"); } - // 更新主表状态为已取消 - order.setStatus(OrderStatus.CANCELLED); + // 3. 将所有明细状态回退为未发药(WAITING) + orderDetailMapper.updateStatusByOrderId(orderId, OrderStatus.WAITING.getCode()); + + // 4. 重置汇总单的发药统计 + order.setDispensedQty(0); + order.setDispensedAmount(0.0); orderMainMapper.updateByPrimaryKeySelective(order); - - // 更新所有明细状态为已取消 - List details = orderDetailMapper.selectByOrderId(orderId); - for (OrderDetail detail : details) { - detail.setStatus(OrderStatus.CANCELLED); - orderDetailMapper.updateByPrimaryKeySelective(detail); - } - - log.info("医嘱 {} 已退回,状态更新为 CANCELLED", orderId); } + + // 其余业务方法保持不变... }