支持为同一学期、同一课程的多个教学任务批量创建相同实验项目。
新增批量排课表,可为多个实验项目分别设置日期、节次、实验室和容量。 批量排课采用原子事务:任一项目发生教室、教师、班级或课表冲突,整批不写入。 已发布项目批量新增场次时,继续按原逻辑通知学生。 后端继续执行管理范围、教学任务状态、开放日期和容量校验。 页面在 390px 手机宽度下无横向溢出。
This commit is contained in:
@@ -12,6 +12,112 @@ namespace Jiaowu.Api.Tests;
|
||||
|
||||
public sealed class ExperimentsControllerTests
|
||||
{
|
||||
[Fact]
|
||||
public async Task BatchProjects_CreateSameDefinitionForSameCourseTasks()
|
||||
{
|
||||
await using var fixture = await ExperimentFixture.CreateAsync();
|
||||
var controller = fixture.Controller(fixture.ManagerScope);
|
||||
|
||||
var result = await controller.CreateProjects(
|
||||
fixture.BatchProjectRequest(
|
||||
ExperimentArrangementMode.Centralized),
|
||||
CancellationToken.None);
|
||||
|
||||
Assert.IsType<CreatedResult>(result);
|
||||
var projects = await fixture.Db.ExperimentProjects
|
||||
.OrderBy(x => x.TeachingTaskId)
|
||||
.ToListAsync();
|
||||
Assert.Equal(2, projects.Count);
|
||||
Assert.Equal(2, projects.Select(x => x.TeachingTaskId).Distinct().Count());
|
||||
Assert.All(projects, project =>
|
||||
{
|
||||
Assert.Equal("LAB-BATCH", project.Code);
|
||||
Assert.Equal("公共实验任务", project.Name);
|
||||
Assert.Equal(ExperimentProjectStatus.Draft, project.Status);
|
||||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task BatchSessions_RollsBackAllRowsWhenOneConflicts()
|
||||
{
|
||||
await using var fixture = await ExperimentFixture.CreateAsync();
|
||||
var controller = fixture.Controller(fixture.ManagerScope);
|
||||
await controller.CreateProjects(
|
||||
fixture.BatchProjectRequest(
|
||||
ExperimentArrangementMode.SelfScheduled),
|
||||
CancellationToken.None);
|
||||
var projectIds = await fixture.Db.ExperimentProjects
|
||||
.OrderBy(x => x.TeachingTaskId)
|
||||
.Select(x => x.Id)
|
||||
.ToListAsync();
|
||||
|
||||
var result = await controller.CreateSessions(
|
||||
new ExperimentSessionBatchRequest(
|
||||
[
|
||||
new ExperimentSessionBatchItem(
|
||||
projectIds[0],
|
||||
fixture.Classroom.Id,
|
||||
fixture.Term.StartDate,
|
||||
1,
|
||||
2,
|
||||
20,
|
||||
null),
|
||||
new ExperimentSessionBatchItem(
|
||||
projectIds[1],
|
||||
fixture.Classroom.Id,
|
||||
fixture.Term.StartDate,
|
||||
1,
|
||||
2,
|
||||
20,
|
||||
null)
|
||||
]),
|
||||
CancellationToken.None);
|
||||
|
||||
Assert.IsType<ConflictObjectResult>(result);
|
||||
fixture.Db.ChangeTracker.Clear();
|
||||
Assert.Empty(await fixture.Db.ExperimentSessions.ToListAsync());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task BatchSessions_CreatesRowsAtomicallyWhenAllAreValid()
|
||||
{
|
||||
await using var fixture = await ExperimentFixture.CreateAsync();
|
||||
var controller = fixture.Controller(fixture.ManagerScope);
|
||||
await controller.CreateProjects(
|
||||
fixture.BatchProjectRequest(
|
||||
ExperimentArrangementMode.SelfScheduled),
|
||||
CancellationToken.None);
|
||||
var projectIds = await fixture.Db.ExperimentProjects
|
||||
.OrderBy(x => x.TeachingTaskId)
|
||||
.Select(x => x.Id)
|
||||
.ToListAsync();
|
||||
|
||||
var result = await controller.CreateSessions(
|
||||
new ExperimentSessionBatchRequest(
|
||||
[
|
||||
new ExperimentSessionBatchItem(
|
||||
projectIds[0],
|
||||
fixture.Classroom.Id,
|
||||
fixture.Term.StartDate,
|
||||
1,
|
||||
2,
|
||||
20,
|
||||
null),
|
||||
new ExperimentSessionBatchItem(
|
||||
projectIds[1],
|
||||
fixture.SecondClassroom.Id,
|
||||
fixture.Term.StartDate,
|
||||
1,
|
||||
2,
|
||||
20,
|
||||
null)
|
||||
]),
|
||||
CancellationToken.None);
|
||||
|
||||
Assert.IsType<CreatedResult>(result);
|
||||
Assert.Equal(2, await fixture.Db.ExperimentSessions.CountAsync());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CentralizedProject_PublishesAndUsesTeachingTaskRoster()
|
||||
{
|
||||
@@ -421,6 +527,15 @@ public sealed class ExperimentsControllerTests
|
||||
}
|
||||
]
|
||||
};
|
||||
var secondTask = new TeachingTask
|
||||
{
|
||||
TaskNumber = "2099-1-CSLAB-02",
|
||||
Name = "系统实验教学班 02",
|
||||
AcademicTermId = term.Id,
|
||||
CourseId = course.Id,
|
||||
Capacity = 40,
|
||||
Status = TeachingTaskStatus.Published
|
||||
};
|
||||
db.AddRange(
|
||||
manager,
|
||||
studentUser,
|
||||
@@ -435,7 +550,8 @@ public sealed class ExperimentsControllerTests
|
||||
teacher,
|
||||
term,
|
||||
course,
|
||||
task);
|
||||
task,
|
||||
secondTask);
|
||||
for (var period = 1; period <= 12; period++)
|
||||
{
|
||||
db.ScheduleTimeSlots.Add(new ScheduleTimeSlot
|
||||
@@ -486,6 +602,21 @@ public sealed class ExperimentsControllerTests
|
||||
Term.StartDate,
|
||||
Term.StartDate.AddDays(14));
|
||||
|
||||
public ExperimentProjectBatchRequest BatchProjectRequest(
|
||||
ExperimentArrangementMode mode) =>
|
||||
new(
|
||||
Db.TeachingTasks
|
||||
.OrderBy(x => x.TaskNumber)
|
||||
.Select(x => x.Id)
|
||||
.ToList(),
|
||||
"LAB-BATCH",
|
||||
"公共实验任务",
|
||||
mode,
|
||||
"多个教学任务共用的实验内容。",
|
||||
"携带校园卡。",
|
||||
Term.StartDate,
|
||||
Term.StartDate.AddDays(14));
|
||||
|
||||
public ExperimentSessionRequest SessionRequest(
|
||||
int startPeriod,
|
||||
int periodCount,
|
||||
|
||||
Reference in New Issue
Block a user