Browse Source

feat(platform): 优化用户角色多框架菜单管理

pull/1189/head
colin 10 months ago
parent
commit
dadef5c62c
  1. 2
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Datas/Dto/DataCreateDto.cs
  2. 9
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Menus/Dto/RoleMenuInput.cs
  3. 7
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Menus/Dto/RoleMenuStartupInput.cs
  4. 10
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Menus/Dto/UserMenuInput.cs
  5. 8
      aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Menus/Dto/UserMenuStartupInput.cs
  6. 20
      aspnet-core/modules/platform/LINGYUN.Platform.Application/LINGYUN/Platform/Menus/MenuAppService.cs
  7. 3
      aspnet-core/modules/platform/LINGYUN.Platform.Domain.Shared/LINGYUN/Platform/Localization/Resources/en.json
  8. 7
      aspnet-core/modules/platform/LINGYUN.Platform.Domain.Shared/LINGYUN/Platform/Localization/Resources/zh-Hans.json
  9. 4
      aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Menus/IRoleMenuRepository.cs
  10. 4
      aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Menus/IUserMenuRepository.cs
  11. 20
      aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Menus/MenuManager.cs
  12. 34
      aspnet-core/modules/platform/LINGYUN.Platform.EntityFrameworkCore/LINGYUN/Platform/Menus/EfCoreRoleMenuRepository.cs
  13. 28
      aspnet-core/modules/platform/LINGYUN.Platform.EntityFrameworkCore/LINGYUN/Platform/Menus/EfCoreUserMenuRepository.cs

2
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Datas/Dto/DataCreateDto.cs

@ -1,8 +1,10 @@
using System;
using System.ComponentModel;
namespace LINGYUN.Platform.Datas;
public class DataCreateDto : DataCreateOrUpdateDto
{
[DisplayName("DisplayName:ParentData")]
public Guid? ParentId { get; set; }
}

9
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Menus/Dto/RoleMenuInput.cs

@ -1,6 +1,8 @@
using System;
using LINGYUN.Platform.Routes;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using Volo.Abp.Validation;
namespace LINGYUN.Platform.Menus;
@ -10,6 +12,11 @@ public class RoleMenuInput
[StringLength(80)]
public string RoleName { get; set; }
[DynamicStringLength(typeof(LayoutConsts), nameof(LayoutConsts.MaxFrameworkLength))]
public string Framework { get; set; }
public Guid? StartupMenuId { get; set; }
[Required]
public List<Guid> MenuIds { get; set; } = new List<Guid>();
}

7
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Menus/Dto/RoleMenuStartupInput.cs

@ -1,4 +1,6 @@
using System.ComponentModel.DataAnnotations;
using LINGYUN.Platform.Routes;
using System.ComponentModel.DataAnnotations;
using Volo.Abp.Validation;
namespace LINGYUN.Platform.Menus;
@ -7,4 +9,7 @@ public class RoleMenuStartupInput
[Required]
[StringLength(80)]
public string RoleName { get; set; }
[DynamicStringLength(typeof(LayoutConsts), nameof(LayoutConsts.MaxFrameworkLength))]
public string Framework { get; set; }
}

10
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Menus/Dto/UserMenuInput.cs

@ -1,6 +1,8 @@
using System;
using LINGYUN.Platform.Routes;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using Volo.Abp.Validation;
namespace LINGYUN.Platform.Menus;
@ -9,6 +11,12 @@ public class UserMenuInput
[Required]
public Guid UserId { get; set; }
[DynamicStringLength(typeof(LayoutConsts), nameof(LayoutConsts.MaxFrameworkLength))]
public string Framework { get; set; }
public Guid? StartupMenuId { get; set; }
[Required]
public List<Guid> MenuIds { get; set; } = new List<Guid>();
}

8
aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Menus/Dto/UserMenuStartupInput.cs

@ -1,8 +1,14 @@
using System;
using LINGYUN.Platform.Routes;
using System;
using Volo.Abp.Validation;
namespace LINGYUN.Platform.Menus;
public class UserMenuStartupInput
{
public Guid UserId { get; set; }
[DynamicStringLength(typeof(LayoutConsts), nameof(LayoutConsts.MaxFrameworkLength))]
public string Framework { get; set; }
}

20
aspnet-core/modules/platform/LINGYUN.Platform.Application/LINGYUN/Platform/Menus/MenuAppService.cs

