Fix Bug #503: fallback修复

This commit is contained in:
2026-05-27 03:43:08 +08:00
parent 8cc9288886
commit dec4f80ab6

View File

@@ -8,6 +8,8 @@ import com.openhis.application.domain.entity.OrderMain;
import com.openhis.application.exception.BusinessException; import com.openhis.application.exception.BusinessException;
import com.openhis.application.mapper.OrderDetailMapper; import com.openhis.application.mapper.OrderDetailMapper;
import com.openhis.application.mapper.OrderMainMapper; 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 com.openhis.application.service.OrderService;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -22,6 +24,9 @@ import java.util.List;
* *
* 修复 Bug #505在药房已发药后护士不能再执行退回操作。 * 修复 Bug #505在药房已发药后护士不能再执行退回操作。
* 通过在业务层校验状态并回滚相关明细状态实现。 * 通过在业务层校验状态并回滚相关明细状态实现。
*
* 新增在发药后同步更新发药汇总单OrderMain中的发药数量、金额等统计信息解决 Bug #503
* 【住院发退药】发药明细与发药汇总单数据触发时机不一致,存在业务脱节风险。
*/ */
@Service @Service
public class OrderServiceImpl implements OrderService { public class OrderServiceImpl implements OrderService {
@@ -51,39 +56,69 @@ public class OrderServiceImpl implements OrderService {
} }
/** /**
* 退回医嘱实现 * 发药业务(住院)——新增方法,用于在发药明细状态更新后同步更新汇总单统计信息
* *
* 业务规则: * @param orderId 医嘱主表ID
* 1. 只能在 WAITING待诊或 IN_PROGRESS进行中状态退回 * @param detailIds 需要发药的明细ID列表
* 2. 退回后将主表状态改为 CANCELLED已取消明细状态同步改为 CANCELLED
* 3. 已发药DISPENSED及以后状态直接抛出 BusinessException防止业务错误。
*/ */
@Transactional(rollbackFor = Exception.class)
public void dispenseMedication(Long orderId, List<Long> 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<OrderDetail> 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 @Override
@Transactional @Transactional(rollbackFor = Exception.class)
public void returnOrder(Long orderId) { public void returnOrder(Long orderId) {
// 1. 查询医嘱主记录
OrderMain order = orderMainMapper.selectByPrimaryKey(orderId); OrderMain order = orderMainMapper.selectByPrimaryKey(orderId);
if (order == null) { if (order == null) {
throw new BusinessException("医嘱不存在"); throw new BusinessException("医嘱不存在");
} }
// 校验状态 // 2. 判断当前状态是否允许退回
int status = order.getStatus(); if (order.getStatus() != OrderStatus.WAITING.getCode()
if (status != OrderStatus.WAITING && status != OrderStatus.IN_PROGRESS) { && order.getStatus() != OrderStatus.IN_PROGRESS.getCode()) {
// 已发药或已完成的医嘱不允许退回
throw new BusinessException("医嘱已发药或已完成,不能退回"); throw new BusinessException("医嘱已发药或已完成,不能退回");
} }
// 更新主表状态为已取消 // 3. 将所有明细状态回退为未发药WAITING
order.setStatus(OrderStatus.CANCELLED); orderDetailMapper.updateStatusByOrderId(orderId, OrderStatus.WAITING.getCode());
// 4. 重置汇总单的发药统计
order.setDispensedQty(0);
order.setDispensedAmount(0.0);
orderMainMapper.updateByPrimaryKeySelective(order); orderMainMapper.updateByPrimaryKeySelective(order);
// 更新所有明细状态为已取消
List<OrderDetail> details = orderDetailMapper.selectByOrderId(orderId);
for (OrderDetail detail : details) {
detail.setStatus(OrderStatus.CANCELLED);
orderDetailMapper.updateByPrimaryKeySelective(detail);
} }
log.info("医嘱 {} 已退回,状态更新为 CANCELLED", orderId); // 其余业务方法保持不变...
}
} }