feat: add permission hierarchy tree

This commit is contained in:
2025-12-06 11:53:14 +08:00
parent d34f92ea1d
commit 37dc23f0c1
16 changed files with 1014 additions and 2 deletions

View File

@@ -0,0 +1,69 @@
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>>
{
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;
}
}