Files
TakeoutSaaS.TenantApi/src/Application/TakeoutSaaS.Application/App/Personal/Handlers/SearchPersonalOperationsQueryHandler.cs

103 lines
3.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using MediatR;
using System.Text.Json;
using TakeoutSaaS.Application.App.Personal.Dto;
using TakeoutSaaS.Application.App.Personal.Queries;
using TakeoutSaaS.Application.App.Personal.Services;
using TakeoutSaaS.Application.App.Personal.Validators;
using TakeoutSaaS.Domain.Tenants.Repositories;
using TakeoutSaaS.Shared.Abstractions.Results;
namespace TakeoutSaaS.Application.App.Personal.Handlers;
/// <summary>
/// 分页查询个人操作记录处理器。
/// </summary>
public sealed class SearchPersonalOperationsQueryHandler(
PersonalContextService personalContextService,
PersonalDateRangeValidator personalDateRangeValidator,
IOperationLogRepository operationLogRepository)
: IRequestHandler<SearchPersonalOperationsQuery, PagedResult<PersonalOperationLogDto>>
{
/// <summary>
/// 处理查询。
/// </summary>
/// <param name="request">查询请求。</param>
/// <param name="cancellationToken">取消标记。</param>
/// <returns>操作记录分页结果。</returns>
public async Task<PagedResult<PersonalOperationLogDto>> Handle(SearchPersonalOperationsQuery request, CancellationToken cancellationToken)
{
// 1. 获取上下文并解析时间窗
var context = personalContextService.GetRequiredContext();
var dateRange = personalDateRangeValidator.Resolve(request.From, request.To);
// 2. 解析分页参数(默认 50上限 50
var page = request.Page <= 0 ? 1 : request.Page;
var pageSize = request.PageSize <= 0 ? 50 : Math.Min(request.PageSize, 50);
// 3. 查询并映射
var paged = await operationLogRepository.SearchByOperatorPagedAsync(
context.TenantId,
context.UserId.ToString(),
dateRange.From,
dateRange.To,
page,
pageSize,
cancellationToken);
var items = paged.Items.Select(log => new PersonalOperationLogDto
{
OperationId = log.Id,
OperatorUserId = ParseOperatorUserId(log.OperatorId, context.UserId),
ActionType = log.OperationType,
TargetType = log.TargetType,
TargetId = ResolveTargetId(log.TargetIds),
IsSuccess = log.Success,
OccurredAt = log.CreatedAt
}).ToList();
// 4. 返回分页结果
return new PagedResult<PersonalOperationLogDto>(items, page, pageSize, paged.Total);
}
private static long ParseOperatorUserId(string? operatorId, long fallbackUserId)
{
// 1. 尝试从字符串解析用户 ID
if (long.TryParse(operatorId, out var parsed) && parsed > 0)
{
return parsed;
}
// 2. 解析失败时回退当前用户
return fallbackUserId;
}
private static string? ResolveTargetId(string? targetIds)
{
// 1. 空值直接返回
if (string.IsNullOrWhiteSpace(targetIds))
{
return null;
}
// 2. 尝试解析 JSON 数组并提取首个元素
var normalized = targetIds.Trim();
if (normalized.StartsWith("[", StringComparison.Ordinal))
{
try
{
using var doc = JsonDocument.Parse(normalized);
if (doc.RootElement.ValueKind == JsonValueKind.Array && doc.RootElement.GetArrayLength() > 0)
{
return doc.RootElement[0].ToString();
}
}
catch (JsonException)
{
// 3. JSON 解析失败时按原始字符串返回
}
}
// 4. 非数组场景直接返回原值
return normalized;
}
}