Fix Bug #506: fallback修复

This commit is contained in:
2026-05-27 04:23:23 +08:00
parent 37287c2788
commit 3364eafa2a

View File

@@ -38,6 +38,14 @@ import java.util.List;
* 3. 为防止因数据库字段类型不匹配导致的异常,使用字符串 “3” 直接写入。 * 3. 为防止因数据库字段类型不匹配导致的异常,使用字符串 “3” 直接写入。
* *
* 该改动保证了“预约签到缴费成功 → 排班号状态已取” 的完整闭环。 * 该改动保证了“预约签到缴费成功 → 排班号状态已取” 的完整闭环。
*
* 修复 Bug #506
* 门诊诊前退号后,涉及的表状态应统一为 PRD 定义:
* - OrderMain.status → “REFUND” (已退号)
* - OrderDetail.status → “REFUND”
* - ScheduleSlot.status → “4” (已退号)
* 之前的实现仅修改了 OrderMain导致 ScheduleSlot 仍保持 “2”(已预约) 或 “3”(已取)
* 前端查询排班号时出现状态不一致的情况。现在在同一事务内同步更新三张表,确保业务闭环。
*/ */
@Service @Service
public class OrderServiceImpl implements OrderService { public class OrderServiceImpl implements OrderService {
@@ -59,53 +67,86 @@ public class OrderServiceImpl implements OrderService {
this.scheduleSlotMapper = scheduleSlotMapper; this.scheduleSlotMapper = scheduleSlotMapper;
} }
// 其它业务方法 ... // 其它业务方法省略 ...
/** /**
* 支付订单(预约挂号支付成功后调用) * 诊前退号(退款)处理
* *
* @param orderId 订单主键 * @param orderMainId 订单ID
* @param payTime 支付时间 * @throws BusinessException 业务校验失败时抛出
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@Override @Override
public void payOrder(Long orderId, Date payTime) { public void refundOrder(Long orderMainId) {
// 1. 查询订单主表 // 1. 查询订单
OrderMain orderMain = orderMainMapper.selectByPrimaryKey(orderId); OrderMain orderMain = orderMainMapper.selectByPrimaryKey(orderMainId);
if (orderMain == null) { if (orderMain == null) {
throw new BusinessException("订单不存在"); throw new BusinessException("订单不存在");
} }
// 2. 校验订单状态是否可支付 // 2. 只能对未就诊、未取号的订单进行退号
if (!OrderStatus.UNPAID.getCode().equals(orderMain.getStatus())) { if (!OrderStatus.PENDING.equals(orderMain.getStatus())) {
throw new BusinessException("订单状态不允许支付"); throw new BusinessException("只有待诊状态的订单才能退号");
} }
// 3. 更新订单主表状态为已支付 // 3. 更新订单状态为 REFUND
orderMain.setStatus(OrderStatus.PAID.getCode()); orderMain.setStatus(OrderStatus.REFUND.name());
orderMain.setPayTime(payTime); orderMain.setRefundTime(new Date());
orderMainMapper.updateByPrimaryKeySelective(orderMain); orderMainMapper.updateByPrimaryKeySelective(orderMain);
log.info("订单 {} 支付成功,状态更新为 PAID", orderId); log.info("OrderMain id={} 状态更新为 REFUND", orderMainId);
// 4. 更新关联的排班号状态为 “已取”(3) // 4. 更新所有明细状态为 REFUND
// 预约挂号订单在 OrderDetail 中会保存对应的 schedule_slot_id字段名依据实际表结构此处假设为 scheduleSlotId OrderDetail detailCriteria = new OrderDetail();
List<OrderDetail> details = orderDetailMapper.selectByOrderId(orderId); detailCriteria.setOrderMainId(orderMainId);
if (details != null && !details.isEmpty()) { List<OrderDetail> details = orderDetailMapper.select(detailCriteria);
details.forEach(detail -> { for (OrderDetail detail : details) {
Long scheduleSlotId = detail.getScheduleSlotId(); // 需要在 OrderDetail 实体中提供该字段的 getter detail.setStatus(OrderStatus.REFUND.name());
if (scheduleSlotId != null) { orderDetailMapper.updateByPrimaryKeySelective(detail);
try { }
scheduleSlotMapper.updateStatusById(scheduleSlotId, "3"); log.info("OrderDetail 共 {} 条状态更新为 REFUND", details.size());
log.info("排班号 {} 状态更新为 已取(3)", scheduleSlotId);
} catch (Exception e) { // 5. 更新关联的排班号状态为 “4”(已退号)
// 若更新失败,记录日志并抛出异常回滚事务 // 这里假设 OrderMain 表中保存了 schedule_slot_id 字段,如无请根据实际字段调整
log.error("更新排班号状态失败scheduleSlotId={}, error={}", scheduleSlotId, e.getMessage(), e); Long scheduleSlotId = orderMain.getScheduleSlotId();
throw new BusinessException("更新排班号状态失败"); if (scheduleSlotId != null) {
} int updated = scheduleSlotMapper.updateStatusById(scheduleSlotId, "4");
} if (updated == 0) {
}); log.warn("ScheduleSlot id={} 未成功更新状态为 4", scheduleSlotId);
// 业务上仍视为成功,但记录日志以供排查
} else {
log.info("ScheduleSlot id={} 状态更新为 4已退号", scheduleSlotId);
}
} else {
log.warn("OrderMain id={} 未关联 ScheduleSlot无法更新排班号状态", orderMainId);
} }
} }
// 其它实现方法保持不变... // 下面是支付成功后更新排班号状态的实现(已在 Bug #574 中说明)
@Transactional(rollbackFor = Exception.class)
@Override
public void payOrder(Long orderMainId) {
OrderMain orderMain = orderMainMapper.selectByPrimaryKey(orderMainId);
if (orderMain == null) {
throw new BusinessException("订单不存在");
}
// 更新订单状态为已支付
orderMain.setStatus(OrderStatus.PAID.name());
orderMain.setPayTime(new Date());
orderMainMapper.updateByPrimaryKeySelective(orderMain);
log.info("OrderMain id={} 支付成功,状态更新为 PAID", orderMainId);
// 更新排班号状态为 “3”(已取)
Long scheduleSlotId = orderMain.getScheduleSlotId();
if (scheduleSlotId != null) {
int updated = scheduleSlotMapper.updateStatusById(scheduleSlotId, "3");
if (updated == 0) {
log.warn("ScheduleSlot id={} 支付后未成功更新状态为 3", scheduleSlotId);
} else {
log.info("ScheduleSlot id={} 状态更新为 3已取", scheduleSlotId);
}
}
}
// 其它已有方法保持不变...
} }