课程库 Excel 导入导出已完成:
支持下载标准导入模板。 导出严格沿用当前关键词、学院、分类、课程性质和状态筛选。 以课程编码为唯一键:存在则更新,不存在则新增。 校验学院编码、课程分类、课程性质、学分学时及考核方式。 整批原子导入,任一行错误则全部不写入,并提示具体行号。 学院管理员仍只能维护本学院的专业课和实践课,无法借 Excel 越权。 界面入口沿用现有课程库工具栏样式。
This commit is contained in:
@@ -5,6 +5,61 @@ namespace Jiaowu.Api.Tests;
|
||||
|
||||
public sealed class GraduationAuditRulesTests
|
||||
{
|
||||
[Fact]
|
||||
public void Curriculum_groups_Accept_Any_Options_That_Fulfill_Required_Credits()
|
||||
{
|
||||
var football = new Course { Code = "PE101", Name = "足球", Credits = 1 };
|
||||
var basketball = new Course { Code = "PE102", Name = "篮球", Credits = 1 };
|
||||
var swimming = new Course { Code = "PE103", Name = "游泳", Credits = 1 };
|
||||
var module = new CurriculumModule
|
||||
{
|
||||
Code = "SPORTS",
|
||||
Name = "大学体育",
|
||||
RequiredCredits = 2,
|
||||
Courses = [Option(football), Option(basketball), Option(swimming)]
|
||||
};
|
||||
|
||||
var completed = CurriculumCompletionRules.Evaluate(
|
||||
[module],
|
||||
new HashSet<Guid>([football.Id, swimming.Id]));
|
||||
var incomplete = CurriculumCompletionRules.Evaluate(
|
||||
[module],
|
||||
new HashSet<Guid>([football.Id]));
|
||||
|
||||
Assert.Equal(1, completed.RequirementCount);
|
||||
Assert.Equal(1, completed.PassedRequirementCount);
|
||||
Assert.Empty(completed.MissingRequirements);
|
||||
Assert.Equal(0, incomplete.PassedRequirementCount);
|
||||
Assert.Contains("大学体育(还差 1 学分)", incomplete.MissingRequirements);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Curriculum_groups_Still_Require_Every_Fixed_Course()
|
||||
{
|
||||
var ideology = new Course { Code = "MORAL101", Name = "思想道德与法治", Credits = 3 };
|
||||
var module = new CurriculumModule
|
||||
{
|
||||
Code = "MORAL",
|
||||
Name = "德育课程",
|
||||
RequiredCredits = 3,
|
||||
Courses =
|
||||
[
|
||||
new CurriculumCourse
|
||||
{
|
||||
CourseId = ideology.Id,
|
||||
Course = ideology,
|
||||
Type = CurriculumCourseType.Required
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
var result = CurriculumCompletionRules.Evaluate([module], new HashSet<Guid>());
|
||||
|
||||
Assert.Equal(1, result.RequirementCount);
|
||||
Assert.Equal(0, result.PassedRequirementCount);
|
||||
Assert.Contains("思想道德与法治", result.MissingRequirements);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Active_student_with_full_credits_and_courses_is_eligible()
|
||||
{
|
||||
@@ -35,4 +90,12 @@ public sealed class GraduationAuditRulesTests
|
||||
|
||||
Assert.Equal(GraduationAuditConclusion.Ineligible, conclusion);
|
||||
}
|
||||
|
||||
private static CurriculumCourse Option(Course course) =>
|
||||
new()
|
||||
{
|
||||
CourseId = course.Id,
|
||||
Course = course,
|
||||
Type = CurriculumCourseType.Elective
|
||||
};
|
||||
}
|
||||
|
||||
@@ -111,6 +111,12 @@ public sealed class PersistenceTests : IAsyncLifetime
|
||||
Nature = CourseNature.MajorRequired,
|
||||
AssessmentMethod = AssessmentMethod.Examination
|
||||
};
|
||||
var category = new CourseCategory
|
||||
{
|
||||
Code = "BASIC",
|
||||
Name = "基础课程"
|
||||
};
|
||||
course.CourseCategoryId = category.Id;
|
||||
var teacher = new Teacher
|
||||
{
|
||||
TeacherNumber = "T2026001",
|
||||
@@ -148,6 +154,7 @@ public sealed class PersistenceTests : IAsyncLifetime
|
||||
counselor,
|
||||
administrativeClass,
|
||||
teacher,
|
||||
category,
|
||||
new Student
|
||||
{
|
||||
StudentNumber = "202601001",
|
||||
@@ -237,7 +244,10 @@ public sealed class PersistenceTests : IAsyncLifetime
|
||||
var savedClass = await _db.AdministrativeClasses
|
||||
.Include(x => x.CounselorUser)
|
||||
.SingleAsync();
|
||||
var savedCourse = await _db.Courses.Include(x => x.College).SingleAsync();
|
||||
var savedCourse = await _db.Courses
|
||||
.Include(x => x.College)
|
||||
.Include(x => x.CourseCategory)
|
||||
.SingleAsync();
|
||||
var curriculumPlan = await _db.CurriculumPlans
|
||||
.Include(x => x.Modules)
|
||||
.ThenInclude(x => x.Courses)
|
||||
@@ -255,6 +265,7 @@ public sealed class PersistenceTests : IAsyncLifetime
|
||||
Assert.Equal("计算机科学与技术", student.AdministrativeClass!.Major!.Name);
|
||||
Assert.Equal("陈老师", savedClass.CounselorUser!.DisplayName);
|
||||
Assert.Equal(4m, savedCourse.Credits);
|
||||
Assert.Equal("基础课程", savedCourse.CourseCategory!.Name);
|
||||
Assert.Equal(savedCourse.TotalHours, savedCourse.LectureHours + savedCourse.PracticeHours);
|
||||
Assert.Single(curriculumPlan.Modules);
|
||||
Assert.Single(curriculumPlan.Modules.Single().Courses);
|
||||
|
||||
Reference in New Issue
Block a user