mirror of
https://gitee.com/xiarenalofs/squad-rain-ops-mini.git
synced 2026-08-06 21:36:25 +08:00
251 lines
10 KiB
C#
251 lines
10 KiB
C#
using Microsoft.AspNetCore.Builder;
|
|
using Microsoft.AspNetCore.Http;
|
|
using SqlSugar;
|
|
using RainOpsMini.Helpers;
|
|
using RainOpsMini.Models;
|
|
using RainOpsMini.Helpers.SquadGameLog;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System;
|
|
using RainOpsMini.Models;
|
|
|
|
namespace RainOpsMini.Apis
|
|
{
|
|
public static class LogApi
|
|
{
|
|
public static void MapLogApis(this IEndpointRouteBuilder app)
|
|
{
|
|
// API: 获取游戏匹配日志
|
|
// 用于日志查询页面,支持分页和搜索
|
|
app.MapGet("/api/logs/game-match", (string? type, string? search, int? page, int? pageSize, HttpContext ctx) =>
|
|
{
|
|
if (!ctx.User.HasClaim("Permission", "logs") && !ctx.User.HasClaim("Permission", "all") && ctx.User.FindFirst("IsSuperAdmin")?.Value != "true") return Results.Unauthorized();
|
|
|
|
int p = page ?? 1;
|
|
int ps = pageSize ?? 20;
|
|
if (ps > 100) ps = 100; // 限制最大页大小
|
|
|
|
int total;
|
|
var logs = LogStorage.Instance.GetLogs(type, search, p, ps, out total);
|
|
|
|
return Results.Ok(new
|
|
{
|
|
total = total,
|
|
page = p,
|
|
pageSize = ps,
|
|
items = logs
|
|
});
|
|
});
|
|
|
|
// API: 获取日志统计信息
|
|
// 用于仪表盘展示各类日志的数量
|
|
app.MapGet("/api/logs/stats", (HttpContext ctx) =>
|
|
{
|
|
if (!ctx.User.HasClaim("Permission", "analytics") && !ctx.User.HasClaim("Permission", "all") && ctx.User.FindFirst("IsSuperAdmin")?.Value != "true") return Results.Unauthorized();
|
|
var stats = LogStorage.Instance.GetLogStats();
|
|
return Results.Json(stats);
|
|
});
|
|
|
|
// API: 获取用户登录统计
|
|
// 用于分析用户活跃度
|
|
app.MapGet("/api/analytics/user-stats", (HttpContext ctx) =>
|
|
{
|
|
if (!ctx.User.HasClaim("Permission", "analytics") && !ctx.User.HasClaim("Permission", "all") && ctx.User.FindFirst("IsSuperAdmin")?.Value != "true") return Results.Unauthorized();
|
|
|
|
using (var db = DbHelper.GetInstance())
|
|
{
|
|
var stats = db.Queryable<RainOpsMini.Models.UserLoginLog>()
|
|
.GroupBy(x => x.Username)
|
|
.Select(x => new
|
|
{
|
|
Username = x.Username,
|
|
Count = SqlFunc.AggregateCount(x.Id),
|
|
LastLogin = SqlFunc.AggregateMax(x.LoginTime)
|
|
})
|
|
.ToList();
|
|
|
|
// 按登录次数降序排序
|
|
var tableData = stats.OrderByDescending(x => x.Count).ToList();
|
|
|
|
return Results.Ok(new { tableData });
|
|
}
|
|
});
|
|
|
|
// API: 获取对局历史列表
|
|
// 分页查询历史对局记录
|
|
app.MapGet("/api/matches", (int? page, int? pageSize, HttpContext ctx) =>
|
|
{
|
|
if (!ctx.User.HasClaim("Permission", "logs") && !ctx.User.HasClaim("Permission", "all") && ctx.User.FindFirst("IsSuperAdmin")?.Value != "true") return Results.Unauthorized();
|
|
|
|
int p = page ?? 1;
|
|
int ps = pageSize ?? 20;
|
|
|
|
try
|
|
{
|
|
using (var db = DbHelper.GetInstance())
|
|
{
|
|
var total = 0;
|
|
var query = db.Queryable<MatchPlayerStats>()
|
|
.GroupBy(x => new { x.MatchId, x.MatchDate, x.MapName })
|
|
.Select(x => new
|
|
{
|
|
x.MatchId,
|
|
x.MatchDate,
|
|
x.MapName,
|
|
PlayerCount = SqlFunc.AggregateCount(x.Id)
|
|
})
|
|
.MergeTable(); // Merge result for pagination
|
|
|
|
var list = query.OrderByDescending(x => x.MatchDate)
|
|
.ToPageList(p, ps, ref total);
|
|
|
|
return Results.Ok(new { total, page = p, pageSize = ps, items = list });
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return Results.BadRequest(new { error = ex.Message });
|
|
}
|
|
});
|
|
|
|
// API: 获取单场对局详情
|
|
// 根据 MatchID 查询该场对局的所有玩家数据
|
|
app.MapGet("/api/matches/{matchId}", (string matchId, HttpContext ctx) =>
|
|
{
|
|
if (!ctx.User.HasClaim("Permission", "logs") && !ctx.User.HasClaim("Permission", "all") && ctx.User.FindFirst("IsSuperAdmin")?.Value != "true") return Results.Unauthorized();
|
|
|
|
if (string.IsNullOrEmpty(matchId)) return Results.BadRequest();
|
|
|
|
try
|
|
{
|
|
using (var db = DbHelper.GetInstance())
|
|
{
|
|
var stats = db.Queryable<MatchPlayerStats>()
|
|
.Where(x => x.MatchId == matchId)
|
|
.OrderByDescending(x => x.Kills) // Order by Kills by default
|
|
.ToList();
|
|
|
|
return Results.Ok(stats);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return Results.BadRequest(new { error = ex.Message });
|
|
}
|
|
});
|
|
|
|
// API: 玩家活跃度分析
|
|
app.MapGet("/api/analytics/players", (string? start, string? end, int? days, HttpContext ctx) =>
|
|
{
|
|
if (!ctx.User.HasClaim("Permission", "analytics") && !ctx.User.HasClaim("Permission", "all") && ctx.User.FindFirst("IsSuperAdmin")?.Value != "true") return Results.Unauthorized();
|
|
|
|
DateTime startDate;
|
|
DateTime endDate = DateTime.Now;
|
|
|
|
if (!string.IsNullOrEmpty(start) && DateTime.TryParse(start, out var s))
|
|
{
|
|
startDate = s;
|
|
}
|
|
else
|
|
{
|
|
int d = days ?? 7;
|
|
startDate = DateTime.Now.AddDays(-d);
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(end) && DateTime.TryParse(end, out var e))
|
|
{
|
|
endDate = e.AddDays(1); // Include the end date
|
|
}
|
|
|
|
using (var db = DbHelper.GetInstance())
|
|
{
|
|
var data = db.Queryable<ServerInfoLog>()
|
|
.Where(x => x.Timestamp >= startDate && x.Timestamp < endDate)
|
|
.OrderBy(x => x.Timestamp)
|
|
.Select(x => new { x.Timestamp, x.PlayerCount, x.MapName })
|
|
.ToList();
|
|
return Results.Json(data);
|
|
}
|
|
});
|
|
|
|
// API: 地图热度分析
|
|
app.MapGet("/api/analytics/maps", (string? start, string? end, int? days, HttpContext ctx) =>
|
|
{
|
|
if (!ctx.User.HasClaim("Permission", "analytics") && !ctx.User.HasClaim("Permission", "all") && ctx.User.FindFirst("IsSuperAdmin")?.Value != "true") return Results.Unauthorized();
|
|
|
|
DateTime startDate;
|
|
DateTime endDate = DateTime.Now;
|
|
|
|
if (!string.IsNullOrEmpty(start) && DateTime.TryParse(start, out var s))
|
|
{
|
|
startDate = s;
|
|
}
|
|
else
|
|
{
|
|
int d = days ?? 7;
|
|
startDate = DateTime.Now.AddDays(-d);
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(end) && DateTime.TryParse(end, out var e))
|
|
{
|
|
endDate = e.AddDays(1); // Include the end date
|
|
}
|
|
|
|
using (var db = DbHelper.GetInstance())
|
|
{
|
|
var data = db.Queryable<ServerInfoLog>()
|
|
.Where(x => x.Timestamp >= startDate && x.Timestamp < endDate)
|
|
.GroupBy(x => x.MapName)
|
|
.Select(x => new { MapName = x.MapName, Count = SqlFunc.AggregateCount(x.Id) })
|
|
.ToList()
|
|
.OrderByDescending(x => x.Count)
|
|
.ToList();
|
|
return Results.Json(data);
|
|
}
|
|
});
|
|
|
|
// API: 获取 Tickrate 历史
|
|
// 查询服务器 Tickrate、玩家数量等历史数据
|
|
app.MapGet("/api/analytics/tickrate", (string? start, string? end, int? days, HttpContext ctx) =>
|
|
{
|
|
if (ctx.User.Identity?.IsAuthenticated != true) return Results.Unauthorized();
|
|
|
|
DateTime startTime;
|
|
DateTime endTime = DateTime.Now;
|
|
|
|
if (!string.IsNullOrEmpty(start) && DateTime.TryParse(start, out var s))
|
|
{
|
|
startTime = s;
|
|
}
|
|
else
|
|
{
|
|
int queryDays = days ?? 3;
|
|
startTime = DateTime.Now.AddDays(-queryDays);
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(end) && DateTime.TryParse(end, out var e))
|
|
{
|
|
endTime = e.AddDays(1); // Include the end date
|
|
}
|
|
|
|
using (var db = DbHelper.GetInstance())
|
|
{
|
|
var data = db.Queryable<Log_Tick>()
|
|
.Where(x => x.LogTime >= startTime && x.LogTime < endTime)
|
|
.OrderBy(x => x.LogTime)
|
|
.Select(x => new
|
|
{
|
|
LogTime = x.LogTime,
|
|
TickRate = x.TickRate,
|
|
PlayerCount = x.PlayerCount,
|
|
MatchTime = x.MatchTime,
|
|
MapName = x.MapName
|
|
})
|
|
.ToList();
|
|
return Results.Ok(data);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|