using IdentityService.Infrastructure; using IM.InitCommon.Management; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; namespace IdentityService.WebApi.Controllers; [ApiController, Route("internal/management")] public sealed class ManagementController(UserDbContext db, InternalClient client) : ControllerBase { [HttpGet("summary")] public async Task Summary() => new { total = await db.Users.CountAsync() }; [HttpGet("access/{id:guid}")] public async Task Access(Guid id) { var u = await db.Users.AsNoTracking().SingleOrDefaultAsync(x => x.Id == id); return new(u is not null && u.Status == Domain.UserState.Normal && !u.IsDeleted, u?.SecurityStamp ?? ""); } [HttpGet("list")] public async Task List(string? q, string? status, int page = 1, int size = 8) { page = Math.Max(1, page); size = Math.Clamp(size, 1, 100); var query = db.Users.AsNoTracking().Where(x => q == null || x.NickName.Contains(q) || x.UserName!.Contains(q) || x.Id.ToString() == q); if (!string.IsNullOrEmpty(status)) { var state = status == "封禁" ? Domain.UserState.Banned : status == "正常" ? Domain.UserState.Normal : Domain.UserState.Inactive; query = query.Where(x => x.Status == state); } return new { items = await query.OrderByDescending(x => x.CreationTime).Skip((page - 1) * size).Take(size).Select(x => new { x.Id, name = x.NickName, account = x.UserName, x.Region, status = x.Status == Domain.UserState.Banned ? "封禁" : x.Status == Domain.UserState.Normal ? "正常" : "未激活", createdAt = x.CreationTime }).ToListAsync(), total = await query.CountAsync(), page, size }; } [HttpGet("detail/{id:guid}")] public async Task Detail(Guid id) { var u = await db.Users.AsNoTracking().SingleOrDefaultAsync(x => x.Id == id); if (u is null) return NotFound(); var groups = await client.Send("group", $"/internal/management/user/{id}/groups"); return Ok(new { u.Id, name = u.NickName, account = u.UserName, u.Region, u.Description, createdAt = u.CreationTime, status = u.Status == Domain.UserState.Banned ? "封禁" : u.Status == Domain.UserState.Normal ? "正常" : "未激活", groups }); } [HttpPost("action")] public async Task Action(InternalAction command, CancellationToken ct) { if (command.Action is not "封禁" and not "解封") return BadRequest(); var receipt = await ReceiptStore.Execute(db, command, async () => { var u = await db.Users.SingleOrDefaultAsync(x => x.Id == command.TargetId, ct) ?? throw new InvalidOperationException("用户不存在"); var before = u.Status == Domain.UserState.Banned ? "封禁" : "正常"; if (command.Action == "封禁") u.Ban(command.Reason); else u.Unban(); u.SecurityStamp = Guid.NewGuid().ToString("N"); return new ActionReceipt(u.NickName, before, command.Action == "封禁" ? "封禁" : "正常"); }, ct); if (command.Action == "封禁") await client.Send("connector", $"/internal/management/disconnect/{command.TargetId}", new { }, ct); return Ok(receipt); } }