开放实验项目发布后修正功能

This commit is contained in:
2026-08-10 17:02:39 +08:00 Unverified
parent fc326ac16e
commit 834574accb
3 changed files with 128 additions and 8 deletions
@@ -666,6 +666,39 @@ public sealed class ExperimentsController(
return NoContent();
}
[HttpPut("{id:guid}/published-details")]
[Authorize(Roles = Managers)]
public async Task<ActionResult> CorrectPublishedProjectDetails(
Guid id,
PublishedExperimentProjectCorrectionRequest request,
CancellationToken cancellationToken)
{
var project = await ScopedProjects()
.Include(x => x.TeachingTask)
.ThenInclude(x => x!.Teachers)
.ThenInclude(x => x.Teacher)
.Include(x => x.TeachingTask)
.ThenInclude(x => x!.Course)
.FirstOrDefaultAsync(x => x.Id == id, cancellationToken);
if (project is null) return NotFound();
if (project.Status != ExperimentProjectStatus.Published)
return ConflictProblem("只有已发布实验项目可以修正教学内容。");
if (!CanCorrectPublishedProject(project.TeachingTask!)) return Forbid();
if (string.IsNullOrWhiteSpace(request.Name))
return ValidationProblem("请填写实验项目名称。");
var changed = project.Name != request.Name.Trim() ||
project.Description != Normalize(request.Description) ||
project.Requirements != Normalize(request.Requirements);
project.Name = request.Name.Trim();
project.Description = Normalize(request.Description);
project.Requirements = Normalize(request.Requirements);
await db.SaveChangesAsync(cancellationToken);
if (changed)
await NotifyProjectCorrectionAsync(project, cancellationToken);
return NoContent();
}
[HttpPut("batch/names")]
[Authorize(Roles = Managers)]
public async Task<ActionResult> UpdateProjectNames(
@@ -1442,6 +1475,16 @@ public sealed class ExperimentsController(
taskIds.Contains(x.TeachingTaskId));
}
private bool CanCorrectPublishedProject(TeachingTask task)
{
var scope = currentUserDataScope.Current;
return scope.IsInRole(SystemRoles.SuperAdmin) ||
scope.IsInRole(SystemRoles.AcademicAdmin) ||
scope.IsInRole(SystemRoles.CollegeAdmin) ||
task.Teachers.Any(item =>
item.Teacher?.UserId == scope.UserId);
}
private Task<Student?> CurrentStudentAsync(
CancellationToken cancellationToken) =>
db.Students.FirstOrDefaultAsync(x =>
@@ -1492,6 +1535,22 @@ public sealed class ExperimentsController(
NotificationCategory.Schedule);
}
private async Task NotifyProjectCorrectionAsync(
ExperimentProject project,
CancellationToken cancellationToken)
{
var userIds = await RosterUserIdsAsync(project.TeachingTaskId, cancellationToken);
if (userIds.Count == 0) return;
await NotificationService.SendToUserIdsAsync(
db,
userIds,
"实验项目内容已更新",
$"《{project.TeachingTask!.Course!.Name}》的“{project.Name}”教学内容或要求已修正,请重新查看。",
"/experiments",
cancellationToken,
NotificationCategory.Schedule);
}
private static List<Guid>? ValidateBulkProjectIds(IReadOnlyList<Guid>? projectIds)
{
var ids = projectIds?.Where(x => x != Guid.Empty).Distinct().ToList();
@@ -1569,6 +1628,11 @@ public sealed record ExperimentProjectRequest(
DateOnly EndDate,
Guid? ScheduleEntryId = null);
public sealed record PublishedExperimentProjectCorrectionRequest(
[Required, MaxLength(120)] string Name,
[MaxLength(1000)] string? Description,
[MaxLength(1000)] string? Requirements);
public sealed record ExperimentProjectBatchRequest(
[Required] IReadOnlyList<Guid> TeachingTaskIds,
[Required, MaxLength(40)] string Code,