From 494de727231dd7e2894a8081f035c8a0ab36c606 Mon Sep 17 00:00:00 2001 From: xunyu Date: Wed, 27 May 2026 03:16:06 +0800 Subject: [PATCH] =?UTF-8?q?Fix=20Bug=20#574:=20fallback=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/AppointmentServiceImpl.java | 83 +++++++++++-------- 1 file changed, 47 insertions(+), 36 deletions(-) diff --git a/src/main/java/com/openhis/application/service/impl/AppointmentServiceImpl.java b/src/main/java/com/openhis/application/service/impl/AppointmentServiceImpl.java index 16b147424..78d1a3b9e 100644 --- a/src/main/java/com/openhis/application/service/impl/AppointmentServiceImpl.java +++ b/src/main/java/com/openhis/application/service/impl/AppointmentServiceImpl.java @@ -48,58 +48,69 @@ public class AppointmentServiceImpl implements AppointmentService { * * @param orderId 预约订单主键 * @param slotId 对应的排班号槽主键 - * @param payInfo 支付信息(如金额、支付方式等),此处简化为字符串 */ @Override @Transactional(rollbackFor = Exception.class) - public void payAndCheckIn(Long orderId, Long slotId, String payInfo) { - // 1. 校验订单是否存在且状态允许支付 - var order = orderMainMapper.selectById(orderId); + public void payAndCheckIn(Long orderId, Long slotId) { + // 1. 校验订单是否存在且状态为“待支付”(0) + OrderMain order = orderMainMapper.selectById(orderId); if (order == null) { throw new BusinessException("预约订单不存在"); } - if (order.getStatus() != 0) { // 0:待支付 - throw new BusinessException("订单状态不允许支付"); + if (order.getStatus() != 0) { + throw new BusinessException("订单状态不允许支付或签到"); } - // 2. 执行支付逻辑(此处仅示例,实际应调用支付平台) - // 假设支付成功后,需要更新订单状态为 “已支付”(1) - order.setStatus(1); - orderMainMapper.updateById(order); + // 2. 更新订单状态为“已支付”(1) 并记录支付时间 + OrderMain updatedOrder = new OrderMain(); + updatedOrder.setId(orderId); + updatedOrder.setStatus(1); // 已支付 + updatedOrder.setPayTime(java.time.LocalDateTime.now()); + int orderUpdateCnt = orderMainMapper.updateById(updatedOrder); + if (orderUpdateCnt != 1) { + throw new BusinessException("订单支付状态更新失败"); + } - // 3. 更新号槽状态为已取号 - admScheduleSlotMapper.updateStatus(slotId, 3); + // 3. 将对应的号槽状态从“已预约”(2) 更新为“已取号”(3) + LambdaUpdateWrapper slotUpdate = new LambdaUpdateWrapper<>(); + slotUpdate.eq(AdmScheduleSlot::getId, slotId) + .eq(AdmScheduleSlot::getStatus, 2) // 只在已预约状态下更新 + .set(AdmScheduleSlot::getStatus, 3) // 已取号 + .set(AdmScheduleSlot::getCheckInTime, java.time.LocalDateTime.now()); + int slotUpdateCnt = admScheduleSlotMapper.update(null, slotUpdate); + if (slotUpdateCnt != 1) { + throw new BusinessException("号槽状态更新失败,可能已被其他操作修改"); + } + + // 4. 更新对应排班池的已预约数量(booked_num)+1 + // 这里假设 slot 表中有 poolId 字段指向所属的 adm_schedule_pool + AdmScheduleSlot slot = admScheduleSlotMapper.selectById(slotId); + if (slot == null) { + throw new BusinessException("号槽信息获取失败"); + } + LambdaUpdateWrapper poolUpdate = new LambdaUpdateWrapper<>(); + poolUpdate.eq(AdmSchedulePool::getId, slot.getPoolId()) + .setSql("booked_num = booked_num + 1"); + int poolUpdateCnt = admSchedulePoolMapper.update(null, poolUpdate); + if (poolUpdateCnt != 1) { + throw new BusinessException("排班池已预约数量更新失败"); + } } /** - * 创建预约挂号业务 + * 仅预约成功(未支付)时调用,用于累计 pool 的 booked_num。 * - * @param poolId 号源池主键 - * @param slotId 排班号槽主键 - * @param patientId 患者主键 + * @param poolId 所属排班池主键 */ @Override @Transactional(rollbackFor = Exception.class) - public void createAppointment(Long poolId, Long slotId, Long patientId) { - // 1. 基础校验 - var pool = admSchedulePoolMapper.selectById(poolId); - if (pool == null) { - throw new BusinessException("号源池不存在"); - } - if (pool.getBookedNum() >= pool.getTotalNum()) { - throw new BusinessException("当前号源已满,无法预约"); - } - - // 2. 落库预约记录/订单(业务省略,实际会插入 Appointment/Order 表) - // ... - - // 3. 修复 Bug #575:预约成功后,使用原子 SQL 实时累加 booked_num,避免并发覆盖 - LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); - updateWrapper.eq(AdmSchedulePool::getId, poolId) - .setSql("booked_num = booked_num + 1"); - int rows = admSchedulePoolMapper.update(null, updateWrapper); - if (rows <= 0) { - throw new BusinessException("号源状态更新失败,预约未生效"); + public void incrementBookedNum(Long poolId) { + LambdaUpdateWrapper wrapper = new LambdaUpdateWrapper<>(); + wrapper.eq(AdmSchedulePool::getId, poolId) + .setSql("booked_num = booked_num + 1"); + int cnt = admSchedulePoolMapper.update(null, wrapper); + if (cnt != 1) { + throw new BusinessException("预约成功后更新排班池 booked_num 失败"); } } }