line-gestao-api/Controllers/HistoricoController.cs

162 lines
4.6 KiB
C#

using System.Text.Json;
using line_gestao_api.Data;
using line_gestao_api.Dtos;
using line_gestao_api.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace line_gestao_api.Controllers;
[ApiController]
[Route("api/historico")]
[Authorize(Roles = "admin")]
public class HistoricoController : ControllerBase
{
private readonly AppDbContext _db;
public HistoricoController(AppDbContext db)
{
_db = db;
}
[HttpGet]
public async Task<ActionResult<PagedResult<AuditLogDto>>> GetAll(
[FromQuery] string? pageName,
[FromQuery] string? action,
[FromQuery] string? entity,
[FromQuery] Guid? userId,
[FromQuery] string? search,
[FromQuery] DateTime? dateFrom,
[FromQuery] DateTime? dateTo,
[FromQuery] int page = 1,
[FromQuery] int pageSize = 20)
{
page = page < 1 ? 1 : page;
pageSize = pageSize < 1 ? 20 : pageSize;
var q = _db.AuditLogs
.AsNoTracking()
.Where(x =>
!EF.Functions.ILike(x.RequestPath ?? "", "%import-excel%") ||
x.Page == AuditLogBuilder.SpreadsheetImportPageName);
if (!string.IsNullOrWhiteSpace(pageName))
{
var p = pageName.Trim();
q = q.Where(x => EF.Functions.ILike(x.Page, $"%{p}%"));
}
if (!string.IsNullOrWhiteSpace(action))
{
var a = action.Trim().ToUpperInvariant();
q = q.Where(x => x.Action == a);
}
if (!string.IsNullOrWhiteSpace(entity))
{
var e = entity.Trim();
q = q.Where(x => EF.Functions.ILike(x.EntityName, $"%{e}%"));
}
if (userId.HasValue)
{
q = q.Where(x => x.UserId == userId.Value);
}
if (!string.IsNullOrWhiteSpace(search))
{
var s = search.Trim();
q = q.Where(x =>
EF.Functions.ILike(x.UserName ?? "", $"%{s}%") ||
EF.Functions.ILike(x.UserEmail ?? "", $"%{s}%") ||
EF.Functions.ILike(x.EntityName ?? "", $"%{s}%") ||
EF.Functions.ILike(x.EntityLabel ?? "", $"%{s}%") ||
EF.Functions.ILike(x.EntityId ?? "", $"%{s}%") ||
EF.Functions.ILike(x.Page ?? "", $"%{s}%"));
}
if (dateFrom.HasValue)
{
var fromUtc = ToUtc(dateFrom.Value);
q = q.Where(x => x.OccurredAtUtc >= fromUtc);
}
if (dateTo.HasValue)
{
var toUtc = ToUtc(dateTo.Value);
if (dateTo.Value.TimeOfDay == TimeSpan.Zero)
{
toUtc = toUtc.Date.AddDays(1).AddTicks(-1);
}
q = q.Where(x => x.OccurredAtUtc <= toUtc);
}
var total = await q.CountAsync();
var items = await q
.OrderByDescending(x => x.OccurredAtUtc)
.ThenByDescending(x => x.Id)
.Skip((page - 1) * pageSize)
.Take(pageSize)
.ToListAsync();
return Ok(new PagedResult<AuditLogDto>
{
Page = page,
PageSize = pageSize,
Total = total,
Items = items.Select(ToDto).ToList()
});
}
private static AuditLogDto ToDto(Models.AuditLog log)
{
return new AuditLogDto
{
Id = log.Id,
OccurredAtUtc = log.OccurredAtUtc,
Action = log.Action,
Page = log.Page,
EntityName = log.EntityName,
EntityId = log.EntityId,
EntityLabel = log.EntityLabel,
UserId = log.UserId,
UserName = log.UserName,
UserEmail = log.UserEmail,
RequestPath = log.RequestPath,
RequestMethod = log.RequestMethod,
IpAddress = log.IpAddress,
Changes = ParseChanges(log.ChangesJson)
};
}
private static List<AuditFieldChangeDto> ParseChanges(string? json)
{
if (string.IsNullOrWhiteSpace(json))
{
return new List<AuditFieldChangeDto>();
}
try
{
return JsonSerializer.Deserialize<List<AuditFieldChangeDto>>(json) ?? new List<AuditFieldChangeDto>();
}
catch
{
return new List<AuditFieldChangeDto>();
}
}
private static DateTime ToUtc(DateTime value)
{
if (value.Kind == DateTimeKind.Utc)
return value;
if (value.Kind == DateTimeKind.Local)
return value.ToUniversalTime();
return DateTime.SpecifyKind(value, DateTimeKind.Utc);
}
}