21 changed files with 3561 additions and 61 deletions
-
41src/Shentun.ProjectManager.Application.Contracts/MenuInfos/CreateMenuInfoDto.cs
-
42src/Shentun.ProjectManager.Application.Contracts/MenuInfos/GetMyMenuInfoListDto.cs
-
49src/Shentun.ProjectManager.Application.Contracts/MenuInfos/MenuInfoDto.cs
-
11src/Shentun.ProjectManager.Application.Contracts/MenuInfos/MenuInfoIdInputDto.cs
-
46src/Shentun.ProjectManager.Application.Contracts/MenuInfos/MenuInfoTreeDto.cs
-
44src/Shentun.ProjectManager.Application.Contracts/MenuInfos/UpdateMenuInfoDto.cs
-
24src/Shentun.ProjectManager.Application.Contracts/RoleMenuInfos/GetRoleMenuInfoIdsDto.cs
-
20src/Shentun.ProjectManager.Application.Contracts/RoleMenuInfos/SetUserMenuInfoRequestDto.cs
-
358src/Shentun.ProjectManager.Application/MenuInfos/MenuInfoAppService.cs
-
92src/Shentun.ProjectManager.Application/RoleMenuInfos/RoleMenuInfoAppService.cs
-
69src/Shentun.ProjectManager.Domain/LanguageConverter.cs
-
84src/Shentun.ProjectManager.Domain/MenuInfos/MenuInfo.cs
-
72src/Shentun.ProjectManager.Domain/MenuInfos/MenuInfoManager.cs
-
30src/Shentun.ProjectManager.Domain/RoleMenuInfos/RoleMenuInfo.cs
-
2src/Shentun.ProjectManager.Domain/Shentun.ProjectManager.Domain.csproj
-
29src/Shentun.ProjectManager.EntityFrameworkCore/Configures/MenuInfoConfigure.cs
-
27src/Shentun.ProjectManager.EntityFrameworkCore/Configures/RoleMenuInfoConfigure.cs
-
4src/Shentun.ProjectManager.EntityFrameworkCore/EntityFrameworkCore/ProjectManagerDbContext.cs
-
2290src/Shentun.ProjectManager.EntityFrameworkCore/Migrations/20250509085622_insert_menu_info_role_menu_info.Designer.cs
-
60src/Shentun.ProjectManager.EntityFrameworkCore/Migrations/20250509085622_insert_menu_info_role_menu_info.cs
-
228src/Shentun.ProjectManager.EntityFrameworkCore/Migrations/ProjectManagerDbContextModelSnapshot.cs
@ -0,0 +1,41 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using System.Text; |
|||
|
|||
namespace Shentun.ProjectManager.MenuInfos |
|||
{ |
|||
public class CreateMenuInfoDto |
|||
{ |
|||
/// <summary>
|
|||
/// 名称
|
|||
/// </summary>
|
|||
public string DisplayName { get; set; } |
|||
|
|||
|
|||
/// <summary>
|
|||
/// 路由地址
|
|||
/// </summary>
|
|||
public string? RouteUrl { get; set; } |
|||
|
|||
|
|||
/// <summary>
|
|||
/// 菜单图标
|
|||
/// </summary>
|
|||
public string? IconName { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 父id
|
|||
/// </summary>
|
|||
public Guid? ParentId { get; set; } |
|||
|
|||
|
|||
/// <summary>
|
|||
/// 菜单类型 0 一级菜单 1 带路径的菜单 2 按钮
|
|||
/// </summary>
|
|||
public char MenuType { get; set; } = '1'; |
|||
|
|||
|
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,42 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Text; |
|||
|
|||
namespace Shentun.ProjectManager.MenuInfos |
|||
{ |
|||
public class GetMyMenuInfoListDto |
|||
{ |
|||
public Guid Id { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 名称
|
|||
/// </summary>
|
|||
public string DisplayName { get; set; } |
|||
|
|||
|
|||
/// <summary>
|
|||
/// 路由地址
|
|||
/// </summary>
|
|||
public string? RouteUrl { get; set; } |
|||
|
|||
|
|||
/// <summary>
|
|||
/// 菜单图标
|
|||
/// </summary>
|
|||
public string? IconName { get; set; } |
|||
|
|||
|
|||
/// <summary>
|
|||
/// 父id
|
|||
/// </summary>
|
|||
public Guid? ParentId { get; set; } |
|||
|
|||
public int DisplayOrder { get; set; } |
|||
|
|||
|
|||
/// <summary>
|
|||
/// 菜单类型 0 一级菜单 1 带路径的菜单 2 按钮
|
|||
/// </summary>
|
|||
public char MenuType { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,49 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Text; |
|||
|
|||
namespace Shentun.ProjectManager.MenuInfos |
|||
{ |
|||
public class MenuInfoDto : AuditedEntityDtoName |
|||
{ |
|||
/// <summary>
|
|||
/// 名称
|
|||
/// </summary>
|
|||
public string DisplayName { get; set; } |
|||
|
|||
|
|||
/// <summary>
|
|||
/// 路由地址
|
|||
/// </summary>
|
|||
public string? RouteUrl { get; set; } |
|||
|
|||
|
|||
/// <summary>
|
|||
/// 菜单图标
|
|||
/// </summary>
|
|||
public string? IconName { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 自定义简码
|
|||
/// </summary>
|
|||
public string SimpleCode { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 父id
|
|||
/// </summary>
|
|||
public Guid? ParentId { get; set; } |
|||
|
|||
public int DisplayOrder { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 是否启用
|
|||
/// </summary>
|
|||
public char IsActive { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 菜单类型 0 一级菜单 1 带路径的菜单 2 按钮
|
|||
/// </summary>
|
|||
public char MenuType { get; set; } |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Text; |
|||
|
|||
namespace Shentun.ProjectManager.MenuInfos |
|||
{ |
|||
public class MenuInfoIdInputDto |
|||
{ |
|||
public Guid MenuInfoId { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,46 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Text; |
|||
|
|||
namespace Shentun.ProjectManager.MenuInfos |
|||
{ |
|||
public class MenuInfoTreeDto |
|||
{ |
|||
//组织Id
|
|||
public Guid Id { get; set; } |
|||
//名称
|
|||
public string DisplayName { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 路由地址
|
|||
/// </summary>
|
|||
public string RouteUrl { get; set; } |
|||
|
|||
|
|||
/// <summary>
|
|||
/// 菜单图标
|
|||
/// </summary>
|
|||
public string IconName { get; set; } |
|||
|
|||
//父节点Id
|
|||
public Guid? ParentId { get; set; } |
|||
|
|||
|
|||
public int DisplayOrder { get; set; } |
|||
|
|||
public char IsActive { get; set; } |
|||
|
|||
|
|||
/// <summary>
|
|||
/// 菜单类型 0 一级菜单 1 带路径的菜单 2 按钮
|
|||
/// </summary>
|
|||
public char MenuType { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 拼音简码
|
|||
/// </summary>
|
|||
public string SimpleCode { get; set; } |
|||
|
|||
public List<MenuInfoTreeDto> TreeChildren { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,44 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using System.Text; |
|||
|
|||
namespace Shentun.ProjectManager.MenuInfos |
|||
{ |
|||
public class UpdateMenuInfoDto |
|||
{ |
|||
public Guid Id { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 名称
|
|||
/// </summary>
|
|||
public string DisplayName { get; set; } |
|||
|
|||
|
|||
/// <summary>
|
|||
/// 路由地址
|
|||
/// </summary>
|
|||
public string? RouteUrl { get; set; } |
|||
|
|||
|
|||
/// <summary>
|
|||
/// 菜单图标
|
|||
/// </summary>
|
|||
public string? IconName { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 是否启用
|
|||
/// </summary>
|
|||
public char IsActive { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 排序值
|
|||
/// </summary>
|
|||
public int? DisplayOrder { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 菜单类型 0 一级菜单 1 带路径的菜单 2 按钮
|
|||
/// </summary>
|
|||
public char MenuType { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,24 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Text; |
|||
|
|||
namespace Shentun.ProjectManager.RoleMenuInfos |
|||
{ |
|||
public class GetRoleMenuInfoIdsDto |
|||
{ |
|||
/// <summary>
|
|||
/// 菜单ID
|
|||
/// </summary>
|
|||
public Guid MenuInfoId { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 上级ID
|
|||
/// </summary>
|
|||
public Guid? ParentId { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 菜单名称
|
|||
/// </summary>
|
|||
public string DisplayName { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using System.Text; |
|||
|
|||
namespace Shentun.ProjectManager.RoleMenuInfos |
|||
{ |
|||
public class SetRoleMenuInfoRequestDto |
|||
{ |
|||
/// <summary>
|
|||
/// 角色ID
|
|||
/// </summary>
|
|||
public Guid RoleId { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 对应的菜单ID集合
|
|||
/// </summary>
|
|||
public List<Guid> MenuInfoIds { get; set; } = new List<Guid>(); |
|||
} |
|||
} |
|||
@ -0,0 +1,358 @@ |
|||
using AutoMapper.Internal.Mappers; |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Microsoft.Extensions.Configuration; |
|||
using Shentun.ProjectManager.Models; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Application.Services; |
|||
using Volo.Abp.Domain.Entities; |
|||
using Volo.Abp.Domain.Repositories; |
|||
using Volo.Abp.Identity; |
|||
using Volo.Abp.Users; |
|||
using Volo.Abp; |
|||
using Shentun.ProjectManager.MyUsers; |
|||
|
|||
namespace Shentun.ProjectManager.MenuInfos |
|||
{ |
|||
/// <summary>
|
|||
/// 后台菜单
|
|||
/// </summary>
|
|||
[ApiExplorerSettings(GroupName = "Bus")] |
|||
[Authorize] |
|||
public class MenuInfoAppService : ApplicationService |
|||
{ |
|||
private readonly IRepository<MenuInfo, Guid> _menuInfoRepository; |
|||
private readonly IRepository<RoleMenuInfo> _roleMenuInfoRepository; |
|||
private readonly ICurrentUser _currentUser; |
|||
private readonly IIdentityUserRepository _userRepository; |
|||
private readonly IRepository<IdentityUser, Guid> _identityUserRepository; |
|||
private readonly IConfiguration _configuration; |
|||
private readonly MenuInfoManager _menuInfoManager; |
|||
private readonly CacheService _cacheService; |
|||
public MenuInfoAppService( |
|||
IRepository<MenuInfo, Guid> menuInfoRepository, |
|||
IRepository<RoleMenuInfo> roleMenuInfoRepository, |
|||
ICurrentUser currentUser, |
|||
MenuInfoManager menuInfoManager, |
|||
IIdentityUserRepository userRepository, |
|||
IRepository<IdentityUser, Guid> identityUserRepository, |
|||
IConfiguration configuration, |
|||
CacheService cacheService) |
|||
{ |
|||
_menuInfoRepository = menuInfoRepository; |
|||
_menuInfoManager = menuInfoManager; |
|||
_roleMenuInfoRepository = roleMenuInfoRepository; |
|||
_currentUser = currentUser; |
|||
_userRepository = userRepository; |
|||
_identityUserRepository = identityUserRepository; |
|||
_configuration = configuration; |
|||
_cacheService = cacheService; |
|||
} |
|||
|
|||
|
|||
/// <summary>
|
|||
/// 查询菜单数据 根据ID
|
|||
/// </summary>
|
|||
/// <param name="input"></param>
|
|||
/// <returns></returns>
|
|||
[HttpPost("api/app/MenuInfo/GetMenuInfo")] |
|||
public async Task<MenuInfoDto> GetMenuInfoAsync(MenuInfoIdInputDto input) |
|||
{ |
|||
var entity = await _menuInfoRepository.GetAsync(input.MenuInfoId); |
|||
var dto = ObjectMapper.Map<MenuInfo, MenuInfoDto>(entity); |
|||
|
|||
dto.CreatorName =await _cacheService.GetNameAsync(dto.CreatorId); |
|||
dto.LastModifierName = await _cacheService.GetNameAsync(dto.LastModifierId); |
|||
return dto; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 创建后台菜单
|
|||
/// </summary>
|
|||
/// <param name="input"></param>
|
|||
/// <returns></returns>
|
|||
[HttpPost("api/app/MenuInfo/CreatetMenuInfo")] |
|||
public async Task<MenuInfoDto> CreatetMenuInfoAsync(CreateMenuInfoDto input) |
|||
{ |
|||
var createEntity = ObjectMapper.Map<CreateMenuInfoDto, MenuInfo>(input); |
|||
var entity = await _menuInfoManager.CreatetMenuInfoAsync(createEntity); |
|||
entity = await _menuInfoRepository.InsertAsync(entity); |
|||
var dto = ObjectMapper.Map<MenuInfo, MenuInfoDto>(entity); |
|||
return dto; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 修改后台菜单
|
|||
/// </summary>
|
|||
/// <param name="input"></param>
|
|||
/// <returns></returns>
|
|||
[HttpPost("api/app/MenuInfo/UpdateMenuInfo")] |
|||
public async Task<MenuInfoDto> UpdateMenuInfoAsync( UpdateMenuInfoDto input) |
|||
{ |
|||
var entity = await _menuInfoRepository.GetAsync(input.Id); |
|||
var sourceEntity = ObjectMapper.Map<UpdateMenuInfoDto, MenuInfo>(input); |
|||
_menuInfoManager.UpdateMenuInfoAsync(sourceEntity, entity); |
|||
entity = await _menuInfoRepository.UpdateAsync(entity); |
|||
var dto = ObjectMapper.Map<MenuInfo, MenuInfoDto>(entity); |
|||
return dto; |
|||
} |
|||
|
|||
|
|||
/// <summary>
|
|||
/// 删除
|
|||
/// </summary>
|
|||
/// <param name="input"></param>
|
|||
/// <returns></returns>
|
|||
/// <exception cref="UserFriendlyException"></exception>
|
|||
[HttpPost("api/app/MenuInfo/DeleteMenuInfo")] |
|||
public async Task DeleteMenuInfoAsync(MenuInfoIdInputDto input) |
|||
{ |
|||
|
|||
//判断是否有下级节点
|
|||
if ((await _menuInfoRepository.GetQueryableAsync()).Where(m => m.ParentId == input.MenuInfoId).Count() > 0) |
|||
throw new UserFriendlyException("当前菜单有下级节点,不能删除"); |
|||
|
|||
//删除角色选择的对应的菜单数据
|
|||
await _roleMenuInfoRepository.DeleteAsync(d => d.MenuInfoId == input.MenuInfoId); |
|||
|
|||
//删除菜单
|
|||
await _menuInfoRepository.DeleteAsync(input.MenuInfoId); |
|||
} |
|||
|
|||
|
|||
/// <summary>
|
|||
/// 获取当前用户的树型菜单结果
|
|||
/// </summary>
|
|||
/// <returns></returns>
|
|||
[HttpPost("api/app/MenuInfo/GetMyMenuInfoTreeList")] |
|||
public async Task<List<MenuInfoTreeDto>> GetMyMenuInfoTreeListAsync() |
|||
{ |
|||
|
|||
var dataList = await _menuInfoRepository.GetQueryableAsync(); |
|||
string AdminId = _configuration.GetValue<string>("AdminId"); |
|||
if (_currentUser.Id.Value != Guid.Parse(AdminId)) |
|||
{ |
|||
var userRoles = await _userRepository.GetRolesAsync(_currentUser.Id.Value); //获取当前用户的角色
|
|||
if (!userRoles.Any()) |
|||
return new List<MenuInfoTreeDto>(); |
|||
var userMenuInfoList = await _roleMenuInfoRepository.GetListAsync(m => userRoles.Select(s => s.Id).Contains(m.RoleId)); //当前持有的菜单项
|
|||
if (!userMenuInfoList.Any()) |
|||
return new List<MenuInfoTreeDto>(); |
|||
dataList = dataList.Where(m => userMenuInfoList.Select(s => s.MenuInfoId).Distinct().Contains(m.Id)); |
|||
} |
|||
var items = from p in dataList.OrderBy(o => o.DisplayOrder).ThenBy(o => o.DisplayName) |
|||
select new MenuInfoTreeDto() |
|||
{ |
|||
Id = p.Id, |
|||
ParentId = p.ParentId, |
|||
DisplayOrder = p.DisplayOrder, |
|||
IconName = p.IconName, |
|||
IsActive = p.IsActive, |
|||
RouteUrl = p.RouteUrl, |
|||
DisplayName = p.DisplayName, |
|||
SimpleCode = p.SimpleCode, |
|||
MenuType = p.MenuType |
|||
}; |
|||
return GetMenuInfoTree(items.ToList(), null); |
|||
} |
|||
|
|||
|
|||
|
|||
/// <summary>
|
|||
/// 获取树型菜单结果
|
|||
/// </summary>
|
|||
/// <returns></returns>
|
|||
[HttpPost("api/app/MenuInfo/GetMenuInfoTreeList")] |
|||
public async Task<List<MenuInfoTreeDto>> GetMenuInfoTreeListAsync() |
|||
{ |
|||
var dataList = await _menuInfoRepository.GetQueryableAsync(); |
|||
var items = from p in dataList.OrderBy(o => o.DisplayOrder).ThenBy(o => o.DisplayName) |
|||
select new MenuInfoTreeDto() |
|||
{ |
|||
Id = p.Id, |
|||
ParentId = p.ParentId, |
|||
DisplayOrder = p.DisplayOrder, |
|||
IconName = p.IconName, |
|||
IsActive = p.IsActive, |
|||
RouteUrl = p.RouteUrl, |
|||
DisplayName = p.DisplayName, |
|||
SimpleCode = p.SimpleCode, |
|||
MenuType = p.MenuType |
|||
}; |
|||
return GetMenuInfoTree(items.ToList(), null); |
|||
} |
|||
|
|||
|
|||
/// <summary>
|
|||
/// 获取当前用户的菜单列表
|
|||
/// </summary>
|
|||
/// <returns></returns>
|
|||
[HttpPost("api/app/MenuInfo/GetMyMenuInfoList")] |
|||
public async Task<List<GetMyMenuInfoListDto>> GetMyMenuInfoListAsync() |
|||
{ |
|||
var query = await _menuInfoRepository.GetQueryableAsync(); |
|||
|
|||
query = query.Where(m => m.IsActive == 'Y'); |
|||
|
|||
string AdminId = _configuration.GetValue<string>("AdminId"); |
|||
|
|||
if (_currentUser.Id.Value != Guid.Parse(AdminId)) |
|||
{ |
|||
var userRoles = await _userRepository.GetRolesAsync(_currentUser.Id.Value); //获取当前用户的角色
|
|||
if (!userRoles.Any()) |
|||
return new List<GetMyMenuInfoListDto>(); |
|||
var userMenuInfoList = await _roleMenuInfoRepository.GetListAsync(m => userRoles.Select(s => s.Id).Contains(m.RoleId)); //当前持有的菜单项
|
|||
if (!userMenuInfoList.Any()) |
|||
return new List<GetMyMenuInfoListDto>(); |
|||
query = query.Where(m => userMenuInfoList.Select(s => s.MenuInfoId).Distinct().Contains(m.Id)); |
|||
} |
|||
|
|||
|
|||
var entlistdto = query.Select(s => new GetMyMenuInfoListDto |
|||
{ |
|||
DisplayName = s.DisplayName, |
|||
DisplayOrder = s.DisplayOrder, |
|||
IconName = s.IconName, |
|||
Id = s.Id, |
|||
MenuType = s.MenuType, |
|||
ParentId = s.ParentId, |
|||
RouteUrl = s.RouteUrl, |
|||
}).OrderBy(o => o.ParentId).ThenBy(o => o.DisplayOrder).ToList(); |
|||
|
|||
return entlistdto; |
|||
} |
|||
|
|||
|
|||
/// <summary>
|
|||
/// 获取指定用户的菜单列表
|
|||
/// </summary>
|
|||
/// <returns></returns>
|
|||
[HttpPost("api/app/MenuInfo/GetMyMenuInfoListInUser")] |
|||
public async Task<List<MenuInfoDto>> GetMyMenuInfoListInUserAsync(AbpUserIdInputDto input) |
|||
{ |
|||
var query = from a in await _menuInfoRepository.GetQueryableAsync() |
|||
join b in await _identityUserRepository.GetQueryableAsync() on a.CreatorId equals b.Id into bb |
|||
from ab in bb.DefaultIfEmpty() |
|||
join c in await _identityUserRepository.GetQueryableAsync() on a.LastModifierId equals c.Id into cc |
|||
from ac in cc.DefaultIfEmpty() |
|||
select new |
|||
{ |
|||
a, |
|||
LastModifierName = ac != null ? ac.Surname : "", |
|||
CreatorName = ab != null ? ab.Surname : "" |
|||
}; |
|||
|
|||
var userRoles = await _userRepository.GetRolesAsync(input.AbpUserId); //获取当前用户的角色
|
|||
if (!userRoles.Any()) |
|||
return new List<MenuInfoDto>(); |
|||
var userMenuInfoList = await _roleMenuInfoRepository.GetListAsync(m => userRoles.Select(s => s.Id).Contains(m.RoleId)); //当前持有的菜单项
|
|||
if (!userMenuInfoList.Any()) |
|||
return new List<MenuInfoDto>(); |
|||
query = query.Where(m => userMenuInfoList.Select(s => s.MenuInfoId).Distinct().Contains(m.a.Id)); |
|||
|
|||
|
|||
|
|||
var entlistdto = query.Select(s => new MenuInfoDto |
|||
{ |
|||
CreationTime = s.a.CreationTime, |
|||
CreatorId = s.a.CreatorId, |
|||
DisplayName = s.a.DisplayName, |
|||
DisplayOrder = s.a.DisplayOrder, |
|||
IconName = s.a.IconName, |
|||
Id = s.a.Id, |
|||
IsActive = s.a.IsActive, |
|||
LastModifierId = s.a.LastModifierId, |
|||
LastModificationTime = s.a.LastModificationTime, |
|||
MenuType = s.a.MenuType, |
|||
ParentId = s.a.ParentId, |
|||
RouteUrl = s.a.RouteUrl, |
|||
SimpleCode = s.a.SimpleCode, |
|||
CreatorName = s.CreatorName, |
|||
LastModifierName = s.LastModifierName |
|||
}).OrderBy(o => o.DisplayOrder).ThenBy(o => o.DisplayName).ToList(); |
|||
|
|||
return entlistdto; |
|||
} |
|||
|
|||
|
|||
|
|||
/// <summary>
|
|||
/// 获取菜单列表
|
|||
/// </summary>
|
|||
/// <returns></returns>
|
|||
[HttpPost("api/app/MenuInfo/GetMenuInfoList")] |
|||
public async Task<List<MenuInfoDto>> GetMenuInfoListAsync() |
|||
{ |
|||
|
|||
var query = from a in await _menuInfoRepository.GetQueryableAsync() |
|||
join b in await _identityUserRepository.GetQueryableAsync() on a.CreatorId equals b.Id into bb |
|||
from ab in bb.DefaultIfEmpty() |
|||
join c in await _identityUserRepository.GetQueryableAsync() on a.LastModifierId equals c.Id into cc |
|||
from ac in cc.DefaultIfEmpty() |
|||
select new |
|||
{ |
|||
a, |
|||
LastModifierName = ac != null ? ac.Surname : "", |
|||
CreatorName = ab != null ? ab.Surname : "" |
|||
}; |
|||
|
|||
|
|||
var entlistdto = query.Select(s => new MenuInfoDto |
|||
{ |
|||
CreationTime = s.a.CreationTime, |
|||
CreatorId = s.a.CreatorId, |
|||
DisplayName = s.a.DisplayName, |
|||
DisplayOrder = s.a.DisplayOrder, |
|||
IconName = s.a.IconName, |
|||
Id = s.a.Id, |
|||
IsActive = s.a.IsActive, |
|||
LastModifierId = s.a.LastModifierId, |
|||
LastModificationTime = s.a.LastModificationTime, |
|||
MenuType = s.a.MenuType, |
|||
ParentId = s.a.ParentId, |
|||
RouteUrl = s.a.RouteUrl, |
|||
SimpleCode = s.a.SimpleCode, |
|||
CreatorName = s.CreatorName, |
|||
LastModifierName = s.LastModifierName |
|||
}).OrderBy(o => o.DisplayOrder).ThenBy(o => o.DisplayName).ToList(); |
|||
|
|||
return entlistdto; |
|||
|
|||
|
|||
} |
|||
|
|||
/// <summary>
|
|||
///
|
|||
/// </summary>
|
|||
/// <param name="items"></param>
|
|||
/// <param name="ParentId"></param>
|
|||
/// <returns></returns>
|
|||
private List<MenuInfoTreeDto> GetMenuInfoTree(List<MenuInfoTreeDto> items, Guid? ParentId) |
|||
{ |
|||
return (from p in items |
|||
where p.ParentId == ParentId |
|||
let subs = GetMenuInfoTree(items, p.Id) |
|||
select new MenuInfoTreeDto() |
|||
{ |
|||
Id = p.Id, |
|||
ParentId = p.ParentId, |
|||
DisplayOrder = p.DisplayOrder, |
|||
IconName = p.IconName, |
|||
IsActive = p.IsActive, |
|||
RouteUrl = p.RouteUrl, |
|||
DisplayName = p.DisplayName, |
|||
SimpleCode = p.SimpleCode, |
|||
MenuType = p.MenuType, |
|||
TreeChildren = subs.ToList() |
|||
} |
|||
).ToList(); |
|||
} |
|||
|
|||
|
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,92 @@ |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Shentun.ProjectManager.Models; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Application.Services; |
|||
using Volo.Abp.Domain.Repositories; |
|||
|
|||
namespace Shentun.ProjectManager.RoleMenuInfos |
|||
{ |
|||
/// <summary>
|
|||
/// 角色对菜单的权限控制
|
|||
/// </summary>
|
|||
[ApiExplorerSettings(GroupName = "Bus")] |
|||
[Authorize] |
|||
public class RoleMenuInfoAppService : ApplicationService |
|||
{ |
|||
private readonly IRepository<RoleMenuInfo> _roleMenuInfoRepository; |
|||
private readonly IRepository<MenuInfo> _menuInfoRepository; |
|||
|
|||
public RoleMenuInfoAppService( |
|||
IRepository<RoleMenuInfo> roleMenuInfoRepository, |
|||
IRepository<MenuInfo> menuInfoRepository) |
|||
{ |
|||
this._roleMenuInfoRepository = roleMenuInfoRepository; |
|||
this._menuInfoRepository = menuInfoRepository; |
|||
} |
|||
|
|||
|
|||
/// <summary>
|
|||
/// 获取角色对应的菜单选项
|
|||
/// </summary>
|
|||
/// <param name="RoleId">角色ID</param>
|
|||
/// <returns></returns>
|
|||
[HttpPost("api/app/RoleMenuInfo/GetRoleMenuInfoList")] |
|||
public async Task<List<GetRoleMenuInfoIdsDto>> GetRoleMenuInfoListAsync(Guid RoleId) |
|||
{ |
|||
var query = from a in await _roleMenuInfoRepository.GetQueryableAsync() |
|||
join b in await _menuInfoRepository.GetQueryableAsync() on a.MenuInfoId equals b.Id into bb |
|||
from ab in bb.DefaultIfEmpty() |
|||
where a.RoleId == RoleId |
|||
orderby ab.DisplayOrder ascending |
|||
select ab; |
|||
|
|||
var entlistdto = query.Select(s => new GetRoleMenuInfoIdsDto |
|||
{ |
|||
DisplayName = s.DisplayName, |
|||
MenuInfoId = s.Id, |
|||
ParentId = s.ParentId |
|||
}).ToList(); |
|||
|
|||
return entlistdto; |
|||
|
|||
} |
|||
|
|||
|
|||
/// <summary>
|
|||
/// 设置角色的菜单权限
|
|||
/// </summary>
|
|||
/// <param name="input"></param>
|
|||
/// <returns></returns>
|
|||
[HttpPost("api/app/RoleMenuInfo/SetRoleMenuInfo")] |
|||
public async Task SetRoleMenuInfoAsync(SetRoleMenuInfoRequestDto input) |
|||
{ |
|||
//删除原有配置
|
|||
await _roleMenuInfoRepository.DeleteAsync(m => m.RoleId == input.RoleId); |
|||
|
|||
List<RoleMenuInfo> roleMenuInfoList = new List<RoleMenuInfo>(); |
|||
|
|||
if (input.MenuInfoIds.Any()) |
|||
{ |
|||
//增加新配置
|
|||
foreach (var item in input.MenuInfoIds) |
|||
{ |
|||
roleMenuInfoList.Add(new RoleMenuInfo |
|||
{ |
|||
RoleId = input.RoleId, |
|||
MenuInfoId = item |
|||
}); |
|||
} |
|||
|
|||
await _roleMenuInfoRepository.InsertManyAsync(roleMenuInfoList); |
|||
|
|||
} |
|||
} |
|||
|
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,69 @@ |
|||
using Microsoft.International.Converters.PinYinConverter; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Shentun.ProjectManager |
|||
{ |
|||
public class LanguageConverter |
|||
{ |
|||
#region 新版
|
|||
|
|||
|
|||
/// <summary>
|
|||
/// 汉字转首字母
|
|||
/// </summary>
|
|||
/// <param name="strChinese"></param>
|
|||
/// <returns></returns>
|
|||
public static string GetPYSimpleCode(string strChinese) |
|||
{ |
|||
|
|||
try |
|||
{ |
|||
if (strChinese.Length != 0) |
|||
{ |
|||
StringBuilder fullSpell = new StringBuilder(); |
|||
for (int i = 0; i < strChinese.Length; i++) |
|||
{ |
|||
var chr = strChinese[i]; |
|||
fullSpell.Append(GetSpell(chr)[0]); |
|||
} |
|||
|
|||
return fullSpell.ToString().ToUpper(); |
|||
} |
|||
} |
|||
catch (Exception e) |
|||
{ |
|||
|
|||
Console.WriteLine("首字母转化出错!" + e.Message); |
|||
} |
|||
|
|||
return string.Empty; |
|||
} |
|||
|
|||
private static string GetSpell(char chr) |
|||
{ |
|||
var coverchr = NPinyin.Pinyin.GetPinyin(chr); |
|||
|
|||
bool isChineses = ChineseChar.IsValidChar(coverchr[0]); |
|||
if (isChineses) |
|||
{ |
|||
ChineseChar chineseChar = new ChineseChar(coverchr[0]); |
|||
foreach (string value in chineseChar.Pinyins) |
|||
{ |
|||
if (!string.IsNullOrEmpty(value)) |
|||
{ |
|||
return value.Remove(value.Length - 1, 1); |
|||
} |
|||
} |
|||
} |
|||
|
|||
return coverchr; |
|||
|
|||
} |
|||
|
|||
#endregion
|
|||
} |
|||
} |
|||
@ -0,0 +1,84 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.ComponentModel.DataAnnotations.Schema; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
using System.Xml.Linq; |
|||
using Volo.Abp.Domain.Entities.Auditing; |
|||
using Volo.Abp.Domain.Entities; |
|||
|
|||
|
|||
namespace Shentun.ProjectManager.Models |
|||
{ |
|||
/// <summary>
|
|||
/// 菜单栏目
|
|||
/// </summary>
|
|||
public class MenuInfo : AuditedEntity<Guid>, IDisplayOrder, IDisplayName, IHasConcurrencyStamp |
|||
{ |
|||
|
|||
protected MenuInfo() |
|||
{ |
|||
|
|||
} |
|||
|
|||
public MenuInfo(Guid id) : base(id) |
|||
{ |
|||
|
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 名称
|
|||
/// </summary>
|
|||
[StringLength(20)] |
|||
public string DisplayName { get; set; } |
|||
|
|||
|
|||
/// <summary>
|
|||
/// 路由地址
|
|||
/// </summary>
|
|||
[StringLength(100)] |
|||
public string? RouteUrl { get; set; } |
|||
|
|||
|
|||
/// <summary>
|
|||
/// 菜单图标
|
|||
/// </summary>
|
|||
[StringLength(50)] |
|||
public string? IconName { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 自定义简码
|
|||
/// </summary>
|
|||
[StringLength(20)] |
|||
public string SimpleCode { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 父id
|
|||
/// </summary>
|
|||
public Guid? ParentId { get; set; } |
|||
|
|||
|
|||
public int DisplayOrder { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 是否启用
|
|||
/// </summary>
|
|||
public char IsActive { get; set; } |
|||
|
|||
|
|||
|
|||
/// <summary>
|
|||
/// 菜单类型 0 一级菜单 1 带路径的菜单 2 按钮
|
|||
/// </summary>
|
|||
public char MenuType { get; set; } |
|||
|
|||
|
|||
public string ConcurrencyStamp { get; set; } |
|||
|
|||
|
|||
|
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,72 @@ |
|||
using Shentun.ProjectManager.Models; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Domain.Repositories; |
|||
using Volo.Abp.Domain.Services; |
|||
|
|||
namespace Shentun.ProjectManager.MenuInfos |
|||
{ |
|||
public class MenuInfoManager : DomainService |
|||
{ |
|||
private readonly IRepository<MenuInfo, Guid> _menuInfoRepository; |
|||
|
|||
public MenuInfoManager( |
|||
IRepository<MenuInfo, Guid> menuInfoRepository |
|||
) |
|||
{ |
|||
_menuInfoRepository = menuInfoRepository; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 创建
|
|||
/// </summary>
|
|||
/// <param name="entity"></param>
|
|||
/// <returns></returns>
|
|||
public async Task<MenuInfo> CreatetMenuInfoAsync(MenuInfo entity) |
|||
{ |
|||
|
|||
var menuInfoList = await _menuInfoRepository.GetListAsync(m => m.ParentId == entity.ParentId); |
|||
int MaxDisplayOrder = 0; |
|||
if (menuInfoList.Any()) |
|||
MaxDisplayOrder = menuInfoList.Max(o => o.DisplayOrder); |
|||
entity.DisplayOrder = MaxDisplayOrder + 1; |
|||
entity.IsActive = 'Y'; |
|||
entity.SimpleCode = LanguageConverter.GetPYSimpleCode(entity.DisplayName); |
|||
return entity; |
|||
} |
|||
|
|||
|
|||
/// <summary>
|
|||
/// 修改
|
|||
/// </summary>
|
|||
/// <param name="sourceEntity">参数实体</param>
|
|||
/// <param name="targetEntity">待修改的实体</param>
|
|||
/// <returns></returns>
|
|||
public void UpdateMenuInfoAsync(MenuInfo sourceEntity, MenuInfo targetEntity) |
|||
{ |
|||
|
|||
if (sourceEntity.DisplayName != targetEntity.DisplayName) |
|||
{ |
|||
targetEntity.DisplayName = sourceEntity.DisplayName; |
|||
targetEntity.SimpleCode = LanguageConverter.GetPYSimpleCode(targetEntity.DisplayName); |
|||
} |
|||
|
|||
if (sourceEntity.DisplayOrder != 0) |
|||
{ |
|||
targetEntity.DisplayOrder = sourceEntity.DisplayOrder; |
|||
} |
|||
targetEntity.IsActive = sourceEntity.IsActive; |
|||
targetEntity.IconName = sourceEntity.IconName; |
|||
targetEntity.RouteUrl = sourceEntity.RouteUrl; |
|||
targetEntity.MenuType = sourceEntity.MenuType; |
|||
|
|||
|
|||
} |
|||
|
|||
|
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,30 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.ComponentModel.DataAnnotations.Schema; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Domain.Entities; |
|||
|
|||
namespace Shentun.ProjectManager.Models |
|||
{ |
|||
/// <summary>
|
|||
/// 角色对应的后台菜单权限
|
|||
/// </summary>
|
|||
public class RoleMenuInfo : Entity |
|||
{ |
|||
|
|||
[Key] |
|||
public Guid RoleId { get; set; } |
|||
[Key] |
|||
public Guid MenuInfoId { get; set; } |
|||
|
|||
|
|||
public override object[] GetKeys() |
|||
{ |
|||
return new object[] { RoleId, MenuInfoId }; |
|||
} |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
using Microsoft.EntityFrameworkCore.Metadata.Builders; |
|||
using Microsoft.EntityFrameworkCore; |
|||
using Shentun.ProjectManager.Models; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Shentun.ProjectManager.Configures |
|||
{ |
|||
internal class MenuInfoConfigure : IEntityTypeConfiguration<MenuInfo> |
|||
{ |
|||
public void Configure(EntityTypeBuilder<MenuInfo> entity) |
|||
{ |
|||
entity.HasComment("菜单栏目").ToTable("menu_info"); |
|||
entity.Property(t => t.DisplayName).HasComment("名称").IsRequired(); |
|||
entity.Property(t => t.SimpleCode).HasComment("自定义简码").IsRequired(); |
|||
entity.Property(t => t.ParentId).HasComment("父id"); |
|||
entity.Property(e => e.Id).IsFixedLength().IsRequired(); |
|||
entity.Property(e => e.DisplayOrder).HasDefaultValue("999999").IsRequired(); |
|||
entity.Property(e => e.MenuType).HasDefaultValue("1").IsRequired(); |
|||
entity.Property(e => e.ParentId).IsFixedLength(); |
|||
entity.Property(t => t.RouteUrl).HasComment("路由地址"); |
|||
entity.Property(t => t.IconName).HasComment("菜单图标"); |
|||
entity.Property(t => t.IsActive).HasComment("是否启用").IsRequired().HasDefaultValueSql("'Y'"); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
using Microsoft.EntityFrameworkCore.Metadata.Builders; |
|||
using Microsoft.EntityFrameworkCore; |
|||
using Shentun.ProjectManager.Models; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Shentun.ProjectManager.Configures |
|||
{ |
|||
|
|||
internal class RoleMenuInfoDbMapping : IEntityTypeConfiguration<RoleMenuInfo> |
|||
{ |
|||
public void Configure(EntityTypeBuilder<RoleMenuInfo> entity) |
|||
{ |
|||
entity.HasComment("角色对应菜单权限").ToTable("role_menu_info"); |
|||
entity.HasKey(e => new { e.RoleId, e.MenuInfoId }) |
|||
.HasName("pk_role_menuinfo"); |
|||
|
|||
|
|||
entity.Property(e => e.RoleId).IsFixedLength(); |
|||
entity.Property(e => e.MenuInfoId).IsFixedLength(); |
|||
|
|||
} |
|||
} |
|||
} |
|||
2290
src/Shentun.ProjectManager.EntityFrameworkCore/Migrations/20250509085622_insert_menu_info_role_menu_info.Designer.cs
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,60 @@ |
|||
using System; |
|||
using Microsoft.EntityFrameworkCore.Migrations; |
|||
|
|||
#nullable disable |
|||
|
|||
namespace Shentun.ProjectManager.Migrations |
|||
{ |
|||
public partial class insert_menu_info_role_menu_info : Migration |
|||
{ |
|||
protected override void Up(MigrationBuilder migrationBuilder) |
|||
{ |
|||
migrationBuilder.CreateTable( |
|||
name: "menu_info", |
|||
columns: table => new |
|||
{ |
|||
id = table.Column<Guid>(type: "uuid", fixedLength: true, nullable: false), |
|||
display_name = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: false, comment: "名称"), |
|||
route_url = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true, comment: "路由地址"), |
|||
icon_name = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true, comment: "菜单图标"), |
|||
simple_code = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: false, comment: "自定义简码"), |
|||
parent_id = table.Column<Guid>(type: "uuid", fixedLength: true, nullable: true, comment: "父id"), |
|||
display_order = table.Column<int>(type: "integer", nullable: false, defaultValue: 999999), |
|||
is_active = table.Column<char>(type: "character(1)", nullable: false, defaultValueSql: "'Y'", comment: "是否启用"), |
|||
menu_type = table.Column<char>(type: "character(1)", nullable: false, defaultValue: '1'), |
|||
concurrency_stamp = table.Column<string>(type: "character varying(40)", maxLength: 40, nullable: true), |
|||
creation_time = table.Column<DateTime>(type: "timestamp without time zone", nullable: false), |
|||
creator_id = table.Column<Guid>(type: "uuid", nullable: true), |
|||
last_modification_time = table.Column<DateTime>(type: "timestamp without time zone", nullable: true), |
|||
last_modifier_id = table.Column<Guid>(type: "uuid", nullable: true) |
|||
}, |
|||
constraints: table => |
|||
{ |
|||
table.PrimaryKey("pk_menu_info", x => x.id); |
|||
}, |
|||
comment: "菜单栏目"); |
|||
|
|||
migrationBuilder.CreateTable( |
|||
name: "role_menu_info", |
|||
columns: table => new |
|||
{ |
|||
role_id = table.Column<Guid>(type: "uuid", fixedLength: true, nullable: false), |
|||
menu_info_id = table.Column<Guid>(type: "uuid", fixedLength: true, nullable: false) |
|||
}, |
|||
constraints: table => |
|||
{ |
|||
table.PrimaryKey("pk_role_menuinfo", x => new { x.role_id, x.menu_info_id }); |
|||
}, |
|||
comment: "角色对应菜单权限"); |
|||
} |
|||
|
|||
protected override void Down(MigrationBuilder migrationBuilder) |
|||
{ |
|||
migrationBuilder.DropTable( |
|||
name: "menu_info"); |
|||
|
|||
migrationBuilder.DropTable( |
|||
name: "role_menu_info"); |
|||
} |
|||
} |
|||
} |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue