实验成绩计算
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Data;
|
||||
using Jiaowu.Api.Domain.Academic;
|
||||
using Jiaowu.Api.Domain.Identity;
|
||||
using Jiaowu.Api.Infrastructure.Auth;
|
||||
@@ -138,7 +139,7 @@ public sealed class ExperimentGradesController(
|
||||
if (student is null)
|
||||
return ConflictProblem("当前账号未关联有效学生档案。");
|
||||
|
||||
return Ok(await db.ExperimentGradeRecords.AsNoTracking()
|
||||
var results = await db.ExperimentGradeRecords.AsNoTracking()
|
||||
.Where(x =>
|
||||
x.StudentId == student.Id &&
|
||||
x.ExperimentGradeSheet!.Status ==
|
||||
@@ -157,12 +158,19 @@ public sealed class ExperimentGradesController(
|
||||
ProjectName =
|
||||
x.ExperimentGradeSheet.ExperimentProject.Name,
|
||||
x.ExperimentGradeSheet.ExperimentProject.ArrangementMode,
|
||||
TeachingTaskId = x.ExperimentGradeSheet.ExperimentProject
|
||||
.TeachingTaskId,
|
||||
AcademicTermId = x.ExperimentGradeSheet.ExperimentProject
|
||||
.TeachingTask!.AcademicTermId,
|
||||
TaskNumber = x.ExperimentGradeSheet.ExperimentProject
|
||||
.TeachingTask.TaskNumber,
|
||||
CourseCode = x.ExperimentGradeSheet.ExperimentProject
|
||||
.TeachingTask!.Course!.Code,
|
||||
CourseName = x.ExperimentGradeSheet.ExperimentProject
|
||||
.TeachingTask.Course.Name,
|
||||
TermName = x.ExperimentGradeSheet.ExperimentProject
|
||||
.TeachingTask.AcademicTerm!.Name,
|
||||
x.ExperimentGradeSheet.ContributionWeight,
|
||||
x.ExperimentGradeSheet.PassScore,
|
||||
x.ParticipationStatus,
|
||||
x.TotalScore,
|
||||
@@ -187,7 +195,40 @@ public sealed class ExperimentGradesController(
|
||||
}),
|
||||
x.ExperimentGradeSheet.PublishedAt
|
||||
})
|
||||
.ToListAsync(cancellationToken));
|
||||
.ToListAsync(cancellationToken);
|
||||
var taskIds = results.Select(x => x.TeachingTaskId).Distinct().ToArray();
|
||||
var aggregates = await db.ExperimentCourseGrades.AsNoTracking()
|
||||
.Where(x =>
|
||||
x.StudentId == student.Id &&
|
||||
taskIds.Contains(x.TeachingTaskId))
|
||||
.ToDictionaryAsync(x => x.TeachingTaskId, cancellationToken);
|
||||
var courses = results
|
||||
.GroupBy(x => x.TeachingTaskId)
|
||||
.Select(group =>
|
||||
{
|
||||
var first = group.First();
|
||||
aggregates.TryGetValue(group.Key, out var aggregate);
|
||||
return new
|
||||
{
|
||||
TeachingTaskId = group.Key,
|
||||
first.AcademicTermId,
|
||||
first.TermName,
|
||||
first.TaskNumber,
|
||||
first.CourseCode,
|
||||
first.CourseName,
|
||||
ExperimentCourseScore = aggregate?.WeightedAverageScore,
|
||||
PublishedProjectCount =
|
||||
aggregate?.PublishedProjectCount ?? group.Count(),
|
||||
TotalWeight = aggregate?.TotalWeight ??
|
||||
group.Sum(x => x.ContributionWeight),
|
||||
RefreshedAt = aggregate?.RefreshedAt,
|
||||
Projects = group.OrderBy(x => x.ProjectCode).ToList()
|
||||
};
|
||||
})
|
||||
.OrderByDescending(x => x.Projects.Max(project => project.PublishedAt))
|
||||
.ThenBy(x => x.CourseCode)
|
||||
.ToList();
|
||||
return Ok(courses);
|
||||
}
|
||||
|
||||
[HttpPost("sheets")]
|
||||
@@ -744,7 +785,15 @@ public sealed class ExperimentGradesController(
|
||||
|
||||
sheet.Status = ExperimentGradeSheetStatus.Published;
|
||||
sheet.PublishedAt = DateTime.UtcNow;
|
||||
await db.SaveChangesAsync(cancellationToken);
|
||||
await db.ExecuteInRetriableTransactionAsync(async transaction =>
|
||||
{
|
||||
await db.SaveChangesAsync(cancellationToken);
|
||||
await ExperimentGradeAggregationService.RefreshTeachingTaskAsync(
|
||||
db,
|
||||
sheet.ExperimentProject!.TeachingTaskId,
|
||||
cancellationToken);
|
||||
await transaction.CommitAsync(cancellationToken);
|
||||
}, cancellationToken, IsolationLevel.Serializable);
|
||||
var userIds = await db.ExperimentGradeRecords
|
||||
.Where(x => x.ExperimentGradeSheetId == sheet.Id)
|
||||
.Select(x => x.Student!.UserId)
|
||||
|
||||
Reference in New Issue
Block a user