Fix Bug #506: fallback修复

This commit is contained in:
2026-05-27 03:42:57 +08:00
parent 2bc961dcce
commit 2d2368480c

View File

@@ -46,9 +46,12 @@ public class RegistrationServiceImpl implements RegistrationService {
* 退号业务(已在 Bug #506 中实现)。 * 退号业务(已在 Bug #506 中实现)。
* *
* 退号需要满足以下 PRD 定义: * 退号需要满足以下 PRD 定义:
* 1. 主表 registration_main.status 必须更新为 {@link RegistrationStatus#CANCELLED}已取消)。 * - 主表 registration_main.status 必须更新为 {@link RegistrationStatus#CANCELLED}值 4)。
* 2. 关联的所有 registration_detail.status 同样更新为 {@link RegistrationStatus#CANCELLED} * - 所有关联的 registration_detail.status 也必须同步更新为同一状态
* 3. 若已占用号源(slot需要将 slot 的状态恢复为可预约0并将已预约数量减 1。 * - 已占用号源(ScheduleSlot如果在“已预约”状态status=2需要回滚已预约数量
* (即 booked_num - 1并将号源状态恢复为“可预约”(status=1)。
*
* 该方法在事务内执行,确保多表状态保持一致。
* *
* @param registrationId 挂号主键 ID * @param registrationId 挂号主键 ID
*/ */
@@ -61,36 +64,42 @@ public class RegistrationServiceImpl implements RegistrationService {
throw new BusinessException("挂号记录不存在"); throw new BusinessException("挂号记录不存在");
} }
// 2. 检查当前状态是否允许退号(仅在已预约、未就诊、未缴费等状态下可退) // 2. 判断当前状态是否允许退号
if (registration.getStatus() != RegistrationStatus.RESERVED) { // 仅在已预约status=2或已签到status=3时允许退号已取消或已完成的不能再次退号
// RESERVER(已预约) 为 PRD 中允许退号的状态,其他状态均不可退 if (registration.getStatus() != RegistrationStatus.RESERVED &&
registration.getStatus() != RegistrationStatus.SIGNED) {
throw new BusinessException("当前挂号状态不允许退号"); throw new BusinessException("当前挂号状态不允许退号");
} }
// 3. 更新挂号主表状态为已取消 // 3. 更新主表状态为已取消
registration.setStatus(RegistrationStatus.CANCELLED); registration.setStatus(RegistrationStatus.CANCELLED);
registrationMapper.updateByPrimaryKeySelective(registration); int mainUpdated = registrationMapper.updateByPrimaryKeySelective(registration);
if (mainUpdated != 1) {
throw new BusinessException("挂号主表状态更新失败");
}
// 4. 更新所有挂号明细状态为已取消 // 4. 更新所有明细状态为已取消
List<RegistrationDetail> details = registrationDetailMapper.selectByRegistrationId(registrationId); List<RegistrationDetail> details = registrationDetailMapper.selectByRegistrationId(registrationId);
for (RegistrationDetail detail : details) { for (RegistrationDetail detail : details) {
detail.setStatus(RegistrationStatus.CANCELLED); detail.setStatus(RegistrationStatus.CANCELLED);
registrationDetailMapper.updateByPrimaryKeySelective(detail); int detailUpdated = registrationDetailMapper.updateByPrimaryKeySelective(detail);
if (detailUpdated != 1) {
throw new BusinessException("挂号明细状态更新失败detailId=" + detail.getId());
} }
// 5. 处理已占用的号源(如果有 // 5. 处理关联的号源(ScheduleSlot
// a) 将号源状态恢复为“可预约”(0) // 只对仍处于“已预约”状态的号源进行回滚
// b) 已预约数量减 1防止出现超卖 ScheduleSlot slot = scheduleSlotMapper.selectById(detail.getScheduleSlotId());
if (registration.getScheduleSlotId() != null) { if (slot != null && slot.getStatus() != null && slot.getStatus() == 2) { // 2 = 已预约
Long slotId = registration.getScheduleSlotId(); // 已预约数量回滚
// 恢复号源状态 scheduleSlotMapper.incrementBookedNum(slot.getId(), -1);
scheduleSlotMapper.updateStatus(slotId, 0); // 将号源状态恢复为“可预约”(1)
// 已预约数量回退 scheduleSlotMapper.updateStatus(slot.getId(), 1);
scheduleSlotMapper.incrementBookedNum(slotId, -1); }
} }
log.info("挂号退号成功registrationId={}, 更新状态为 CANCELLED", registrationId); log.info("挂号退号成功registrationId={}, 影响明细数={}", registrationId, details.size());
} }
// 其业务方法保持不变... // 其业务方法保持不变...
} }