已改成后台“检查并发布”任务,原来的超时主要就是同步逐条校验导致的。

发布接口立即返回 202 Accepted,页面轮询显示检查进度。
校验改为批量读取,减少重复数据库查询。
检查失败保留草稿并显示具体原因;成功后原子完成旧课表归档和新课表发布。
同一学期禁止两个发布任务并发,服务重启后未完成任务会自动恢复。
发布期间锁定编辑、自动排课等冲突操作。
已补齐 SQLite 开发迁移及 MySQL 生产迁移。
This commit is contained in:
2026-07-25 12:07:03 +08:00 Unverified
parent fdca6a3edf
commit b015514115
12 changed files with 4116 additions and 81 deletions
@@ -38,6 +38,8 @@ public sealed class AppDbContext(DbContextOptions<AppDbContext> options)
Set<TeachingTaskAllowedClassroom>();
public DbSet<AutomaticScheduleJob> AutomaticScheduleJobs =>
Set<AutomaticScheduleJob>();
public DbSet<SchedulePublishJob> SchedulePublishJobs =>
Set<SchedulePublishJob>();
public DbSet<CourseSelectionRound> CourseSelectionRounds =>
Set<CourseSelectionRound>();
public DbSet<CourseSelectionOffering> CourseSelectionOfferings =>
@@ -400,6 +402,24 @@ public sealed class AppDbContext(DbContextOptions<AppDbContext> options)
.OnDelete(DeleteBehavior.SetNull);
});
builder.Entity<SchedulePublishJob>(entity =>
{
entity.Property(x => x.CurrentStep).HasMaxLength(200);
entity.Property(x => x.ErrorMessage).HasMaxLength(2000);
entity.HasIndex(x => x.ActiveAcademicTermId).IsUnique();
entity.HasIndex(x => new { x.SchedulePlanId, x.CreatedAt });
entity.HasIndex(x => new { x.Status, x.CreatedAt });
entity.HasIndex(x => x.RequestedByUserId);
entity.HasOne(x => x.SchedulePlan)
.WithMany()
.HasForeignKey(x => x.SchedulePlanId)
.OnDelete(DeleteBehavior.Cascade);
entity.HasOne<ApplicationUser>()
.WithMany()
.HasForeignKey(x => x.RequestedByUserId)
.OnDelete(DeleteBehavior.SetNull);
});
builder.Entity<CourseSelectionRound>(entity =>
{
entity.Property(x => x.Name).HasMaxLength(120);