From e39ab4579f13cb859014710933de7c7de44f59c8 Mon Sep 17 00:00:00 2001 From: biss Date: Sun, 9 Aug 2026 16:04:17 +0800 Subject: [PATCH] =?UTF-8?q?=E7=A9=BA=E9=97=B2=E6=95=99=E5=AE=A4=E4=B8=8E?= =?UTF-8?q?=E5=9C=BA=E5=9C=B0=E9=A2=84=E7=BA=A6=E5=8D=A0=E7=94=A8=E6=A3=80?= =?UTF-8?q?=E6=9F=A5=EF=BC=8C=E7=8E=B0=E5=9C=A8=E5=AF=B9=E6=96=B0=E5=8F=91?= =?UTF-8?q?=E5=B8=83=E8=AF=BE=E8=A1=A8=E4=BC=98=E5=85=88=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=20PublishedScheduleOccurrences=E3=80=82=20=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E7=9B=B4=E6=8E=A5=E6=8C=89=E2=80=9C=E5=AD=A6=E6=9C=9F=20+=20?= =?UTF-8?q?=E5=91=A8=E6=AC=A1=20+=20=E6=98=9F=E6=9C=9F=20+=20=E8=8A=82?= =?UTF-8?q?=E6=AC=A1=E2=80=9D=E5=91=BD=E4=B8=AD=E6=8A=95=E5=BD=B1=E7=B4=A2?= =?UTF-8?q?=E5=BC=95=EF=BC=8C=E4=B8=8D=E5=86=8D=E6=89=AB=E6=8F=8F=E5=91=A8?= =?UTF-8?q?=E6=9C=9F=E8=A7=84=E5=88=99=E5=B9=B6=E5=9C=A8=E5=BA=94=E7=94=A8?= =?UTF-8?q?=E5=B1=82=E5=88=A4=E6=96=AD=E5=8D=95=E5=8F=8C=E5=91=A8=E3=80=82?= =?UTF-8?q?=20=E5=8E=86=E5=8F=B2=E5=B7=B2=E5=8F=91=E5=B8=83=E8=AF=BE?= =?UTF-8?q?=E8=A1=A8=E8=8B=A5=E5=B0=9A=E6=9C=AA=E7=94=9F=E6=88=90=E6=8A=95?= =?UTF-8?q?=E5=BD=B1=EF=BC=8C=E8=87=AA=E5=8A=A8=E5=9B=9E=E9=80=80=E5=88=B0?= =?UTF-8?q?=E5=8E=9F=E8=A7=84=E5=88=99=E8=A1=A8=EF=BC=8C=E5=85=BC=E5=AE=B9?= =?UTF-8?q?=E7=8E=B0=E6=9C=89=E6=95=B0=E6=8D=AE=E3=80=82=20=E8=B0=83?= =?UTF-8?q?=E5=81=9C=E8=AF=BE=E5=AE=A1=E6=89=B9=E5=90=8E=E4=BC=9A=E9=87=8D?= =?UTF-8?q?=E5=BB=BA=E5=8F=97=E5=BD=B1=E5=93=8D=E6=95=99=E5=AD=A6=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E7=9A=84=E5=B7=B2=E5=8F=91=E5=B8=83=E6=8A=95=E5=BD=B1?= =?UTF-8?q?=EF=BC=8C=E5=9B=A0=E6=AD=A4=E5=8D=A0=E7=94=A8=E7=BB=93=E6=9E=9C?= =?UTF-8?q?=E5=90=8C=E6=AD=A5=E6=9B=B4=E6=96=B0=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...ClassroomReservationAvailabilityService.cs | 53 ++++++++++--------- 1 file changed, 27 insertions(+), 26 deletions(-) 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()