using Fengling.Platform.Domain.AggregatesModel.UserAggregate; using Fengling.Platform.Domain.AggregatesModel.RoleAggregate; using Fengling.Platform.Infrastructure; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; namespace Fengling.AuthService.Controllers; [ApiController] [Route("api/[controller]")] [Authorize] public class AuditLogsController : ControllerBase { private readonly PlatformDbContext _context; private readonly ILogger _logger; public AuditLogsController( PlatformDbContext context, ILogger logger) { _context = context; _logger = logger; } [HttpGet] public async Task> GetAuditLogs( [FromQuery] int page = 1, [FromQuery] int pageSize = 20, [FromQuery] string? operatorName = null, [FromQuery] string? tenantId = null, [FromQuery] string? operation = null, [FromQuery] string? action = null, [FromQuery] DateTime? startTime = null, [FromQuery] DateTime? endTime = null) { var query = _context.AuditLogs.AsQueryable(); if (!string.IsNullOrEmpty(operatorName)) { query = query.Where(l => l.Operator.Contains(operatorName)); } if (!string.IsNullOrEmpty(tenantId)) { query = query.Where(l => l.TenantId == tenantId); } if (!string.IsNullOrEmpty(operation)) { query = query.Where(l => l.Operation == operation); } if (!string.IsNullOrEmpty(action)) { query = query.Where(l => l.Action == action); } 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, @operator = l.Operator, tenantId = l.TenantId, operation = l.Operation, action = l.Action, targetType = l.TargetType, targetId = l.TargetId, targetName = l.TargetName, ipAddress = l.IpAddress, description = l.Description, oldValue = l.OldValue, newValue = l.NewValue, errorMessage = l.ErrorMessage, status = l.Status, createdAt = l.CreatedAt, }); return Ok(new { items = result, totalCount, page, pageSize }); } [HttpGet("export")] public async Task ExportAuditLogs( [FromQuery] string? operatorName = null, [FromQuery] string? tenantId = null, [FromQuery] string? operation = null, [FromQuery] string? action = null, [FromQuery] DateTime? startTime = null, [FromQuery] DateTime? endTime = null) { var query = _context.AuditLogs.AsQueryable(); if (!string.IsNullOrEmpty(operatorName)) { query = query.Where(l => l.Operator.Contains(operatorName)); } if (!string.IsNullOrEmpty(tenantId)) { query = query.Where(l => l.TenantId == tenantId); } if (!string.IsNullOrEmpty(operation)) { query = query.Where(l => l.Operation == operation); } if (!string.IsNullOrEmpty(action)) { query = query.Where(l => l.Action == action); } 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,Operator,TenantId,Operation,Action,TargetType,TargetId,TargetName,IpAddress,Description,Status,CreatedAt"); foreach (var log in logs) { csv.AppendLine($"{log.Id},{log.Operator},{log.TenantId},{log.Operation},{log.Action},{log.TargetType},{log.TargetId},{log.TargetName},{log.IpAddress},\"{log.Description}\",{log.Status},{log.CreatedAt:yyyy-MM-dd HH:mm:ss}"); } return File(System.Text.Encoding.UTF8.GetBytes(csv.ToString()), "text/csv", $"audit-logs-{DateTime.UtcNow:yyyyMMdd}.csv"); } }