实验预约
This commit is contained in:
@@ -44,6 +44,9 @@ public sealed class AppDbContext(DbContextOptions<AppDbContext> options)
|
||||
Set<SchedulePublishJob>();
|
||||
public DbSet<ClassroomReservation> ClassroomReservations =>
|
||||
Set<ClassroomReservation>();
|
||||
public DbSet<ExperimentProject> ExperimentProjects => Set<ExperimentProject>();
|
||||
public DbSet<ExperimentSession> ExperimentSessions => Set<ExperimentSession>();
|
||||
public DbSet<ExperimentBooking> ExperimentBookings => Set<ExperimentBooking>();
|
||||
public DbSet<CourseSelectionRound> CourseSelectionRounds =>
|
||||
Set<CourseSelectionRound>();
|
||||
public DbSet<CourseSelectionRoundGrade> CourseSelectionRoundGrades =>
|
||||
@@ -547,6 +550,64 @@ public sealed class AppDbContext(DbContextOptions<AppDbContext> options)
|
||||
.OnDelete(DeleteBehavior.SetNull);
|
||||
});
|
||||
|
||||
builder.Entity<ExperimentProject>(entity =>
|
||||
{
|
||||
entity.Property(x => x.Code).HasMaxLength(40);
|
||||
entity.Property(x => x.Name).HasMaxLength(120);
|
||||
entity.Property(x => x.Description).HasMaxLength(1000);
|
||||
entity.Property(x => x.Requirements).HasMaxLength(1000);
|
||||
entity.HasIndex(x => new { x.TeachingTaskId, x.Code }).IsUnique();
|
||||
entity.HasIndex(x => new { x.Status, x.StartDate, x.EndDate });
|
||||
entity.HasOne(x => x.TeachingTask).WithMany()
|
||||
.HasForeignKey(x => x.TeachingTaskId)
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
});
|
||||
|
||||
builder.Entity<ExperimentSession>(entity =>
|
||||
{
|
||||
entity.Property(x => x.Notes).HasMaxLength(500);
|
||||
entity.HasIndex(x => new
|
||||
{
|
||||
x.ExperimentProjectId,
|
||||
x.SessionDate,
|
||||
x.StartPeriod
|
||||
});
|
||||
entity.HasIndex(x => new
|
||||
{
|
||||
x.ClassroomId,
|
||||
x.SessionDate,
|
||||
x.Status,
|
||||
x.StartPeriod
|
||||
});
|
||||
entity.HasOne(x => x.ExperimentProject).WithMany(x => x.Sessions)
|
||||
.HasForeignKey(x => x.ExperimentProjectId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
entity.HasOne(x => x.Classroom).WithMany()
|
||||
.HasForeignKey(x => x.ClassroomId)
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
});
|
||||
|
||||
builder.Entity<ExperimentBooking>(entity =>
|
||||
{
|
||||
entity.HasIndex(x => new { x.ExperimentProjectId, x.StudentId })
|
||||
.IsUnique();
|
||||
entity.HasIndex(x => new
|
||||
{
|
||||
x.ExperimentSessionId,
|
||||
x.Status,
|
||||
x.BookedAt
|
||||
});
|
||||
entity.HasOne(x => x.ExperimentProject).WithMany(x => x.Bookings)
|
||||
.HasForeignKey(x => x.ExperimentProjectId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
entity.HasOne(x => x.ExperimentSession).WithMany(x => x.Bookings)
|
||||
.HasForeignKey(x => x.ExperimentSessionId)
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
entity.HasOne(x => x.Student).WithMany()
|
||||
.HasForeignKey(x => x.StudentId)
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
});
|
||||
|
||||
builder.Entity<CourseSelectionRound>(entity =>
|
||||
{
|
||||
entity.Property(x => x.Name).HasMaxLength(120);
|
||||
|
||||
@@ -68,6 +68,10 @@ public sealed class DevelopmentSqliteMigrator(
|
||||
"20260727_36_exam_room_mixing";
|
||||
private const string AttendanceCheckInAuditMigration =
|
||||
"20260728_37_attendance_check_in_audit";
|
||||
private const string ExamPublishJobsMigration =
|
||||
"20260728_38_exam_publish_jobs";
|
||||
private const string ExperimentManagementMigration =
|
||||
"20260728_39_experiment_management";
|
||||
|
||||
public async Task MigrateAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
@@ -513,6 +517,32 @@ public sealed class DevelopmentSqliteMigrator(
|
||||
ExamRoomMixingMigration,
|
||||
examRoomsExist ? [] : ExamRoomMixingStatements,
|
||||
cancellationToken);
|
||||
|
||||
var examPublishJobsExist = await db.Database
|
||||
.SqlQueryRaw<int>(
|
||||
"""
|
||||
SELECT COUNT(*) AS "Value"
|
||||
FROM sqlite_master
|
||||
WHERE type = 'table' AND name = 'ExamPublishJobs'
|
||||
""")
|
||||
.AnyAsync(value => value > 0, cancellationToken);
|
||||
await ApplyMigrationAsync(
|
||||
ExamPublishJobsMigration,
|
||||
examPublishJobsExist ? [] : ExamPublishJobStatements,
|
||||
cancellationToken);
|
||||
|
||||
var experimentProjectsExist = await db.Database
|
||||
.SqlQueryRaw<int>(
|
||||
"""
|
||||
SELECT COUNT(*) AS "Value"
|
||||
FROM sqlite_master
|
||||
WHERE type = 'table' AND name = 'ExperimentProjects'
|
||||
""")
|
||||
.AnyAsync(value => value > 0, cancellationToken);
|
||||
await ApplyMigrationAsync(
|
||||
ExperimentManagementMigration,
|
||||
experimentProjectsExist ? [] : ExperimentManagementStatements,
|
||||
cancellationToken);
|
||||
}
|
||||
|
||||
private async Task ApplyMigrationAsync(
|
||||
@@ -2351,4 +2381,134 @@ public sealed class DevelopmentSqliteMigrator(
|
||||
ON "ExamRoomInvigilators" ("TeacherId");
|
||||
"""
|
||||
];
|
||||
|
||||
private static readonly string[] ExamPublishJobStatements =
|
||||
[
|
||||
"""
|
||||
CREATE TABLE "ExamPublishJobs" (
|
||||
"Id" TEXT NOT NULL CONSTRAINT "PK_ExamPublishJobs" PRIMARY KEY,
|
||||
"Kind" INTEGER NOT NULL,
|
||||
"PlanId" TEXT NOT NULL,
|
||||
"ActivePlanId" TEXT NULL,
|
||||
"RequestedByUserId" TEXT NULL,
|
||||
"Status" INTEGER NOT NULL,
|
||||
"CurrentStep" TEXT NULL,
|
||||
"ErrorMessage" TEXT NULL,
|
||||
"StartedAt" TEXT NULL,
|
||||
"CompletedAt" TEXT NULL,
|
||||
"CreatedAt" TEXT NOT NULL,
|
||||
"UpdatedAt" TEXT NOT NULL
|
||||
);
|
||||
"""
|
||||
];
|
||||
|
||||
private static readonly string[] ExperimentManagementStatements =
|
||||
[
|
||||
"""
|
||||
CREATE TABLE "ExperimentProjects" (
|
||||
"Id" TEXT NOT NULL CONSTRAINT "PK_ExperimentProjects" PRIMARY KEY,
|
||||
"TeachingTaskId" TEXT NOT NULL,
|
||||
"Code" TEXT NOT NULL,
|
||||
"Name" TEXT NOT NULL,
|
||||
"ArrangementMode" INTEGER NOT NULL,
|
||||
"Description" TEXT NULL,
|
||||
"Requirements" TEXT NULL,
|
||||
"StartDate" TEXT NOT NULL,
|
||||
"EndDate" TEXT NOT NULL,
|
||||
"Status" INTEGER NOT NULL,
|
||||
"PublishedAt" TEXT NULL,
|
||||
"ClosedAt" TEXT NULL,
|
||||
"CreatedAt" TEXT NOT NULL,
|
||||
"UpdatedAt" TEXT NOT NULL,
|
||||
CONSTRAINT "FK_ExperimentProjects_TeachingTasks_TeachingTaskId"
|
||||
FOREIGN KEY ("TeachingTaskId") REFERENCES "TeachingTasks" ("Id")
|
||||
ON DELETE RESTRICT
|
||||
);
|
||||
""",
|
||||
"""
|
||||
CREATE UNIQUE INDEX "IX_ExperimentProjects_TeachingTaskId_Code"
|
||||
ON "ExperimentProjects" ("TeachingTaskId", "Code");
|
||||
""",
|
||||
"""
|
||||
CREATE INDEX "IX_ExperimentProjects_Status_StartDate_EndDate"
|
||||
ON "ExperimentProjects" ("Status", "StartDate", "EndDate");
|
||||
""",
|
||||
"""
|
||||
CREATE TABLE "ExperimentSessions" (
|
||||
"Id" TEXT NOT NULL CONSTRAINT "PK_ExperimentSessions" PRIMARY KEY,
|
||||
"ExperimentProjectId" TEXT NOT NULL,
|
||||
"ClassroomId" TEXT NOT NULL,
|
||||
"SessionDate" TEXT NOT NULL,
|
||||
"StartPeriod" INTEGER NOT NULL,
|
||||
"PeriodCount" INTEGER NOT NULL,
|
||||
"Capacity" INTEGER NOT NULL,
|
||||
"ReservedCount" INTEGER NOT NULL,
|
||||
"Notes" TEXT NULL,
|
||||
"Status" INTEGER NOT NULL,
|
||||
"CancelledAt" TEXT NULL,
|
||||
"CreatedAt" TEXT NOT NULL,
|
||||
"UpdatedAt" TEXT NOT NULL,
|
||||
CONSTRAINT "FK_ExperimentSessions_ExperimentProjects_ExperimentProjectId"
|
||||
FOREIGN KEY ("ExperimentProjectId")
|
||||
REFERENCES "ExperimentProjects" ("Id")
|
||||
ON DELETE CASCADE,
|
||||
CONSTRAINT "FK_ExperimentSessions_Classrooms_ClassroomId"
|
||||
FOREIGN KEY ("ClassroomId") REFERENCES "Classrooms" ("Id")
|
||||
ON DELETE RESTRICT
|
||||
);
|
||||
""",
|
||||
"""
|
||||
CREATE INDEX "IX_ExperimentSessions_ExperimentProjectId_SessionDate_StartPeriod"
|
||||
ON "ExperimentSessions" (
|
||||
"ExperimentProjectId",
|
||||
"SessionDate",
|
||||
"StartPeriod"
|
||||
);
|
||||
""",
|
||||
"""
|
||||
CREATE INDEX "IX_ExperimentSessions_ClassroomId_SessionDate_Status_StartPeriod"
|
||||
ON "ExperimentSessions" (
|
||||
"ClassroomId",
|
||||
"SessionDate",
|
||||
"Status",
|
||||
"StartPeriod"
|
||||
);
|
||||
""",
|
||||
"""
|
||||
CREATE TABLE "ExperimentBookings" (
|
||||
"Id" TEXT NOT NULL CONSTRAINT "PK_ExperimentBookings" PRIMARY KEY,
|
||||
"ExperimentProjectId" TEXT NOT NULL,
|
||||
"ExperimentSessionId" TEXT NOT NULL,
|
||||
"StudentId" TEXT NOT NULL,
|
||||
"Status" INTEGER NOT NULL,
|
||||
"BookedAt" TEXT NOT NULL,
|
||||
"CancelledAt" TEXT NULL,
|
||||
"CreatedAt" TEXT NOT NULL,
|
||||
"UpdatedAt" TEXT NOT NULL,
|
||||
CONSTRAINT "FK_ExperimentBookings_ExperimentProjects_ExperimentProjectId"
|
||||
FOREIGN KEY ("ExperimentProjectId")
|
||||
REFERENCES "ExperimentProjects" ("Id")
|
||||
ON DELETE CASCADE,
|
||||
CONSTRAINT "FK_ExperimentBookings_ExperimentSessions_ExperimentSessionId"
|
||||
FOREIGN KEY ("ExperimentSessionId")
|
||||
REFERENCES "ExperimentSessions" ("Id")
|
||||
ON DELETE RESTRICT,
|
||||
CONSTRAINT "FK_ExperimentBookings_Students_StudentId"
|
||||
FOREIGN KEY ("StudentId") REFERENCES "Students" ("Id")
|
||||
ON DELETE RESTRICT
|
||||
);
|
||||
""",
|
||||
"""
|
||||
CREATE UNIQUE INDEX "IX_ExperimentBookings_ExperimentProjectId_StudentId"
|
||||
ON "ExperimentBookings" ("ExperimentProjectId", "StudentId");
|
||||
""",
|
||||
"""
|
||||
CREATE INDEX "IX_ExperimentBookings_ExperimentSessionId_Status_BookedAt"
|
||||
ON "ExperimentBookings" (
|
||||
"ExperimentSessionId",
|
||||
"Status",
|
||||
"BookedAt"
|
||||
);
|
||||
"""
|
||||
];
|
||||
}
|
||||
|
||||
+5641
File diff suppressed because it is too large
Load Diff
+170
@@ -0,0 +1,170 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Jiaowu.Api.Infrastructure.Persistence.Migrations.MySql
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class ExperimentManagement : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ExperimentProjects",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
TeachingTaskId = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
Code = table.Column<string>(type: "varchar(40)", maxLength: 40, nullable: false),
|
||||
Name = table.Column<string>(type: "varchar(120)", maxLength: 120, nullable: false),
|
||||
ArrangementMode = table.Column<int>(type: "int", nullable: false),
|
||||
Description = table.Column<string>(type: "varchar(1000)", maxLength: 1000, nullable: true),
|
||||
Requirements = table.Column<string>(type: "varchar(1000)", maxLength: 1000, nullable: true),
|
||||
StartDate = table.Column<DateTime>(type: "date", nullable: false),
|
||||
EndDate = table.Column<DateTime>(type: "date", nullable: false),
|
||||
Status = table.Column<int>(type: "int", nullable: false),
|
||||
PublishedAt = table.Column<DateTime>(type: "datetime(6)", nullable: true),
|
||||
ClosedAt = table.Column<DateTime>(type: "datetime(6)", nullable: true),
|
||||
CreatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false),
|
||||
UpdatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ExperimentProjects", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ExperimentProjects_TeachingTasks_TeachingTaskId",
|
||||
column: x => x.TeachingTaskId,
|
||||
principalTable: "TeachingTasks",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
})
|
||||
.Annotation("MySQL:Charset", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ExperimentSessions",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
ExperimentProjectId = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
ClassroomId = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
SessionDate = table.Column<DateTime>(type: "date", nullable: false),
|
||||
StartPeriod = table.Column<int>(type: "int", nullable: false),
|
||||
PeriodCount = table.Column<int>(type: "int", nullable: false),
|
||||
Capacity = table.Column<int>(type: "int", nullable: false),
|
||||
ReservedCount = table.Column<int>(type: "int", nullable: false),
|
||||
Notes = table.Column<string>(type: "varchar(500)", maxLength: 500, nullable: true),
|
||||
Status = table.Column<int>(type: "int", nullable: false),
|
||||
CancelledAt = table.Column<DateTime>(type: "datetime(6)", nullable: true),
|
||||
CreatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false),
|
||||
UpdatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ExperimentSessions", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ExperimentSessions_Classrooms_ClassroomId",
|
||||
column: x => x.ClassroomId,
|
||||
principalTable: "Classrooms",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
table.ForeignKey(
|
||||
name: "FK_ExperimentSessions_ExperimentProjects_ExperimentProjectId",
|
||||
column: x => x.ExperimentProjectId,
|
||||
principalTable: "ExperimentProjects",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
})
|
||||
.Annotation("MySQL:Charset", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ExperimentBookings",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
ExperimentProjectId = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
ExperimentSessionId = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
StudentId = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
Status = table.Column<int>(type: "int", nullable: false),
|
||||
BookedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false),
|
||||
CancelledAt = table.Column<DateTime>(type: "datetime(6)", nullable: true),
|
||||
CreatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false),
|
||||
UpdatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ExperimentBookings", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ExperimentBookings_ExperimentProjects_ExperimentProjectId",
|
||||
column: x => x.ExperimentProjectId,
|
||||
principalTable: "ExperimentProjects",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_ExperimentBookings_ExperimentSessions_ExperimentSessionId",
|
||||
column: x => x.ExperimentSessionId,
|
||||
principalTable: "ExperimentSessions",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
table.ForeignKey(
|
||||
name: "FK_ExperimentBookings_Students_StudentId",
|
||||
column: x => x.StudentId,
|
||||
principalTable: "Students",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
})
|
||||
.Annotation("MySQL:Charset", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ExperimentBookings_ExperimentProjectId_StudentId",
|
||||
table: "ExperimentBookings",
|
||||
columns: new[] { "ExperimentProjectId", "StudentId" },
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ExperimentBookings_ExperimentSessionId_Status_BookedAt",
|
||||
table: "ExperimentBookings",
|
||||
columns: new[] { "ExperimentSessionId", "Status", "BookedAt" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ExperimentBookings_StudentId",
|
||||
table: "ExperimentBookings",
|
||||
column: "StudentId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ExperimentProjects_Status_StartDate_EndDate",
|
||||
table: "ExperimentProjects",
|
||||
columns: new[] { "Status", "StartDate", "EndDate" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ExperimentProjects_TeachingTaskId_Code",
|
||||
table: "ExperimentProjects",
|
||||
columns: new[] { "TeachingTaskId", "Code" },
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ExperimentSessions_ClassroomId_SessionDate_Status_StartPeriod",
|
||||
table: "ExperimentSessions",
|
||||
columns: new[] { "ClassroomId", "SessionDate", "Status", "StartPeriod" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ExperimentSessions_ExperimentProjectId_SessionDate_StartPeri~",
|
||||
table: "ExperimentSessions",
|
||||
columns: new[] { "ExperimentProjectId", "SessionDate", "StartPeriod" });
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "ExperimentBookings");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "ExperimentSessions");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "ExperimentProjects");
|
||||
}
|
||||
}
|
||||
}
|
||||
+224
@@ -2001,6 +2001,161 @@ namespace Jiaowu.Api.Infrastructure.Persistence.Migrations.MySql
|
||||
b.ToTable("ExamSignInExportJobs");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.ExperimentBooking", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<DateTime>("BookedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<DateTime?>("CancelledAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<Guid>("ExperimentProjectId")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<Guid>("ExperimentSessionId")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<int>("Status")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<Guid>("StudentId")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<DateTime>("UpdatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("StudentId");
|
||||
|
||||
b.HasIndex("ExperimentProjectId", "StudentId")
|
||||
.IsUnique();
|
||||
|
||||
b.HasIndex("ExperimentSessionId", "Status", "BookedAt");
|
||||
|
||||
b.ToTable("ExperimentBookings");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.ExperimentProject", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<int>("ArrangementMode")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<DateTime?>("ClosedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<string>("Code")
|
||||
.IsRequired()
|
||||
.HasMaxLength(40)
|
||||
.HasColumnType("varchar(40)");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasMaxLength(1000)
|
||||
.HasColumnType("varchar(1000)");
|
||||
|
||||
b.Property<DateTime>("EndDate")
|
||||
.HasColumnType("date");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(120)
|
||||
.HasColumnType("varchar(120)");
|
||||
|
||||
b.Property<DateTime?>("PublishedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<string>("Requirements")
|
||||
.HasMaxLength(1000)
|
||||
.HasColumnType("varchar(1000)");
|
||||
|
||||
b.Property<DateTime>("StartDate")
|
||||
.HasColumnType("date");
|
||||
|
||||
b.Property<int>("Status")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<Guid>("TeachingTaskId")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<DateTime>("UpdatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("TeachingTaskId", "Code")
|
||||
.IsUnique();
|
||||
|
||||
b.HasIndex("Status", "StartDate", "EndDate");
|
||||
|
||||
b.ToTable("ExperimentProjects");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.ExperimentSession", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<DateTime?>("CancelledAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<int>("Capacity")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<Guid>("ClassroomId")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<Guid>("ExperimentProjectId")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<string>("Notes")
|
||||
.HasMaxLength(500)
|
||||
.HasColumnType("varchar(500)");
|
||||
|
||||
b.Property<int>("PeriodCount")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("ReservedCount")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<DateTime>("SessionDate")
|
||||
.HasColumnType("date");
|
||||
|
||||
b.Property<int>("StartPeriod")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("Status")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<DateTime>("UpdatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ExperimentProjectId", "SessionDate", "StartPeriod");
|
||||
|
||||
b.HasIndex("ClassroomId", "SessionDate", "Status", "StartPeriod");
|
||||
|
||||
b.ToTable("ExperimentSessions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.GradeItem", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
@@ -4630,6 +4785,63 @@ namespace Jiaowu.Api.Infrastructure.Persistence.Migrations.MySql
|
||||
b.Navigation("Teacher");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.ExperimentBooking", b =>
|
||||
{
|
||||
b.HasOne("Jiaowu.Api.Domain.Academic.ExperimentProject", "ExperimentProject")
|
||||
.WithMany("Bookings")
|
||||
.HasForeignKey("ExperimentProjectId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Jiaowu.Api.Domain.Academic.ExperimentSession", "ExperimentSession")
|
||||
.WithMany("Bookings")
|
||||
.HasForeignKey("ExperimentSessionId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Jiaowu.Api.Domain.Academic.Student", "Student")
|
||||
.WithMany()
|
||||
.HasForeignKey("StudentId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("ExperimentProject");
|
||||
|
||||
b.Navigation("ExperimentSession");
|
||||
|
||||
b.Navigation("Student");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.ExperimentProject", b =>
|
||||
{
|
||||
b.HasOne("Jiaowu.Api.Domain.Academic.TeachingTask", "TeachingTask")
|
||||
.WithMany()
|
||||
.HasForeignKey("TeachingTaskId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("TeachingTask");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.ExperimentSession", b =>
|
||||
{
|
||||
b.HasOne("Jiaowu.Api.Domain.Academic.Classroom", "Classroom")
|
||||
.WithMany()
|
||||
.HasForeignKey("ClassroomId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Jiaowu.Api.Domain.Academic.ExperimentProject", "ExperimentProject")
|
||||
.WithMany("Sessions")
|
||||
.HasForeignKey("ExperimentProjectId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Classroom");
|
||||
|
||||
b.Navigation("ExperimentProject");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.GradeItem", b =>
|
||||
{
|
||||
b.HasOne("Jiaowu.Api.Domain.Academic.GradeSheet", "GradeSheet")
|
||||
@@ -5338,6 +5550,18 @@ namespace Jiaowu.Api.Infrastructure.Persistence.Migrations.MySql
|
||||
b.Navigation("SeatAssignments");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.ExperimentProject", b =>
|
||||
{
|
||||
b.Navigation("Bookings");
|
||||
|
||||
b.Navigation("Sessions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.ExperimentSession", b =>
|
||||
{
|
||||
b.Navigation("Bookings");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Jiaowu.Api.Domain.Academic.GradeItem", b =>
|
||||
{
|
||||
b.Navigation("Scores");
|
||||
|
||||
@@ -81,6 +81,20 @@ public sealed class ClassroomReservationAvailabilityService(AppDbContext db)
|
||||
.ToListAsync(cancellationToken);
|
||||
occupiedIds.UnionWith(makeupExamRoomIds);
|
||||
|
||||
var experimentRoomIds = await db.ExperimentSessions.AsNoTracking()
|
||||
.Where(session =>
|
||||
session.ExperimentProject!.TeachingTask!.AcademicTermId ==
|
||||
term.Id &&
|
||||
session.ExperimentProject.Status !=
|
||||
ExperimentProjectStatus.Closed &&
|
||||
session.Status == ExperimentSessionStatus.Scheduled &&
|
||||
session.SessionDate == reservationDate &&
|
||||
session.StartPeriod < startPeriod + periodCount &&
|
||||
startPeriod < session.StartPeriod + session.PeriodCount)
|
||||
.Select(session => session.ClassroomId)
|
||||
.ToListAsync(cancellationToken);
|
||||
occupiedIds.UnionWith(experimentRoomIds);
|
||||
|
||||
var reservationQuery = db.ClassroomReservations.AsNoTracking()
|
||||
.Where(reservation =>
|
||||
reservation.AcademicTermId == term.Id &&
|
||||
|
||||
Reference in New Issue
Block a user