You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
182 lines
7.0 KiB
182 lines
7.0 KiB
using Microsoft.AspNetCore.Authorization; |
|
using Microsoft.Extensions.Localization; |
|
using Sanhe.Abp.MenuManagement.Permissions; |
|
using System; |
|
using System.Collections.Generic; |
|
using System.Linq; |
|
using System.Threading.Tasks; |
|
using Volo.Abp; |
|
using Volo.Abp.Application.Dtos; |
|
using Volo.Abp.Application.Services; |
|
using Volo.Abp.Authorization.Permissions; |
|
using Volo.Abp.Domain.Repositories; |
|
using Volo.Abp.MultiTenancy; |
|
|
|
namespace Sanhe.Abp.MenuManagement |
|
{ |
|
[Authorize] |
|
public class MenuAppService : CrudAppService<Menu, MenuDto, Guid, MenuRequestDto, CreateOrUpdateMenuDto, CreateOrUpdateMenuDto>, |
|
IMenuAppService |
|
{ |
|
private readonly IPermissionDefinitionManager _permissionDefinitionManager; |
|
private readonly IMenuManager _menuManager; |
|
private readonly IStringLocalizerFactory _stringLocalizerFactory; |
|
|
|
public MenuAppService( |
|
IRepository<Menu, Guid> repository, |
|
IPermissionDefinitionManager permissionDefinitionManager, |
|
IMenuManager menuManager, |
|
IStringLocalizerFactory stringLocalizerFactory |
|
) : base(repository) |
|
{ |
|
_permissionDefinitionManager = permissionDefinitionManager; |
|
_menuManager = menuManager; |
|
_stringLocalizerFactory = stringLocalizerFactory; |
|
} |
|
|
|
protected override string GetListPolicyName => MenuManagementPermissions.Menus.Default; |
|
protected override string CreatePolicyName => MenuManagementPermissions.Menus.Create; |
|
protected override string UpdatePolicyName => MenuManagementPermissions.Menus.Update; |
|
protected override string DeletePolicyName => MenuManagementPermissions.Menus.Delete; |
|
|
|
public override async Task<MenuDto> UpdateAsync(Guid id, CreateOrUpdateMenuDto input) |
|
{ |
|
await PermissionChecker(input.PermissionKey, id); |
|
|
|
// 当更新菜单权限时,同时刷 PermissionGrant |
|
var menu = await GetEntityByIdAsync(id); |
|
if (menu.PermissionKey != input.PermissionKey) |
|
{ |
|
await _menuManager.UpdatePermissionGrantAsync(id, menu.PermissionKey, input.PermissionKey); |
|
} |
|
|
|
return await base.UpdateAsync(id, input); |
|
} |
|
|
|
public virtual Task<List<AuthPolicyDto>> GetAuthPolicies() |
|
{ |
|
var result = new List<AuthPolicyDto>(); |
|
var groups = _permissionDefinitionManager.GetGroups(); |
|
var multiTenancySide = CurrentTenant.GetMultiTenancySide(); |
|
foreach (var group in groups) |
|
{ |
|
if (group.Permissions.Count == 0) |
|
{ |
|
continue; |
|
} |
|
|
|
foreach (var permission in group.Permissions) |
|
{ |
|
if (multiTenancySide != MultiTenancySides.Host && |
|
!permission.MultiTenancySide.HasFlag(multiTenancySide)) |
|
{ |
|
continue; |
|
} |
|
|
|
var policy = new AuthPolicyDto() |
|
{ |
|
Name = permission.Name, |
|
DisplayName = permission.DisplayName.Localize(_stringLocalizerFactory), |
|
Children = new List<AuthPolicyDto> |
|
{ |
|
new AuthPolicyDto |
|
{ |
|
Name = permission.Name, |
|
DisplayName = permission.DisplayName.Localize(_stringLocalizerFactory) |
|
} |
|
} |
|
}; |
|
result.Add(policy); |
|
|
|
foreach (var c in permission.Children) |
|
{ |
|
if (multiTenancySide != MultiTenancySides.Host && |
|
!c.MultiTenancySide.HasFlag(multiTenancySide)) |
|
{ |
|
continue; |
|
} |
|
|
|
policy.Children.Add(new AuthPolicyDto |
|
{ |
|
Name = c.Name, |
|
DisplayName = c.DisplayName.Localize(_stringLocalizerFactory) |
|
}); |
|
} |
|
} |
|
} |
|
|
|
return Task.FromResult(result); |
|
} |
|
|
|
public override async Task<MenuDto> CreateAsync(CreateOrUpdateMenuDto input) |
|
{ |
|
await PermissionChecker(input.PermissionKey); |
|
return await base.CreateAsync(input); |
|
} |
|
|
|
public override async Task<PagedResultDto<MenuDto>> GetListAsync(MenuRequestDto input) |
|
{ |
|
//await CheckGetListPolicyAsync(); |
|
var queryable = await Repository.GetQueryableAsync(); |
|
var allMenus = queryable |
|
.WhereIf(input.Type.HasValue, m => m.MenuType == input.Type) |
|
.WhereIf(!input.Name.IsNullOrWhiteSpace(), m => m.DisplayName.Contains(input.Name)) |
|
.ToList(); |
|
|
|
var root = allMenus |
|
.Where(x => !x.ParentId.HasValue) // 没有parentId |
|
.Union( |
|
// 有parentId,但是“allMenus"中不存在他的Parent。 |
|
allMenus.Where(x => x.ParentId.HasValue).Where(x => allMenus.All(y => x.ParentId != y.Id)) |
|
) |
|
.OrderBy(x => x.Sort); |
|
|
|
var menuDtos = new List<MenuDto>(); |
|
foreach (var menu in root) |
|
{ |
|
var dto = ObjectMapper.Map<Menu, MenuDto>(menu); |
|
menuDtos.Add(dto); |
|
// AddChildrenMenuRecursively(dto, allMenus); |
|
|
|
SortChildrenMenu(dto); |
|
} |
|
|
|
return new PagedResultDto<MenuDto>(allMenus.Count, menuDtos); |
|
} |
|
|
|
private async Task PermissionChecker(string permissionName, Guid? menuId = null) |
|
{ |
|
if (!permissionName.IsNullOrWhiteSpace()) |
|
{ |
|
var permission = _permissionDefinitionManager.GetOrNull(permissionName); |
|
if (permission == null) |
|
{ |
|
throw new UserFriendlyException($"未知的权限:“{permissionName}”。"); |
|
} |
|
|
|
var menu = await Repository.FirstOrDefaultAsync(x => x.PermissionKey == permissionName && x.Id != menuId); |
|
if (menu != null) |
|
{ |
|
throw new UserFriendlyException($"权限已经被菜单“{menu.DisplayName}”绑定。"); |
|
} |
|
} |
|
} |
|
|
|
private void SortChildrenMenu(MenuDto dto) |
|
{ |
|
dto.Children.Sort((a, b) => string.Compare(a.Sort, b.Sort, StringComparison.Ordinal)); |
|
dto.Children.ForEach(SortChildrenMenu); |
|
} |
|
|
|
private void AddChildrenMenuRecursively(MenuDto parent, List<Menu> allMenus) |
|
{ |
|
foreach (var menu in allMenus.Where(x => x.ParentId == parent.Id).OrderBy(x => x.Sort)) |
|
{ |
|
var dto = ObjectMapper.Map<Menu, MenuDto>(menu); |
|
parent.Children.Add(dto); |
|
|
|
AddChildrenMenuRecursively(dto, allMenus); |
|
} |
|
} |
|
} |
|
} |