补考、缓考成绩自动替换
This commit is contained in:
1 parent
d7d2560587
commit
51b83e9d78
7 files changed
+122
-20
No files matched your search
@@ -754,6 +754,27 @@ public sealed class MakeupExamsController(
|
||||
}
|
||||
|
||||
var enrollmentByStudent = session.Enrollments.ToDictionary(e => e.StudentId);
|
||||
var unresolvedStudentIds = scores
|
||||
.Where(x => enrollmentByStudent.TryGetValue(x.StudentId, out var enrollment) &&
|
||||
!enrollment.SourceGradeRecordId.HasValue)
|
||||
.Select(x => x.StudentId)
|
||||
.Distinct()
|
||||
.ToArray();
|
||||
var fallbackGradeRecordIds = unresolvedStudentIds.Length == 0
|
||||
? new Dictionary<Guid, Guid>()
|
||||
: (await db.GradeRecords.AsNoTracking()
|
||||
.Where(x => x.GradeSheet!.TeachingTaskId == session.TeachingTaskId)
|
||||
.WhereIn(unresolvedStudentIds, x => x.StudentId)
|
||||
.OrderByDescending(x => x.UpdatedAt)
|
||||
.Select(x => new { x.StudentId, x.Id })
|
||||
.ToListAsync(cancellationToken))
|
||||
.GroupBy(x => x.StudentId)
|
||||
.ToDictionary(x => x.Key, x => x.First().Id);
|
||||
var missingReplacementTargets = unresolvedStudentIds
|
||||
.Where(studentId => !fallbackGradeRecordIds.ContainsKey(studentId))
|
||||
.ToArray();
|
||||
if (missingReplacementTargets.Length > 0)
|
||||
return ConflictProblem("存在无法关联原课程成绩的补考考生,不能录入补考成绩。请先建立该教学班成绩单后重试。");
|
||||
|
||||
foreach (var entry in scores)
|
||||
{
|
||||
@@ -762,22 +783,54 @@ public sealed class MakeupExamsController(
|
||||
|
||||
enrollment.MakeupScore = entry.Score;
|
||||
|
||||
// Backfill legacy deferred-exam enrollments created before they
|
||||
// carried SourceGradeRecordId, then use the same replacement
|
||||
// path as absent and failed candidates.
|
||||
if (!enrollment.SourceGradeRecordId.HasValue &&
|
||||
fallbackGradeRecordIds.TryGetValue(entry.StudentId, out var fallbackGradeRecordId))
|
||||
enrollment.SourceGradeRecordId = fallbackGradeRecordId;
|
||||
|
||||
// Update the grade record — 补考合格按60分记
|
||||
if (enrollment.SourceGradeRecordId.HasValue)
|
||||
{
|
||||
var record = await db.GradeRecords
|
||||
.Include(x => x.GradeSheet)
|
||||
.ThenInclude(x => x!.Items)
|
||||
.Include(x => x.ItemScores)
|
||||
.FirstOrDefaultAsync(x => x.Id == enrollment.SourceGradeRecordId.Value,
|
||||
cancellationToken);
|
||||
if (record is not null)
|
||||
{
|
||||
record.ExamStatus = GradeExamStatus.Makeup;
|
||||
// Cap passing score at 60
|
||||
var cappedScore = entry.Score >= 60 ? 60m : entry.Score;
|
||||
record.TotalScore = cappedScore;
|
||||
record.GradePoint = GradeCalculator.CalculateGradePoint(cappedScore);
|
||||
record.Notes = entry.Score >= 60
|
||||
? $"补考合格(原始{entry.Score}分,按60分记)"
|
||||
: $"补考不合格({entry.Score}分)";
|
||||
if (enrollment.Reason == MakeupReason.DeferredApproved &&
|
||||
record.GradeSheet is not null)
|
||||
{
|
||||
// A deferred exam is a later sitting of the normal
|
||||
// final. Its score therefore combines with the
|
||||
// already-entered regular and component scores.
|
||||
record.ExamStatus = GradeExamStatus.Deferred;
|
||||
record.FinalScore = entry.Score;
|
||||
record.TotalScore = GradeCalculator.CalculateTotal(
|
||||
record.RegularScore,
|
||||
record.FinalScore,
|
||||
record.ItemScores.ToList(),
|
||||
record.GradeSheet.RegularWeight,
|
||||
record.GradeSheet.FinalWeight,
|
||||
record.GradeSheet.Items.ToList(),
|
||||
record.ExamStatus);
|
||||
record.GradePoint = GradeCalculator.CalculateGradePoint(record.TotalScore);
|
||||
record.Notes = $"缓考成绩(期末{entry.Score}分,已按正常权重计入平时分)";
|
||||
}
|
||||
else
|
||||
{
|
||||
record.ExamStatus = GradeExamStatus.Makeup;
|
||||
// Cap passing score at 60
|
||||
var cappedScore = entry.Score >= 60 ? 60m : entry.Score;
|
||||
record.TotalScore = cappedScore;
|
||||
record.GradePoint = GradeCalculator.CalculateGradePoint(cappedScore);
|
||||
record.Notes = entry.Score >= 60
|
||||
? $"补考合格(原始{entry.Score}分,按60分记)"
|
||||
: $"补考不合格({entry.Score}分)";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user