Files
squad-rain-ops-mini/Apis/BanApi.cs

92 lines
4.3 KiB
C#

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using RainOpsMini.Helpers;
using RainOpsMini.Models;
using RainOpsMini.Services;
using System.Collections.Generic;
using System;
using System.Threading.Tasks;
namespace RainOpsMini.Apis
{
public static class BanApi
{
public static void MapBanApis(this IEndpointRouteBuilder app)
{
// API: 获取封禁列表
// 分页查询封禁记录,支持搜索
app.MapGet("/api/bans", async (int? page, int? pageSize, string? search, HttpContext ctx, BanService banService) =>
{
if (!ctx.User.HasClaim("Permission", "bans.view") && !ctx.User.HasClaim("Permission", "all") && ctx.User.FindFirst("IsSuperAdmin")?.Value != "true") return Results.Unauthorized();
return Results.Json(await banService.GetBansAsync(page ?? 1, pageSize ?? 20, search ?? ""));
});
// API: 解除封禁
// 从数据库和配置文件中移除封禁记录
app.MapPost("/api/bans/unban", async (BanRequest req, HttpContext ctx, BanService banService) =>
{
if (!ctx.User.HasClaim("Permission", "bans.delete") && !ctx.User.HasClaim("Permission", "all") && ctx.User.FindFirst("IsSuperAdmin")?.Value != "true") return Results.Unauthorized();
if (string.IsNullOrWhiteSpace(req.SteamId)) return Results.BadRequest("SteamID required");
string operatorName = ctx.User.Identity?.Name ?? "Unknown";
bool success = await banService.UnbanAsync(req.SteamId, operatorName);
if (success)
{
// Trigger immediate sync if needed, or wait for background task.
// Also try to RCON unban if possible, though Squad unban usually requires file update + reload.
// We will rely on background sync for file update.
return Results.Ok(new { message = "Unbanned" });
}
else
{
return Results.NotFound("Ban not found or already unbanned");
}
});
// API: 同步封禁列表
// 强制将数据库中的封禁记录写入 Bans.cfg
app.MapPost("/api/bans/sync", async (HttpContext ctx, BanService banService, BanSyncState syncState) =>
{
if (!ctx.User.HasClaim("Permission", "bans.edit") && !ctx.User.HasClaim("Permission", "all") && ctx.User.FindFirst("IsSuperAdmin")?.Value != "true") return Results.Unauthorized();
try
{
await banService.SyncToConfigFileAsync();
// Update sync state manually since user forced it
syncState.LastSyncTime = DateTime.Now;
// Reset next sync time based on interval from now,
// Note: Background service timer won't be reset by this, so it might run sooner than expected.
// This is acceptable for simple implementation.
// Ideally we should signal background service to restart timer, but that's complex.
// We just update the display state here.
syncState.NextSyncTime = DateTime.Now.Add(syncState.Interval);
return Results.Ok(new { message = "Synced to Bans.cfg", nextSync = syncState.NextSyncTime });
}
catch (Exception ex)
{
return Results.Json(new { error = ex.Message }, statusCode: 500);
}
});
// API: 获取同步状态
// 查看上次同步时间和下次计划同步时间
app.MapGet("/api/bans/sync-status", (HttpContext ctx, BanSyncState syncState) =>
{
if (!ctx.User.HasClaim("Permission", "bans.view") && !ctx.User.HasClaim("Permission", "all") && ctx.User.FindFirst("IsSuperAdmin")?.Value != "true") return Results.Unauthorized();
return Results.Json(new
{
lastSync = syncState.LastSyncTime,
nextSync = syncState.NextSyncTime,
intervalMinutes = syncState.Interval.TotalMinutes
});
});
}
}
}