@ -52,12 +52,12 @@ public class MenuAppService : PlatformApplicationServiceBase, IMenuAppService
var menus = ObjectMapper.Map<List<Menu>, List<MenuDto>>(myMenus);
var startupMenu = await UserMenuRepository.GetStartupMenuAsync(
var startupMenu = await UserMenuRepository.FindStartupMenuAsync(
CurrentUser.GetId());
if (startupMenu == null && CurrentUser.Roles.Any())
{
startupMenu = await RoleMenuRepository.GetStartupMenuAsync(CurrentUser.Roles);
startupMenu = await RoleMenuRepository.FindStartupMenuAsync(CurrentUser.Roles);
}
if (startupMenu != null)
@ -240,11 +240,11 @@ public class MenuAppService : PlatformApplicationServiceBase, IMenuAppService
var menuDtos = ObjectMapper.Map<List<Menu>, List<MenuDto>>(menus);
var startupMenu = await UserMenuRepository.GetStartupMenuAsync(input.UserId);
var startupMenu = await UserMenuRepository.FindStartupMenuAsync(input.UserId, input.Framework);
if (startupMenu == null)
{
startupMenu = await RoleMenuRepository.GetStartupMenuAsync(input.Roles);
startupMenu = await RoleMenuRepository.FindStartupMenuAsync(input.Roles, input.Framework);
}
if (startupMenu != null)
@ -263,25 +263,27 @@ public class MenuAppService : PlatformApplicationServiceBase, IMenuAppService
[Authorize(PlatformPermissions.Menu.ManageUsers)]
public async virtual Task SetUserMenusAsync(UserMenuInput input)
{
await MenuManager.SetUserMenusAsync(input.UserId, input.MenuIds);
await MenuManager.SetUserMenusAsync(input.UserId, input.MenuIds, input.Framework);
await MenuManager.SetUserStartupMenuAsync(input.UserId, input.StartupMenuId, input.Framework);
}
[Authorize(PlatformPermissions.Menu.ManageUsers)]
public async virtual Task SetUserStartupAsync(Guid id, UserMenuStartupInput input)
{
await MenuManager.SetUserStartupMenuAsync(input.UserId, id);
await MenuManager.SetUserStartupMenuAsync(input.UserId, id, input.Framework);
}
[Authorize(PlatformPermissions.Menu.ManageRoles)]
public async virtual Task SetRoleMenusAsync(RoleMenuInput input)
{
await MenuManager.SetRoleMenusAsync(input.RoleName, input.MenuIds);
await MenuManager.SetRoleMenusAsync(input.RoleName, input.MenuIds, input.Framework);
await MenuManager.SetRoleStartupMenuAsync(input.RoleName, input.StartupMenuId, input.Framework);
}
[Authorize(PlatformPermissions.Menu.ManageRoles)]
public async virtual Task SetRoleStartupAsync(Guid id, RoleMenuStartupInput input)
{
await MenuManager.SetRoleStartupMenuAsync(input.RoleName, id);
await MenuManager.SetRoleStartupMenuAsync(input.RoleName, id, input.Framework);
}
[Authorize(PlatformPermissions.Menu.ManageRoles)]
@ -291,7 +293,7 @@ public class MenuAppService : PlatformApplicationServiceBase, IMenuAppService
var menuDtos = ObjectMapper.Map<List<Menu>, List<MenuDto>>(menus);
var startupMenu = await RoleMenuRepository.GetStartupMenuAsync(new string[] { input.Role });
var startupMenu = await RoleMenuRepository.FindStartupMenuAsync(new string[] { input.Role }, input.Framework);
if (startupMenu != null)
{

3
aspnet-core/modules/platform/LINGYUN.Platform.Domain.Shared/LINGYUN/Platform/Localization/Resources/en.json

@ -76,6 +76,9 @@
"DisplayName:BlobName": "Blob Name",
"DisplayName:Key": "Key",
"DisplayName:Value": "Value",
"DisplayName:ParentData": "Parent Data",
"DisplayName:ParentMenu": "Parent Menu",
"DisplayName:LayoutConstraint": "Layout Constraint",
"MailPriority:Normal": "Normal",
"MailPriority:Low": "Low",
"MailPriority:High": "High",

7
aspnet-core/modules/platform/LINGYUN.Platform.Domain.Shared/LINGYUN/Platform/Localization/Resources/zh-Hans.json

@ -76,6 +76,9 @@
"DisplayName:BlobName": "存储名称",
"DisplayName:Key": "键名",
"DisplayName:Value": "键值",
"DisplayName:ParentData": "上级字典",
"DisplayName:ParentMenu": "上级菜单",
"DisplayName:LayoutConstraint": "布局约束",
"MailPriority:Normal": "普通",
"MailPriority:Low": "低",
"MailPriority:High": "高",
@ -115,6 +118,8 @@
"SmsMessages": "短信消息",
"SendMessage": "发送消息",
"MessageWillBeReSendWarningMessage": "将重新发送选择的消息.",
"SuccessfullySent": "发送成功,请稍后在消息中心查看状态!"
"SuccessfullySent": "发送成功,请稍后在消息中心查看状态!",
"PreStep": "上一步",
"NextStep": "下一步"
}
}

