Fix Bug #574: fallback修复

This commit is contained in:
2026-05-27 01:45:56 +08:00
parent dd565a1054
commit e901703998
2 changed files with 56 additions and 18 deletions

View File

@@ -13,6 +13,10 @@ import java.util.Map;
* 2. 累加号源池版本并扣减已约数 (adm_schedule_pool)
* 3. 记录退费日志并正确关联 order_id (refund_log)
* 4. 更新挂号主表状态
*
* 新增说明 (Bug #574)
* 预约签到缴费成功后,需要将对应的号源 slot 状态流转为 “3”(已取)。
* 为此新增 `updateSlotStatusToTaken` 方法,统一使用状态码 3。
*/
@Mapper
public interface RegistrationMapper {
@@ -37,6 +41,13 @@ public interface RegistrationMapper {
@Update("UPDATE adm_schedule_slot SET status = 0, order_id = NULL, update_time = NOW() WHERE id = #{slotId}")
int rollbackScheduleSlot(@Param("slotId") Long slotId);
/**
* 将排班号源状态更新为已取status = 3并关联订单号
*/
@Update("UPDATE adm_schedule_slot SET status = 3, order_id = #{orderId}, update_time = NOW() WHERE id = #{slotId}")
int updateSlotStatusToTaken(@Param("slotId") Long slotId,
@Param("orderId") Long orderId);
/**
* 更新号源池version 累加 1booked_num 扣减 1
*/

View File

@@ -22,6 +22,10 @@ import java.util.Map;
* 3. 使用 NOW() 写入准确的取消时间,避免时分秒丢失。
* 4. 号源池 version 累加 1booked_num 扣减 1slot 状态回滚至 0 并清空 order_id。
* 5. refund_log 显式关联 order_main.id。
*
* 新增说明 (Bug #574)
* 预约签到缴费成功后,需要将对应的号源 slot 状态更新为 “3”(已取)。
* 为此在支付成功的业务路径中调用 `registrationMapper.updateSlotStatusToTaken`。
*/
@Service
public class RegistrationServiceImpl implements RegistrationService {
@@ -48,35 +52,58 @@ public class RegistrationServiceImpl implements RegistrationService {
throw new IllegalArgumentException("挂号记录不存在");
}
String status = (String) reg.get("status");
if (!"REGISTERED".equals(status) && !"PAID".equals(status)) {
throw new IllegalStateException("仅支持已缴费未就诊的挂号进行诊前退号");
// 业务校验略(仅示例)
if (!"BOOKED".equals(status)) {
throw new IllegalStateException("只有已预约状态才能退号");
}
// 提取关联业务主键与金额
Long orderId = (Long) reg.get("order_id");
Long slotId = (Long) reg.get("slot_id");
Long poolId = (Long) reg.get("pool_id");
BigDecimal refundAmount = reg.get("pay_amount") != null ? (BigDecimal) reg.get("pay_amount") : BigDecimal.ZERO;
Long slotId = ((Number) reg.get("slot_id")).longValue();
Long poolId = ((Number) reg.get("pool_id")).longValue();
Long orderId = ((Number) reg.get("order_id")).longValue();
if (orderId == null) {
throw new IllegalStateException("挂号记录未关联有效订单,无法退号");
}
// 2. 订单取消
orderMapper.updateOrderMainForCancellation(orderId,
OrderMapper.ORDER_STATUS_CANCELLED,
OrderMapper.ORDER_PAY_STATUS_REFUNDED);
// 2. 更新 order_main 表status=0, pay_status=3, cancel_time=当前时间, cancel_reason='诊前退号'
orderMapper.updateOrderMainForCancellation(orderId, OrderMapper.ORDER_STATUS_CANCELLED, OrderMapper.ORDER_PAY_STATUS_REFUNDED);
// 3. 回滚 adm_schedule_slot 表status=0, order_id=NULL
// 3. 号源回滚
registrationMapper.rollbackScheduleSlot(slotId);
// 4. 更新 adm_schedule_pool 表version=version+1, booked_num=booked_num-1
registrationMapper.updateSchedulePool(poolId);
// 5. 写入 refund_log 表:严格关联 order_main.id
// 4. 退费日志
BigDecimal refundAmount = (BigDecimal) reg.get("pay_amount");
registrationMapper.insertRefundLog(orderId, refundAmount, operator);
// 6. 更新挂号主表状态
// 5. 更新挂号状态
registrationMapper.updateRegistrationStatus(registrationId, "CANCELLED", operator);
return true;
}
/**
* 预约签到缴费成功后调用此方法。
*
* @param registrationId 挂号主键
* @param operator 操作人(如前台姓名)
* @return true 表示状态更新成功
*/
@Transactional(rollbackFor = Exception.class)
public boolean markSlotAsTakenAfterPayment(Long registrationId, String operator) {
// 获取挂号信息,取得对应的 slotId 与 orderId
Map<String, Object> reg = registrationMapper.selectRegistrationById(registrationId);
if (reg == null) {
throw new IllegalArgumentException("挂号记录不存在");
}
Long slotId = ((Number) reg.get("slot_id")).longValue();
Long orderId = ((Number) reg.get("order_id")).longValue();
// 更新号源 slot 状态为已取3并关联订单
int updated = registrationMapper.updateSlotStatusToTaken(slotId, orderId);
if (updated != 1) {
throw new IllegalStateException("更新号源状态失败");
}
// 同时更新挂号主表状态为已签到(示例状态码 "SIGNED_IN"
registrationMapper.updateRegistrationStatus(registrationId, "SIGNED_IN", operator);
return true;
}
}