教室预约
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
using Jiaowu.Api.Domain.Academic;
|
||||
using Jiaowu.Api.Infrastructure.Persistence;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Jiaowu.Api.Infrastructure.Timetables;
|
||||
|
||||
public sealed class ClassroomReservationAvailabilityService(AppDbContext db)
|
||||
{
|
||||
public async Task<HashSet<Guid>> GetOccupiedClassroomIdsAsync(
|
||||
AcademicTerm term,
|
||||
DateOnly reservationDate,
|
||||
int startPeriod,
|
||||
int periodCount,
|
||||
Guid? excludedReservationId,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var occupiedIds = new HashSet<Guid>();
|
||||
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)))
|
||||
{
|
||||
occupiedIds.Add(entry.ClassroomId!.Value);
|
||||
}
|
||||
|
||||
var examRoomIds = await db.ExamSessions.AsNoTracking()
|
||||
.Where(session =>
|
||||
session.ClassroomId.HasValue &&
|
||||
session.ExamPlan!.AcademicTermId == term.Id &&
|
||||
session.ExamPlan.Status == ExamPlanStatus.Published &&
|
||||
session.ExamDate == reservationDate &&
|
||||
session.StartPeriod < startPeriod + periodCount &&
|
||||
startPeriod < session.StartPeriod + session.PeriodCount)
|
||||
.Select(session => session.ClassroomId!.Value)
|
||||
.ToListAsync(cancellationToken);
|
||||
occupiedIds.UnionWith(examRoomIds);
|
||||
|
||||
var makeupExamRoomIds = await db.MakeupExamSessions.AsNoTracking()
|
||||
.Where(session =>
|
||||
session.ClassroomId.HasValue &&
|
||||
session.MakeupExamPlan!.AcademicTermId == term.Id &&
|
||||
session.MakeupExamPlan.Status == MakeupExamPlanStatus.Published &&
|
||||
session.ExamDate == reservationDate &&
|
||||
session.StartPeriod < startPeriod + periodCount &&
|
||||
startPeriod < session.StartPeriod + session.PeriodCount)
|
||||
.Select(session => session.ClassroomId!.Value)
|
||||
.ToListAsync(cancellationToken);
|
||||
occupiedIds.UnionWith(makeupExamRoomIds);
|
||||
|
||||
var reservationQuery = db.ClassroomReservations.AsNoTracking()
|
||||
.Where(reservation =>
|
||||
reservation.AcademicTermId == term.Id &&
|
||||
reservation.Status == ClassroomReservationStatus.Approved &&
|
||||
reservation.ReservationDate == reservationDate &&
|
||||
reservation.StartPeriod < startPeriod + periodCount &&
|
||||
startPeriod <
|
||||
reservation.StartPeriod + reservation.PeriodCount);
|
||||
if (excludedReservationId.HasValue)
|
||||
reservationQuery = reservationQuery.Where(reservation =>
|
||||
reservation.Id != excludedReservationId.Value);
|
||||
var reservationRoomIds = await reservationQuery
|
||||
.Select(reservation => reservation.ClassroomId)
|
||||
.ToListAsync(cancellationToken);
|
||||
occupiedIds.UnionWith(reservationRoomIds);
|
||||
return occupiedIds;
|
||||
}
|
||||
|
||||
public static (int Week, int DayOfWeek) ResolveTeachingWeek(
|
||||
AcademicTerm term,
|
||||
DateOnly date)
|
||||
{
|
||||
var termStartDay = (int)term.StartDate.DayOfWeek;
|
||||
var daysSinceMonday = (termStartDay + 6) % 7;
|
||||
var firstWeekMonday = term.StartDate.AddDays(-daysSinceMonday);
|
||||
var week = (date.DayNumber - firstWeekMonday.DayNumber) / 7 + 1;
|
||||
var dayOfWeek = ((int)date.DayOfWeek + 6) % 7 + 1;
|
||||
return (week, dayOfWeek);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user