实验成绩导出

This commit is contained in:
biss committed 2026-08-21 17:51:33 +08:00
1 parent bcdb00ee2e
commit 4446cfbd30
3 files changed
+194

No files matched your search

@@ -190,6 +190,84 @@ public sealed class ExperimentGradesController(
});
}
[HttpGet("teaching-tasks/{teachingTaskId:guid}/export.xlsx")]
[Authorize(Roles = Managers)]
public async Task<IActionResult> ExportTeachingTaskScores(
Guid teachingTaskId,
CancellationToken cancellationToken)
{
var sheets = await ScopedSheets()
.Where(sheet =>
sheet.ExperimentProject!.TeachingTaskId == teachingTaskId)
.Include(sheet => sheet.Records)
.ThenInclude(record => record.Student)
.ThenInclude(student => student!.AdministrativeClass)
.Include(sheet => sheet.ExperimentProject)
.ThenInclude(project => project!.TeachingTask)
.ThenInclude(task => task!.AcademicTerm)
.Include(sheet => sheet.ExperimentProject)
.ThenInclude(project => project!.TeachingTask)
.ThenInclude(task => task!.Course)
.ThenInclude(course => course!.College)
.AsSplitQuery()
.AsNoTracking()
.OrderBy(sheet => sheet.ExperimentProject!.Code)
.ToListAsync(cancellationToken);
if (sheets.Count == 0)
return NotFound();
var task = sheets[0].ExperimentProject!.TeachingTask!;
var course = task.Course!;
var students = sheets
.SelectMany(sheet => sheet.Records)
.Select(record => record.Student!)
.GroupBy(student => student.Id)
.Select(group => group.First())
.OrderBy(student => student.StudentNumber)
.ToList();
var aggregate = await ExperimentGradeAggregationService.CalculateAsync(
db,
teachingTaskId,
students.Select(student => student.Id).ToArray(),
cancellationToken);
var headers = new List<string>
{
"学期", "开课学院", "课程代码", "课程名称", "教学班",
"学号", "姓名", "行政班"
};
headers.AddRange(sheets.Select(sheet =>
$"{sheet.ExperimentProject!.Code}·{sheet.ExperimentProject.Name}" +
$"({SheetStatusLabel(sheet.Status)})"));
headers.Add("实验合成总分(仅已发布项目)");
var rows = students.Select(student =>
{
var values = new List<object?>
{
task.AcademicTerm!.Name,
course.College!.Name,
course.Code,
course.Name,
task.TaskNumber,
student.StudentNumber,
student.Name,
student.AdministrativeClass!.Name
};
values.AddRange(sheets.Select(sheet => (object?)sheet.Records
.FirstOrDefault(record => record.StudentId == student.Id)
?.TotalScore));
values.Add(aggregate.Scores.GetValueOrDefault(student.Id));
return (IReadOnlyList<object?>)values;
}).ToList();
var bytes = ExcelWorkbookHelper.Create("课程实验成绩", headers, rows);
return File(bytes, ExcelWorkbookHelper.ContentType,
DownloadFileName.Export(
"课程实验成绩",
".xlsx",
course.Code,
task.TaskNumber));
}
[HttpGet("mine")]
[Authorize(Roles = SystemRoles.Student)]
public async Task<ActionResult> GetMine(CancellationToken cancellationToken)
@@ -1300,6 +1378,17 @@ public sealed class ExperimentGradesController(
_ => "待登记"
};
private static string SheetStatusLabel(ExperimentGradeSheetStatus status) =>
status switch
{
ExperimentGradeSheetStatus.Draft => "录入中",
ExperimentGradeSheetStatus.Submitted => "待审核",
ExperimentGradeSheetStatus.Approved => "审核通过",
ExperimentGradeSheetStatus.Published => "已发布",
ExperimentGradeSheetStatus.Returned => "已退回",
_ => status.ToString()
};
private static bool TryParseParticipationStatus(
ExcelRow row,
out ExperimentParticipationStatus status,