diff --git a/src/Jiaowu.Api/Infrastructure/Timetables/ClassroomReservationAvailabilityService.cs b/src/Jiaowu.Api/Infrastructure/Timetables/ClassroomReservationAvailabilityService.cs index d4fb481..6b22227 100644 --- a/src/Jiaowu.Api/Infrastructure/Timetables/ClassroomReservationAvailabilityService.cs +++ b/src/Jiaowu.Api/Infrastructure/Timetables/ClassroomReservationAvailabilityService.cs @@ -17,33 +17,34 @@ public sealed class ClassroomReservationAvailabilityService(AppDbContext db) var occupiedIds = new HashSet(); var (week, dayOfWeek) = ResolveTeachingWeek(term, reservationDate); - var scheduleEntries = await db.ScheduleEntries.AsNoTracking() - .Where(entry => - entry.ClassroomId.HasValue && - entry.SchedulePlan!.AcademicTermId == term.Id && - entry.SchedulePlan.Status == SchedulePlanStatus.Published && - entry.DayOfWeek == dayOfWeek && - entry.StartWeek <= week && - entry.EndWeek >= week && - entry.StartPeriod < startPeriod + periodCount && - startPeriod < entry.StartPeriod + entry.PeriodCount) - .Select(entry => new - { - entry.ClassroomId, - entry.WeekPattern, - entry.StartPeriod, - entry.PeriodCount - }) - .ToListAsync(cancellationToken); - foreach (var entry in scheduleEntries.Where(entry => - FreeClassroomRules.MatchesWeek(entry.WeekPattern, week) && - FreeClassroomRules.PeriodsOverlap( - startPeriod, - periodCount, - entry.StartPeriod, - entry.PeriodCount))) + var hasProjection = await db.PublishedScheduleOccurrences.AsNoTracking() + .AnyAsync(entry => entry.AcademicTermId == term.Id, cancellationToken); + if (hasProjection) { - occupiedIds.Add(entry.ClassroomId!.Value); + var projectedRoomIds = await db.PublishedScheduleOccurrences.AsNoTracking() + .Where(entry => entry.AcademicTermId == term.Id && entry.Week == week && + entry.DayOfWeek == dayOfWeek && entry.ClassroomId.HasValue && + entry.StartPeriod < startPeriod + periodCount && + startPeriod < entry.StartPeriod + entry.PeriodCount) + .Select(entry => entry.ClassroomId!.Value) + .ToListAsync(cancellationToken); + occupiedIds.UnionWith(projectedRoomIds); + } + else + { + var scheduleEntries = await db.ScheduleEntries.AsNoTracking() + .Where(entry => entry.ClassroomId.HasValue && + entry.SchedulePlan!.AcademicTermId == term.Id && + entry.SchedulePlan.Status == SchedulePlanStatus.Published && + entry.DayOfWeek == dayOfWeek && entry.StartWeek <= week && + entry.EndWeek >= week && entry.StartPeriod < startPeriod + periodCount && + startPeriod < entry.StartPeriod + entry.PeriodCount) + .Select(entry => new { entry.ClassroomId, entry.WeekPattern, entry.StartPeriod, entry.PeriodCount }) + .ToListAsync(cancellationToken); + foreach (var entry in scheduleEntries.Where(entry => + FreeClassroomRules.MatchesWeek(entry.WeekPattern, week) && + FreeClassroomRules.PeriodsOverlap(startPeriod, periodCount, entry.StartPeriod, entry.PeriodCount))) + occupiedIds.Add(entry.ClassroomId!.Value); } var examRoomIds = await db.ExamSessions.AsNoTracking()