using Fengling.AuthService.Data; using Fengling.AuthService.Models; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; namespace Fengling.AuthService.Controllers; [ApiController] [Route("api/[controller]")] [Authorize] public class AccessLogsController : ControllerBase { private readonly ApplicationDbContext _context; private readonly ILogger _logger; public AccessLogsController( ApplicationDbContext context, ILogger logger) { _context = context; _logger = logger; } [HttpGet] public async Task> GetAccessLogs( [FromQuery] int page = 1, [FromQuery] int pageSize = 20, [FromQuery] string? userName = null, [FromQuery] string? tenantId = null, [FromQuery] string? action = null, [FromQuery] string? status = null, [FromQuery] DateTime? startTime = null, [FromQuery] DateTime? endTime = null) { var query = _context.AccessLogs.AsQueryable(); if (!string.IsNullOrEmpty(userName)) { query = query.Where(l => l.UserName != null && l.UserName.Contains(userName)); } if (!string.IsNullOrEmpty(tenantId)) { query = query.Where(l => l.TenantId == tenantId); } if (!string.IsNullOrEmpty(action)) { query = query.Where(l => l.Action == action); } if (!string.IsNullOrEmpty(status)) { query = query.Where(l => l.Status == status); } if (startTime.HasValue) { query = query.Where(l => l.CreatedAt >= startTime.Value); } if (endTime.HasValue) { query = query.Where(l => l.CreatedAt <= endTime.Value); } var totalCount = await query.CountAsync(); var logs = await query .OrderByDescending(l => l.CreatedAt) .Skip((page - 1) * pageSize) .Take(pageSize) .ToListAsync(); var result = logs.Select(l => new { id = l.Id, userName = l.UserName, tenantId = l.TenantId, action = l.Action, resource = l.Resource, method = l.Method, ipAddress = l.IpAddress, userAgent = l.UserAgent, status = l.Status, duration = l.Duration, requestData = l.RequestData, responseData = l.ResponseData, errorMessage = l.ErrorMessage, createdAt = l.CreatedAt, }); return Ok(new { items = result, totalCount, page, pageSize }); } [HttpGet("export")] public async Task ExportAccessLogs( [FromQuery] string? userName = null, [FromQuery] string? tenantId = null, [FromQuery] string? action = null, [FromQuery] string? status = null, [FromQuery] DateTime? startTime = null, [FromQuery] DateTime? endTime = null) { var query = _context.AccessLogs.AsQueryable(); if (!string.IsNullOrEmpty(userName)) { query = query.Where(l => l.UserName != null && l.UserName.Contains(userName)); } if (!string.IsNullOrEmpty(tenantId)) { query = query.Where(l => l.TenantId == tenantId); } if (!string.IsNullOrEmpty(action)) { query = query.Where(l => l.Action == action); } if (!string.IsNullOrEmpty(status)) { query = query.Where(l => l.Status == status); } if (startTime.HasValue) { query = query.Where(l => l.CreatedAt >= startTime.Value); } if (endTime.HasValue) { query = query.Where(l => l.CreatedAt <= endTime.Value); } var logs = await query .OrderByDescending(l => l.CreatedAt) .Take(10000) .ToListAsync(); var csv = new System.Text.StringBuilder(); csv.AppendLine("ID,UserName,TenantId,Action,Resource,Method,IpAddress,UserAgent,Status,Duration,CreatedAt"); foreach (var log in logs) { csv.AppendLine($"{log.Id},{log.UserName},{log.TenantId},{log.Action},{log.Resource},{log.Method},{log.IpAddress},\"{log.UserAgent}\",{log.Status},{log.Duration},{log.CreatedAt:yyyy-MM-dd HH:mm:ss}"); } return File(System.Text.Encoding.UTF8.GetBytes(csv.ToString()), "text/csv", $"access-logs-{DateTime.UtcNow:yyyyMMdd}.csv"); } }