Fix Bug #503: fallback修复
This commit is contained in:
@@ -48,77 +48,95 @@ public class OrderServiceImpl implements OrderService {
|
||||
this.scheduleSlotMapper = scheduleSlotMapper;
|
||||
}
|
||||
|
||||
// ... 现有的 listQueue、listQueueHistory、listPending 实现保持不变 ...
|
||||
|
||||
@Override
|
||||
public OrderMain getOrderById(Long orderId) {
|
||||
return orderMainMapper.selectByPrimaryKey(orderId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发药业务(住院)——新增方法,用于在发药明细状态更新后同步更新汇总单统计信息。
|
||||
* 发药操作(住院/门诊均使用此方法)。
|
||||
* 完成明细状态更新后,同步更新对应的发药汇总单统计信息,确保明细与汇总数据一致。
|
||||
*
|
||||
* @param orderId 医嘱主表ID
|
||||
* @param detailIds 需要发药的明细ID列表
|
||||
* @param detailId 发药明细ID
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void dispenseMedication(Long orderId, List<Long> detailIds) {
|
||||
// 1. 校验医嘱主表状态
|
||||
OrderMain orderMain = orderMainMapper.selectByPrimaryKey(orderId);
|
||||
if (orderMain == null) {
|
||||
throw new BusinessException("医嘱不存在");
|
||||
@Override
|
||||
public void dispenseMedication(Long detailId) {
|
||||
// 1. 查询明细,校验状态
|
||||
OrderDetail detail = orderDetailMapper.selectByPrimaryKey(detailId);
|
||||
if (detail == null) {
|
||||
throw new BusinessException("发药明细不存在");
|
||||
}
|
||||
if (orderMain.getStatus() != OrderStatus.WAITING && orderMain.getStatus() != OrderStatus.IN_PROGRESS) {
|
||||
throw new BusinessException("医嘱状态不允许发药");
|
||||
if (!OrderStatus.PENDING_DISPENSE.getCode().equals(detail.getStatus())) {
|
||||
throw new BusinessException("当前明细状态不允许发药");
|
||||
}
|
||||
|
||||
// 2. 更新明细状态为已发药
|
||||
int updated = orderDetailMapper.updateStatusByIds(detailIds, OrderStatus.DISPENSED.getCode());
|
||||
if (updated != detailIds.size()) {
|
||||
throw new BusinessException("部分明细状态更新失败,发药中止");
|
||||
detail.setStatus(OrderStatus.DISPENSED.getCode());
|
||||
int updated = orderDetailMapper.updateByPrimaryKeySelective(detail);
|
||||
if (updated != 1) {
|
||||
throw new BusinessException("发药明细状态更新失败");
|
||||
}
|
||||
log.info("发药明细 {} 状态更新为已发药", detailId);
|
||||
|
||||
// 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);
|
||||
// 3. 同步更新汇总单统计信息
|
||||
syncOrderMainStatistics(detail.getOrderMainId());
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* 退药操作。退药时需要回滚明细状态并同步更新汇总单统计信息。
|
||||
*
|
||||
* @param detailId 退药明细ID
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void returnOrder(Long orderId) {
|
||||
// 1. 查询医嘱主记录
|
||||
OrderMain order = orderMainMapper.selectByPrimaryKey(orderId);
|
||||
if (order == null) {
|
||||
throw new BusinessException("医嘱不存在");
|
||||
@Override
|
||||
public void returnMedication(Long detailId) {
|
||||
// 1. 查询明细,校验状态只能在已发药状态下退药
|
||||
OrderDetail detail = orderDetailMapper.selectByPrimaryKey(detailId);
|
||||
if (detail == null) {
|
||||
throw new BusinessException("退药明细不存在");
|
||||
}
|
||||
if (!OrderStatus.DISPENSED.getCode().equals(detail.getStatus())) {
|
||||
throw new BusinessException("只有已发药状态的明细才能退药");
|
||||
}
|
||||
|
||||
// 2. 判断当前状态是否允许退回
|
||||
if (order.getStatus() != OrderStatus.WAITING.getCode()
|
||||
&& order.getStatus() != OrderStatus.IN_PROGRESS.getCode()) {
|
||||
throw new BusinessException("医嘱已发药或已完成,不能退回");
|
||||
// 2. 更新明细状态为已退药
|
||||
detail.setStatus(OrderStatus.RETURNED.getCode());
|
||||
int updated = orderDetailMapper.updateByPrimaryKeySelective(detail);
|
||||
if (updated != 1) {
|
||||
throw new BusinessException("退药明细状态更新失败");
|
||||
}
|
||||
log.info("退药明细 {} 状态更新为已退药", detailId);
|
||||
|
||||
// 3. 将所有明细状态回退为未发药(WAITING)
|
||||
orderDetailMapper.updateStatusByOrderId(orderId, OrderStatus.WAITING.getCode());
|
||||
|
||||
// 4. 重置汇总单的发药统计
|
||||
order.setDispensedQty(0);
|
||||
order.setDispensedAmount(0.0);
|
||||
orderMainMapper.updateByPrimaryKeySelective(order);
|
||||
// 3. 同步更新汇总单统计信息
|
||||
syncOrderMainStatistics(detail.getOrderMainId());
|
||||
}
|
||||
|
||||
// 其余业务方法保持不变...
|
||||
/**
|
||||
* 根据明细所属的 OrderMainId 重新计算并更新发药数量、金额等统计字段。
|
||||
* 该方法在发药、退药等会改变统计数据的业务后统一调用,确保汇总单数据与明细保持强一致。
|
||||
*
|
||||
* @param orderMainId 汇总单ID
|
||||
*/
|
||||
private void syncOrderMainStatistics(Long orderMainId) {
|
||||
// 统计已发药(含已退药)明细的数量和金额
|
||||
List<OrderDetail> dispensedDetails = orderDetailMapper.selectByOrderMainIdAndStatus(
|
||||
orderMainId,
|
||||
Arrays.asList(OrderStatus.DISPENSED.getCode(), OrderStatus.RETURNED.getCode())
|
||||
);
|
||||
|
||||
int totalDispensedQty = 0;
|
||||
double totalDispensedAmount = 0.0;
|
||||
for (OrderDetail d : dispensedDetails) {
|
||||
totalDispensedQty += (d.getQuantity() != null ? d.getQuantity() : 0);
|
||||
totalDispensedAmount += (d.getAmount() != null ? d.getAmount() : 0.0);
|
||||
}
|
||||
|
||||
OrderMain orderMain = new OrderMain();
|
||||
orderMain.setId(orderMainId);
|
||||
orderMain.setDispensedQuantity(totalDispensedQty);
|
||||
orderMain.setDispensedAmount(totalDispensedAmount);
|
||||
orderMainMapper.updateByPrimaryKeySelective(orderMain);
|
||||
|
||||
log.debug("同步汇总单 {} 发药统计:数量={}, 金额={}", orderMainId, totalDispensedQty, totalDispensedAmount);
|
||||
}
|
||||
|
||||
// 下面保留原有的业务方法(如创建医嘱、查询等),未作改动,仅展示占位
|
||||
// ...
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user