2.3.0-rc2

This commit is contained in:
biss committed 2026-08-04 10:48:08 +08:00
1 parent 6735a6d3fc
commit 10b51eb08a
19 files changed
+7292 -7

No files matched your search

@@ -1639,13 +1639,25 @@ public sealed class CourseSelectionsController(
var students = await LoadTeachingTaskRosterAsync(id, cancellationToken);
var bytes = ExcelWorkbookHelper.Create(
"教学班名单",
["学号", "姓名", "班级", "专业", "进入方式", "选课时间"],
[
"学号", "姓名", "班级", "专业", "联系电话", "电子邮箱",
"微信", "紧急联系人", "与本人关系", "紧急联系电话",
"特殊标记", "特殊情况说明", "进入方式", "选课时间"
],
students.Select(student => new List<object?>
{
student.StudentNumber,
student.Name,
student.ClassName,
student.MajorName,
student.Phone,
student.Email,
student.WeChat,
student.EmergencyContactName,
student.EmergencyContactRelationship,
student.EmergencyContactPhone,
student.SpecialTags,
student.SpecialNeeds,
student.EnrolledAt.HasValue ? "选课" : "行政班关联",
student.EnrolledAt?.ToString("yyyy-MM-dd HH:mm") ?? "-"
}).ToList<IReadOnlyList<object?>>());
@@ -1754,6 +1766,14 @@ public sealed class CourseSelectionsController(
x.Name,
x.AdministrativeClass!.Name,
x.AdministrativeClass.Major!.Name,
x.Phone,
x.Email,
x.WeChat,
x.EmergencyContactName,
x.EmergencyContactRelationship,
x.EmergencyContactPhone,
x.SpecialTags,
x.SpecialNeeds,
db.CourseEnrollments
.Where(enrollment =>
enrollment.StudentId == x.Id &&
@@ -2154,6 +2174,14 @@ public sealed class CourseSelectionsController(
string Name,
string ClassName,
string MajorName,
string? Phone,
string? Email,
string? WeChat,
string? EmergencyContactName,
string? EmergencyContactRelationship,
string? EmergencyContactPhone,
string? SpecialTags,
string? SpecialNeeds,
DateTime? EnrolledAt);
}
@@ -224,6 +224,12 @@ public sealed class PersonnelController(
[FromQuery] PersonnelQuery query,
CancellationToken cancellationToken)
{
var roles = currentUserDataScope.Current.Roles;
var canReadFullProfile = roles.Any(role =>
role is SystemRoles.SuperAdmin or
SystemRoles.AcademicAdmin or
SystemRoles.CollegeAdmin or
SystemRoles.Counselor);
var page = NormalizePage(query.Page);
var pageSize = NormalizePageSize(query.PageSize);
var source = ApplyStudentScope(db.Students.AsNoTracking());
@@ -268,9 +274,26 @@ public sealed class PersonnelController(
x.EnrollmentDate,
x.Status,
x.DateOfBirth,
EnglishName = canReadFullProfile ? x.EnglishName : null,
IdCardNumber = canReadFullProfile ? x.IdCardNumber : null,
Nationality = canReadFullProfile ? x.Nationality : null,
Ethnicity = canReadFullProfile ? x.Ethnicity : null,
PoliticalStatus = canReadFullProfile ? x.PoliticalStatus : null,
NativePlace = canReadFullProfile ? x.NativePlace : null,
HouseholdAddress = canReadFullProfile ? x.HouseholdAddress : null,
CurrentAddress = canReadFullProfile ? x.CurrentAddress : null,
PostalCode = canReadFullProfile ? x.PostalCode : null,
x.Phone,
x.Email,
x.Notes,
Qq = canReadFullProfile ? x.Qq : null,
x.WeChat,
x.EmergencyContactName,
x.EmergencyContactRelationship,
x.EmergencyContactPhone,
x.SpecialTags,
x.SpecialNeeds,
Biography = canReadFullProfile ? x.Biography : null,
Notes = canReadFullProfile ? x.Notes : null,
x.UserId,
x.CreatedAt
})
@@ -304,8 +327,26 @@ public sealed class PersonnelController(
EnrollmentDate = request.EnrollmentDate,
Status = request.Status,
DateOfBirth = request.DateOfBirth,
EnglishName = Normalize(request.EnglishName),
IdCardNumber = Normalize(request.IdCardNumber),
Nationality = Normalize(request.Nationality),
Ethnicity = Normalize(request.Ethnicity),
PoliticalStatus = Normalize(request.PoliticalStatus),
NativePlace = Normalize(request.NativePlace),
HouseholdAddress = Normalize(request.HouseholdAddress),
CurrentAddress = Normalize(request.CurrentAddress),
PostalCode = Normalize(request.PostalCode),
Phone = Normalize(request.Phone),
Email = Normalize(request.Email),
Qq = Normalize(request.Qq),
WeChat = Normalize(request.WeChat),
EmergencyContactName = Normalize(request.EmergencyContactName),
EmergencyContactRelationship = Normalize(
request.EmergencyContactRelationship),
EmergencyContactPhone = Normalize(request.EmergencyContactPhone),
SpecialTags = Normalize(request.SpecialTags),
SpecialNeeds = Normalize(request.SpecialNeeds),
Biography = Normalize(request.Biography),
Notes = Normalize(request.Notes)
};
db.Students.Add(entity);
@@ -343,8 +384,26 @@ public sealed class PersonnelController(
entity.EnrollmentDate = request.EnrollmentDate;
entity.Status = request.Status;
entity.DateOfBirth = request.DateOfBirth;
entity.EnglishName = Normalize(request.EnglishName);
entity.IdCardNumber = Normalize(request.IdCardNumber);
entity.Nationality = Normalize(request.Nationality);
entity.Ethnicity = Normalize(request.Ethnicity);
entity.PoliticalStatus = Normalize(request.PoliticalStatus);
entity.NativePlace = Normalize(request.NativePlace);
entity.HouseholdAddress = Normalize(request.HouseholdAddress);
entity.CurrentAddress = Normalize(request.CurrentAddress);
entity.PostalCode = Normalize(request.PostalCode);
entity.Phone = Normalize(request.Phone);
entity.Email = Normalize(request.Email);
entity.Qq = Normalize(request.Qq);
entity.WeChat = Normalize(request.WeChat);
entity.EmergencyContactName = Normalize(request.EmergencyContactName);
entity.EmergencyContactRelationship = Normalize(
request.EmergencyContactRelationship);
entity.EmergencyContactPhone = Normalize(request.EmergencyContactPhone);
entity.SpecialTags = Normalize(request.SpecialTags);
entity.SpecialNeeds = Normalize(request.SpecialNeeds);
entity.Biography = Normalize(request.Biography);
entity.Notes = Normalize(request.Notes);
return await SaveNoContentAsync(cancellationToken);
}
@@ -522,8 +581,25 @@ public sealed record StudentRequest(
DateOnly EnrollmentDate,
StudentStatus Status,
DateOnly? DateOfBirth,
[MaxLength(100)] string? EnglishName,
[MaxLength(30)] string? IdCardNumber,
[MaxLength(50)] string? Nationality,
[MaxLength(50)] string? Ethnicity,
[MaxLength(50)] string? PoliticalStatus,
[MaxLength(100)] string? NativePlace,
[MaxLength(300)] string? HouseholdAddress,
[MaxLength(300)] string? CurrentAddress,
[MaxLength(20)] string? PostalCode,
[MaxLength(30)] string? Phone,
[EmailAddress, MaxLength(100)] string? Email,
[MaxLength(30)] string? Qq,
[MaxLength(60)] string? WeChat,
[MaxLength(50)] string? EmergencyContactName,
[MaxLength(30)] string? EmergencyContactRelationship,
[MaxLength(30)] string? EmergencyContactPhone,
[MaxLength(300)] string? SpecialTags,
[MaxLength(1000)] string? SpecialNeeds,
[MaxLength(1000)] string? Biography,
[MaxLength(500)] string? Notes);
public sealed record TeacherAccountActivationRequest(
@@ -31,6 +31,9 @@ public sealed class PersonnelExcelController(
SystemRoles.AcademicAdmin + "," +
SystemRoles.CollegeAdmin;
private const string ExportRoles =
WriteRoles + "," + SystemRoles.Counselor;
private static readonly string[] TeacherHeaders =
[
"工号", "姓名", "性别", "学院编码", "职称", "任职状态",
@@ -40,7 +43,10 @@ public sealed class PersonnelExcelController(
private static readonly string[] StudentHeaders =
[
"学号", "姓名", "性别", "行政班编码", "入学年级", "入学日期",
"学籍状态", "出生日期", "联系电话", "电子邮箱", "备注"
"学籍状态", "出生日期", "英文姓名", "证件号码", "国籍", "民族",
"政治面貌", "籍贯", "户籍地址", "现居住地址", "邮政编码",
"联系电话", "电子邮箱", "QQ", "微信", "紧急联系人", "与本人关系",
"紧急联系电话", "特殊标记", "特殊情况说明", "个人简介", "备注"
];
[HttpGet("{kind}/template")]
@@ -66,6 +72,7 @@ public sealed class PersonnelExcelController(
}
[HttpGet("{kind}/export")]
[Authorize(Roles = ExportRoles)]
public async Task<IActionResult> Export(
string kind,
[FromQuery] PersonnelQuery query,
@@ -96,7 +103,12 @@ public sealed class PersonnelExcelController(
.Select(x => Row(
x.StudentNumber, x.Name, GenderName(x.Gender),
x.AdministrativeClass!.Code, x.EnrollmentYear, x.EnrollmentDate,
StudentStatusName(x.Status), x.DateOfBirth, x.Phone, x.Email, x.Notes))
StudentStatusName(x.Status), x.DateOfBirth, x.EnglishName,
x.IdCardNumber, x.Nationality, x.Ethnicity, x.PoliticalStatus,
x.NativePlace, x.HouseholdAddress, x.CurrentAddress, x.PostalCode,
x.Phone, x.Email, x.Qq, x.WeChat, x.EmergencyContactName,
x.EmergencyContactRelationship, x.EmergencyContactPhone,
x.SpecialTags, x.SpecialNeeds, x.Biography, x.Notes))
.ToList();
}
@@ -296,8 +308,25 @@ public sealed class PersonnelExcelController(
entity.EnrollmentDate = enrollmentDate.Value;
entity.Status = status.Value;
entity.DateOfBirth = dateOfBirth;
entity.EnglishName = Optional(row, "英文姓名");
entity.IdCardNumber = Optional(row, "证件号码");
entity.Nationality = Optional(row, "国籍");
entity.Ethnicity = Optional(row, "民族");
entity.PoliticalStatus = Optional(row, "政治面貌");
entity.NativePlace = Optional(row, "籍贯");
entity.HouseholdAddress = Optional(row, "户籍地址");
entity.CurrentAddress = Optional(row, "现居住地址");
entity.PostalCode = Optional(row, "邮政编码");
entity.Phone = Optional(row, "联系电话");
entity.Email = Optional(row, "电子邮箱");
entity.Qq = Optional(row, "QQ");
entity.WeChat = Optional(row, "微信");
entity.EmergencyContactName = Optional(row, "紧急联系人");
entity.EmergencyContactRelationship = Optional(row, "与本人关系");
entity.EmergencyContactPhone = Optional(row, "紧急联系电话");
entity.SpecialTags = Optional(row, "特殊标记");
entity.SpecialNeeds = Optional(row, "特殊情况说明");
entity.Biography = Optional(row, "个人简介");
entity.Notes = Optional(row, "备注");
}
return new(created, updated, rows.Count);
Loaded 3 of 19 files, more files were not shown because too many files have changed in this diff. Show more