修复Mysql

This commit is contained in:
2026-07-26 10:19:46 +08:00 Unverified
parent 634ef69a27
commit 72297aa23f
31 changed files with 1642 additions and 1192 deletions
@@ -44,8 +44,14 @@ public sealed class MakeupExamsController(
.ThenByDescending(x => x.CreatedAt)
.Select(x => new
{
x.Id, x.Name, x.AcademicTermId, TermName = x.AcademicTerm!.Name,
x.Status, SessionCount = x.Sessions.Count, x.Notes, x.PublishedAt
x.Id,
x.Name,
x.AcademicTermId,
TermName = x.AcademicTerm!.Name,
x.Status,
SessionCount = x.Sessions.Count,
x.Notes,
x.PublishedAt
}).ToListAsync(cancellationToken));
}
@@ -77,46 +83,51 @@ public sealed class MakeupExamsController(
.Where(x => x.Id == id && (manager || x.Status == MakeupExamPlanStatus.Published))
.Select(x => new
{
x.Id, x.Name, x.AcademicTermId, TermName = x.AcademicTerm!.Name,
x.Status, x.Notes, x.PublishedAt,
x.Id,
x.Name,
x.AcademicTermId,
TermName = x.AcademicTerm!.Name,
x.Status,
x.Notes,
x.PublishedAt,
Sessions = x.Sessions.OrderBy(item => item.ExamDate)
.ThenBy(item => item.StartPeriod).Select(item => new
{
item.Id,
item.TeachingTaskId,
item.TeachingTask!.TaskNumber,
TaskName = item.TeachingTask.Name,
CourseCode = item.TeachingTask.Course!.Code,
CourseName = item.TeachingTask.Course.Name,
item.ClassroomId,
ClassroomName = item.Classroom != null ? item.Classroom.Name : null,
BuildingName = item.Classroom != null ? item.Classroom.Building!.Name : null,
ClassroomCapacity = item.Classroom != null ? (int?)item.Classroom.Capacity : null,
item.ExamDate,
item.StartPeriod,
item.PeriodCount,
item.StartsAt,
item.EndsAt,
item.RequiredBuildingId,
RequiredBuildingName = item.RequiredBuilding != null
? item.RequiredBuilding.Name : null,
item.RequiredInvigilatorCount,
item.Notes,
InvigilatorIds = item.Invigilators.Select(i => i.TeacherId),
InvigilatorNames = item.Invigilators.Select(i => i.Teacher!.Name),
EnrolledCount = item.Enrollments.Count,
Enrollments = item.Enrollments.Select(e => new
{
e.StudentId,
e.Student!.StudentNumber,
e.Student.Name,
ClassName = e.Student.AdministrativeClass!.Name,
e.Reason,
e.SourceGradeRecordId,
e.SourceDeferredExamId,
e.MakeupScore
item.Id,
item.TeachingTaskId,
item.TeachingTask!.TaskNumber,
TaskName = item.TeachingTask.Name,
CourseCode = item.TeachingTask.Course!.Code,
CourseName = item.TeachingTask.Course.Name,
item.ClassroomId,
ClassroomName = item.Classroom != null ? item.Classroom.Name : null,
BuildingName = item.Classroom != null ? item.Classroom.Building!.Name : null,
ClassroomCapacity = item.Classroom != null ? (int?)item.Classroom.Capacity : null,
item.ExamDate,
item.StartPeriod,
item.PeriodCount,
item.StartsAt,
item.EndsAt,
item.RequiredBuildingId,
RequiredBuildingName = item.RequiredBuilding != null
? item.RequiredBuilding.Name : null,
item.RequiredInvigilatorCount,
item.Notes,
InvigilatorIds = item.Invigilators.Select(i => i.TeacherId),
InvigilatorNames = item.Invigilators.Select(i => i.Teacher!.Name),
EnrolledCount = item.Enrollments.Count,
Enrollments = item.Enrollments.Select(e => new
{
e.StudentId,
e.Student!.StudentNumber,
e.Student.Name,
ClassName = e.Student.AdministrativeClass!.Name,
e.Reason,
e.SourceGradeRecordId,
e.SourceDeferredExamId,
e.MakeupScore
})
})
})
}).FirstOrDefaultAsync(cancellationToken);
return plan is null ? NotFound() : Ok(plan);
}
@@ -311,8 +322,12 @@ public sealed class MakeupExamsController(
.OrderByDescending(x => x.CreatedAt)
.FirstOrDefaultAsync(cancellationToken);
if (existing is not null)
return Ok(new { jobId = existing.Id, status = existing.Status.ToString(),
message = "该计划已有正在执行的任务。" });
return Ok(new
{
jobId = existing.Id,
status = existing.Status.ToString(),
message = "该计划已有正在执行的任务。"
});
var job = new MakeupExamAutoJob
{
@@ -404,9 +419,9 @@ public sealed class MakeupExamsController(
// Check for time conflicts with other makeup sessions
var conflictIds = await db.MakeupExamEnrollments.AsNoTracking()
.Where(x => validIds.Contains(x.StudentId) &&
x.MakeupExamSession!.StartsAt < session.EndsAt &&
.Where(x => x.MakeupExamSession!.StartsAt < session.EndsAt &&
session.StartsAt < x.MakeupExamSession.EndsAt)
.WhereIn(validIds, x => x.StudentId)
.Select(x => x.StudentId)
.Distinct()
.ToListAsync(cancellationToken);
@@ -414,7 +429,7 @@ public sealed class MakeupExamsController(
if (conflictIds.Count > 0)
{
var conflictNumbers = await db.Students
.Where(s => conflictIds.Contains(s.Id))
.WhereIn(conflictIds, s => s.Id)
.Select(s => s.StudentNumber)
.ToListAsync(cancellationToken);
return ConflictProblem(
@@ -590,7 +605,7 @@ public sealed class MakeupExamsController(
.ToListAsync(cancellationToken);
if (occupiedIds.Count > 0)
query = query.Where(x => !occupiedIds.Contains(x.Id));
query = query.WhereNotIn(occupiedIds, x => x.Id);
return Ok(await query.OrderBy(x => x.Building!.Name)
.ThenBy(x => x.Capacity)
@@ -634,8 +649,8 @@ public sealed class MakeupExamsController(
.ToListAsync(cancellationToken);
return Ok(await db.Teachers.AsNoTracking()
.Where(x => x.Status == TeacherStatus.Active &&
!busyIds.Contains(x.Id))
.Where(x => x.Status == TeacherStatus.Active)
.WhereNotIn(busyIds, x => x.Id)
.OrderBy(x => x.Name)
.Select(x => new
{
@@ -845,8 +860,10 @@ public sealed class MakeupExamsController(
var teacherIds = (invigilatorIds ?? []).Distinct().ToArray();
if (teacherIds.Length > 0)
{
if (await db.Teachers.CountAsync(x => teacherIds.Contains(x.Id) &&
x.Status == TeacherStatus.Active, cancellationToken) != teacherIds.Length)
if (await db.Teachers
.Where(x => x.Status == TeacherStatus.Active)
.WhereIn(teacherIds, x => x.Id)
.CountAsync(cancellationToken) != teacherIds.Length)
return ValidationProblem("存在无效监考教师。");
}
@@ -862,9 +879,10 @@ public sealed class MakeupExamsController(
if (teacherIds.Length > 0)
{
if (await overlaps.AnyAsync(x =>
x.Invigilators.Any(i => teacherIds.Contains(i.TeacherId)),
cancellationToken))
if (await db.MakeupExamSessionInvigilators
.Where(i => overlaps.Any(x => x.Id == i.MakeupExamSessionId))
.WhereIn(teacherIds, i => i.TeacherId)
.AnyAsync(cancellationToken))
return ConflictProblem("监考教师在该时段已有补考任务。");
}