using System.Security.Claims; using IM.Admin.Data; using IM.InitCommon.Management; using Microsoft.EntityFrameworkCore; namespace IM.Admin.Api; public sealed class ApiError(int status, string message) : Exception(message) { public int Status { get; } = status; } public static class ApiSupport { public static Guid Actor(this HttpContext c) => Guid.Parse(c.User.FindFirstValue(ClaimTypes.NameIdentifier)!); public static string ActorName(this HttpContext c) => c.User.Identity?.Name ?? ""; public static bool IsSuper(this HttpContext c) => c.User.IsInRole("super"); public static void Reason(string? reason) { if (string.IsNullOrWhiteSpace(reason) || reason.Length > 500) throw new ApiError(400, "请填写 1–500 字的操作原因"); } public static void Audit(this AdminDb db, HttpContext c, string action, string target, string before, string after, string reason, Guid? reportId = null) => db.Audit.Add(new AuditRecord { ActorId = c.Actor(), ActorName = c.ActorName(), Action = action, TargetId = target, TargetName = target, Before = before, After = after, Reason = reason, ReportId = reportId }); public static async Task> Page(IQueryable query, int page, int size, CancellationToken ct) { page = Math.Max(1, page); size = Math.Clamp(size, 1, 100); return new(await query.Skip((page - 1) * size).Take(size).ToListAsync(ct), await query.CountAsync(ct), page, size); } }