主要改动:
自动排课接口立即返回 202 + jobId 后台服务独立执行,不受浏览器关闭或前端超时影响 进度、成功、失败状态持久化到数据库 服务重启后自动恢复排队中或中断的任务 同一草稿禁止重复提交后台任务 运行期间禁止编辑、发布或删除该课表 排课结果和任务成功状态在同一事务中提交 前端每秒轮询进度,显示已处理教学班和已规划安排数
This commit is contained in:
@@ -23,6 +23,8 @@ public sealed class DevelopmentSqliteMigrator(
|
||||
"20260724_14_scheduling_optimization";
|
||||
private const string TeacherCourseApplicationsMigration =
|
||||
"20260724_15_teacher_course_applications";
|
||||
private const string AutomaticScheduleJobsMigration =
|
||||
"20260724_16_automatic_schedule_jobs";
|
||||
|
||||
public async Task MigrateAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
@@ -135,6 +137,18 @@ public sealed class DevelopmentSqliteMigrator(
|
||||
TeacherCourseApplicationsMigration,
|
||||
teacherCourseApplicationsExist ? [] : TeacherCourseApplicationStatements,
|
||||
cancellationToken);
|
||||
var automaticScheduleJobsExist = await db.Database
|
||||
.SqlQueryRaw<int>(
|
||||
"""
|
||||
SELECT COUNT(*) AS "Value"
|
||||
FROM sqlite_master
|
||||
WHERE type = 'table' AND name = 'AutomaticScheduleJobs'
|
||||
""")
|
||||
.AnyAsync(value => value > 0, cancellationToken);
|
||||
await ApplyMigrationAsync(
|
||||
AutomaticScheduleJobsMigration,
|
||||
automaticScheduleJobsExist ? [] : AutomaticScheduleJobStatements,
|
||||
cancellationToken);
|
||||
}
|
||||
|
||||
private async Task ApplyMigrationAsync(
|
||||
@@ -1022,4 +1036,49 @@ public sealed class DevelopmentSqliteMigrator(
|
||||
ON "TeacherCourseApplications" ("ReviewedByUserId");
|
||||
"""
|
||||
];
|
||||
|
||||
private static readonly string[] AutomaticScheduleJobStatements =
|
||||
[
|
||||
"""
|
||||
CREATE TABLE "AutomaticScheduleJobs" (
|
||||
"Id" TEXT NOT NULL CONSTRAINT "PK_AutomaticScheduleJobs" PRIMARY KEY,
|
||||
"SchedulePlanId" TEXT NOT NULL,
|
||||
"ActiveSchedulePlanId" TEXT NULL,
|
||||
"RequestedByUserId" TEXT NULL,
|
||||
"Status" INTEGER NOT NULL,
|
||||
"TotalTasks" INTEGER NOT NULL,
|
||||
"ProcessedTasks" INTEGER NOT NULL,
|
||||
"CreatedEntries" INTEGER NOT NULL,
|
||||
"CompletedTasks" INTEGER NOT NULL,
|
||||
"MessagesJson" TEXT NULL,
|
||||
"ErrorMessage" TEXT NULL,
|
||||
"StartedAt" TEXT NULL,
|
||||
"CompletedAt" TEXT NULL,
|
||||
"CreatedAt" TEXT NOT NULL,
|
||||
"UpdatedAt" TEXT NOT NULL,
|
||||
CONSTRAINT "FK_AutomaticScheduleJobs_SchedulePlans"
|
||||
FOREIGN KEY ("SchedulePlanId") REFERENCES "SchedulePlans" ("Id")
|
||||
ON DELETE CASCADE,
|
||||
CONSTRAINT "FK_AutomaticScheduleJobs_RequestedBy"
|
||||
FOREIGN KEY ("RequestedByUserId") REFERENCES "AspNetUsers" ("Id")
|
||||
ON DELETE SET NULL
|
||||
);
|
||||
""",
|
||||
"""
|
||||
CREATE UNIQUE INDEX "IX_AutomaticScheduleJobs_ActiveSchedulePlanId"
|
||||
ON "AutomaticScheduleJobs" ("ActiveSchedulePlanId");
|
||||
""",
|
||||
"""
|
||||
CREATE INDEX "IX_AutomaticScheduleJobs_SchedulePlanId_CreatedAt"
|
||||
ON "AutomaticScheduleJobs" ("SchedulePlanId", "CreatedAt");
|
||||
""",
|
||||
"""
|
||||
CREATE INDEX "IX_AutomaticScheduleJobs_Status_CreatedAt"
|
||||
ON "AutomaticScheduleJobs" ("Status", "CreatedAt");
|
||||
""",
|
||||
"""
|
||||
CREATE INDEX "IX_AutomaticScheduleJobs_RequestedByUserId"
|
||||
ON "AutomaticScheduleJobs" ("RequestedByUserId");
|
||||
"""
|
||||
];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user