学籍异动:休学、复学、退学申请及辅导员→学院→教务处分级审批。
毕业审核:批次计算、缺失课程检查、人工复核、结果发布。 学位授予:毕业资格与 GPA 计算、人工调整、发布授予结果。 毕业离校:离校事项配置、责任角色分工、逐项办理及批次关闭。
This commit is contained in:
@@ -30,6 +30,37 @@ public sealed class StudentStatusChangesController(
|
||||
}).ToListAsync(token));
|
||||
}
|
||||
|
||||
[HttpGet("options")]
|
||||
[Authorize(Roles = SystemRoles.Student)]
|
||||
public async Task<ActionResult> GetOptions(CancellationToken token)
|
||||
{
|
||||
var userId = currentUserDataScope.Current.UserId;
|
||||
var student = await db.Students.AsNoTracking()
|
||||
.FirstOrDefaultAsync(x => x.UserId == userId, token);
|
||||
if (student is null) return ConflictProblem("当前账号未关联学生档案。");
|
||||
|
||||
var types = student.Status switch
|
||||
{
|
||||
StudentStatus.Active => new[]
|
||||
{
|
||||
StudentStatusChangeType.Suspension,
|
||||
StudentStatusChangeType.Withdrawal
|
||||
},
|
||||
StudentStatus.Suspended => new[]
|
||||
{
|
||||
StudentStatusChangeType.Resumption,
|
||||
StudentStatusChangeType.Withdrawal
|
||||
},
|
||||
_ => []
|
||||
};
|
||||
var hasPending = await db.StudentStatusChanges.AnyAsync(x =>
|
||||
x.StudentId == student.Id &&
|
||||
(x.State == StudentStatusChangeState.Submitted ||
|
||||
x.State == StudentStatusChangeState.CounselorApproved ||
|
||||
x.State == StudentStatusChangeState.CollegeApproved), token);
|
||||
return Ok(new { student.Status, Types = types, HasPending = hasPending });
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Authorize(Roles = SystemRoles.Student)]
|
||||
public async Task<ActionResult> Create(
|
||||
@@ -76,14 +107,19 @@ public sealed class StudentStatusChangesController(
|
||||
.FirstOrDefaultAsync(x => x.Id == id, token);
|
||||
if (change is null) return NotFound();
|
||||
var scope = currentUserDataScope.Current;
|
||||
if (!CanReviewCurrentStage(scope, change.State))
|
||||
return ConflictProblem("当前角色或审核阶段不允许执行该操作。");
|
||||
|
||||
if (!request.Approved)
|
||||
{
|
||||
if (change.State is StudentStatusChangeState.Approved or
|
||||
StudentStatusChangeState.Rejected or StudentStatusChangeState.Cancelled)
|
||||
return ConflictProblem("该申请已经结束。");
|
||||
if (string.IsNullOrWhiteSpace(request.Comment))
|
||||
return BadRequest(new ProblemDetails
|
||||
{
|
||||
Title = "审核意见不完整",
|
||||
Detail = "驳回申请时必须填写审核意见。",
|
||||
Status = StatusCodes.Status400BadRequest
|
||||
});
|
||||
change.State = StudentStatusChangeState.Rejected;
|
||||
change.ReviewComment = request.Comment?.Trim();
|
||||
change.ReviewedAt = DateTime.UtcNow;
|
||||
}
|
||||
else if (scope.IsInRole(SystemRoles.Counselor) &&
|
||||
change.State == StudentStatusChangeState.Submitted)
|
||||
@@ -100,12 +136,30 @@ public sealed class StudentStatusChangesController(
|
||||
change.ApprovedAt = DateTime.UtcNow;
|
||||
}
|
||||
else return ConflictProblem("当前角色或审核阶段不允许执行该操作。");
|
||||
|
||||
change.ReviewComment = request.Comment?.Trim();
|
||||
change.ReviewedAt = DateTime.UtcNow;
|
||||
await db.SaveChangesAsync(token);
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
[HttpPost("{id:guid}/cancel")]
|
||||
[Authorize(Roles = SystemRoles.Student)]
|
||||
public async Task<ActionResult> Cancel(Guid id, CancellationToken token)
|
||||
{
|
||||
var userId = currentUserDataScope.Current.UserId;
|
||||
var change = await db.StudentStatusChanges.FirstOrDefaultAsync(
|
||||
x => x.Id == id && x.Student!.UserId == userId, token);
|
||||
if (change is null) return NotFound();
|
||||
if (change.State != StudentStatusChangeState.Submitted)
|
||||
return ConflictProblem("只有尚未进入审核的申请可以撤回。");
|
||||
|
||||
change.State = StudentStatusChangeState.Cancelled;
|
||||
change.ReviewedAt = DateTime.UtcNow;
|
||||
await db.SaveChangesAsync(token);
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
private IQueryable<StudentStatusChange> ScopedChanges()
|
||||
{
|
||||
var scope = currentUserDataScope.Current;
|
||||
@@ -123,6 +177,21 @@ public sealed class StudentStatusChangesController(
|
||||
return source.Where(_ => false);
|
||||
}
|
||||
|
||||
private static bool CanReviewCurrentStage(
|
||||
CurrentUserScope scope,
|
||||
StudentStatusChangeState state) =>
|
||||
state switch
|
||||
{
|
||||
StudentStatusChangeState.Submitted =>
|
||||
scope.IsInRole(SystemRoles.Counselor),
|
||||
StudentStatusChangeState.CounselorApproved =>
|
||||
scope.IsInRole(SystemRoles.CollegeAdmin),
|
||||
StudentStatusChangeState.CollegeApproved =>
|
||||
scope.IsInRole(SystemRoles.AcademicAdmin) ||
|
||||
scope.IsInRole(SystemRoles.SuperAdmin),
|
||||
_ => false
|
||||
};
|
||||
|
||||
private ActionResult ConflictProblem(string detail) => Conflict(new ProblemDetails
|
||||
{
|
||||
Title = "无法完成学籍异动操作", Detail = detail,
|
||||
|
||||
Reference in New Issue
Block a user