Commit 0268b0d0a66813891ececa229b6ea2e2e0fb74ca
1 parent
557c9c0e
菜单权限模块实现
Showing
6 changed files
with
261 additions
and
60 deletions
美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacMenu/RbacMenuCreateInputVo.cs
| @@ -7,7 +7,10 @@ public class RbacMenuCreateInputVo | @@ -7,7 +7,10 @@ public class RbacMenuCreateInputVo | ||
| 7 | { | 7 | { |
| 8 | public string MenuName { get; set; } = string.Empty; | 8 | public string MenuName { get; set; } = string.Empty; |
| 9 | 9 | ||
| 10 | - public Guid ParentId { get; set; } | 10 | + /// <summary> |
| 11 | + /// 父级ID(menu 表为字符串ID,可能是数字;根节点默认 0) | ||
| 12 | + /// </summary> | ||
| 13 | + public string ParentId { get; set; } = "0"; | ||
| 11 | 14 | ||
| 12 | public int MenuType { get; set; } | 15 | public int MenuType { get; set; } |
| 13 | 16 |
美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacMenu/RbacMenuGetListOutputDto.cs
| @@ -5,9 +5,9 @@ namespace FoodLabeling.Application.Contracts.Dtos.RbacMenu; | @@ -5,9 +5,9 @@ namespace FoodLabeling.Application.Contracts.Dtos.RbacMenu; | ||
| 5 | /// </summary> | 5 | /// </summary> |
| 6 | public class RbacMenuGetListOutputDto | 6 | public class RbacMenuGetListOutputDto |
| 7 | { | 7 | { |
| 8 | - public Guid Id { get; set; } | 8 | + public string Id { get; set; } = string.Empty; |
| 9 | 9 | ||
| 10 | - public Guid ParentId { get; set; } | 10 | + public string ParentId { get; set; } = string.Empty; |
| 11 | 11 | ||
| 12 | public string MenuName { get; set; } = string.Empty; | 12 | public string MenuName { get; set; } = string.Empty; |
| 13 | 13 |
美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacMenu/RbacMenuTreeDto.cs
0 → 100644
| 1 | +namespace FoodLabeling.Application.Contracts.Dtos.RbacMenu; | ||
| 2 | + | ||
| 3 | +/// <summary> | ||
| 4 | +/// 权限树节点(返回菜单表全部字段) | ||
| 5 | +/// </summary> | ||
| 6 | +public class RbacMenuTreeDto | ||
| 7 | +{ | ||
| 8 | + public string Id { get; set; } = string.Empty; | ||
| 9 | + | ||
| 10 | + public bool IsDeleted { get; set; } | ||
| 11 | + | ||
| 12 | + public DateTime CreationTime { get; set; } | ||
| 13 | + | ||
| 14 | + public string? CreatorId { get; set; } | ||
| 15 | + | ||
| 16 | + public string? LastModifierId { get; set; } | ||
| 17 | + | ||
| 18 | + public DateTime? LastModificationTime { get; set; } | ||
| 19 | + | ||
| 20 | + public int OrderNum { get; set; } | ||
| 21 | + | ||
| 22 | + public bool State { get; set; } | ||
| 23 | + | ||
| 24 | + public string MenuName { get; set; } = string.Empty; | ||
| 25 | + | ||
| 26 | + public string? RouterName { get; set; } | ||
| 27 | + | ||
| 28 | + public int MenuType { get; set; } | ||
| 29 | + | ||
| 30 | + public string? PermissionCode { get; set; } | ||
| 31 | + | ||
| 32 | + public string ParentId { get; set; } = string.Empty; | ||
| 33 | + | ||
| 34 | + public string? MenuIcon { get; set; } | ||
| 35 | + | ||
| 36 | + public string? Router { get; set; } | ||
| 37 | + | ||
| 38 | + public bool IsLink { get; set; } | ||
| 39 | + | ||
| 40 | + public bool IsCache { get; set; } | ||
| 41 | + | ||
| 42 | + public bool IsShow { get; set; } | ||
| 43 | + | ||
| 44 | + public string? Remark { get; set; } | ||
| 45 | + | ||
| 46 | + public string? Component { get; set; } | ||
| 47 | + | ||
| 48 | + public int MenuSource { get; set; } | ||
| 49 | + | ||
| 50 | + public string? Query { get; set; } | ||
| 51 | + | ||
| 52 | + public string? ConcurrencyStamp { get; set; } | ||
| 53 | + | ||
| 54 | + public List<RbacMenuTreeDto>? Children { get; set; } | ||
| 55 | +} | ||
| 56 | + |
美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/IServices/IRbacMenuAppService.cs
| 1 | using FoodLabeling.Application.Contracts.Dtos.RbacMenu; | 1 | using FoodLabeling.Application.Contracts.Dtos.RbacMenu; |
| 2 | -using FoodLabeling.Application.Contracts.Dtos.Common; | ||
| 3 | -using Volo.Abp.Application.Dtos; | ||
| 4 | using Volo.Abp.Application.Services; | 2 | using Volo.Abp.Application.Services; |
| 5 | 3 | ||
| 6 | namespace FoodLabeling.Application.Contracts.IServices; | 4 | namespace FoodLabeling.Application.Contracts.IServices; |
| @@ -11,14 +9,14 @@ namespace FoodLabeling.Application.Contracts.IServices; | @@ -11,14 +9,14 @@ namespace FoodLabeling.Application.Contracts.IServices; | ||
| 11 | public interface IRbacMenuAppService : IApplicationService | 9 | public interface IRbacMenuAppService : IApplicationService |
| 12 | { | 10 | { |
| 13 | /// <summary> | 11 | /// <summary> |
| 14 | - /// 权限分页列表 | 12 | + /// 权限列表(不分页) |
| 15 | /// </summary> | 13 | /// </summary> |
| 16 | - Task<PagedResultWithPageDto<RbacMenuGetListOutputDto>> GetListAsync(RbacMenuGetListInputVo input); | 14 | + Task<List<RbacMenuGetListOutputDto>> GetListAsync(RbacMenuGetListInputVo input); |
| 17 | 15 | ||
| 18 | /// <summary> | 16 | /// <summary> |
| 19 | /// 权限详情 | 17 | /// 权限详情 |
| 20 | /// </summary> | 18 | /// </summary> |
| 21 | - Task<RbacMenuGetListOutputDto> GetAsync(Guid id); | 19 | + Task<RbacMenuGetListOutputDto> GetAsync(string id); |
| 22 | 20 | ||
| 23 | /// <summary> | 21 | /// <summary> |
| 24 | /// 新增权限 | 22 | /// 新增权限 |
| @@ -28,11 +26,17 @@ public interface IRbacMenuAppService : IApplicationService | @@ -28,11 +26,17 @@ public interface IRbacMenuAppService : IApplicationService | ||
| 28 | /// <summary> | 26 | /// <summary> |
| 29 | /// 编辑权限 | 27 | /// 编辑权限 |
| 30 | /// </summary> | 28 | /// </summary> |
| 31 | - Task<RbacMenuGetListOutputDto> UpdateAsync(Guid id, RbacMenuUpdateInputVo input); | 29 | + Task<RbacMenuGetListOutputDto> UpdateAsync(string id, RbacMenuUpdateInputVo input); |
| 32 | 30 | ||
| 33 | /// <summary> | 31 | /// <summary> |
| 34 | /// 删除权限(逻辑删除) | 32 | /// 删除权限(逻辑删除) |
| 35 | /// </summary> | 33 | /// </summary> |
| 36 | - Task DeleteAsync(List<Guid> ids); | 34 | + Task DeleteAsync(List<string> ids); |
| 35 | + | ||
| 36 | + /// <summary> | ||
| 37 | + /// 获取全部权限树(GET) | ||
| 38 | + /// </summary> | ||
| 39 | + /// <returns>树状权限列表</returns> | ||
| 40 | + Task<List<RbacMenuTreeDto>> GetTreeAsync(); | ||
| 37 | } | 41 | } |
| 38 | 42 |
美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/DbModels/MenuDbEntity.cs
0 → 100644
| 1 | +using SqlSugar; | ||
| 2 | + | ||
| 3 | +namespace FoodLabeling.Application.Services.DbModels; | ||
| 4 | + | ||
| 5 | +/// <summary> | ||
| 6 | +/// menu 表映射(兼容数字/字符串类型的 Id、ParentId) | ||
| 7 | +/// </summary> | ||
| 8 | +[SugarTable("menu")] | ||
| 9 | +public class MenuDbEntity | ||
| 10 | +{ | ||
| 11 | + [SugarColumn(IsPrimaryKey = true)] | ||
| 12 | + public string Id { get; set; } = string.Empty; | ||
| 13 | + | ||
| 14 | + public bool IsDeleted { get; set; } | ||
| 15 | + | ||
| 16 | + public DateTime CreationTime { get; set; } | ||
| 17 | + | ||
| 18 | + public string? CreatorId { get; set; } | ||
| 19 | + | ||
| 20 | + public string? LastModifierId { get; set; } | ||
| 21 | + | ||
| 22 | + public DateTime? LastModificationTime { get; set; } | ||
| 23 | + | ||
| 24 | + public int OrderNum { get; set; } | ||
| 25 | + | ||
| 26 | + public bool State { get; set; } | ||
| 27 | + | ||
| 28 | + public string MenuName { get; set; } = string.Empty; | ||
| 29 | + | ||
| 30 | + public string? RouterName { get; set; } | ||
| 31 | + | ||
| 32 | + public int MenuType { get; set; } | ||
| 33 | + | ||
| 34 | + public string? PermissionCode { get; set; } | ||
| 35 | + | ||
| 36 | + public string ParentId { get; set; } = "0"; | ||
| 37 | + | ||
| 38 | + public string? MenuIcon { get; set; } | ||
| 39 | + | ||
| 40 | + public string? Router { get; set; } | ||
| 41 | + | ||
| 42 | + public bool IsLink { get; set; } | ||
| 43 | + | ||
| 44 | + public bool IsCache { get; set; } | ||
| 45 | + | ||
| 46 | + public bool IsShow { get; set; } | ||
| 47 | + | ||
| 48 | + public string? Remark { get; set; } | ||
| 49 | + | ||
| 50 | + public string? Component { get; set; } | ||
| 51 | + | ||
| 52 | + public int MenuSource { get; set; } | ||
| 53 | + | ||
| 54 | + public string? Query { get; set; } | ||
| 55 | + | ||
| 56 | + public string? ConcurrencyStamp { get; set; } | ||
| 57 | +} | ||
| 58 | + |
美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/RbacMenuAppService.cs
| 1 | using FoodLabeling.Application.Contracts.Dtos.RbacMenu; | 1 | using FoodLabeling.Application.Contracts.Dtos.RbacMenu; |
| 2 | -using FoodLabeling.Application.Contracts.Dtos.Common; | ||
| 3 | using FoodLabeling.Application.Contracts.IServices; | 2 | using FoodLabeling.Application.Contracts.IServices; |
| 3 | +using FoodLabeling.Application.Services.DbModels; | ||
| 4 | using Microsoft.AspNetCore.Mvc; | 4 | using Microsoft.AspNetCore.Mvc; |
| 5 | using SqlSugar; | 5 | using SqlSugar; |
| 6 | using Volo.Abp; | 6 | using Volo.Abp; |
| 7 | using Volo.Abp.Application.Services; | 7 | using Volo.Abp.Application.Services; |
| 8 | -using Volo.Abp.Domain.Entities; | ||
| 9 | -using Yi.Framework.Rbac.Domain.Entities; | ||
| 10 | using Yi.Framework.SqlSugarCore.Abstractions; | 8 | using Yi.Framework.SqlSugarCore.Abstractions; |
| 11 | 9 | ||
| 12 | namespace FoodLabeling.Application.Services; | 10 | namespace FoodLabeling.Application.Services; |
| @@ -16,57 +14,44 @@ namespace FoodLabeling.Application.Services; | @@ -16,57 +14,44 @@ namespace FoodLabeling.Application.Services; | ||
| 16 | /// </summary> | 14 | /// </summary> |
| 17 | public class RbacMenuAppService : ApplicationService, IRbacMenuAppService | 15 | public class RbacMenuAppService : ApplicationService, IRbacMenuAppService |
| 18 | { | 16 | { |
| 19 | - private readonly ISqlSugarRepository<MenuAggregateRoot, Guid> _menuRepository; | 17 | + private readonly ISqlSugarDbContext _dbContext; |
| 20 | 18 | ||
| 21 | - public RbacMenuAppService(ISqlSugarRepository<MenuAggregateRoot, Guid> menuRepository) | 19 | + public RbacMenuAppService(ISqlSugarDbContext dbContext) |
| 22 | { | 20 | { |
| 23 | - _menuRepository = menuRepository; | 21 | + _dbContext = dbContext; |
| 24 | } | 22 | } |
| 25 | 23 | ||
| 26 | /// <inheritdoc /> | 24 | /// <inheritdoc /> |
| 27 | - public async Task<PagedResultWithPageDto<RbacMenuGetListOutputDto>> GetListAsync([FromQuery] RbacMenuGetListInputVo input) | 25 | + public async Task<List<RbacMenuGetListOutputDto>> GetListAsync([FromQuery] RbacMenuGetListInputVo input) |
| 28 | { | 26 | { |
| 29 | - RefAsync<int> total = 0; | ||
| 30 | - | ||
| 31 | - var query = _menuRepository._DbQueryable | 27 | + var query = _dbContext.SqlSugarClient.Queryable<MenuDbEntity>() |
| 32 | .Where(x => x.IsDeleted == false) | 28 | .Where(x => x.IsDeleted == false) |
| 33 | .WhereIF(!string.IsNullOrWhiteSpace(input.MenuName), x => x.MenuName.Contains(input.MenuName!.Trim())) | 29 | .WhereIF(!string.IsNullOrWhiteSpace(input.MenuName), x => x.MenuName.Contains(input.MenuName!.Trim())) |
| 34 | .WhereIF(input.State is not null, x => x.State == input.State) | 30 | .WhereIF(input.State is not null, x => x.State == input.State) |
| 35 | - .WhereIF(input.MenuSource is not null, x => x.MenuSource == (Yi.Framework.Rbac.Domain.Shared.Enums.MenuSourceEnum)input.MenuSource!.Value) | 31 | + .WhereIF(input.MenuSource is not null, x => x.MenuSource == input.MenuSource!.Value) |
| 36 | .OrderBy(x => x.OrderNum, OrderByType.Desc); | 32 | .OrderBy(x => x.OrderNum, OrderByType.Desc); |
| 37 | 33 | ||
| 38 | - var entities = await query.ToPageListAsync(input.SkipCount, input.MaxResultCount, total); | 34 | + var entities = await query.ToListAsync(); |
| 39 | 35 | ||
| 40 | - var items = entities.Select(x => new RbacMenuGetListOutputDto | 36 | + return entities.Select(x => new RbacMenuGetListOutputDto |
| 41 | { | 37 | { |
| 42 | Id = x.Id, | 38 | Id = x.Id, |
| 43 | ParentId = x.ParentId, | 39 | ParentId = x.ParentId, |
| 44 | MenuName = x.MenuName ?? string.Empty, | 40 | MenuName = x.MenuName ?? string.Empty, |
| 45 | PermissionCode = x.PermissionCode, | 41 | PermissionCode = x.PermissionCode, |
| 46 | - MenuType = (int)x.MenuType, | ||
| 47 | - MenuSource = (int)x.MenuSource, | 42 | + MenuType = x.MenuType, |
| 43 | + MenuSource = x.MenuSource, | ||
| 48 | OrderNum = x.OrderNum, | 44 | OrderNum = x.OrderNum, |
| 49 | State = x.State | 45 | State = x.State |
| 50 | }).ToList(); | 46 | }).ToList(); |
| 51 | - | ||
| 52 | - var pageSize = input.MaxResultCount <= 0 ? items.Count : input.MaxResultCount; | ||
| 53 | - var pageIndex = pageSize <= 0 ? 1 : (input.SkipCount / pageSize) + 1; | ||
| 54 | - var totalPages = pageSize <= 0 ? 0 : (int)Math.Ceiling(total / (double)pageSize); | ||
| 55 | - | ||
| 56 | - return new PagedResultWithPageDto<RbacMenuGetListOutputDto> | ||
| 57 | - { | ||
| 58 | - PageIndex = pageIndex, | ||
| 59 | - PageSize = pageSize, | ||
| 60 | - TotalCount = total, | ||
| 61 | - TotalPages = totalPages, | ||
| 62 | - Items = items | ||
| 63 | - }; | ||
| 64 | } | 47 | } |
| 65 | 48 | ||
| 66 | /// <inheritdoc /> | 49 | /// <inheritdoc /> |
| 67 | - public async Task<RbacMenuGetListOutputDto> GetAsync(Guid id) | 50 | + public async Task<RbacMenuGetListOutputDto> GetAsync(string id) |
| 68 | { | 51 | { |
| 69 | - var entity = await _menuRepository.GetSingleAsync(x => x.Id == id && x.IsDeleted == false); | 52 | + var entity = await _dbContext.SqlSugarClient.Queryable<MenuDbEntity>() |
| 53 | + .Where(x => x.Id == id && x.IsDeleted == false) | ||
| 54 | + .SingleAsync(); | ||
| 70 | if (entity is null) | 55 | if (entity is null) |
| 71 | { | 56 | { |
| 72 | throw new UserFriendlyException("权限不存在"); | 57 | throw new UserFriendlyException("权限不存在"); |
| @@ -78,8 +63,8 @@ public class RbacMenuAppService : ApplicationService, IRbacMenuAppService | @@ -78,8 +63,8 @@ public class RbacMenuAppService : ApplicationService, IRbacMenuAppService | ||
| 78 | ParentId = entity.ParentId, | 63 | ParentId = entity.ParentId, |
| 79 | MenuName = entity.MenuName ?? string.Empty, | 64 | MenuName = entity.MenuName ?? string.Empty, |
| 80 | PermissionCode = entity.PermissionCode, | 65 | PermissionCode = entity.PermissionCode, |
| 81 | - MenuType = (int)entity.MenuType, | ||
| 82 | - MenuSource = (int)entity.MenuSource, | 66 | + MenuType = entity.MenuType, |
| 67 | + MenuSource = entity.MenuSource, | ||
| 83 | OrderNum = entity.OrderNum, | 68 | OrderNum = entity.OrderNum, |
| 84 | State = entity.State | 69 | State = entity.State |
| 85 | }; | 70 | }; |
| @@ -94,28 +79,35 @@ public class RbacMenuAppService : ApplicationService, IRbacMenuAppService | @@ -94,28 +79,35 @@ public class RbacMenuAppService : ApplicationService, IRbacMenuAppService | ||
| 94 | throw new UserFriendlyException("权限名称不能为空"); | 79 | throw new UserFriendlyException("权限名称不能为空"); |
| 95 | } | 80 | } |
| 96 | 81 | ||
| 97 | - var entity = new MenuAggregateRoot | 82 | + var entity = new MenuDbEntity |
| 98 | { | 83 | { |
| 84 | + Id = GuidGenerator.Create().ToString(), | ||
| 99 | MenuName = name, | 85 | MenuName = name, |
| 100 | - ParentId = input.ParentId, | ||
| 101 | - MenuType = (Yi.Framework.Rbac.Domain.Shared.Enums.MenuTypeEnum)input.MenuType, | ||
| 102 | - MenuSource = (Yi.Framework.Rbac.Domain.Shared.Enums.MenuSourceEnum)input.MenuSource, | 86 | + ParentId = string.IsNullOrWhiteSpace(input.ParentId) ? "0" : input.ParentId.Trim(), |
| 87 | + MenuType = input.MenuType, | ||
| 88 | + MenuSource = input.MenuSource, | ||
| 103 | PermissionCode = input.PermissionCode?.Trim(), | 89 | PermissionCode = input.PermissionCode?.Trim(), |
| 104 | Router = input.Router?.Trim(), | 90 | Router = input.Router?.Trim(), |
| 105 | Component = input.Component?.Trim(), | 91 | Component = input.Component?.Trim(), |
| 106 | OrderNum = input.OrderNum, | 92 | OrderNum = input.OrderNum, |
| 107 | - State = input.State | 93 | + State = input.State, |
| 94 | + IsDeleted = false, | ||
| 95 | + CreationTime = DateTime.Now, | ||
| 96 | + IsCache = false, | ||
| 97 | + IsLink = false, | ||
| 98 | + IsShow = true, | ||
| 99 | + ConcurrencyStamp = string.Empty | ||
| 108 | }; | 100 | }; |
| 109 | - EntityHelper.TrySetId(entity, () => GuidGenerator.Create()); | ||
| 110 | - | ||
| 111 | - await _menuRepository.InsertAsync(entity); | 101 | + await _dbContext.SqlSugarClient.Insertable(entity).ExecuteCommandAsync(); |
| 112 | return await GetAsync(entity.Id); | 102 | return await GetAsync(entity.Id); |
| 113 | } | 103 | } |
| 114 | 104 | ||
| 115 | /// <inheritdoc /> | 105 | /// <inheritdoc /> |
| 116 | - public async Task<RbacMenuGetListOutputDto> UpdateAsync(Guid id, [FromBody] RbacMenuUpdateInputVo input) | 106 | + public async Task<RbacMenuGetListOutputDto> UpdateAsync(string id, [FromBody] RbacMenuUpdateInputVo input) |
| 117 | { | 107 | { |
| 118 | - var entity = await _menuRepository.GetSingleAsync(x => x.Id == id && x.IsDeleted == false); | 108 | + var entity = await _dbContext.SqlSugarClient.Queryable<MenuDbEntity>() |
| 109 | + .Where(x => x.Id == id && x.IsDeleted == false) | ||
| 110 | + .SingleAsync(); | ||
| 119 | if (entity is null) | 111 | if (entity is null) |
| 120 | { | 112 | { |
| 121 | throw new UserFriendlyException("权限不存在"); | 113 | throw new UserFriendlyException("权限不存在"); |
| @@ -128,30 +120,118 @@ public class RbacMenuAppService : ApplicationService, IRbacMenuAppService | @@ -128,30 +120,118 @@ public class RbacMenuAppService : ApplicationService, IRbacMenuAppService | ||
| 128 | } | 120 | } |
| 129 | 121 | ||
| 130 | entity.MenuName = name; | 122 | entity.MenuName = name; |
| 131 | - entity.ParentId = input.ParentId; | ||
| 132 | - entity.MenuType = (Yi.Framework.Rbac.Domain.Shared.Enums.MenuTypeEnum)input.MenuType; | ||
| 133 | - entity.MenuSource = (Yi.Framework.Rbac.Domain.Shared.Enums.MenuSourceEnum)input.MenuSource; | 123 | + entity.ParentId = string.IsNullOrWhiteSpace(input.ParentId) ? "0" : input.ParentId.Trim(); |
| 124 | + entity.MenuType = input.MenuType; | ||
| 125 | + entity.MenuSource = input.MenuSource; | ||
| 134 | entity.PermissionCode = input.PermissionCode?.Trim(); | 126 | entity.PermissionCode = input.PermissionCode?.Trim(); |
| 135 | entity.Router = input.Router?.Trim(); | 127 | entity.Router = input.Router?.Trim(); |
| 136 | entity.Component = input.Component?.Trim(); | 128 | entity.Component = input.Component?.Trim(); |
| 137 | entity.OrderNum = input.OrderNum; | 129 | entity.OrderNum = input.OrderNum; |
| 138 | entity.State = input.State; | 130 | entity.State = input.State; |
| 131 | + entity.LastModificationTime = DateTime.Now; | ||
| 139 | 132 | ||
| 140 | - await _menuRepository.UpdateAsync(entity); | 133 | + await _dbContext.SqlSugarClient.Updateable(entity) |
| 134 | + .Where(x => x.Id == entity.Id) | ||
| 135 | + .ExecuteCommandAsync(); | ||
| 141 | return await GetAsync(entity.Id); | 136 | return await GetAsync(entity.Id); |
| 142 | } | 137 | } |
| 143 | 138 | ||
| 144 | /// <inheritdoc /> | 139 | /// <inheritdoc /> |
| 145 | - public async Task DeleteAsync([FromBody] List<Guid> ids) | 140 | + public async Task DeleteAsync([FromBody] List<string> ids) |
| 146 | { | 141 | { |
| 147 | - var idList = ids?.Distinct().ToList() ?? new List<Guid>(); | 142 | + var idList = ids?.Where(x => !string.IsNullOrWhiteSpace(x)).Select(x => x.Trim()).Distinct().ToList() ?? new List<string>(); |
| 148 | if (idList.Count == 0) | 143 | if (idList.Count == 0) |
| 149 | { | 144 | { |
| 150 | return; | 145 | return; |
| 151 | } | 146 | } |
| 152 | 147 | ||
| 153 | - // 权限表为软删(ISoftDelete) | ||
| 154 | - await _menuRepository.DeleteAsync(x => idList.Contains(x.Id)); | 148 | + await _dbContext.SqlSugarClient.Updateable<MenuDbEntity>() |
| 149 | + .SetColumns(x => new MenuDbEntity { IsDeleted = true }) | ||
| 150 | + .Where(x => idList.Contains(x.Id)) | ||
| 151 | + .ExecuteCommandAsync(); | ||
| 152 | + } | ||
| 153 | + | ||
| 154 | + /// <inheritdoc /> | ||
| 155 | + public async Task<List<RbacMenuTreeDto>> GetTreeAsync() | ||
| 156 | + { | ||
| 157 | + // 返回所有字段,但过滤逻辑删除数据 | ||
| 158 | + var menus = await _dbContext.SqlSugarClient.Queryable<MenuDbEntity>() | ||
| 159 | + .Where(x => x.IsDeleted == false) | ||
| 160 | + .OrderBy(x => x.OrderNum, OrderByType.Desc) | ||
| 161 | + .ToListAsync(); | ||
| 162 | + | ||
| 163 | + var nodes = menus.Select(m => new RbacMenuTreeDto | ||
| 164 | + { | ||
| 165 | + Id = m.Id, | ||
| 166 | + IsDeleted = m.IsDeleted, | ||
| 167 | + CreationTime = m.CreationTime, | ||
| 168 | + CreatorId = m.CreatorId, | ||
| 169 | + LastModifierId = m.LastModifierId, | ||
| 170 | + LastModificationTime = m.LastModificationTime, | ||
| 171 | + OrderNum = m.OrderNum, | ||
| 172 | + State = m.State, | ||
| 173 | + MenuName = m.MenuName ?? string.Empty, | ||
| 174 | + RouterName = m.RouterName, | ||
| 175 | + MenuType = m.MenuType, | ||
| 176 | + PermissionCode = m.PermissionCode, | ||
| 177 | + ParentId = m.ParentId, | ||
| 178 | + MenuIcon = m.MenuIcon, | ||
| 179 | + Router = m.Router, | ||
| 180 | + IsLink = m.IsLink, | ||
| 181 | + IsCache = m.IsCache, | ||
| 182 | + IsShow = m.IsShow, | ||
| 183 | + Remark = m.Remark, | ||
| 184 | + Component = m.Component, | ||
| 185 | + MenuSource = m.MenuSource, | ||
| 186 | + Query = m.Query, | ||
| 187 | + ConcurrencyStamp = m.ConcurrencyStamp, | ||
| 188 | + Children = new List<RbacMenuTreeDto>() | ||
| 189 | + }).ToList(); | ||
| 190 | + | ||
| 191 | + // TreeHelper 仅支持 Guid Id/ParentId,这里使用字符串 ParentId 自行构建树 | ||
| 192 | + var nodeById = nodes | ||
| 193 | + .Where(x => !string.IsNullOrWhiteSpace(x.Id)) | ||
| 194 | + .GroupBy(x => x.Id) | ||
| 195 | + .ToDictionary(g => g.Key, g => g.First()); | ||
| 196 | + | ||
| 197 | + foreach (var node in nodes) | ||
| 198 | + { | ||
| 199 | + node.Children ??= new List<RbacMenuTreeDto>(); | ||
| 200 | + var parentId = string.IsNullOrWhiteSpace(node.ParentId) ? "0" : node.ParentId.Trim(); | ||
| 201 | + if (parentId == "0" || parentId == "00000000-0000-0000-0000-000000000000") | ||
| 202 | + { | ||
| 203 | + continue; | ||
| 204 | + } | ||
| 205 | + | ||
| 206 | + if (nodeById.TryGetValue(parentId, out var parent)) | ||
| 207 | + { | ||
| 208 | + parent.Children ??= new List<RbacMenuTreeDto>(); | ||
| 209 | + parent.Children.Add(node); | ||
| 210 | + } | ||
| 211 | + } | ||
| 212 | + | ||
| 213 | + var roots = nodes | ||
| 214 | + .Where(n => | ||
| 215 | + { | ||
| 216 | + var pid = string.IsNullOrWhiteSpace(n.ParentId) ? "0" : n.ParentId.Trim(); | ||
| 217 | + return pid == "0" || pid == "00000000-0000-0000-0000-000000000000" || !nodeById.ContainsKey(pid); | ||
| 218 | + }) | ||
| 219 | + .ToList(); | ||
| 220 | + | ||
| 221 | + SortTree(roots); | ||
| 222 | + return roots; | ||
| 223 | + } | ||
| 224 | + | ||
| 225 | + private static void SortTree(List<RbacMenuTreeDto> nodes) | ||
| 226 | + { | ||
| 227 | + nodes.Sort((a, b) => b.OrderNum.CompareTo(a.OrderNum)); | ||
| 228 | + foreach (var node in nodes) | ||
| 229 | + { | ||
| 230 | + if (node.Children is { Count: > 0 }) | ||
| 231 | + { | ||
| 232 | + SortTree(node.Children); | ||
| 233 | + } | ||
| 234 | + } | ||
| 155 | } | 235 | } |
| 156 | } | 236 | } |
| 157 | 237 |