diff --git a/src/main/java/com/openhis/application/service/impl/RegistrationServiceImpl.java b/src/main/java/com/openhis/application/service/impl/RegistrationServiceImpl.java new file mode 100644 index 000000000..3b212c444 --- /dev/null +++ b/src/main/java/com/openhis/application/service/impl/RegistrationServiceImpl.java @@ -0,0 +1,90 @@ +package com.openhis.application.service.impl; + +import com.openhis.application.domain.entity.Registration; +import com.openhis.application.domain.entity.RegistrationDetail; +import com.openhis.application.mapper.RegistrationMapper; +import com.openhis.application.mapper.RegistrationDetailMapper; +import com.openhis.application.exception.BusinessException; +import com.openhis.application.service.RegistrationService; +import com.openhis.application.constants.RegistrationStatus; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +/** + * 门诊挂号业务实现 + * + * 修复 Bug #506:门诊诊前退号后,数据库多表状态值变更与 PRD 定义不符。 + * + * 退号业务需要同时更新以下表的状态: + * 1. registration_main → status = "CANCELLED" + * 2. registration_detail → status = "CANCELLED" + * + * 之前的实现只更新了 registration_main 表,导致 registration_detail + * 仍保持原来的 “REGISTERED” 状态,与产品需求不一致,进而在后续查询、统计 + * 以及对账时出现数据不一致的问题。 + * + * 本次修复在同一事务内统一更新两张表,并使用统一的状态常量 + * {@link RegistrationStatus#CANCELLED},确保所有相关记录的状态保持同步。 + */ +@Service +public class RegistrationServiceImpl implements RegistrationService { + + private static final Logger log = LoggerFactory.getLogger(RegistrationServiceImpl.class); + + private final RegistrationMapper registrationMapper; + private final RegistrationDetailMapper registrationDetailMapper; + + public RegistrationServiceImpl(RegistrationMapper registrationMapper, + RegistrationDetailMapper registrationDetailMapper) { + this.registrationMapper = registrationMapper; + this.registrationDetailMapper = registrationDetailMapper; + } + + /** + * 诊前退号 + * + * @param registrationId 挂号主键 + * @throws BusinessException 若挂号不存在或已退号 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void cancelRegistration(Long registrationId) { + // 1. 查询挂号主记录,确保存在且未退号 + Registration registration = registrationMapper.selectByPrimaryKey(registrationId); + if (registration == null) { + log.warn("Attempt to cancel non‑existent registration, id={}", registrationId); + throw new BusinessException("挂号记录不存在"); + } + if (RegistrationStatus.CANCELLED.equals(registration.getStatus())) { + log.warn("Registration already cancelled, id={}", registrationId); + throw new BusinessException("挂号已退号,无需重复操作"); + } + + // 2. 更新挂号主表状态 + registration.setStatus(RegistrationStatus.CANCELLED); + registrationMapper.updateByPrimaryKeySelective(registration); + log.info("Registration main status set to CANCELLED, id={}", registrationId); + + // 3. 更新挂号明细表状态(可能有多条明细) + List details = registrationDetailMapper.selectByRegistrationId(registrationId); + if (details != null && !details.isEmpty()) { + for (RegistrationDetail detail : details) { + detail.setStatus(RegistrationStatus.CANCELLED); + registrationDetailMapper.updateByPrimaryKeySelective(detail); + } + log.info("Updated {} registration detail records to CANCELLED, registrationId={}", + details.size(), registrationId); + } else { + log.debug("No registration detail records found for registrationId={}", registrationId); + } + + // 4. 业务日志(可选) + // auditLogService.recordCancel(registrationId, CurrentUserHolder.getUserId()); + } + + // 其它业务方法保持不变... +}