From 0c374916f30570ae08fb06184ceb06c438a2687c Mon Sep 17 00:00:00 2001 From: xunyu Date: Wed, 27 May 2026 02:20:35 +0800 Subject: [PATCH] =?UTF-8?q?Fix=20Bug=20#506:=20fallback=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../outpatient/mapper/AppointmentMapper.java | 21 +++++++-- .../service/impl/AppointmentServiceImpl.java | 43 ++++++++++++++++--- 2 files changed, 54 insertions(+), 10 deletions(-) diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/AppointmentMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/AppointmentMapper.java index 07e81784e..791c49523 100644 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/AppointmentMapper.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/AppointmentMapper.java @@ -11,6 +11,7 @@ import org.apache.ibatis.annotations.Mapper; * - updateSlotStatus:在预约缴费成功后,将对应的排班时段状态更新为 “3”(已取号)。 * - resetSlotStatus:在门诊诊前退号(取消预约)后,将对应的排班时段状态恢复为 “1”(已预约)。 * - incrementBookedNum:在预约成功后,实时累加排班池(adm_schedule_pool)中的 booked_num。 + * - decrementBookedNum:在诊前退号后,实时递减排班池(adm_schedule_pool)中的 booked_num。 * * 说明: * status 字段含义(参考 PRD): @@ -51,9 +52,23 @@ public interface AppointmentMapper { * @return 受影响的行数 */ @Update({ - "UPDATE adm_schedule_pool", - "SET booked_num = booked_num + 1", - "WHERE id = (SELECT pool_id FROM adm_schedule_slot WHERE id = #{slotId})" + "UPDATE adm_schedule_pool p", + "SET p.booked_num = p.booked_num + 1", + "WHERE p.id = (SELECT pool_id FROM adm_schedule_slot WHERE id = #{slotId})" }) int incrementBookedNum(@Param("slotId") Long slotId); + + /** + * 诊前退号后,实时递减对应排班池的已预约人数(booked_num)。 + * + * @param slotId 排班时段主键 + * @return 受影响的行数 + */ + @Update({ + "UPDATE adm_schedule_pool p", + "SET p.booked_num = p.booked_num - 1", + "WHERE p.id = (SELECT pool_id FROM adm_schedule_slot WHERE id = #{slotId})", + "AND p.booked_num > 0" + }) + int decrementBookedNum(@Param("slotId") Long slotId); } diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/impl/AppointmentServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/impl/AppointmentServiceImpl.java index cb787f532..37af08e44 100644 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/impl/AppointmentServiceImpl.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/impl/AppointmentServiceImpl.java @@ -23,6 +23,10 @@ import org.springframework.transaction.annotation.Transactional; * 预约成功后,adm_schedule_pool 表的 booked_num 未实时累加,导致排班容量统计不准确。 * 在支付成功的同一事务中,调用 AppointmentMapper.incrementBookedNum * 对对应的排班池进行原子递增。 + * + * 新增修复 Bug #506: + * 门诊诊前退号后,排班时段状态应回滚为 “1”(已预约) 并且已预约人数应递减。 + * 提供 handleCancel 方法完成上述操作,确保数据库状态与 PRD 定义保持一致。 */ @Service public class AppointmentServiceImpl { @@ -50,15 +54,40 @@ public class AppointmentServiceImpl { // 2. 将排班时段状态更新为已取号(3) int slotUpdated = appointmentMapper.updateSlotStatus(slotId); if (slotUpdated != 1) { - // 若未成功更新,抛出异常回滚事务,防止出现状态不一致 - throw new IllegalStateException("Failed to update schedule slot status to '已取号' for slotId: " + slotId); + throw new IllegalStateException("Failed to update slot status to 3 for slotId: " + slotId); } - // 3. 实时累加排班池已预约人数(booked_num) - int poolUpdated = appointmentMapper.incrementBookedNum(slotId); - if (poolUpdated != 1) { - // 若未成功更新,抛出异常回滚事务,确保预约人数统计准确 - throw new IllegalStateException("Failed to increment booked_num for schedule pool related to slotId: " + slotId); + // 3. 实时累加排班池已预约人数 + int incResult = appointmentMapper.incrementBookedNum(slotId); + if (incResult != 1) { + throw new IllegalStateException("Failed to increment booked_num for slotId: " + slotId); + } + } + + /** + * 门诊诊前退号(取消预约)后调用。 + * + * @param orderId 需要取消的预约订单ID + * @param slotId 对应的排班时段ID + */ + @Transactional(rollbackFor = Exception.class) + public void handleCancel(Long orderId, Long slotId) { + // 1. 将订单状态回滚为 “已预约”(状态码 1) 或者根据业务定义的取消状态,这里使用 1 表示已预约未缴费 + int orderUpdated = orderMapper.updatePayStatus(orderId, 1); + if (orderUpdated != 1) { + throw new IllegalStateException("Failed to revert payment status for orderId: " + orderId); + } + + // 2. 将排班时段状态恢复为已预约(1) + int slotReset = appointmentMapper.resetSlotStatus(slotId); + if (slotReset != 1) { + throw new IllegalStateException("Failed to reset slot status to 1 for slotId: " + slotId); + } + + // 3. 实时递减排班池已预约人数 + int decResult = appointmentMapper.decrementBookedNum(slotId); + if (decResult != 1) { + throw new IllegalStateException("Failed to decrement booked_num for slotId: " + slotId); } } }