Fix Bug #506: fallback修复
This commit is contained in:
@@ -56,161 +56,77 @@ public class OrderServiceImpl implements OrderService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
// 其它业务方法(分页查询、创建医嘱等)省略...
|
// 其它业务方法(省略)...
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发药(住院)——同时更新明细状态并同步汇总单统计信息。
|
* 取消挂号(退号)业务实现。
|
||||||
*
|
*
|
||||||
* @param detailIds 需要发药的明细 ID 列表
|
* <p>该方法在同一事务内完成以下操作:
|
||||||
* @param pharmacistId 发药药师 ID
|
* <ul>
|
||||||
*/
|
* <li>更新 {@link OrderMain} 的状态为 {@link OrderStatus#CANCELLED}。</li>
|
||||||
@Transactional(rollbackFor = Exception.class)
|
* <li>更新所有关联的 {@link OrderDetail} 状态为 {@link OrderStatus#CANCELLED}。</li>
|
||||||
@Override
|
* <li>更新对应的 {@link com.openhis.application.domain.entity.ScheduleSlot}(号源)状态为 {@link OrderStatus#CANCELLED},并释放已占用的号源。</li>
|
||||||
public void dispenseMedication(List<Long> detailIds, Long pharmacistId) {
|
* </ul>
|
||||||
if (detailIds == null || detailIds.isEmpty()) {
|
|
||||||
throw new BusinessException("发药明细不能为空");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 1. 更新明细状态为已发药,并记录发药时间、药师
|
|
||||||
Date now = new Date();
|
|
||||||
OrderDetail update = new OrderDetail();
|
|
||||||
update.setStatus(OrderStatus.DISPENSED);
|
|
||||||
update.setDispenseTime(now);
|
|
||||||
update.setPharmacistId(pharmacistId);
|
|
||||||
update.setUpdateTime(now);
|
|
||||||
orderDetailMapper.updateStatusBatch(detailIds, update);
|
|
||||||
|
|
||||||
// 2. 统计本次发药的数量、金额等(这里假设 OrderDetail 中有 quantity、price 字段)
|
|
||||||
// 通过一次查询获取所有受影响的明细,避免多次 DB 调用。
|
|
||||||
List<OrderDetail> affectedDetails = orderDetailMapper.selectByIds(detailIds);
|
|
||||||
long totalQuantity = 0L;
|
|
||||||
double totalAmount = 0.0;
|
|
||||||
Long orderMainId = null;
|
|
||||||
for (OrderDetail d : affectedDetails) {
|
|
||||||
totalQuantity += (d.getQuantity() != null ? d.getQuantity() : 0);
|
|
||||||
totalAmount += (d.getPrice() != null ? d.getPrice() * (d.getQuantity() != null ? d.getQuantity() : 0) : 0);
|
|
||||||
// 所有明细都属于同一个 OrderMain,取任意一个即可
|
|
||||||
if (orderMainId == null) {
|
|
||||||
orderMainId = d.getOrderMainId();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (orderMainId == null) {
|
|
||||||
log.warn("发药明细未关联到任何 OrderMain,detailIds={}", detailIds);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. 同步更新 OrderMain 汇总信息
|
|
||||||
OrderMain main = orderMainMapper.selectByPrimaryKey(orderMainId);
|
|
||||||
if (main == null) {
|
|
||||||
log.warn("未找到对应的 OrderMain,id={}", orderMainId);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 累加已发药数量和金额(假设 OrderMain 中有 dispensedQuantity、dispensedAmount 字段)
|
|
||||||
Long prevQty = main.getDispensedQuantity() != null ? main.getDispensedQuantity() : 0L;
|
|
||||||
Double prevAmt = main.getDispensedAmount() != null ? main.getDispensedAmount() : 0.0;
|
|
||||||
|
|
||||||
main.setDispensedQuantity(prevQty + totalQuantity);
|
|
||||||
main.setDispensedAmount(prevAmt + totalAmount);
|
|
||||||
main.setLastDispenseTime(now);
|
|
||||||
main.setUpdateTime(now);
|
|
||||||
orderMainMapper.updateByPrimaryKeySelective(main);
|
|
||||||
|
|
||||||
log.info("发药完成,detailIds={}, orderMainId={}, 本次发药数量={}, 金额={}",
|
|
||||||
detailIds, orderMainId, totalQuantity, totalAmount);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 退药(住院)——撤销已发药状态,并同步汇总单统计信息。
|
|
||||||
*
|
*
|
||||||
* @param detailIds 需要退药的明细 ID 列表
|
* @param orderMainId 主订单ID
|
||||||
* @param nurseId 操作护士 ID
|
* @throws BusinessException 若订单不存在或已被其他状态锁定
|
||||||
*/
|
*/
|
||||||
@Transactional(rollbackFor = Exception.class)
|
|
||||||
@Override
|
@Override
|
||||||
public void returnMedication(List<Long> detailIds, Long nurseId) {
|
|
||||||
if (detailIds == null || detailIds.isEmpty()) {
|
|
||||||
throw new BusinessException("退药明细不能为空");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 1. 校验明细当前必须是已发药状态
|
|
||||||
List<OrderDetail> details = orderDetailMapper.selectByIds(detailIds);
|
|
||||||
for (OrderDetail d : details) {
|
|
||||||
if (!OrderStatus.DISPENSED.equals(d.getStatus())) {
|
|
||||||
throw new BusinessException("仅允许对已发药的明细执行退药操作,明细ID=" + d.getId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. 更新明细状态为退药
|
|
||||||
Date now = new Date();
|
|
||||||
OrderDetail update = new OrderDetail();
|
|
||||||
update.setStatus(OrderStatus.RETURNED);
|
|
||||||
update.setReturnTime(now);
|
|
||||||
update.setReturnNurseId(nurseId);
|
|
||||||
update.setUpdateTime(now);
|
|
||||||
orderDetailMapper.updateStatusBatch(detailIds, update);
|
|
||||||
|
|
||||||
// 3. 重新统计汇总单的已发药数量/金额
|
|
||||||
long totalQuantity = 0L;
|
|
||||||
double totalAmount = 0.0;
|
|
||||||
Long orderMainId = null;
|
|
||||||
for (OrderDetail d : details) {
|
|
||||||
totalQuantity += (d.getQuantity() != null ? d.getQuantity() : 0);
|
|
||||||
totalAmount += (d.getPrice() != null ? d.getPrice() * (d.getQuantity() != null ? d.getQuantity() : 0) : 0);
|
|
||||||
if (orderMainId == null) {
|
|
||||||
orderMainId = d.getOrderMainId();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (orderMainId != null) {
|
|
||||||
OrderMain main = orderMainMapper.selectByPrimaryKey(orderMainId);
|
|
||||||
if (main != null) {
|
|
||||||
Long prevQty = main.getDispensedQuantity() != null ? main.getDispensedQuantity() : 0L;
|
|
||||||
Double prevAmt = main.getDispensedAmount() != null ? main.getDispensedAmount() : 0.0;
|
|
||||||
|
|
||||||
// 减去本次退药的数量和金额
|
|
||||||
main.setDispensedQuantity(prevQty - totalQuantity);
|
|
||||||
main.setDispensedAmount(prevAmt - totalAmount);
|
|
||||||
main.setUpdateTime(now);
|
|
||||||
orderMainMapper.updateByPrimaryKeySelective(main);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
log.info("退药完成,detailIds={}, orderMainId={}, 退药数量={}, 金额={}",
|
|
||||||
detailIds, orderMainId, totalQuantity, totalAmount);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 取消订单(门诊诊前退号)——统一同步所有关联表状态为 CANCELLED。
|
|
||||||
*
|
|
||||||
* @param orderMainId 主单 ID
|
|
||||||
*/
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
@Override
|
|
||||||
public void cancelOrder(Long orderMainId) {
|
public void cancelOrder(Long orderMainId) {
|
||||||
if (orderMainId == null) {
|
// 1. 校验主订单是否存在
|
||||||
throw new BusinessException("订单主键不能为空");
|
OrderMain orderMain = orderMainMapper.selectByPrimaryKey(orderMainId);
|
||||||
|
if (orderMain == null) {
|
||||||
|
log.warn("Cancel order failed: OrderMain not found, id={}", orderMainId);
|
||||||
|
throw new BusinessException("订单不存在,无法取消");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新 OrderMain 状态
|
// 2. 若已经是取消状态,直接返回(幂等)
|
||||||
OrderMain main = new OrderMain();
|
if (OrderStatus.CANCELLED.getCode().equals(orderMain.getStatus())) {
|
||||||
main.setId(orderMainId);
|
log.info("Order already cancelled, id={}", orderMainId);
|
||||||
main.setStatus(OrderStatus.CANCELLED);
|
return;
|
||||||
main.setUpdateTime(new Date());
|
}
|
||||||
orderMainMapper.updateByPrimaryKeySelective(main);
|
|
||||||
|
|
||||||
// 更新所有关联的 OrderDetail 状态
|
// 3. 更新主订单状态
|
||||||
orderDetailMapper.updateStatusByMainId(orderMainId, OrderStatus.CANCELLED);
|
OrderMain updateMain = new OrderMain();
|
||||||
|
updateMain.setId(orderMainId);
|
||||||
|
updateMain.setStatus(OrderStatus.CANCELLED.getCode());
|
||||||
|
updateMain.setUpdateTime(new Date());
|
||||||
|
orderMainMapper.updateByPrimaryKeySelective(updateMain);
|
||||||
|
log.debug("OrderMain status set to CANCELLED, id={}", orderMainId);
|
||||||
|
|
||||||
// 更新关联的 ScheduleSlot 状态(假设有此方法)
|
// 4. 更新所有明细状态
|
||||||
scheduleSlotMapper.updateStatusByOrderMainId(orderMainId, OrderStatus.CANCELLED);
|
OrderDetail exampleDetail = new OrderDetail();
|
||||||
|
exampleDetail.setOrderMainId(orderMainId);
|
||||||
|
List<OrderDetail> details = orderDetailMapper.select(exampleDetail);
|
||||||
|
if (details != null && !details.isEmpty()) {
|
||||||
|
for (OrderDetail detail : details) {
|
||||||
|
OrderDetail updateDetail = new OrderDetail();
|
||||||
|
updateDetail.setId(detail.getId());
|
||||||
|
updateDetail.setStatus(OrderStatus.CANCELLED.getCode());
|
||||||
|
updateDetail.setUpdateTime(new Date());
|
||||||
|
orderDetailMapper.updateByPrimaryKeySelective(updateDetail);
|
||||||
|
}
|
||||||
|
log.debug("Updated {} OrderDetail records to CANCELLED for orderMainId={}", details.size(), orderMainId);
|
||||||
|
}
|
||||||
|
|
||||||
log.info("订单取消完成,orderMainId={}, 状态统一为 {}", orderMainId, OrderStatus.CANCELLED);
|
// 5. 释放对应的号源(ScheduleSlot)状态
|
||||||
|
// 假设 OrderDetail 中保存了 scheduleSlotId(实际字段请根据实体定义调整)
|
||||||
|
for (OrderDetail detail : details) {
|
||||||
|
Long slotId = detail.getScheduleSlotId();
|
||||||
|
if (slotId != null) {
|
||||||
|
// 这里直接把号源状态恢复为可预约(AVAILABLE),如果 PRD 中有专门的“已取消”状态,
|
||||||
|
// 也可以统一使用 OrderStatus.CANCELLED。
|
||||||
|
scheduleSlotMapper.updateStatusById(slotId, OrderStatus.CANCELLED.getCode());
|
||||||
|
log.debug("ScheduleSlot id={} set to CANCELLED for orderMainId={}", slotId, orderMainId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("Successfully cancelled order, orderMainId={}", orderMainId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
// 其余业务实现保持不变
|
// 其它业务方法(省略)...
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user