新建时可选“自动生成顺序号”:例如 数据库实验 01、02…

或选“逐行粘贴名称”:每行一个名称,按实际生成顺序对应项目。
草稿项目支持勾选后“批量改名”,可直接粘贴多行名称。
服务端会校验名称数量、长度和草稿状态,避免错位或修改已发布项目。
This commit is contained in:
2026-08-10 09:45:02 +08:00 Unverified
parent 4be61ab921
commit 3bcb976aa4
3 changed files with 207 additions and 4 deletions
@@ -37,6 +37,59 @@ public sealed class ExperimentsControllerTests
});
}
[Fact]
public async Task BatchProjects_AssignsPastedNamesAndSequentialNamesInGenerationOrder()
{
await using var fixture = await ExperimentFixture.CreateAsync();
var controller = fixture.Controller(fixture.ManagerScope);
var pasted = fixture.BatchProjectRequest(ExperimentArrangementMode.SelfScheduled) with
{
Names = ["实验一", "实验二"]
};
Assert.IsType<CreatedResult>(await controller.CreateProjects(pasted, CancellationToken.None));
Assert.Equal(["实验一", "实验二"], await fixture.Db.ExperimentProjects
.OrderBy(x => x.TeachingTask!.TaskNumber)
.Select(x => x.Name)
.ToListAsync());
fixture.Db.ExperimentProjects.RemoveRange(fixture.Db.ExperimentProjects);
await fixture.Db.SaveChangesAsync();
var sequential = fixture.BatchProjectRequest(ExperimentArrangementMode.SelfScheduled) with
{
Name = "数据库实验",
GenerateSequentialNames = true
};
Assert.IsType<CreatedResult>(await controller.CreateProjects(sequential, CancellationToken.None));
Assert.Equal(["数据库实验 01", "数据库实验 02"], await fixture.Db.ExperimentProjects
.OrderBy(x => x.TeachingTask!.TaskNumber)
.Select(x => x.Name)
.ToListAsync());
}
[Fact]
public async Task BatchProjectNames_UpdatesOnlySelectedDraftProjectsInRequestOrder()
{
await using var fixture = await ExperimentFixture.CreateAsync();
var controller = fixture.Controller(fixture.ManagerScope);
await controller.CreateProjects(
fixture.BatchProjectRequest(ExperimentArrangementMode.SelfScheduled),
CancellationToken.None);
var ids = await fixture.Db.ExperimentProjects
.OrderByDescending(x => x.TeachingTask!.TaskNumber)
.Select(x => x.Id)
.ToListAsync();
var result = await controller.UpdateProjectNames(
new ExperimentProjectBatchNamesRequest(ids, ["第二个", "第一个"]),
CancellationToken.None);
Assert.IsType<NoContentResult>(result);
var projectsById = await fixture.Db.ExperimentProjects.ToDictionaryAsync(x => x.Id, x => x.Name);
Assert.Equal("第二个", projectsById[ids[0]]);
Assert.Equal("第一个", projectsById[ids[1]]);
}
[Fact]
public async Task CentralizedBatchProjects_CreatesOneProjectForEveryScheduledExperimentLesson()
{