260 预约管理-》医生排班管理:系统未正确限制同一天同一时段(上午/下午)的重复排班,导致同一医生在同一时间段可被多次排班,产生数据冲突和资源调度混乱

This commit is contained in:
HuangXinQuan
2026-03-24 11:51:17 +08:00
parent 4060be4de7
commit 4e58601b2c
2 changed files with 128 additions and 11 deletions

View File

@@ -163,6 +163,30 @@ public class DoctorScheduleAppServiceImpl implements IDoctorScheduleAppService {
return R.fail("限号数量必须大于0");
}
// 检查结束时间必须大于开始时间
if (doctorSchedule.getStartTime() != null && doctorSchedule.getEndTime() != null) {
if (!doctorSchedule.getStartTime().isBefore(doctorSchedule.getEndTime())) {
return R.fail("结束时间必须大于开始时间");
}
}
// 检查时间重叠(同一医生、同一天时间段有重叠)
if (doctorSchedule.getDoctorId() != null && scheduledDate != null
&& doctorSchedule.getStartTime() != null && doctorSchedule.getEndTime() != null) {
LocalDate scheduleDate = LocalDate.parse(scheduledDate);
boolean hasOverlap = checkTimeOverlap(
doctorSchedule.getDoctorId(),
scheduleDate,
doctorSchedule.getStartTime(),
doctorSchedule.getEndTime()
);
if (hasOverlap) {
return R.fail("该医生在 " + scheduledDate + ""
+ doctorSchedule.getStartTime() + "-" + doctorSchedule.getEndTime()
+ " 时间段与已有排班重叠,不能重复添加");
}
}
// 创建新对象排除id字段数据库id列是GENERATED ALWAYS由数据库自动生成
DoctorSchedule newSchedule = new DoctorSchedule();
newSchedule.setWeekday(doctorSchedule.getWeekday());
@@ -381,6 +405,42 @@ public class DoctorScheduleAppServiceImpl implements IDoctorScheduleAppService {
return slots;
}
/**
* 检查同一医生、同一天、同时段是否已存在排班
*
* @param doctorId 医生ID
* @param scheduleDate 出诊日期
* @param timePeriod 时段(上午/下午)
* @return true表示存在重复排班false表示不存在
*/
// private boolean checkDuplicateSchedule(Long doctorId, LocalDate scheduleDate, String timePeriod) {
// return schedulePoolService.lambdaQuery()
// .eq(SchedulePool::getDoctorId, doctorId)
// .eq(SchedulePool::getScheduleDate, scheduleDate)
// .eq(SchedulePool::getShift, timePeriod)
// .exists();
// }
/**
* 检查同一医生、同一天是否有时间重叠的排班
* 重叠判断startA < endB AND startB < endA即时间段有交集
*
* @param doctorId 医生ID
* @param scheduleDate 出诊日期
* @param startTime 开始时间
* @param endTime 结束时间
* @return true表示存在时间重叠false表示不重叠
*/
private boolean checkTimeOverlap(Long doctorId, LocalDate scheduleDate,
LocalTime startTime, LocalTime endTime) {
return schedulePoolService.lambdaQuery()
.eq(SchedulePool::getDoctorId, doctorId)
.eq(SchedulePool::getScheduleDate, scheduleDate)
.lt(SchedulePool::getStartTime, endTime) // 已有开始时间 < 新结束时间
.gt(SchedulePool::getEndTime, startTime) // 已有结束时间 > 新开始时间
.exists();
}
/**
* 根据星期几计算具体日期(下周的对应星期)
*/