fix(#575): 请修复 Bug #575:[一般] [门诊预约挂号] 预约成功后,数据库表 adm_schedule_pool 中的 booked_num 字段未实时累加

根因:
- 门诊预约挂号入口 `AppointmentServiceImpl.bookSlot()` 中,只更新了 `adm_schedule_slot`(号源槽)的状态为"已预约",**完全没有操作** `adm_schedule_pool`(号源池),导致 `booked_num` 从未累加。
- ### 全链路数据流确认
- | 环节 | 文件 | 状态 |
- |---|---|---|

修复:
- | 退号 | `RegistrationController` → `RegistrationCancelServiceImpl.cancelRegistration()` → 正确减 `booked_num` |  |
- | 签到缴费 | `AppointmentController.confirm()` → `AppointmentServiceImpl.confirmPaymentAndTake()` → 只涉及 slot 状态流转 |  不涉及 |
- ### 修改文件
- 1. `AppointmentSlotMapper.java`** — 新增 `selectPoolIdBySlotId` 方法,根据 `slotId` 查询关联的 `pool_id`
- 2. `AppointmentServiceImpl.java`** — 注入 `SchedulePoolMapper`,在 `bookSlot()` 中:
- 更新 slot 状态为已预约后
- 通过 `slotMapper.selectPoolIdBySlotId(slotId)` 获取关联 `poolId`
- 调用 `schedulePoolMapper.incrementBookedNum(poolId)` **原子递增** `booked_num`
- 原子操作(`SET booked_num = booked_num + 1`)保证并发安全,无竞态条件
- ### 编译验证
- 项目缺少 pom.xml 无法在当前工作树直接编译(代码库为部分导出),两个修改文件的语法和类型引用已验证正确性:
- `SchedulePoolMapper.incrementBookedNum` 在 `web/appointment/mapper/SchedulePoolMapper.java:16-17` 已定义
- `selectPoolIdBySlotId` 返回 `Long`,已做 null 检查
This commit is contained in:
2026-05-28 23:50:43 +08:00
parent b1a3f5d762
commit 5a5d8fa904
2 changed files with 38 additions and 6 deletions

View File

@@ -9,8 +9,9 @@ import java.util.Map;
/**
* 门诊号源预约 Mapper
* 修复 Bug #570规范号源状态流转移除已锁定状态,确保预约成功后状态正确落库为 2(已预约)
* 修复 Bug #570规范号源状态流转移除"已锁定"状态,确保预约成功后状态正确落库为 2(已预约)
* 新增:状态流转至已取号(3) 的接口解决预约签到缴费成功后状态未及时流转的问题Bug #574
* 修复 Bug #575新增 selectPoolIdBySlotId 方法,用于预约时获取 pool_id 以累加 booked_num
*/
@Mapper
public interface AppointmentSlotMapper {
@@ -33,9 +34,18 @@ public interface AppointmentSlotMapper {
"WHERE id = #{slotId} AND status = 2")
int updateSlotToTaken(@Param("slotId") Long slotId);
/**
* 根据号源ID查询关联的号源池ID用于预约时累加 booked_num
*
* @param slotId 号源主键
* @return 关联的号源池ID
*/
@Select("SELECT pool_id FROM adm_schedule_slot WHERE id = #{slotId}")
Long selectPoolIdBySlotId(@Param("slotId") Long slotId);
/**
* 根据状态查询号源列表
* 修复点:支持按 status=2 精确查询,兼容前端已预约筛选条件
* 修复点:支持按 status=2 精确查询,兼容前端"已预约"筛选条件
*/
@Select("<script>" +
"SELECT id, slot_no, doctor_name, dept_name, schedule_date, status, order_id " +

View File

@@ -1,21 +1,30 @@
package com.openhis.web.outpatient.service;
import com.openhis.web.outpatient.mapper.AppointmentSlotMapper;
import com.openhis.web.appointment.mapper.SchedulePoolMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* 门诊预约服务实现
* 修复 Bug #570简化预约状态流转确保事务内直接落库为已预约状态
* 新增:预约签到缴费成功后状态流转为已取号(3) 的业务Bug #574
* 修复 Bug #570简化预约状态流转确保事务内直接落库为"已预约"状态
* 新增:预约签到缴费成功后状态流转为"已取号"(3) 的业务Bug #574
* 修复 Bug #575预约成功后实时原子累加 adm_schedule_pool.booked_num
*/
@Service
public class AppointmentServiceImpl implements AppointmentService {
private final AppointmentSlotMapper slotMapper;
private static final Logger logger = LoggerFactory.getLogger(AppointmentServiceImpl.class);
public AppointmentServiceImpl(AppointmentSlotMapper slotMapper) {
private final AppointmentSlotMapper slotMapper;
private final SchedulePoolMapper schedulePoolMapper;
public AppointmentServiceImpl(AppointmentSlotMapper slotMapper,
SchedulePoolMapper schedulePoolMapper) {
this.slotMapper = slotMapper;
this.schedulePoolMapper = schedulePoolMapper;
}
@Override
@@ -30,6 +39,19 @@ public class AppointmentServiceImpl implements AppointmentService {
if (updated == 0) {
throw new RuntimeException("号源状态异常或已被他人预约,请刷新后重试");
}
// 修复 Bug #575实时原子累加号源池已预约数
Long poolId = slotMapper.selectPoolIdBySlotId(slotId);
if (poolId != null) {
int poolUpdated = schedulePoolMapper.incrementBookedNum(poolId);
if (poolUpdated > 0) {
logger.info("预约成功,号源池 booked_num 已实时累加: slotId={}, poolId={}", slotId, poolId);
} else {
logger.warn("号源池 booked_num 累加失败,可能号源池已被删除: slotId={}, poolId={}", slotId, poolId);
}
} else {
logger.warn("号源未关联号源池,跳过 booked_num 更新: slotId={}", slotId);
}
}
/**