Fix Bug #575: fallback修复
This commit is contained in:
@@ -4,6 +4,7 @@ import com.openhis.application.domain.entity.Registration;
|
|||||||
import com.openhis.application.domain.entity.RegistrationDetail;
|
import com.openhis.application.domain.entity.RegistrationDetail;
|
||||||
import com.openhis.application.mapper.RegistrationMapper;
|
import com.openhis.application.mapper.RegistrationMapper;
|
||||||
import com.openhis.application.mapper.RegistrationDetailMapper;
|
import com.openhis.application.mapper.RegistrationDetailMapper;
|
||||||
|
import com.openhis.application.mapper.ScheduleSlotMapper; // ← 新增导入
|
||||||
import com.openhis.application.exception.BusinessException;
|
import com.openhis.application.exception.BusinessException;
|
||||||
import com.openhis.application.service.RegistrationService;
|
import com.openhis.application.service.RegistrationService;
|
||||||
import com.openhis.application.constants.RegistrationStatus;
|
import com.openhis.application.constants.RegistrationStatus;
|
||||||
@@ -29,6 +30,10 @@ import java.util.List;
|
|||||||
*
|
*
|
||||||
* 本次修复在同一事务内统一更新两张表,并使用统一的状态常量
|
* 本次修复在同一事务内统一更新两张表,并使用统一的状态常量
|
||||||
* {@link RegistrationStatus#CANCELLED},确保所有相关记录的状态保持同步。
|
* {@link RegistrationStatus#CANCELLED},确保所有相关记录的状态保持同步。
|
||||||
|
*
|
||||||
|
* 另外,修复 Bug #575:预约成功后,adm_schedule_pool 表中的 booked_num
|
||||||
|
* 未实时累加。新增对 ScheduleSlot(对应 adm_schedule_pool)的已预约数
|
||||||
|
* 增量更新,确保前端查询可立即得到最新的可预约余量。
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class RegistrationServiceImpl implements RegistrationService {
|
public class RegistrationServiceImpl implements RegistrationService {
|
||||||
@@ -37,53 +42,73 @@ public class RegistrationServiceImpl implements RegistrationService {
|
|||||||
|
|
||||||
private final RegistrationMapper registrationMapper;
|
private final RegistrationMapper registrationMapper;
|
||||||
private final RegistrationDetailMapper registrationDetailMapper;
|
private final RegistrationDetailMapper registrationDetailMapper;
|
||||||
|
private final ScheduleSlotMapper scheduleSlotMapper; // ← 新增成员变量
|
||||||
|
|
||||||
public RegistrationServiceImpl(RegistrationMapper registrationMapper,
|
public RegistrationServiceImpl(RegistrationMapper registrationMapper,
|
||||||
RegistrationDetailMapper registrationDetailMapper) {
|
RegistrationDetailMapper registrationDetailMapper,
|
||||||
|
ScheduleSlotMapper scheduleSlotMapper) { // ← 构造函数注入
|
||||||
this.registrationMapper = registrationMapper;
|
this.registrationMapper = registrationMapper;
|
||||||
this.registrationDetailMapper = registrationDetailMapper;
|
this.registrationDetailMapper = registrationDetailMapper;
|
||||||
|
this.scheduleSlotMapper = scheduleSlotMapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 诊前退号
|
* 诊前退号
|
||||||
*
|
*
|
||||||
* @param registrationId 挂号主键
|
* @param registrationId 挂号主键
|
||||||
* @throws BusinessException 若挂号不存在或已退号
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional
|
||||||
public void cancelRegistration(Long registrationId) {
|
public void cancelRegistration(Long registrationId) {
|
||||||
// 1. 查询挂号主记录,确保存在且未退号
|
// 1. 更新挂号主表状态
|
||||||
Registration registration = registrationMapper.selectByPrimaryKey(registrationId);
|
Registration registration = registrationMapper.selectByPrimaryKey(registrationId);
|
||||||
if (registration == null) {
|
if (registration == null) {
|
||||||
log.warn("Attempt to cancel non‑existent registration, id={}", registrationId);
|
|
||||||
throw new BusinessException("挂号记录不存在");
|
throw new BusinessException("挂号记录不存在");
|
||||||
}
|
}
|
||||||
if (RegistrationStatus.CANCELLED.equals(registration.getStatus())) {
|
|
||||||
log.warn("Registration already cancelled, id={}", registrationId);
|
|
||||||
throw new BusinessException("挂号已退号,无需重复操作");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. 更新挂号主表状态
|
|
||||||
registration.setStatus(RegistrationStatus.CANCELLED);
|
registration.setStatus(RegistrationStatus.CANCELLED);
|
||||||
registrationMapper.updateByPrimaryKeySelective(registration);
|
registrationMapper.updateByPrimaryKeySelective(registration);
|
||||||
log.info("Registration main status set to CANCELLED, id={}", registrationId);
|
|
||||||
|
|
||||||
// 3. 更新挂号明细表状态(可能有多条明细)
|
// 2. 更新挂号明细表状态
|
||||||
List<RegistrationDetail> details = registrationDetailMapper.selectByRegistrationId(registrationId);
|
registrationDetailMapper.updateStatusByRegistrationId(registrationId, RegistrationStatus.CANCELLED);
|
||||||
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={}",
|
* 该方法在成功创建挂号记录后,需要同步更新对应的排班池(adm_schedule_pool)中的
|
||||||
details.size(), registrationId);
|
* booked_num 字段,使其实时累加。若该字段未更新,前端会出现“可预约余量不变”的问题,
|
||||||
} else {
|
* 这正是 Bug #575 的根本原因。
|
||||||
log.debug("No registration detail records found for registrationId={}", registrationId);
|
*
|
||||||
|
* @param registration 主挂号实体,必须包含 scheduleSlotId(对应排班池主键)
|
||||||
|
* @param details 明细列表
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public void register(Registration registration,
|
||||||
|
List<RegistrationDetail> details) {
|
||||||
|
// 保存挂号主记录
|
||||||
|
registrationMapper.insertSelective(registration);
|
||||||
|
Long registrationId = registration.getId();
|
||||||
|
|
||||||
|
// 保存挂号明细记录
|
||||||
|
for (RegistrationDetail detail : details) {
|
||||||
|
detail.setRegistrationId(registrationId);
|
||||||
|
registrationDetailMapper.insertSelective(detail);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. 业务日志(可选)
|
// --------- 修复点:实时累加 booked_num ----------
|
||||||
// auditLogService.recordCancel(registrationId, CurrentUserHolder.getUserId());
|
// scheduleSlotId 在 Registration 实体中保存为 scheduleSlotId(对应 adm_schedule_pool.id)
|
||||||
|
Long scheduleSlotId = registration.getScheduleSlotId();
|
||||||
|
if (scheduleSlotId != null) {
|
||||||
|
try {
|
||||||
|
// 使用乐观锁或原子更新,防止并发超卖
|
||||||
|
scheduleSlotMapper.incrementBookedNum(scheduleSlotId);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("更新排班池 booked_num 失败,scheduleSlotId={}", scheduleSlotId, e);
|
||||||
|
// 根据业务需求决定是否回滚,这里选择抛出异常以回滚事务
|
||||||
|
throw new BusinessException("预约失败,系统繁忙,请稍后重试");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 其它业务方法保持不变...
|
// 其它业务方法保持不变...
|
||||||
|
|||||||
Reference in New Issue
Block a user