空闲教室与场地预约占用检查,现在对新发布课表优先查询 PublishedScheduleOccurrences。
查询直接按“学期 + 周次 + 星期 + 节次”命中投影索引,不再扫描周期规则并在应用层判断单双周。 历史已发布课表若尚未生成投影,自动回退到原规则表,兼容现有数据。 调停课审批后会重建受影响教学任务的已发布投影,因此占用结果同步更新。
This commit is contained in:
+27
-26
@@ -17,33 +17,34 @@ public sealed class ClassroomReservationAvailabilityService(AppDbContext db)
|
|||||||
var occupiedIds = new HashSet<Guid>();
|
var occupiedIds = new HashSet<Guid>();
|
||||||
var (week, dayOfWeek) = ResolveTeachingWeek(term, reservationDate);
|
var (week, dayOfWeek) = ResolveTeachingWeek(term, reservationDate);
|
||||||
|
|
||||||
var scheduleEntries = await db.ScheduleEntries.AsNoTracking()
|
var hasProjection = await db.PublishedScheduleOccurrences.AsNoTracking()
|
||||||
.Where(entry =>
|
.AnyAsync(entry => entry.AcademicTermId == term.Id, cancellationToken);
|
||||||
entry.ClassroomId.HasValue &&
|
if (hasProjection)
|
||||||
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 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()
|
var examRoomIds = await db.ExamSessions.AsNoTracking()
|
||||||
|
|||||||
Reference in New Issue
Block a user