feat(web): migrate course adjustment workflow
This commit is contained in:
1 parent
2ac0a82bb8
commit
c5b6954f9c
8 files changed
+209
-1
No files matched your search
@@ -170,6 +170,25 @@ public sealed class CourseAdjustmentsController(
|
|||||||
return Ok(new { Task = task, Sessions = sessions, Classrooms = classrooms, Periods = periods });
|
return Ok(new { Task = task, Sessions = sessions, Classrooms = classrooms, Periods = periods });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpGet("teacher-options")]
|
||||||
|
[Authorize(Roles = Applicants)]
|
||||||
|
public async Task<ActionResult> GetTeacherOptions(CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
return Ok(await db.Teachers.AsNoTracking()
|
||||||
|
.Where(x => x.Status == TeacherStatus.Active && !x.IsArchived)
|
||||||
|
.OrderBy(x => x.College!.Name)
|
||||||
|
.ThenBy(x => x.TeacherNumber)
|
||||||
|
.Select(x => new
|
||||||
|
{
|
||||||
|
x.Id,
|
||||||
|
x.TeacherNumber,
|
||||||
|
x.Name,
|
||||||
|
x.Title,
|
||||||
|
CollegeName = x.College!.Name
|
||||||
|
})
|
||||||
|
.ToListAsync(cancellationToken));
|
||||||
|
}
|
||||||
|
|
||||||
// ═══════════════ My adjustments ═══════════════
|
// ═══════════════ My adjustments ═══════════════
|
||||||
|
|
||||||
[HttpGet("mine")]
|
[HttpGet("mine")]
|
||||||
@@ -611,7 +630,8 @@ public sealed class CourseAdjustmentsController(
|
|||||||
return ValidationProblem("请选择代课教师。");
|
return ValidationProblem("请选择代课教师。");
|
||||||
if (!await db.Teachers.AnyAsync(x =>
|
if (!await db.Teachers.AnyAsync(x =>
|
||||||
x.Id == request.SubstituteTeacherId &&
|
x.Id == request.SubstituteTeacherId &&
|
||||||
x.Status == TeacherStatus.Active, cancellationToken))
|
x.Status == TeacherStatus.Active &&
|
||||||
|
!x.IsArchived, cancellationToken))
|
||||||
return ValidationProblem("代课教师不存在或已离职。");
|
return ValidationProblem("代课教师不存在或已离职。");
|
||||||
break;
|
break;
|
||||||
case CourseAdjustmentType.Cancel:
|
case CourseAdjustmentType.Cancel:
|
||||||
|
|||||||
@@ -6,11 +6,46 @@ using Jiaowu.Api.Infrastructure.Persistence;
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.Data.Sqlite;
|
using Microsoft.Data.Sqlite;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using System.Text.Json;
|
||||||
|
|
||||||
namespace Jiaowu.Api.Tests;
|
namespace Jiaowu.Api.Tests;
|
||||||
|
|
||||||
public sealed class CourseAdjustmentsControllerTests
|
public sealed class CourseAdjustmentsControllerTests
|
||||||
{
|
{
|
||||||
|
[Fact]
|
||||||
|
public async Task TeacherOptions_ReturnOnlyActiveNonArchivedTeachers()
|
||||||
|
{
|
||||||
|
await using var fixture = await Fixture.CreateAsync();
|
||||||
|
var collegeId = await fixture.Db.Courses.Select(x => x.CollegeId).SingleAsync();
|
||||||
|
fixture.Db.Teachers.AddRange(
|
||||||
|
new Teacher
|
||||||
|
{
|
||||||
|
TeacherNumber = "T002",
|
||||||
|
Name = "离职教师",
|
||||||
|
CollegeId = collegeId,
|
||||||
|
Status = TeacherStatus.Retired
|
||||||
|
},
|
||||||
|
new Teacher
|
||||||
|
{
|
||||||
|
TeacherNumber = "T003",
|
||||||
|
Name = "归档教师",
|
||||||
|
CollegeId = collegeId,
|
||||||
|
IsArchived = true
|
||||||
|
});
|
||||||
|
await fixture.Db.SaveChangesAsync();
|
||||||
|
|
||||||
|
var controller = new CourseAdjustmentsController(
|
||||||
|
fixture.Db,
|
||||||
|
new TestScope(fixture.TeacherUserId, DataScope.Self, SystemRoles.Teacher));
|
||||||
|
var result = await controller.GetTeacherOptions(CancellationToken.None);
|
||||||
|
|
||||||
|
var ok = Assert.IsType<OkObjectResult>(result);
|
||||||
|
var json = JsonSerializer.Serialize(ok.Value);
|
||||||
|
Assert.Contains("T001", json);
|
||||||
|
Assert.DoesNotContain("T002", json);
|
||||||
|
Assert.DoesNotContain("T003", json);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task Reschedule_MovesOnlyTheSelectedOccurrence()
|
public async Task Reschedule_MovesOnlyTheSelectedOccurrence()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -51,6 +51,7 @@
|
|||||||
| `/teaching-tasks` | 教学任务 | SuperAdmin、AcademicAdmin、CollegeAdmin | 游标分页、职责范围、草稿编制、授课资格、状态流转、批量操作与公共课合班生成 | verification |
|
| `/teaching-tasks` | 教学任务 | SuperAdmin、AcademicAdmin、CollegeAdmin | 游标分页、职责范围、草稿编制、授课资格、状态流转、批量操作与公共课合班生成 | verification |
|
||||||
| `/schedules` | 排课管理 | SuperAdmin、AcademicAdmin | 版本草稿、手工排课、冲突校验、后台自动排课、异步发布、作息、优化策略与课程约束 | verification |
|
| `/schedules` | 排课管理 | SuperAdmin、AcademicAdmin | 版本草稿、手工排课、冲突校验、后台自动排课、异步发布、作息、优化策略与课程约束 | verification |
|
||||||
| `/timetable`、`/class-timetable`、`/teacher-timetable/:teacherId` | 公开/管理/教师课表 | 公开;教务管理与领导可查草稿 | 班级/教师/教室资源、版本切换、周/日/总览、考试实验融合、单项与批量 Excel/PDF | verification |
|
| `/timetable`、`/class-timetable`、`/teacher-timetable/:teacherId` | 公开/管理/教师课表 | 公开;教务管理与领导可查草稿 | 班级/教师/教室资源、版本切换、周/日/总览、考试实验融合、单项与批量 Excel/PDF | verification |
|
||||||
|
| `/course-adjustments` | 调停课管理 | Teacher、SuperAdmin、AcademicAdmin、CollegeAdmin | 原课次锁定、调课/停课/补课/代课申请、草稿提交、学院范围审核、冲突复核与通知定位 | verification |
|
||||||
| `/activate` | 学生账号激活 | 公开 | 学籍选项、身份匹配、强密码和一次性激活 | verification |
|
| `/activate` | 学生账号激活 | 公开 | 学籍选项、身份匹配、强密码和一次性激活 | verification |
|
||||||
| `/verify/:verificationCode?` | 电子凭证验真 | 公开 | 唯一编号、实时状态、签发信息和 PDF 哈希 | verification |
|
| `/verify/:verificationCode?` | 电子凭证验真 | 公开 | 唯一编号、实时状态、签发信息和 PDF 哈希 | verification |
|
||||||
| `/classroom-repairs/report/:classroomId` | 教室扫码报修 | 公开 | 教室设备、故障类别、联系方式和工单提交 | verification |
|
| `/classroom-repairs/report/:classroomId` | 教室扫码报修 | 公开 | 教室设备、故障类别、联系方式和工单提交 | verification |
|
||||||
|
|||||||
Loaded 3 of 8 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user