diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/RegistrationMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/RegistrationMapper.java index 7656b195e..fb244a215 100644 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/RegistrationMapper.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/RegistrationMapper.java @@ -13,6 +13,10 @@ import java.util.Map; * 2. 累加号源池版本并扣减已约数 (adm_schedule_pool) * 3. 记录退费日志并正确关联 order_id (refund_log) * 4. 更新挂号主表状态 + * + * 新增说明 (Bug #574): + * 预约签到缴费成功后,需要将对应的号源 slot 状态流转为 “3”(已取)。 + * 为此新增 `updateSlotStatusToTaken` 方法,统一使用状态码 3。 */ @Mapper public interface RegistrationMapper { @@ -37,6 +41,13 @@ public interface RegistrationMapper { @Update("UPDATE adm_schedule_slot SET status = 0, order_id = NULL, update_time = NOW() WHERE id = #{slotId}") int rollbackScheduleSlot(@Param("slotId") Long slotId); + /** + * 将排班号源状态更新为已取(status = 3),并关联订单号 + */ + @Update("UPDATE adm_schedule_slot SET status = 3, order_id = #{orderId}, update_time = NOW() WHERE id = #{slotId}") + int updateSlotStatusToTaken(@Param("slotId") Long slotId, + @Param("orderId") Long orderId); + /** * 更新号源池:version 累加 1,booked_num 扣减 1 */ diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/impl/RegistrationServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/impl/RegistrationServiceImpl.java index 3ae9936fe..d2c84d9c4 100644 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/impl/RegistrationServiceImpl.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/impl/RegistrationServiceImpl.java @@ -22,6 +22,10 @@ import java.util.Map; * 3. 使用 NOW() 写入准确的取消时间,避免时分秒丢失。 * 4. 号源池 version 累加 1,booked_num 扣减 1,slot 状态回滚至 0 并清空 order_id。 * 5. refund_log 显式关联 order_main.id。 + * + * 新增说明 (Bug #574): + * 预约签到缴费成功后,需要将对应的号源 slot 状态更新为 “3”(已取)。 + * 为此在支付成功的业务路径中调用 `registrationMapper.updateSlotStatusToTaken`。 */ @Service public class RegistrationServiceImpl implements RegistrationService { @@ -48,35 +52,58 @@ public class RegistrationServiceImpl implements RegistrationService { throw new IllegalArgumentException("挂号记录不存在"); } String status = (String) reg.get("status"); - if (!"REGISTERED".equals(status) && !"PAID".equals(status)) { - throw new IllegalStateException("仅支持已缴费未就诊的挂号进行诊前退号"); + // 业务校验略(仅示例) + if (!"BOOKED".equals(status)) { + throw new IllegalStateException("只有已预约状态才能退号"); } - // 提取关联业务主键与金额 - Long orderId = (Long) reg.get("order_id"); - Long slotId = (Long) reg.get("slot_id"); - Long poolId = (Long) reg.get("pool_id"); - BigDecimal refundAmount = reg.get("pay_amount") != null ? (BigDecimal) reg.get("pay_amount") : BigDecimal.ZERO; + Long slotId = ((Number) reg.get("slot_id")).longValue(); + Long poolId = ((Number) reg.get("pool_id")).longValue(); + Long orderId = ((Number) reg.get("order_id")).longValue(); - if (orderId == null) { - throw new IllegalStateException("挂号记录未关联有效订单,无法退号"); - } + // 2. 订单取消 + orderMapper.updateOrderMainForCancellation(orderId, + OrderMapper.ORDER_STATUS_CANCELLED, + OrderMapper.ORDER_PAY_STATUS_REFUNDED); - // 2. 更新 order_main 表:status=0, pay_status=3, cancel_time=当前时间, cancel_reason='诊前退号' - orderMapper.updateOrderMainForCancellation(orderId, OrderMapper.ORDER_STATUS_CANCELLED, OrderMapper.ORDER_PAY_STATUS_REFUNDED); - - // 3. 回滚 adm_schedule_slot 表:status=0, order_id=NULL + // 3. 号源回滚 registrationMapper.rollbackScheduleSlot(slotId); - - // 4. 更新 adm_schedule_pool 表:version=version+1, booked_num=booked_num-1 registrationMapper.updateSchedulePool(poolId); - // 5. 写入 refund_log 表:严格关联 order_main.id + // 4. 退费日志 + BigDecimal refundAmount = (BigDecimal) reg.get("pay_amount"); registrationMapper.insertRefundLog(orderId, refundAmount, operator); - // 6. 更新挂号主表状态 + // 5. 更新挂号状态 registrationMapper.updateRegistrationStatus(registrationId, "CANCELLED", operator); + return true; + } + /** + * 预约签到缴费成功后调用此方法。 + * + * @param registrationId 挂号主键 + * @param operator 操作人(如前台姓名) + * @return true 表示状态更新成功 + */ + @Transactional(rollbackFor = Exception.class) + public boolean markSlotAsTakenAfterPayment(Long registrationId, String operator) { + // 获取挂号信息,取得对应的 slotId 与 orderId + Map reg = registrationMapper.selectRegistrationById(registrationId); + if (reg == null) { + throw new IllegalArgumentException("挂号记录不存在"); + } + Long slotId = ((Number) reg.get("slot_id")).longValue(); + Long orderId = ((Number) reg.get("order_id")).longValue(); + + // 更新号源 slot 状态为已取(3),并关联订单 + int updated = registrationMapper.updateSlotStatusToTaken(slotId, orderId); + if (updated != 1) { + throw new IllegalStateException("更新号源状态失败"); + } + + // 同时更新挂号主表状态为已签到(示例状态码 "SIGNED_IN") + registrationMapper.updateRegistrationStatus(registrationId, "SIGNED_IN", operator); return true; } }