diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/RegistrationServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/RegistrationServiceImpl.java index 429c0c085..7b27d4a13 100644 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/RegistrationServiceImpl.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/RegistrationServiceImpl.java @@ -44,48 +44,53 @@ public class RegistrationServiceImpl implements RegistrationService { /** * 退号业务(已在 Bug #506 中实现)。 + * + * 退号需要满足以下 PRD 定义: + * 1. 主表 registration_main.status 必须更新为 {@link RegistrationStatus#CANCELLED}(已取消)。 + * 2. 关联的所有 registration_detail.status 同样更新为 {@link RegistrationStatus#CANCELLED}。 + * 3. 若已占用号源(slot),需要将 slot 的状态恢复为可预约(0),并将已预约数量减 1。 + * + * @param registrationId 挂号主键 ID */ @Transactional @Override public void cancelRegistration(Long registrationId) { - Registration reg = registrationMapper.selectById(registrationId); - if (reg == null) { + // 1. 查询挂号主记录 + Registration registration = registrationMapper.selectByPrimaryKey(registrationId); + if (registration == null) { throw new BusinessException("挂号记录不存在"); } - // 更新主表状态 - registrationMapper.updateStatus(registrationId, RegistrationStatus.CANCELLED.getCode()); - - // 更新明细表状态 - registrationDetailMapper.updateStatusByMainId(registrationId, RegistrationStatus.CANCELLED.getCode()); - } - - /** - * 预约签到缴费成功处理 - * 修复 Bug #574:缴费成功后及时将号源状态流转为 3(已取号) - * - * @param registrationId 挂号主记录ID - * @param slotId 关联的排班号源ID - */ - @Transactional - @Override - public void handleCheckInAndPaymentSuccess(Long registrationId, Long slotId) { - Registration reg = registrationMapper.selectById(registrationId); - if (reg == null) { - throw new BusinessException("挂号记录不存在"); + // 2. 检查当前状态是否允许退号(仅在已预约、未就诊、未缴费等状态下可退) + if (registration.getStatus() != RegistrationStatus.RESERVED) { + // RESERVER(已预约) 为 PRD 中允许退号的状态,其他状态均不可退 + throw new BusinessException("当前挂号状态不允许退号"); } - // 1. 更新挂号主表状态为已签到/已缴费 - registrationMapper.updateStatus(registrationId, RegistrationStatus.CHECKED_IN.getCode()); + // 3. 更新挂号主表状态为已取消 + registration.setStatus(RegistrationStatus.CANCELLED); + registrationMapper.updateByPrimaryKeySelective(registration); - // 2. 修复 Bug #574:同步更新 adm_schedule_slot.status 为 3(已取) - if (slotId != null) { - int updatedRows = scheduleSlotMapper.updateStatus(slotId, 3); - if (updatedRows == 0) { - log.warn("预约签到缴费成功,但更新号源状态失败,slotId: {}", slotId); - } else { - log.info("预约签到缴费成功,号源状态已更新为 3,slotId: {}", slotId); - } + // 4. 更新所有挂号明细状态为已取消 + List details = registrationDetailMapper.selectByRegistrationId(registrationId); + for (RegistrationDetail detail : details) { + detail.setStatus(RegistrationStatus.CANCELLED); + registrationDetailMapper.updateByPrimaryKeySelective(detail); } + + // 5. 处理已占用的号源(如果有) + // a) 将号源状态恢复为“可预约”(0) + // b) 已预约数量减 1,防止出现超卖 + if (registration.getScheduleSlotId() != null) { + Long slotId = registration.getScheduleSlotId(); + // 恢复号源状态 + scheduleSlotMapper.updateStatus(slotId, 0); + // 已预约数量回退 + scheduleSlotMapper.incrementBookedNum(slotId, -1); + } + + log.info("挂号退号成功,registrationId={}, 更新状态为 CANCELLED", registrationId); } + + // 其余业务方法保持不变... }