支持考试创建、草稿修改、发布状态切换及不可逆归档。 支持科目、费用、满分和合格线策略校验。 保留已有报名禁止修改科目、待处理成绩复议禁止归档等规则。 数据修改、科目替换与审计日志使用同一数据库事务。 新增 ADMIN_NATIVE_EXAM_MANAGEMENT_ENABLED 独立开关。 路由与实现见 [AdminExamManagementService.cs (line 9)](C:/Users/BI/Documents/EIS-dotnet/src/Eis.Infrastructure/Administration/AdminExamManagementService.cs:9) 和 [NativeAdminReadEndpoints.cs (line 133)](C:/Users/BI/Documents/EIS-dotnet/src/Eis.Web/Administration/NativeAdminReadEndpoints.cs:133)。 迁移说明已更新至 [MIGRATION.md (line 57)](C:/Users/BI/Documents/EIS-dotnet/MIGRATION.md:57)。
156 lines
14 KiB
C#
156 lines
14 KiB
C#
using Eis.Application.Administration;
|
|
using Eis.Infrastructure.Administration;
|
|
using System.Text.Json.Nodes;
|
|
|
|
namespace Eis.Web.Administration;
|
|
|
|
public static class NativeAdminReadEndpoints
|
|
{
|
|
public static IEndpointRouteBuilder MapNativeAdminReadEndpoints(
|
|
this IEndpointRouteBuilder endpoints,
|
|
AdminMigrationOptions options)
|
|
{
|
|
if (!options.NativeReadsEnabled) return endpoints;
|
|
|
|
endpoints.MapGet("/api/admin/context", (HttpContext context, IAdminReadService service, CancellationToken cancellationToken) =>
|
|
Execute(context, service.GetContextAsync(Token(context), cancellationToken)));
|
|
endpoints.MapGet("/api/admin/dashboard", (HttpContext context, IAdminReadService service, CancellationToken cancellationToken) =>
|
|
Execute(context, service.GetDashboardAsync(Token(context), cancellationToken)));
|
|
endpoints.MapGet("/api/admin/schools", (HttpContext context, IAdminReadService service, CancellationToken cancellationToken) =>
|
|
Execute(context, service.GetSchoolsAsync(Token(context), cancellationToken)));
|
|
endpoints.MapGet("/api/admin/school-organization", (HttpContext context, IAdminReadService service, CancellationToken cancellationToken) =>
|
|
Execute(context, service.GetSchoolOrganizationAsync(Token(context), cancellationToken)));
|
|
endpoints.MapGet("/api/admin/admins", (HttpContext context, IAdminReadService service, CancellationToken cancellationToken) =>
|
|
Execute(context, service.GetAdminsAsync(Token(context), cancellationToken)));
|
|
endpoints.MapGet("/api/admin/exams", (HttpContext context, IAdminReadService service, CancellationToken cancellationToken) =>
|
|
Execute(context, service.GetExamsAsync(Token(context), cancellationToken)));
|
|
|
|
if (options.NativeOrganizationWritesEnabled)
|
|
{
|
|
endpoints.MapPost("/api/admin/schools", (HttpContext context, JsonObject body, IAdminOrganizationService service, CancellationToken cancellationToken) =>
|
|
Execute(context, service.CreateSchoolAsync(Token(context), body, cancellationToken)));
|
|
endpoints.MapPatch("/api/admin/schools/{schoolId}", (HttpContext context, string schoolId, JsonObject body, IAdminOrganizationService service, CancellationToken cancellationToken) =>
|
|
Execute(context, service.UpdateSchoolAsync(Token(context), schoolId, body, cancellationToken)));
|
|
endpoints.MapPost("/api/admin/classes", (HttpContext context, JsonObject body, IAdminOrganizationService service, CancellationToken cancellationToken) =>
|
|
Execute(context, service.CreateClassAsync(Token(context), body, cancellationToken)));
|
|
endpoints.MapPatch("/api/admin/classes/{classId}", (HttpContext context, string classId, JsonObject body, IAdminOrganizationService service, CancellationToken cancellationToken) =>
|
|
Execute(context, service.UpdateClassAsync(Token(context), classId, body, cancellationToken)));
|
|
endpoints.MapPost("/api/admin/admins", (HttpContext context, JsonObject body, IAdminOrganizationService service, CancellationToken cancellationToken) =>
|
|
Execute(context, service.CreateAdminAsync(Token(context), body, cancellationToken)));
|
|
endpoints.MapPatch("/api/admin/admins/{adminId}", (HttpContext context, string adminId, JsonObject body, IAdminOrganizationService service, CancellationToken cancellationToken) =>
|
|
Execute(context, service.UpdateAdminAsync(Token(context), adminId, body, cancellationToken)));
|
|
endpoints.MapPost("/api/admin/admins/{adminId}/reset-password", (HttpContext context, string adminId, IAdminOrganizationService service, CancellationToken cancellationToken) =>
|
|
Execute(context, service.ResetAdminPasswordAsync(Token(context), adminId, cancellationToken)));
|
|
endpoints.MapPut("/api/admin/settings/self-registration", (HttpContext context, JsonObject body, IAdminOrganizationService service, CancellationToken cancellationToken) =>
|
|
Execute(context, service.UpdateSelfRegistrationAsync(Token(context), body, cancellationToken)));
|
|
}
|
|
|
|
if (options.NativeAccountBatchesEnabled)
|
|
{
|
|
endpoints.MapGet("/api/admin/candidate-account-batches", (HttpContext context, IAdminAccountBatchService service, CancellationToken cancellationToken) =>
|
|
Execute(context, service.GetAsync(Token(context), cancellationToken)));
|
|
endpoints.MapPost("/api/admin/candidate-account-batches", (HttpContext context, JsonObject body, IAdminAccountBatchService service, CancellationToken cancellationToken) =>
|
|
Execute(context, service.SubmitAsync(Token(context), body, cancellationToken)));
|
|
endpoints.MapPatch("/api/admin/candidate-account-batches/{batchId}", (HttpContext context, string batchId, JsonObject body, IAdminAccountBatchService service, CancellationToken cancellationToken) =>
|
|
Execute(context, service.ReviewAsync(Token(context), batchId, body, cancellationToken)));
|
|
}
|
|
|
|
if (options.NativeConfigurationEnabled)
|
|
{
|
|
endpoints.MapGet("/api/admin/number-rules", (HttpContext context, IAdminConfigurationService service, CancellationToken cancellationToken) =>
|
|
Execute(context, service.GetNumberRulesAsync(Token(context), cancellationToken)));
|
|
endpoints.MapPost("/api/admin/number-rules", (HttpContext context, JsonObject body, IAdminConfigurationService service, CancellationToken cancellationToken) =>
|
|
Execute(context, service.SaveNumberRuleAsync(Token(context), body, cancellationToken)));
|
|
endpoints.MapGet("/api/admin/workflows", (HttpContext context, IAdminConfigurationService service, CancellationToken cancellationToken) =>
|
|
Execute(context, service.GetWorkflowsAsync(Token(context), cancellationToken)));
|
|
endpoints.MapPut("/api/admin/workflows/{businessType}", (HttpContext context, string businessType, JsonObject body, IAdminConfigurationService service, CancellationToken cancellationToken) =>
|
|
Execute(context, service.SaveWorkflowAsync(Token(context), businessType, body, cancellationToken)));
|
|
}
|
|
|
|
if (options.NativeNoticeManagementEnabled)
|
|
{
|
|
endpoints.MapGet("/api/admin/notices", (HttpContext context, IAdminNoticeService service, CancellationToken cancellationToken) =>
|
|
Execute(context, service.ListAsync(Token(context), cancellationToken)));
|
|
endpoints.MapPost("/api/admin/notices", (HttpContext context, JsonObject body, IAdminNoticeService service, CancellationToken cancellationToken) =>
|
|
Execute(context, service.CreateAsync(Token(context), body, cancellationToken)));
|
|
endpoints.MapPatch("/api/admin/notices/{noticeId}", (HttpContext context, string noticeId, JsonObject body, IAdminNoticeService service, CancellationToken cancellationToken) =>
|
|
Execute(context, service.UpdateAsync(Token(context), noticeId, body, cancellationToken)));
|
|
endpoints.MapPatch("/api/admin/publications/{sourceType:regex(^(plan|qualification|admission|cutoff|reporting)$)}/{publicationId}",
|
|
(HttpContext context, string sourceType, string publicationId, JsonObject body, IAdminNoticeService service, CancellationToken cancellationToken) =>
|
|
Execute(context, service.UpdatePublicationVisibilityAsync(Token(context), sourceType, publicationId, body, cancellationToken)));
|
|
}
|
|
|
|
if (options.NativeCentersEnabled)
|
|
{
|
|
endpoints.MapGet("/api/admin/centers", (HttpContext context, IAdminCenterService service, CancellationToken cancellationToken) =>
|
|
Execute(context, service.GetAsync(Token(context), cancellationToken)));
|
|
endpoints.MapPost("/api/admin/centers", (HttpContext context, JsonObject body, IAdminCenterService service, CancellationToken cancellationToken) =>
|
|
Execute(context, service.CreateAsync(Token(context), body, cancellationToken)));
|
|
endpoints.MapPatch("/api/admin/centers/{centerId}", (HttpContext context, string centerId, JsonObject body, IAdminCenterService service, CancellationToken cancellationToken) =>
|
|
Execute(context, service.UpdateAsync(Token(context), centerId, body, cancellationToken)));
|
|
endpoints.MapPatch("/api/admin/center-change-requests/{changeRequestId}", (HttpContext context, string changeRequestId, JsonObject body, IAdminCenterService service, CancellationToken cancellationToken) =>
|
|
Execute(context, service.ReviewAsync(Token(context), changeRequestId, body, cancellationToken)));
|
|
}
|
|
|
|
if (options.NativeOperationalReadsEnabled)
|
|
{
|
|
endpoints.MapGet("/api/admin/candidates", (HttpContext context, IAdminOperationalReadService service, CancellationToken cancellationToken) =>
|
|
Execute(context, service.GetCandidatesAsync(Token(context), cancellationToken)));
|
|
endpoints.MapGet("/api/admin/registrations", (HttpContext context, IAdminOperationalReadService service, CancellationToken cancellationToken) =>
|
|
Execute(context, service.GetRegistrationsAsync(Token(context), cancellationToken)));
|
|
endpoints.MapGet("/api/admin/payments", (HttpContext context, IAdminOperationalReadService service, CancellationToken cancellationToken) =>
|
|
Execute(context, service.GetPaymentsAsync(Token(context), cancellationToken)));
|
|
}
|
|
|
|
if (options.NativeCandidateManagementEnabled)
|
|
{
|
|
endpoints.MapPost("/api/admin/candidate-accounts/archive", (HttpContext context, JsonObject body, IAdminCandidateManagementService service, CancellationToken cancellationToken) =>
|
|
Execute(context, service.ArchiveAccountsAsync(Token(context), body, cancellationToken)));
|
|
endpoints.MapPost("/api/admin/candidates/{profileId}/reset-password", (HttpContext context, string profileId, IAdminCandidateManagementService service, CancellationToken cancellationToken) =>
|
|
Execute(context, service.ResetPasswordAsync(Token(context), profileId, cancellationToken)));
|
|
endpoints.MapPatch("/api/admin/candidates/{profileId}", (HttpContext context, string profileId, JsonObject body, IAdminCandidateManagementService service, CancellationToken cancellationToken) =>
|
|
Execute(context, service.ReviewProfileAsync(Token(context), profileId, body, cancellationToken)));
|
|
}
|
|
|
|
if (options.NativeRegistrationPaymentWritesEnabled)
|
|
{
|
|
endpoints.MapPatch("/api/admin/registrations/{registrationId}", (HttpContext context, string registrationId, JsonObject body, IAdminRegistrationManagementService service, CancellationToken cancellationToken) =>
|
|
Execute(context, service.ReviewAsync(Token(context), registrationId, body, cancellationToken)));
|
|
endpoints.MapPatch("/api/admin/payments/{registrationId}", (HttpContext context, string registrationId, JsonObject body, IAdminRegistrationManagementService service, CancellationToken cancellationToken) =>
|
|
Execute(context, service.UpdatePaymentAsync(Token(context), registrationId, body, cancellationToken)));
|
|
}
|
|
|
|
if (options.NativeWorkflowOperationsEnabled)
|
|
{
|
|
endpoints.MapGet("/api/admin/workflow-instances", (HttpContext context, IAdminWorkflowService service, CancellationToken cancellationToken) =>
|
|
Execute(context, service.GetAsync(Token(context), cancellationToken)));
|
|
endpoints.MapPatch("/api/admin/workflow-instances/{instanceId}/transfer", (HttpContext context, string instanceId, JsonObject body, IAdminWorkflowService service, CancellationToken cancellationToken) =>
|
|
Execute(context, service.TransferAsync(Token(context), instanceId, body, cancellationToken)));
|
|
endpoints.MapPatch("/api/admin/workflow-instances/{instanceId}/supervise", (HttpContext context, string instanceId, JsonObject body, IAdminWorkflowService service, CancellationToken cancellationToken) =>
|
|
Execute(context, service.SuperviseAsync(Token(context), instanceId, body, cancellationToken)));
|
|
}
|
|
|
|
if (options.NativeExamManagementEnabled)
|
|
{
|
|
endpoints.MapPost("/api/admin/exams", (HttpContext context, JsonObject body, IAdminExamManagementService service, CancellationToken cancellationToken) =>
|
|
Execute(context, service.CreateAsync(Token(context), body, cancellationToken)));
|
|
endpoints.MapPatch("/api/admin/exams/{examId}", (HttpContext context, string examId, JsonObject body, IAdminExamManagementService service, CancellationToken cancellationToken) =>
|
|
Execute(context, service.UpdateAsync(Token(context), examId, body, cancellationToken)));
|
|
endpoints.MapPost("/api/admin/exams/{examId}/archive", (HttpContext context, string examId, IAdminExamManagementService service, CancellationToken cancellationToken) =>
|
|
Execute(context, service.ArchiveAsync(Token(context), examId, cancellationToken)));
|
|
}
|
|
return endpoints;
|
|
}
|
|
|
|
private static async Task<IResult> Execute(HttpContext context, Task<AdminEndpointResult> operation)
|
|
{
|
|
var result = await operation;
|
|
context.Response.Headers.CacheControl = "no-store";
|
|
context.Response.Headers["X-EIS-Implementation"] = "aspnet-core";
|
|
return Results.Json(result.Body, statusCode: result.StatusCode);
|
|
}
|
|
|
|
private static string Token(HttpContext context) =>
|
|
context.Request.Cookies.TryGetValue("hz_session", out var token) ? token : string.Empty;
|
|
}
|