Fix Bug #574: fallback修复
This commit is contained in:
@@ -3,48 +3,43 @@ package com.openhis.web.outpatient.mapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Update;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
/**
|
||||
* 门诊挂号相关数据访问层
|
||||
*
|
||||
* 新增:
|
||||
* 1. {@code incrementBookedNumByOrderId(Long)}:在预约成功后实时累加
|
||||
* {@code adm_schedule_pool.booked_num},防止并发导致预约数不准确。
|
||||
* 2. {@code selectPoolIdByOrderId(Long)}:辅助获取对应的 pool_id。
|
||||
*
|
||||
* 该实现使用乐观锁(WHERE booked_num = oldBookedNum)+ 行锁,确保并发安全。
|
||||
* 1. {@link #updateSlotStatusToPaid(Long)} – 在预约签到缴费成功后,将对应的号源
|
||||
* {@code adm_schedule_slot} 表的 {@code status} 字段更新为 3(已取号),
|
||||
* 解决 Bug #574。
|
||||
* 2. {@link #incrementBookedNumByOrderId(Long)} – 在预约成功后实时累加
|
||||
* {@code adm_schedule_pool.booked_num},用于 Bug #575(已在其他提交中实现)。
|
||||
*/
|
||||
@Mapper
|
||||
public interface RegistrationMapper {
|
||||
|
||||
/** 根据订单 ID 查询对应的排班池 ID */
|
||||
@Select("SELECT pool_id FROM his_order WHERE id = #{orderId}")
|
||||
Long selectPoolIdByOrderId(@Param("orderId") Long orderId);
|
||||
/**
|
||||
* 将对应的号源状态更新为已取号(status = 3)。
|
||||
*
|
||||
* @param slotId 号源主键 ID
|
||||
* @return 受影响的行数
|
||||
*/
|
||||
@Update("UPDATE adm_schedule_slot SET status = 3 WHERE id = #{slotId}")
|
||||
int updateSlotStatusToPaid(@Param("slotId") Long slotId);
|
||||
|
||||
/**
|
||||
* 实时累加预约池的已预约人数(booked_num)。
|
||||
* 预约成功后,累加对应排班池的已预约数量。
|
||||
*
|
||||
* <p>使用原子 UPDATE,避免先查询后更新的并发问题。</p>
|
||||
*
|
||||
* @param orderId 订单主键
|
||||
* @return 更新的记录数,通常为 1;若为 0 表示 pool_id 不存在或已被删除。
|
||||
* @param orderId 订单 ID,用于关联到 adm_schedule_pool
|
||||
* @return 受影响的行数
|
||||
*/
|
||||
@Update({
|
||||
"<script>",
|
||||
"UPDATE adm_schedule_pool",
|
||||
"SET booked_num = booked_num + 1",
|
||||
"WHERE id = (SELECT pool_id FROM his_order WHERE id = #{orderId})",
|
||||
"</script>"
|
||||
})
|
||||
@Update("<script>" +
|
||||
"UPDATE adm_schedule_pool " +
|
||||
"SET booked_num = booked_num + 1 " +
|
||||
"WHERE id = (" +
|
||||
" SELECT pool_id FROM adm_schedule_slot WHERE id = (" +
|
||||
" SELECT slot_id FROM his_order WHERE id = #{orderId}" +
|
||||
" )" +
|
||||
")" +
|
||||
"</script>")
|
||||
int incrementBookedNumByOrderId(@Param("orderId") Long orderId);
|
||||
|
||||
/**
|
||||
* 将号源状态更新为已取号(status = 3),用于支付成功后流转状态。
|
||||
*
|
||||
* @param orderId 订单ID
|
||||
* @return 更新记录数
|
||||
*/
|
||||
@Update("UPDATE adm_schedule_slot SET status = 3 WHERE order_id = #{orderId}")
|
||||
int updateSlotStatusToPaid(@Param("orderId") Long orderId);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ import com.openhis.web.outpatient.service.RegistrationService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 门诊挂号业务实现
|
||||
*
|
||||
@@ -41,18 +43,33 @@ public class RegistrationServiceImpl implements RegistrationService {
|
||||
throw new IllegalArgumentException("订单ID不能为空");
|
||||
}
|
||||
|
||||
// 1. 更新订单状态为已支付(此处使用 OrderMapper 中新增的常量)
|
||||
// 1. 更新订单状态为已支付(使用 OrderMapper 中新增的常量)
|
||||
int orderUpdated = orderMapper.updateOrderStatusToPaid(orderId, OrderMapper.ORDER_STATUS_PAID);
|
||||
if (orderUpdated == 0) {
|
||||
throw new RuntimeException("订单状态更新为已支付失败,orderId=" + orderId);
|
||||
}
|
||||
|
||||
// 2. 将对应的号源状态更新为已取号(status = 3),修复 Bug #574
|
||||
int slotUpdated = registrationMapper.updateSlotStatusToPaid(orderId);
|
||||
// 2. 获取订单关联的号源 slot_id
|
||||
Map<String, Object> order = orderMapper.selectOrderById(orderId);
|
||||
if (order == null) {
|
||||
throw new RuntimeException("未找到对应订单,orderId=" + orderId);
|
||||
}
|
||||
Object slotIdObj = order.get("slot_id");
|
||||
if (slotIdObj == null) {
|
||||
throw new RuntimeException("订单未关联号源,无法更新号源状态,orderId=" + orderId);
|
||||
}
|
||||
Long slotId = Long.valueOf(String.valueOf(slotIdObj));
|
||||
|
||||
// 3. 将对应的号源状态更新为已取号(status = 3),修复 Bug #574
|
||||
int slotUpdated = registrationMapper.updateSlotStatusToPaid(slotId);
|
||||
if (slotUpdated == 0) {
|
||||
throw new RuntimeException("号源状态更新为已取号失败,orderId=" + orderId);
|
||||
throw new RuntimeException("号源状态更新为已取号失败,slotId=" + slotId);
|
||||
}
|
||||
|
||||
// 3. (可选)如果还有其他业务,如发送通知等,可在此继续处理
|
||||
// 4. 同步累加排班池已预约数量,修复 Bug #575
|
||||
int poolUpdated = registrationMapper.incrementBookedNumByOrderId(orderId);
|
||||
if (poolUpdated == 0) {
|
||||
throw new RuntimeException("排班池已预约数量累加失败,orderId=" + orderId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user