76 lines
2.6 KiB
C#
76 lines
2.6 KiB
C#
using MediatR;
|
|
using TakeoutSaaS.Application.Identity.Contracts;
|
|
using TakeoutSaaS.Application.Identity.Queries;
|
|
using TakeoutSaaS.Domain.Identity.Repositories;
|
|
using TakeoutSaaS.Shared.Abstractions.Tenancy;
|
|
|
|
namespace TakeoutSaaS.Application.Identity.Handlers;
|
|
|
|
/// <summary>
|
|
/// 权限树查询处理器。
|
|
/// </summary>
|
|
public sealed class PermissionTreeQueryHandler(
|
|
IPermissionRepository permissionRepository,
|
|
ITenantProvider tenantProvider)
|
|
: IRequestHandler<PermissionTreeQuery, IReadOnlyList<PermissionTreeDto>>
|
|
{
|
|
/// <summary>
|
|
/// 构建权限树。
|
|
/// </summary>
|
|
/// <param name="request">查询参数。</param>
|
|
/// <param name="cancellationToken">取消标记。</param>
|
|
/// <returns>权限树列表。</returns>
|
|
public async Task<IReadOnlyList<PermissionTreeDto>> Handle(PermissionTreeQuery request, CancellationToken cancellationToken)
|
|
{
|
|
// 1. 获取租户上下文并查询权限
|
|
var tenantId = tenantProvider.GetCurrentTenantId();
|
|
var permissions = await permissionRepository.SearchAsync(tenantId, request.Keyword, cancellationToken);
|
|
|
|
// 2. 构建节点映射与父子分组
|
|
var nodeMap = permissions.ToDictionary(
|
|
x => x.Id,
|
|
x => new PermissionTreeDto
|
|
{
|
|
Id = x.Id,
|
|
TenantId = x.TenantId,
|
|
ParentId = x.ParentId,
|
|
SortOrder = x.SortOrder,
|
|
Type = x.Type,
|
|
Name = x.Name,
|
|
Code = x.Code,
|
|
Description = x.Description,
|
|
Children = Array.Empty<PermissionTreeDto>()
|
|
});
|
|
var childrenLookup = permissions
|
|
.GroupBy(x => x.ParentId)
|
|
.ToDictionary(g => g.Key, g => g.OrderBy(c => c.SortOrder).ThenBy(c => c.Id).Select(c => c.Id).ToList());
|
|
|
|
// 3. 递归组装树,确保子节点引用最新
|
|
List<PermissionTreeDto> Build(long parentId)
|
|
{
|
|
if (!childrenLookup.TryGetValue(parentId, out var childIds))
|
|
{
|
|
return [];
|
|
}
|
|
|
|
var result = new List<PermissionTreeDto>(childIds.Count);
|
|
foreach (var childId in childIds)
|
|
{
|
|
if (!nodeMap.TryGetValue(childId, out var child))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var withChildren = child with { Children = Build(child.Id) };
|
|
result.Add(withChildren);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
// 4. 返回根节点集合
|
|
var roots = Build(0);
|
|
return roots;
|
|
}
|
|
}
|