变更摘要:考试安排注入课表
问题根因
TimetableDataService.LoadExamEntriesAsync 只查询旧的 ExamSession(legacy 直接分配教室),完全忽略自动编排生成的
ExamRoomAssignment(混排考场),导致:
┌──────────┬──────────────────────────┬───────────────────────────────────┐
│ 课表类型 │ 之前 │ 之后 │
├──────────┼──────────────────────────┼───────────────────────────────────┤
│ 教室课表 │ return [] 硬编码空数组 │ 查询 legacy + mixed room 两类数据 │
├──────────┼──────────────────────────┼───────────────────────────────────┤
│ 教师课表 │ 只显示监考 │ 监考 + 自己授课的考试 │
├──────────┼──────────────────────────┼───────────────────────────────────┤
│ 学生课表 │ 只通过 CourseEnrollments │ 同时查 ExamSeats(座位分配) │
├──────────┼──────────────────────────┼───────────────────────────────────┤
│ 空闲教室 │ 只排除 legacy 考试占用 │ 同时排除混排考场占用 │
└──────────┴──────────────────────────┴───────────────────────────────────┘
修改的文件
1. TimetableDataService.cs — 重写 LoadExamEntriesAsync
- 拆分为两个数据源:legacy ExamSessions + mixed ExamRoomAssignment(通过 ExamRoomSession 关联)
- 新增 ApplyLegacyResourceFilter / ApplyMixedResourceFilter
两个过滤方法,按资源类型(Classroom/Teacher/Student/Class)分别过滤
- 新增 MapToEntryDto 统一映射到 TimetableEntryDto
- 新增 ExamSessionProjection record 统一两个数据源的投影
各资源类型的数据来源:
┌───────────┬────────────────────────────────┬──────────────────────────────────────┐
│ 资源类型 │ Legacy 过滤 │ Mixed-room 过滤 │
├───────────┼────────────────────────────────┼──────────────────────────────────────┤
│ Classroom │ ExamSessions.ClassroomId == id │ ExamRoom.ClassroomId == id │
├───────────┼────────────────────────────────┼──────────────────────────────────────┤
│ Teacher │ 监考 + 授课教师 │ 监考 + 授课教师 │
├───────────┼────────────────────────────────┼──────────────────────────────────────┤
│ Student │ CourseEnrollments + 行政班 │ ExamSeats.StudentId │
├───────────┼────────────────────────────────┼──────────────────────────────────────┤
│ Class │ TeachingTask.Classes │ SessionLinks → ExamSession → Classes │
└───────────┴────────────────────────────────┴──────────────────────────────────────┘
2. ClassroomReservationAvailabilityService.cs — 补充混排考场占用
在 GetOccupiedClassroomIdsAsync 新增 ExamRoomAssignment 查询,空闲教室查询现在会正确排除混排考场占用的教室。
3. TimetablesController.cs — 课表选项含考试学期
- 学期级的 HasPublishedTimetable 增加 ExamPlans.Status == Published 判断
- 班级级的 HasPublishedTimetable 增加 ExamSessions 关联判断