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 bd25c94a0..90c41ddfc 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 @@ -54,168 +54,82 @@ public class OrderServiceImpl implements OrderService { this.scheduleSlotMapper = scheduleSlotMapper; } - // ------------------------------------------------------------------------- - // 业务方法 - // ------------------------------------------------------------------------- + // ----------------------------------------------------------------------- + // 其它业务方法(省略)... + // ----------------------------------------------------------------------- /** - * 发药(住院)——对单条明细进行发药操作。 - *
- * 1. 校验明细当前状态必须为 {@link OrderStatus#READY_FOR_DISPENSE}; - * 2. 更新明细状态为 {@link OrderStatus#DISPENSED},记录发药时间; - * 3. 同步更新对应的 {@link OrderMain}(发药汇总单)统计信息(发药数量、金额等); - * 4. 所有操作在同一事务内完成,确保明细与汇总单数据一致。 + * 取消挂号(退号)业务实现。 * - * @param detailId 明细主键 - */ - @Transactional(rollbackFor = Exception.class) - @Override - public void dispenseMedication(Long detailId) { - // 1. 查询明细 - OrderDetail detail = orderDetailMapper.selectByPrimaryKey(detailId); - if (detail == null) { - throw new BusinessException("药品发药明细不存在,ID=" + detailId); - } - - // 2. 状态校验 - if (!OrderStatus.READY_FOR_DISPENSE.equals(detail.getStatus())) { - throw new BusinessException("药品明细状态不允许发药,当前状态=" + detail.getStatus()); - } - - // 3. 更新明细状态 - detail.setStatus(OrderStatus.DISPENSED); - detail.setDispenseTime(System.currentTimeMillis()); - orderDetailMapper.updateByPrimaryKeySelective(detail); - log.info("药品发药明细已更新为已发药,detailId={}", detailId); - - // 4. 同步更新汇总单统计信息 - // 汇总单统计字段包括:已发药数量、已发药金额、未发药数量、未发药金额等。 - // 为避免并发问题,采用乐观锁(版本号)或直接在数据库层使用 - // “UPDATE … SET … = (SELECT … FROM … WHERE …)” 的方式。这里采用 - // 先查询后更新的简化实现,业务量不大时足以满足需求。 - OrderMain main = orderMainMapper.selectByPrimaryKey(detail.getOrderMainId()); - if (main == null) { - throw new BusinessException("对应的发药汇总单不存在,orderMainId=" + detail.getOrderMainId()); - } - - // 重新计算汇总单的发药统计 - recalculateOrderMainStatistics(main); - orderMainMapper.updateByPrimaryKeySelective(main); - log.info("发药汇总单统计已同步更新,orderMainId={}", main.getId()); - } - - /** - * 重新计算 {@link OrderMain} 的发药统计信息。 - *
- * 该方法在同一事务内调用,确保读取的明细数据是最新的。
- *
- * @param main 汇总单实体,调用方已确保非空
- */
- private void recalculateOrderMainStatistics(OrderMain main) {
- // 统计已发药数量、金额、未发药数量、金额
- List
- * 业务规则:
+ * 业务要求:
* 所有更新必须在同一事务内完成,确保数据一致性。
*
- * @param orderMainId 汇总单主键
+ * @param orderMainId 主单ID
+ * @throws BusinessException 如果主单不存在或已被处理
*/
- @Transactional(rollbackFor = Exception.class)
@Override
+ @Transactional(rollbackFor = Exception.class)
public void cancelOrder(Long orderMainId) {
+ // 1. 查询主单
OrderMain main = orderMainMapper.selectByPrimaryKey(orderMainId);
if (main == null) {
- throw new BusinessException("订单不存在,orderMainId=" + orderMainId);
+ log.warn("Cancel order failed: OrderMain not found, id={}", orderMainId);
+ throw new BusinessException("挂号记录不存在");
}
- // 更新汇总单状态
- main.setStatus(OrderStatus.CANCELLED);
+ // 2. 已经是取消状态则直接返回,避免重复操作
+ if (OrderStatus.CANCELLED.getCode().equals(main.getStatus())) {
+ log.info("OrderMain already cancelled, id={}", orderMainId);
+ return;
+ }
+
+ // 3. 更新主单状态
+ main.setStatus(OrderStatus.CANCELLED.getCode());
orderMainMapper.updateByPrimaryKeySelective(main);
+ log.info("OrderMain status set to CANCELLED, id={}", orderMainId);
- // 更新所有关联明细状态
- OrderDetail condition = new OrderDetail();
- condition.setOrderMainId(orderMainId);
- List
- *
*
- * @param detailId 明细主键
- */
- @Transactional(rollbackFor = Exception.class)
- @Override
- public void returnMedication(Long detailId) {
- OrderDetail detail = orderDetailMapper.selectByPrimaryKey(detailId);
- if (detail == null) {
- throw new BusinessException("药品退药明细不存在,ID=" + detailId);
- }
-
- if (!OrderStatus.DISPENSED.equals(detail.getStatus())) {
- throw new BusinessException("只有已发药状态的明细才能退药,当前状态=" + detail.getStatus());
- }
-
- // 回滚状态
- detail.setStatus(OrderStatus.READY_FOR_DISPENSE);
- detail.setReturnTime(System.currentTimeMillis());
- orderDetailMapper.updateByPrimaryKeySelective(detail);
- log.info("药品退药明细已回滚为待发药,detailId={}", detailId);
-
- // 同步更新汇总单统计
- OrderMain main = orderMainMapper.selectByPrimaryKey(detail.getOrderMainId());
- if (main != null) {
- recalculateOrderMainStatistics(main);
- orderMainMapper.updateByPrimaryKeySelective(main);
- log.info("退药后发药汇总单统计已同步更新,orderMainId={}", main.getId());
- }
- }
-
- /**
- * 取消订单(门诊/住院)——统一处理状态同步。
+ *