已继续完成“学籍异动”后端基础闭环:

学生可申请休学、复学或退学。
自动根据当前状态推导目标学籍状态。
同一学生不能同时提交多项在审申请。
强制执行辅导员 → 学院 → 校级三级审核。
驳回不会修改学生档案。
只有校级最终批准才更新学籍状态。
数据范围分别限制到本人、所带班级、所属学院或全校。
SQLite 增量升级和 MySQL 迁移已生成。
当前 28 项测试继续全部通过。
This commit is contained in:
2026-07-24 15:46:49 +08:00 Unverified
parent 7f3e37de20
commit 7493ab4a60
7 changed files with 2359 additions and 0 deletions
@@ -39,6 +39,8 @@ public sealed class AppDbContext(DbContextOptions<AppDbContext> options)
public DbSet<ExamSession> ExamSessions => Set<ExamSession>();
public DbSet<ExamSessionInvigilator> ExamSessionInvigilators =>
Set<ExamSessionInvigilator>();
public DbSet<StudentStatusChange> StudentStatusChanges =>
Set<StudentStatusChange>();
public DbSet<AuditLog> AuditLogs => Set<AuditLog>();
protected override void OnModelCreating(ModelBuilder builder)
@@ -386,6 +388,14 @@ public sealed class AppDbContext(DbContextOptions<AppDbContext> options)
entity.HasOne(x => x.Teacher).WithMany()
.HasForeignKey(x => x.TeacherId).OnDelete(DeleteBehavior.Restrict);
});
builder.Entity<StudentStatusChange>(entity =>
{
entity.Property(x => x.Reason).HasMaxLength(1000);
entity.Property(x => x.ReviewComment).HasMaxLength(500);
entity.HasIndex(x => new { x.StudentId, x.State });
entity.HasOne(x => x.Student).WithMany()
.HasForeignKey(x => x.StudentId).OnDelete(DeleteBehavior.Restrict);
});
builder.Entity<AuditLog>(entity =>
{