4
aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Menus/IRoleMenuRepository.cs

@ -22,9 +22,11 @@ public interface IRoleMenuRepository : IBasicRepository<RoleMenu, Guid>
Task<List<RoleMenu>> GetListByRoleNameAsync(
string roleName,
string framework = null,
CancellationToken cancellationToken = default);
Task<Menu> GetStartupMenuAsync(
Task<Menu> FindStartupMenuAsync(
IEnumerable<string> roleNames,
string framework = null,
CancellationToken cancellationToken = default);
}

4
aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Menus/IUserMenuRepository.cs

@ -22,9 +22,11 @@ public interface IUserMenuRepository : IBasicRepository<UserMenu, Guid>
Task<List<UserMenu>> GetListByUserIdAsync(
Guid userId,
string framework = null,
CancellationToken cancellationToken = default);
Task<Menu> GetStartupMenuAsync(
Task<Menu> FindStartupMenuAsync(
Guid userId,
string framework = null,
CancellationToken cancellationToken = default);
}

20
aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Menus/MenuManager.cs

@ -126,16 +126,16 @@ public class MenuManager : DomainService
return false;
}
public async virtual Task SetUserStartupMenuAsync(Guid userId, Guid menuId)
public async virtual Task SetUserStartupMenuAsync(Guid userId, Guid? menuId = null, string framework = null)
{
using (var unitOfWork = UnitOfWorkManager.Begin())
{
var userMenus = await UserMenuRepository.GetListByUserIdAsync(userId);
var userMenus = await UserMenuRepository.GetListByUserIdAsync(userId, framework);
foreach (var menu in userMenus)
{
menu.Startup = false;
if (menu.MenuId.Equals(menuId))
if (menuId.HasValue && menu.MenuId.Equals(menuId))
{
menu.Startup = true;
}
@ -147,11 +147,11 @@ public class MenuManager : DomainService
}
}
public async virtual Task SetUserMenusAsync(Guid userId, IEnumerable<Guid> menuIds)
public async virtual Task SetUserMenusAsync(Guid userId, IEnumerable<Guid> menuIds, string framework = null)
{
using (var unitOfWork = UnitOfWorkManager.Begin())
{
var userMenus = await UserMenuRepository.GetListByUserIdAsync(userId);
var userMenus = await UserMenuRepository.GetListByUserIdAsync(userId, framework);
// 移除不存在的菜单
// TODO: 升级框架版本解决未能删除不需要菜单的问题
@ -173,16 +173,16 @@ public class MenuManager : DomainService
}
}
public async virtual Task SetRoleStartupMenuAsync(string roleName, Guid menuId)
public async virtual Task SetRoleStartupMenuAsync(string roleName, Guid? menuId = null, string framework = null)
{
using (var unitOfWork = UnitOfWorkManager.Begin())
{
var roleMenus = await RoleMenuRepository.GetListByRoleNameAsync(roleName);
var roleMenus = await RoleMenuRepository.GetListByRoleNameAsync(roleName, framework);
foreach (var menu in roleMenus)
{
menu.Startup = false;
if (menu.MenuId.Equals(menuId))
if (menuId.HasValue && menu.MenuId.Equals(menuId))
{
menu.Startup = true;
}
@ -194,11 +194,11 @@ public class MenuManager : DomainService
}
}
public async virtual Task SetRoleMenusAsync(string roleName, IEnumerable<Guid> menuIds)
public async virtual Task SetRoleMenusAsync(string roleName, IEnumerable<Guid> menuIds, string framework = null)
{
using (var unitOfWork = UnitOfWorkManager.Begin())
{
var roleMenus = await RoleMenuRepository.GetListByRoleNameAsync(roleName);
var roleMenus = await RoleMenuRepository.GetListByRoleNameAsync(roleName, framework);
// 移除不存在的菜单
// TODO: 升级框架版本解决未能删除不需要菜单的问题

34
aspnet-core/modules/platform/LINGYUN.Platform.EntityFrameworkCore/LINGYUN/Platform/Menus/EfCoreRoleMenuRepository.cs

@ -3,6 +3,7 @@ using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
@ -18,10 +19,31 @@ public class EfCoreRoleMenuRepository : EfCoreRepository<PlatformDbContext, Role
{
}
public async virtual Task<List<RoleMenu>> GetListByRoleNameAsync(string roleName, CancellationToken cancellationToken = default)
public async virtual Task<List<RoleMenu>> GetListByRoleNameAsync(
string roleName,
string framework = null,
CancellationToken cancellationToken = default)
{
return await (await GetDbSetAsync()).Where(x => x.RoleName.Equals(roleName))
.ToListAsync(GetCancellationToken(cancellationToken));
var dbContext = await GetDbContextAsync();
var menus = dbContext.Set<Menu>();
var roleMenus = dbContext.Set<RoleMenu>().Where(x => x.RoleName == roleName);
IQueryable<RoleMenu> queryable;
if (!framework.IsNullOrWhiteSpace())
{
queryable = from menu in menus
join roleMenu in roleMenus
on menu.Id equals roleMenu.MenuId
where menu.Framework == framework
select roleMenu;
}
else
{
queryable = roleMenus;
}
return await queryable.ToListAsync(GetCancellationToken(cancellationToken));
}
public async virtual Task<bool> RoleHasInMenuAsync(
@ -40,8 +62,9 @@ public class EfCoreRoleMenuRepository : EfCoreRepository<PlatformDbContext, Role
GetCancellationToken(cancellationToken));
}
public async virtual Task<Menu> GetStartupMenuAsync(
IEnumerable<string> roleNames,
public async virtual Task<Menu> FindStartupMenuAsync(
IEnumerable<string> roleNames,
string framework = null,
CancellationToken cancellationToken = default)
{
var dbContext = await GetDbContextAsync();
@ -54,6 +77,7 @@ public class EfCoreRoleMenuRepository : EfCoreRepository<PlatformDbContext, Role
join menu in dbContext.Set<Menu>()
on roleMenu.MenuId equals menu.Id
select menu)
.WhereIf(!framework.IsNullOrWhiteSpace(), x => x.Framework == framework)
.OrderByDescending(x => x.CreationTime)
.FirstOrDefaultAsync(GetCancellationToken(cancellationToken));
}

28
aspnet-core/modules/platform/LINGYUN.Platform.EntityFrameworkCore/LINGYUN/Platform/Menus/EfCoreUserMenuRepository.cs

@ -37,15 +37,34 @@ public class EfCoreUserMenuRepository : EfCoreRepository<PlatformDbContext, User
public async virtual Task<List<UserMenu>> GetListByUserIdAsync(
Guid userId,
string framework = null,
CancellationToken cancellationToken = default)
{
var dbSet = await GetDbSetAsync();
return await dbSet.Where(x => x.UserId.Equals(userId))
.ToListAsync(GetCancellationToken(cancellationToken));
var dbContext = await GetDbContextAsync();
var menus = dbContext.Set<Menu>();
var userMenus = dbContext.Set<UserMenu>().Where(x => x.UserId == userId);
IQueryable<UserMenu> queryable;
if (!framework.IsNullOrWhiteSpace())
{
queryable = from menu in menus
join userMenu in userMenus
on menu.Id equals userMenu.MenuId
where menu.Framework == framework
select userMenu;
}
else
{
queryable = userMenus;
}
return await queryable.ToListAsync(GetCancellationToken(cancellationToken));
}
public async virtual Task<Menu> GetStartupMenuAsync(
public async virtual Task<Menu> FindStartupMenuAsync(
Guid userId,
string framework = null,
CancellationToken cancellationToken = default)
{
var dbContext = await GetDbContextAsync();
@ -58,6 +77,7 @@ public class EfCoreUserMenuRepository : EfCoreRepository<PlatformDbContext, User
join menu in dbContext.Set<Menu>()
on userMenu.MenuId equals menu.Id
select menu)
.WhereIf(!framework.IsNullOrWhiteSpace(), x => x.Framework == framework)
.OrderByDescending(x => x.CreationTime)
.FirstOrDefaultAsync(GetCancellationToken(cancellationToken));
}

Loading…
Cancel
Save