This commit is contained in:
biss committed 2026-08-12 11:39:30 +08:00
1 parent e5afe60a11
commit 7994ed1ed3
8 files changed
+408 -13

No files matched your search

@@ -4,6 +4,7 @@ using Jiaowu.Api.Domain.Academic;
using Jiaowu.Api.Domain.Identity;
using Jiaowu.Api.Infrastructure.Auth;
using Jiaowu.Api.Infrastructure.Caching;
using Jiaowu.Api.Infrastructure.Academic;
using Jiaowu.Api.Infrastructure.Persistence;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
@@ -302,6 +303,30 @@ public sealed class PersonnelController(
return Ok(new PagedResult<object>(items, total, page, pageSize));
}
[HttpGet("students/current-courses")]
public async Task<ActionResult> GetStudentCurrentCourses(
[FromQuery] Guid[] studentIds,
CancellationToken cancellationToken)
{
var requestedIds = studentIds.Distinct().Take(100).ToArray();
if (requestedIds.Length == 0) return Ok(Array.Empty<object>());
var students = await ApplyStudentScope(db.Students.AsNoTracking())
.WhereIn(requestedIds, x => x.Id)
.Select(x => new CurrentCourseStudent(x.Id, x.AdministrativeClassId))
.ToListAsync(cancellationToken);
var summaries = await StudentCurrentCourseQuery.GetAsync(
db,
students,
cancellationToken);
return Ok(students.Select(student => new
{
student.Id,
CurrentCourses = summaries[student.Id].Courses,
summaries[student.Id].TotalCredits
}));
}
[HttpPost("students")]
[Authorize(Roles = WriteRoles)]
public async Task<ActionResult> CreateStudent(
@@ -2,6 +2,7 @@ using Jiaowu.Api.Domain.Academic;
using Jiaowu.Api.Domain.Identity;
using Jiaowu.Api.Infrastructure.Auth;
using Jiaowu.Api.Infrastructure.Caching;
using Jiaowu.Api.Infrastructure.Academic;
using Jiaowu.Api.Infrastructure.Excel;
using Jiaowu.Api.Infrastructure.Persistence;
using Microsoft.AspNetCore.Authorization;
@@ -49,6 +50,11 @@ public sealed class PersonnelExcelController(
"紧急联系电话", "特殊标记", "特殊情况说明", "个人简介", "备注"
];
private static readonly string[] StudentCurrentCourseHeaders =
[
"学号", "姓名", "学院", "专业", "行政班", "正在修读课程", "学分", "总学分"
];
[HttpGet("{kind}/template")]
[Authorize(Roles = WriteRoles)]
public IActionResult DownloadTemplate(string kind)
@@ -117,6 +123,60 @@ public sealed class PersonnelExcelController(
$"{RegistryName(kind)}-{DateTime.Now:yyyyMMdd-HHmm}.xlsx");
}
[HttpGet("students/current-courses/export")]
[Authorize(Roles = ExportRoles)]
public async Task<IActionResult> ExportStudentCurrentCourses(
[FromQuery] PersonnelQuery query,
[FromQuery] Guid[]? studentIds,
CancellationToken cancellationToken)
{
var source = ApplyStudentFilters(
ApplyStudentScope(db.Students.AsNoTracking()),
query);
var selectedIds = studentIds?.Distinct().ToArray() ?? [];
if (selectedIds.Length > 0)
source = source.WhereIn(selectedIds, x => x.Id);
var students = await source.OrderBy(x => x.StudentNumber)
.Select(x => new
{
x.Id,
x.StudentNumber,
x.Name,
x.AdministrativeClassId,
ClassName = x.AdministrativeClass!.Name,
MajorName = x.AdministrativeClass.Major!.Name,
CollegeName = x.AdministrativeClass.Major.College!.Name
})
.ToListAsync(cancellationToken);
var summaries = await StudentCurrentCourseQuery.GetAsync(
db,
students.Select(x => new CurrentCourseStudent(x.Id, x.AdministrativeClassId))
.ToList(),
cancellationToken);
var rows = students.Select(student =>
{
var summary = summaries[student.Id];
return Row(
student.StudentNumber,
student.Name,
student.CollegeName,
student.MajorName,
student.ClassName,
string.Join(";", summary.Courses.Select(course =>
$"{course.CourseCode} {course.CourseName}")),
string.Join(";", summary.Courses.Select(course =>
$"{course.Credits:0.##}")),
summary.TotalCredits);
}).ToList();
var bytes = ExcelWorkbookHelper.Create(
"学生正在修读课程",
StudentCurrentCourseHeaders,
rows);
return File(bytes, ExcelWorkbookHelper.ContentType,
$"学生正在修读课程-{DateTime.Now:yyyyMMdd-HHmm}.xlsx");
}
[HttpPost("{kind}/import")]
[Authorize(Roles = WriteRoles)]
[RequestSizeLimit(10 * 1024 * 1024)]