20 lines
1.4 KiB
C#
20 lines
1.4 KiB
C#
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<PageResult<T>> Page<T>(IQueryable<T> 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); }
|
||
}
|