bug343:门诊预约挂号:系统未校验重复预约,允许同一患者在同一科室同一天/时间段内多次预约

This commit is contained in:
2026-04-08 10:04:30 +08:00
parent e7413396b2
commit 5d280640e8
3 changed files with 25 additions and 14 deletions

View File

@@ -44,10 +44,12 @@ public interface OrderMapper extends BaseMapper<Order> {
int updatePayStatus(@Param("orderId") Long orderId, @Param("payStatus") Integer payStatus, @Param("payTime") Date payTime); int updatePayStatus(@Param("orderId") Long orderId, @Param("payStatus") Integer payStatus, @Param("payTime") Date payTime);
/** /**
* 统计同一患者在同一科室、同一时段(上午/下午)内的有效预约订单数量 * 统计同一患者在同一科室、同一自然日(预约日 00:00次日 00:00)内的有效预约订单数量
* 匹配规则:优先 {@code department_id}(对应 adm_organization.id仅当 ID 为空时用 {@code department_name} 兜底。
* *
* @param patientId 患者ID * @param patientId 患者ID
* @param departmentId 科室ID * @param departmentId 科室 IDorder_main.department_id
* @param departmentName 科室名称ID 为空时与 order_main.department_name 比对)
* @param startTime 时段起始时间(含) * @param startTime 时段起始时间(含)
* @param endTime 时段结束时间(不含) * @param endTime 时段结束时间(不含)
* @param statuses 订单状态集合(如 1=已预约,2=已取号) * @param statuses 订单状态集合(如 1=已预约,2=已取号)
@@ -55,6 +57,7 @@ public interface OrderMapper extends BaseMapper<Order> {
*/ */
int countPatientDeptOrdersInPeriod(@Param("patientId") Long patientId, int countPatientDeptOrdersInPeriod(@Param("patientId") Long patientId,
@Param("departmentId") Long departmentId, @Param("departmentId") Long departmentId,
@Param("departmentName") String departmentName,
@Param("startTime") Date startTime, @Param("startTime") Date startTime,
@Param("endTime") Date endTime, @Param("endTime") Date endTime,
@Param("statuses") List<Integer> statuses); @Param("statuses") List<Integer> statuses);

View File

@@ -183,25 +183,23 @@ public class TicketServiceImpl extends ServiceImpl<TicketMapper, Ticket> impleme
throw new RuntimeException("该排班医生已停诊"); throw new RuntimeException("该排班医生已停诊");
} }
// 2.1 同一患者同一天/同一科室/同一时段(上午/下午)不可重复预约 // 2.1 同一患者同一天/同一科室不可重复预约(自然日 00:00次日 00:00上午+下午共限 1 次;科室以 department_id 为准,无 ID 时用科室名兜底)
if (dto.getPatientId() != null && slot.getDepartmentId() != null && slot.getScheduleDate() != null && slot.getExpectTime() != null) { if (dto.getPatientId() != null && slot.getScheduleDate() != null
boolean isMorning = slot.getExpectTime().isBefore(LocalTime.NOON); && (slot.getDepartmentId() != null
|| (slot.getDepartmentName() != null && !slot.getDepartmentName().isBlank()))) {
LocalDate scheduleDateForCheck = slot.getScheduleDate(); LocalDate scheduleDateForCheck = slot.getScheduleDate();
LocalDateTime periodStart = isMorning LocalDateTime periodStart = LocalDateTime.of(scheduleDateForCheck, LocalTime.MIN);
? LocalDateTime.of(scheduleDateForCheck, LocalTime.MIN) LocalDateTime periodEnd = LocalDateTime.of(scheduleDateForCheck.plusDays(1), LocalTime.MIN);
: LocalDateTime.of(scheduleDateForCheck, LocalTime.NOON);
LocalDateTime periodEnd = isMorning
? LocalDateTime.of(scheduleDateForCheck, LocalTime.NOON)
: LocalDateTime.of(scheduleDateForCheck.plusDays(1), LocalTime.MIN);
Date startTime = Date.from(periodStart.atZone(ZoneId.systemDefault()).toInstant()); Date startTime = Date.from(periodStart.atZone(ZoneId.systemDefault()).toInstant());
Date endTime = Date.from(periodEnd.atZone(ZoneId.systemDefault()).toInstant()); Date endTime = Date.from(periodEnd.atZone(ZoneId.systemDefault()).toInstant());
// 预约去重以订单为准order_main因为预约成功会先落订单clinical_ticket 不一定在此链路写入 // 预约去重以订单为准order_main因为预约成功会先落订单clinical_ticket 不一定在此链路写入
List<Integer> effectiveOrderStatuses = Arrays.asList(AppointmentOrderStatus.BOOKED, AppointmentOrderStatus.CHECKED_IN); List<Integer> effectiveOrderStatuses = Arrays.asList(AppointmentOrderStatus.BOOKED, AppointmentOrderStatus.CHECKED_IN);
int exists = orderMapper.countPatientDeptOrdersInPeriod(dto.getPatientId(), slot.getDepartmentId(), startTime, endTime, effectiveOrderStatuses); int exists = orderMapper.countPatientDeptOrdersInPeriod(dto.getPatientId(), slot.getDepartmentId(), slot.getDepartmentName(),
startTime, endTime, effectiveOrderStatuses);
if (exists > 0) { if (exists > 0) {
throw new RuntimeException("该患者已在当前科室该时段存在预约记录,不可重复预约"); throw new RuntimeException("该患者已在当前科室当日存在预约记录,不可重复预约");
} }
} }

View File

@@ -222,7 +222,17 @@
from order_main from order_main
<where> <where>
and patient_id = #{patientId} and patient_id = #{patientId}
<choose>
<when test="departmentId != null">
and department_id = #{departmentId} and department_id = #{departmentId}
</when>
<when test="departmentName != null and departmentName != ''">
and trim(department_name) = trim(#{departmentName})
</when>
<otherwise>
and 1 = 0
</otherwise>
</choose>
and appointment_time &gt;= #{startTime} and appointment_time &gt;= #{startTime}
and appointment_time &lt; #{endTime} and appointment_time &lt; #{endTime}
<if test="statuses != null and statuses.size() &gt; 0"> <if test="statuses != null and statuses.size() &gt; 0">