已把选课的“年级划分”和限制规则补成完整闭环:

选课批次可指定多个适用年级;留空兼容原有“全部年级”。
新增可选的“最多课程门数”,与原有学分上限并行。
年级、门数限制统一作用于学生可见批次、自主选课、候补、管理员代选和自动递补。
普通候选名单遵守年级及行政班范围;强制选课可绕过业务限制,但仍严格遵守管理员学院权限。
管理页面会展示“2026 级 · 最多 6 门 · 最多 30 学分”,名单和候补列表也增加年级列。
新增 MySQL 迁移:[CourseSelectionGradeLimits.cs](E:/jiaowu/src/Jiaowu.Api/Infrastructure/Persistence/Migrations/MySql/20260726180000_CourseSelectionGradeLimits.cs)。
This commit is contained in:
2026-07-26 16:12:21 +08:00 Unverified
parent 56b13b3adb
commit f62cd21319
11 changed files with 4920 additions and 25 deletions
@@ -40,13 +40,13 @@ namespace Jiaowu.Api.Infrastructure.Persistence.Migrations.MySql
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime(6)");
b.Property<DateOnly>("EndDate")
b.Property<DateTime>("EndDate")
.HasColumnType("date");
b.Property<bool>("IsCurrent")
b.Property<bool>("IsArchived")
.HasColumnType("tinyint(1)");
b.Property<bool>("IsArchived")
b.Property<bool>("IsCurrent")
.HasColumnType("tinyint(1)");
b.Property<bool>("IsEnabled")
@@ -63,7 +63,7 @@ namespace Jiaowu.Api.Infrastructure.Persistence.Migrations.MySql
b.Property<int>("SortOrder")
.HasColumnType("int");
b.Property<DateOnly>("StartDate")
b.Property<DateTime>("StartDate")
.HasColumnType("date");
b.Property<DateTime>("UpdatedAt")
@@ -74,10 +74,10 @@ namespace Jiaowu.Api.Infrastructure.Persistence.Migrations.MySql
b.HasIndex("Code")
.IsUnique();
b.HasIndex("IsCurrent");
b.HasIndex("IsArchived");
b.HasIndex("IsCurrent");
b.HasIndex("IsEnabled", "SortOrder");
b.ToTable("AcademicTerms");
@@ -595,7 +595,7 @@ namespace Jiaowu.Api.Infrastructure.Persistence.Migrations.MySql
b.Property<Guid>("ApplicantUserId")
.HasColumnType("char(36)");
b.Property<DateOnly?>("CancelDate")
b.Property<DateTime?>("CancelDate")
.HasColumnType("date");
b.Property<int?>("CancelWeek")
@@ -640,7 +640,7 @@ namespace Jiaowu.Api.Infrastructure.Persistence.Migrations.MySql
b.Property<Guid?>("SubstituteTeacherId")
.HasColumnType("char(36)");
b.Property<DateOnly?>("TargetDate")
b.Property<DateTime?>("TargetDate")
.HasColumnType("date");
b.Property<Guid>("TeachingTaskId")
@@ -743,10 +743,10 @@ namespace Jiaowu.Api.Infrastructure.Persistence.Migrations.MySql
b.HasIndex("CourseSelectionOfferingId", "StudentId")
.IsUnique();
b.HasIndex("CourseSelectionOfferingId", "Status", "WaitlistedAt");
b.HasIndex("StudentId", "Status");
b.HasIndex("CourseSelectionOfferingId", "Status", "WaitlistedAt");
b.ToTable("CourseEnrollments");
});
@@ -854,6 +854,9 @@ namespace Jiaowu.Api.Infrastructure.Persistence.Migrations.MySql
b.Property<DateTime>("EndsAt")
.HasColumnType("datetime(6)");
b.Property<int?>("MaxCourseCount")
.HasColumnType("int");
b.Property<decimal>("MaxCredits")
.HasPrecision(6, 1)
.HasColumnType("decimal(6,1)");
@@ -886,6 +889,34 @@ namespace Jiaowu.Api.Infrastructure.Persistence.Migrations.MySql
b.ToTable("CourseSelectionRounds");
});
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.CourseSelectionRoundGrade", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<Guid>("CourseSelectionRoundId")
.HasColumnType("char(36)");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime(6)");
b.Property<int>("Grade")
.HasColumnType("int");
b.Property<DateTime>("UpdatedAt")
.HasColumnType("datetime(6)");
b.HasKey("Id");
b.HasIndex("Grade");
b.HasIndex("CourseSelectionRoundId", "Grade")
.IsUnique();
b.ToTable("CourseSelectionRoundGrades");
});
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.CourseSubstitution", b =>
{
b.Property<Guid>("Id")
@@ -1407,7 +1438,7 @@ namespace Jiaowu.Api.Infrastructure.Persistence.Migrations.MySql
b.Property<DateTime>("EndsAt")
.HasColumnType("datetime(6)");
b.Property<DateOnly>("ExamDate")
b.Property<DateTime>("ExamDate")
.HasColumnType("date");
b.Property<Guid>("ExamPlanId")
@@ -2117,7 +2148,7 @@ namespace Jiaowu.Api.Infrastructure.Persistence.Migrations.MySql
b.Property<DateTime>("EndsAt")
.HasColumnType("datetime(6)");
b.Property<DateOnly>("ExamDate")
b.Property<DateTime>("ExamDate")
.HasColumnType("date");
b.Property<Guid>("MakeupExamPlanId")
@@ -2391,7 +2422,7 @@ namespace Jiaowu.Api.Infrastructure.Persistence.Migrations.MySql
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime(6)");
b.Property<TimeOnly>("EndsAt")
b.Property<TimeSpan>("EndsAt")
.HasColumnType("time");
b.Property<bool>("IsEnabled")
@@ -2405,7 +2436,7 @@ namespace Jiaowu.Api.Infrastructure.Persistence.Migrations.MySql
b.Property<int>("PeriodNumber")
.HasColumnType("int");
b.Property<TimeOnly>("StartsAt")
b.Property<TimeSpan>("StartsAt")
.HasColumnType("time");
b.Property<DateTime>("UpdatedAt")
@@ -2431,14 +2462,14 @@ namespace Jiaowu.Api.Infrastructure.Persistence.Migrations.MySql
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime(6)");
b.Property<DateOnly?>("DateOfBirth")
b.Property<DateTime?>("DateOfBirth")
.HasColumnType("date");
b.Property<string>("Email")
.HasMaxLength(100)
.HasColumnType("varchar(100)");
b.Property<DateOnly>("EnrollmentDate")
b.Property<DateTime>("EnrollmentDate")
.HasColumnType("date");
b.Property<int>("EnrollmentYear")
@@ -2559,7 +2590,7 @@ namespace Jiaowu.Api.Infrastructure.Persistence.Migrations.MySql
b.Property<int>("Gender")
.HasColumnType("int");
b.Property<DateOnly?>("HireDate")
b.Property<DateTime?>("HireDate")
.HasColumnType("date");
b.Property<bool>("IsExternal")
@@ -3412,6 +3443,17 @@ namespace Jiaowu.Api.Infrastructure.Persistence.Migrations.MySql
b.Navigation("AcademicTerm");
});
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.CourseSelectionRoundGrade", b =>
{
b.HasOne("Jiaowu.Api.Domain.Academic.CourseSelectionRound", "CourseSelectionRound")
.WithMany("EligibleGrades")
.HasForeignKey("CourseSelectionRoundId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("CourseSelectionRound");
});
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.CourseSubstitution", b =>
{
b.HasOne("Jiaowu.Api.Domain.Academic.Course", "OriginalCourse")
@@ -4232,6 +4274,8 @@ namespace Jiaowu.Api.Infrastructure.Persistence.Migrations.MySql
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.CourseSelectionRound", b =>
{
b.Navigation("EligibleGrades");
b.Navigation("Offerings");
});