From 2a96d6896d550a478d6dd71d557f3cad5fdf22eb Mon Sep 17 00:00:00 2001 From: zhou-hao Date: Tue, 12 Oct 2021 09:39:11 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=8F=9C=E5=8D=95=E7=AE=A1?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../community/auth/entity/MenuButtonInfo.java | 47 +++++ .../community/auth/entity/MenuEntity.java | 96 +++++++++- .../community/auth/entity/MenuView.java | 58 ++++++ .../community/auth/entity/PermissionInfo.java | 23 +++ .../community/auth/web/MenuController.java | 176 ++++++++++++++---- .../request/AuthorizationSettingDetail.java | 45 ++++- .../auth/web/request/MenuGrantRequest.java | 97 ++++++++++ 7 files changed, 493 insertions(+), 49 deletions(-) create mode 100644 jetlinks-manager/authentication-manager/src/main/java/org/jetlinks/community/auth/entity/MenuButtonInfo.java mode change 100644 => 100755 jetlinks-manager/authentication-manager/src/main/java/org/jetlinks/community/auth/entity/MenuEntity.java create mode 100644 jetlinks-manager/authentication-manager/src/main/java/org/jetlinks/community/auth/entity/MenuView.java create mode 100644 jetlinks-manager/authentication-manager/src/main/java/org/jetlinks/community/auth/entity/PermissionInfo.java mode change 100644 => 100755 jetlinks-manager/authentication-manager/src/main/java/org/jetlinks/community/auth/web/MenuController.java mode change 100644 => 100755 jetlinks-manager/authentication-manager/src/main/java/org/jetlinks/community/auth/web/request/AuthorizationSettingDetail.java create mode 100644 jetlinks-manager/authentication-manager/src/main/java/org/jetlinks/community/auth/web/request/MenuGrantRequest.java diff --git a/jetlinks-manager/authentication-manager/src/main/java/org/jetlinks/community/auth/entity/MenuButtonInfo.java b/jetlinks-manager/authentication-manager/src/main/java/org/jetlinks/community/auth/entity/MenuButtonInfo.java new file mode 100644 index 00000000..049428bb --- /dev/null +++ b/jetlinks-manager/authentication-manager/src/main/java/org/jetlinks/community/auth/entity/MenuButtonInfo.java @@ -0,0 +1,47 @@ +package org.jetlinks.community.auth.entity; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; +import org.apache.commons.collections4.CollectionUtils; + +import java.util.*; +import java.util.function.BiPredicate; + +@Getter +@Setter +public class MenuButtonInfo { + + @Schema(description = "按钮ID") + private String id; + + @Schema(description = "按钮名称") + private String name; + + @Schema(description = "权限信息") + private List permissions; + + @Schema(description = "其他配置") + private Map options; + + public boolean hasPermission(BiPredicate> predicate) { + if (CollectionUtils.isEmpty(permissions)) { + return true; + } + + for (PermissionInfo permission : permissions) { + if (!predicate.test(permission.getPermission(), permission.getActions())) { + return false; + } + } + return true; + } + + public static MenuButtonInfo of(String id, String name, String permission, String... actions) { + MenuButtonInfo info = new MenuButtonInfo(); + info.setId(id); + info.setName(name); + info.setPermissions(Arrays.asList(PermissionInfo.of(permission, new HashSet<>(Arrays.asList(actions))))); + return info; + } +} diff --git a/jetlinks-manager/authentication-manager/src/main/java/org/jetlinks/community/auth/entity/MenuEntity.java b/jetlinks-manager/authentication-manager/src/main/java/org/jetlinks/community/auth/entity/MenuEntity.java old mode 100644 new mode 100755 index e237c40c..9baf25c4 --- a/jetlinks-manager/authentication-manager/src/main/java/org/jetlinks/community/auth/entity/MenuEntity.java +++ b/jetlinks-manager/authentication-manager/src/main/java/org/jetlinks/community/auth/entity/MenuEntity.java @@ -1,29 +1,41 @@ package org.jetlinks.community.auth.entity; +import io.swagger.v3.oas.annotations.Hidden; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Getter; import lombok.Setter; +import org.apache.commons.collections4.CollectionUtils; import org.hswebframework.ezorm.rdb.mapping.annotation.ColumnType; import org.hswebframework.ezorm.rdb.mapping.annotation.Comment; +import org.hswebframework.ezorm.rdb.mapping.annotation.DefaultValue; +import org.hswebframework.ezorm.rdb.mapping.annotation.JsonCodec; import org.hswebframework.web.api.crud.entity.GenericTreeSortSupportEntity; +import org.jetlinks.community.auth.web.request.AuthorizationSettingDetail; import javax.persistence.Column; import javax.persistence.Index; import javax.persistence.Table; import java.sql.JDBCType; -import java.util.List; +import java.util.*; +import java.util.function.BiPredicate; +import java.util.function.Predicate; +import java.util.stream.Collectors; /** + * 菜单定义实体类 + * * @author wangzheng * @since 1.0 */ @Getter @Setter @Table(name = "s_menu", indexes = { - @Index(name = "idx_menu_path", columnList = "path") + @Index(name = "idx_menu_path", columnList = "path") }) public class MenuEntity - extends GenericTreeSortSupportEntity { + extends GenericTreeSortSupportEntity { + @Schema(description = "名称") @Comment("菜单名称") @Column(length = 32) private String name; @@ -31,29 +43,101 @@ public class MenuEntity @Comment("描述") @Column @ColumnType(jdbcType = JDBCType.CLOB) + @Schema(description = "描述") private String describe; + @Hidden + @Deprecated @Comment("权限表达式") @Column(name = "permission_expression", length = 256) private String permissionExpression; @Comment("菜单对应的url") @Column(length = 512) + @Schema(description = "URL,路由") private String url; @Comment("图标") @Column(length = 256) + @Schema(description = "图标") private String icon; @Comment("状态") @Column @ColumnType(jdbcType = JDBCType.SMALLINT) + @Schema(description = "状态,0为禁用,1为启用") + @DefaultValue("1") private Byte status; + + @Schema(description = "默认权限信息") + @Column + @JsonCodec + @ColumnType(jdbcType = JDBCType.LONGVARCHAR, javaType = String.class) + private List permissions; + + @Schema(description = "按钮定义信息") + @Column + @JsonCodec + @ColumnType(jdbcType = JDBCType.LONGVARCHAR, javaType = String.class) + private List buttons; + + @Schema(description = "其他配置信息") + @Column + @JsonCodec + @ColumnType(jdbcType = JDBCType.LONGVARCHAR, javaType = String.class) + private Map options; + //子菜单 + @Schema(description = "子菜单") private List children; - @Override - public List getChildren() { - return children; + public MenuEntity copy(Predicate buttonPredicate) { + MenuEntity entity = this.copyTo(new MenuEntity()); + + if (CollectionUtils.isEmpty(entity.getButtons())) { + return entity; + } + entity.setButtons( + entity + .getButtons() + .stream() + .filter(buttonPredicate) + .collect(Collectors.toList()) + ); + return entity; + } + + public boolean hasPermission(BiPredicate> predicate) { + if (CollectionUtils.isEmpty(permissions) && CollectionUtils.isEmpty(buttons)) { + return false; + } + //有权限信息 + if (CollectionUtils.isNotEmpty(permissions)) { + for (PermissionInfo permission : permissions) { + if (!predicate.test(permission.getPermission(), permission.getActions())) { + return false; + } + } + return true; + } + //有任意按钮信息 + if (CollectionUtils.isNotEmpty(buttons)) { + for (MenuButtonInfo button : buttons) { + if (button.hasPermission(predicate)) { + return true; + } + } + } + return false; + } + + public Optional getButton(String id) { + if (buttons == null) { + return Optional.empty(); + } + return buttons + .stream() + .filter(button -> Objects.equals(button.getId(), id)) + .findAny(); } } diff --git a/jetlinks-manager/authentication-manager/src/main/java/org/jetlinks/community/auth/entity/MenuView.java b/jetlinks-manager/authentication-manager/src/main/java/org/jetlinks/community/auth/entity/MenuView.java new file mode 100644 index 00000000..7b100002 --- /dev/null +++ b/jetlinks-manager/authentication-manager/src/main/java/org/jetlinks/community/auth/entity/MenuView.java @@ -0,0 +1,58 @@ +package org.jetlinks.community.auth.entity; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.hswebframework.web.api.crud.entity.GenericTreeSortSupportEntity; +import org.hswebframework.web.bean.FastBeanCopier; + +import java.util.List; +import java.util.Map; + +@Getter +@Setter +public class MenuView extends GenericTreeSortSupportEntity { + + @Schema(description = "菜单名称") + private String name; + + @Schema(description = "图标") + private String icon; + + @Schema(description = "URL") + private String url; + + @Schema(description = "父节点") + private String parentId; + + @Schema(description = "按钮") + private List buttons; + + @Schema(description = "其他配置") + private Map options; + + @Schema(description = "子节点") + private List children; + + @Getter + @Setter + @AllArgsConstructor(staticName = "of") + @NoArgsConstructor + public static class ButtonView{ + + @Schema(description = "按钮ID") + private String id; + + @Schema(description = "按钮名称") + private String name; + + @Schema(description = "其他配置") + private Map options; + } + + public static MenuView of(MenuEntity entity){ + return FastBeanCopier.copy(entity,new MenuView()); + } +} diff --git a/jetlinks-manager/authentication-manager/src/main/java/org/jetlinks/community/auth/entity/PermissionInfo.java b/jetlinks-manager/authentication-manager/src/main/java/org/jetlinks/community/auth/entity/PermissionInfo.java new file mode 100644 index 00000000..8e3abcbe --- /dev/null +++ b/jetlinks-manager/authentication-manager/src/main/java/org/jetlinks/community/auth/entity/PermissionInfo.java @@ -0,0 +1,23 @@ +package org.jetlinks.community.auth.entity; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.util.Set; + +@Getter +@Setter +@AllArgsConstructor(staticName = "of") +@NoArgsConstructor +public class PermissionInfo { + + @Schema(description = "权限ID") + private String permission; + + @Schema(description = "权限操作") + private Set actions; + +} diff --git a/jetlinks-manager/authentication-manager/src/main/java/org/jetlinks/community/auth/web/MenuController.java b/jetlinks-manager/authentication-manager/src/main/java/org/jetlinks/community/auth/web/MenuController.java old mode 100644 new mode 100755 index 01bfd42f..b0b3152c --- a/jetlinks-manager/authentication-manager/src/main/java/org/jetlinks/community/auth/web/MenuController.java +++ b/jetlinks-manager/authentication-manager/src/main/java/org/jetlinks/community/auth/web/MenuController.java @@ -1,31 +1,37 @@ package org.jetlinks.community.auth.web; -import io.swagger.v3.oas.annotations.Hidden; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.AllArgsConstructor; import org.hswebframework.web.api.crud.entity.TreeSupportEntity; import org.hswebframework.web.authorization.Authentication; -import org.hswebframework.web.authorization.AuthenticationUtils; import org.hswebframework.web.authorization.annotation.Authorize; import org.hswebframework.web.authorization.annotation.Resource; +import org.hswebframework.web.authorization.annotation.ResourceAction; import org.hswebframework.web.authorization.exception.UnAuthorizedException; import org.hswebframework.web.crud.service.ReactiveCrudService; import org.hswebframework.web.crud.web.reactive.ReactiveServiceCrudController; +import org.jetlinks.community.auth.entity.MenuButtonInfo; import org.jetlinks.community.auth.entity.MenuEntity; +import org.jetlinks.community.auth.entity.MenuView; +import org.jetlinks.community.auth.service.AuthorizationSettingDetailService; import org.jetlinks.community.auth.service.DefaultMenuService; -import org.springframework.beans.factory.annotation.Autowired; +import org.jetlinks.community.auth.web.request.MenuGrantRequest; import org.springframework.util.StringUtils; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; -import java.util.*; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; /** * 菜单管理 + * * @author wangzheng * @since 1.0 */ @@ -33,27 +39,140 @@ import java.util.stream.Collectors; @RequestMapping("/menu") @Authorize @Resource(id = "menu", name = "菜单管理", group = "system") -@Hidden +@Tag(name = "菜单管理") +@AllArgsConstructor public class MenuController implements ReactiveServiceCrudController { - @Autowired - private DefaultMenuService defaultMenuService; + private final DefaultMenuService defaultMenuService; + + private final AuthorizationSettingDetailService settingService; @Override public ReactiveCrudService getService() { return defaultMenuService; } - public Collection predicateUserMenu(Map menuMap, Authentication autz) { + /** + * 获取用户自己的菜单列表 + * + * @return 菜单列表 + */ + @GetMapping("/user-own/tree") + @Authorize(merge = false) + @Operation(summary = "获取当前用户可访问的菜单(树结构)") + public Flux getUserMenuAsTree() { + return this + .getUserMenuAsList() + .as(MenuController::listToTree); + } + + + @GetMapping("/user-own/list") + @Authorize(merge = false) + @Operation(summary = "获取当前用户可访问的菜单(列表结构)") + public Flux getUserMenuAsList() { + return Authentication + .currentReactive() + .switchIfEmpty(Mono.error(UnAuthorizedException::new)) + .flatMapMany(autz -> defaultMenuService + .createQuery() + .where(MenuEntity::getStatus,1) + .fetch() + .collect(Collectors.toMap(MenuEntity::getId, Function.identity())) + .flatMapIterable(menuMap -> MenuController + .convertMenuView(menuMap, + menu -> "admin".equals(autz.getUser().getUsername()) || + menu.hasPermission(autz::hasPermission), + button -> "admin".equals(autz.getUser().getUsername()) || + button.hasPermission(autz::hasPermission) + ))); + } + + @PutMapping("/_grant") + @Operation(summary = "根据菜单进行授权") + @ResourceAction(id = "grant", name = "授权") + public Mono grant(@RequestBody Mono body) { + return Mono + .zip( + //T1: 当前用户权限信息 + Authentication.currentReactive(), + //T2: 将菜单信息转为授权信息 + Mono + .zip(body, + defaultMenuService + .createQuery() + .where(MenuEntity::getStatus,1) + .fetch() + .collectList(), + MenuGrantRequest::toAuthorizationSettingDetail + ) + .map(Flux::just), + //保存授权信息 + settingService::saveDetail + ) + .flatMap(Function.identity()); + } + + @GetMapping("/{targetType}/{targetId}/_grant/tree") + @ResourceAction(id = "grant", name = "授权") + @Operation(summary = "获取菜单授权信息(树结构)") + public Flux getGrantInfoTree(@PathVariable String targetType, + @PathVariable String targetId) { + + return this + .getGrantInfo(targetType, targetId) + .as(MenuController::listToTree); + } + + @GetMapping("/{targetType}/{targetId}/_grant/list") + @ResourceAction(id = "grant", name = "授权") + @Operation(summary = "获取菜单授权信息(列表结构)") + public Flux getGrantInfo(@PathVariable String targetType, + @PathVariable String targetId) { + + return Mono + .zip( + //权限设置信息 + settingService.getSettingDetail(targetType, targetId), + //菜单 + defaultMenuService + .createQuery() + .where(MenuEntity::getStatus,1) + .fetch() + .collectMap(MenuEntity::getId, Function.identity()), + (detail, menuMap) -> MenuController + .convertMenuView(menuMap, + menu -> menu.hasPermission(detail::hasPermission), + button -> button.hasPermission(detail::hasPermission) + ) + ) + .flatMapIterable(Function.identity()); + } + + private static Flux listToTree(Flux flux) { + return flux + .collectList() + .flatMapIterable(list -> TreeSupportEntity + .list2tree(list, + MenuView::setChildren, + (Predicate) n -> + StringUtils.isEmpty(n.getParentId()) + || "-1".equals(n.getParentId()))); + } + + private static Collection convertMenuView(Map menuMap, + Predicate menuPredicate, + Predicate buttonPredicate) { Map group = new HashMap<>(); for (MenuEntity menu : menuMap.values()) { if (group.containsKey(menu.getId())) { continue; } - if (autz.getUser().getUsername().equals("admin") || AuthenticationUtils.createPredicate(menu.getPermissionExpression()).test(autz)) { + if (menuPredicate.test(menu)) { String parentId = menu.getParentId(); MenuEntity parent; group.put(menu.getId(), menu); + //有子菜单默认就有父菜单 while (!StringUtils.isEmpty(parentId)) { parent = menuMap.get(parentId); if (parent == null) { @@ -64,33 +183,12 @@ public class MenuController implements ReactiveServiceCrudController list = new ArrayList<>(group.values()); - Collections.sort(list); - - return list; + return group + .values() + .stream() + .map(menu -> MenuView.of(menu.copy(buttonPredicate))) + .sorted() + .collect(Collectors.toList()); } - /** - * 获取用户自己的菜单列表 - * @return 菜单列表 - */ - @GetMapping("user-own/tree") - @Authorize(merge = false) - public Flux getUserMenuAsTree() { - return Authentication - .currentReactive() - .switchIfEmpty(Mono.error(UnAuthorizedException::new)) - .flatMapMany(autz -> defaultMenuService - .createQuery() - .fetch() - .collect(Collectors.toMap(MenuEntity::getId, Function.identity())) - .map(menuMap -> predicateUserMenu(menuMap, autz)) - .map(menus -> TreeSupportEntity.list2tree( - menus, - MenuEntity::setChildren, - (Predicate) n -> - StringUtils.isEmpty(n.getParentId()) - || "-1".equals(n.getParentId()))).flatMapMany(Flux::fromIterable)); - - } } diff --git a/jetlinks-manager/authentication-manager/src/main/java/org/jetlinks/community/auth/web/request/AuthorizationSettingDetail.java b/jetlinks-manager/authentication-manager/src/main/java/org/jetlinks/community/auth/web/request/AuthorizationSettingDetail.java old mode 100644 new mode 100755 index cce2ea31..666bd953 --- a/jetlinks-manager/authentication-manager/src/main/java/org/jetlinks/community/auth/web/request/AuthorizationSettingDetail.java +++ b/jetlinks-manager/authentication-manager/src/main/java/org/jetlinks/community/auth/web/request/AuthorizationSettingDetail.java @@ -1,5 +1,7 @@ package org.jetlinks.community.auth.web.request; +import io.swagger.v3.oas.annotations.Hidden; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import org.apache.commons.collections.CollectionUtils; import org.hswebframework.web.authorization.Dimension; @@ -25,56 +27,85 @@ public class AuthorizationSettingDetail { * 设置目标类型(维度)标识,如: org, role */ @NotBlank + @Schema(description = "权限类型,如: org,openApi") private String targetType; /** * 设置目标. */ @NotBlank + @Schema(description = "权限类型对应的数据ID") private String targetId; /** * 冲突时是否合并 */ + @Schema(description = "冲突时是否合并") private boolean merge = true; /** * 冲突时优先级 */ + @Schema(description = "冲突时合并优先级") private int priority = 10; /** * 权限列表 */ + @Schema(description = "权限列表") private List permissionList; + public boolean hasPermission(String id, Collection actions) { + if (CollectionUtils.isEmpty(permissionList)) { + return false; + } + for (PermissionInfo info : permissionList) { + if (Objects.equals(info.getId(), id)) { + if (CollectionUtils.isEmpty(actions)) { + return true; + } + if (CollectionUtils.isNotEmpty(info.getActions())) { + if (info.getActions().containsAll(actions)) { + return true; + } + } + } + } + return false; + } + /** * 授权信息 */ @Getter @Setter @EqualsAndHashCode(of = "id") + @Generated public static class PermissionInfo { /** * 权限ID */ @NotBlank + @Schema(description = "权限ID") private String id; /** * 授权操作 */ + @Schema(description = "允许执行的操作") private Set actions; /** * 字段权限 */ + @Hidden private List fieldAccess; /** * 数据权限 */ + @Hidden private List dataAccess; private PermissionInfo unwrap(AuthorizationSettingEntity entity) { @@ -94,8 +125,8 @@ public class AuthorizationSettingDetail { //字段权限 if (DataAccessConfig.DefaultType.DENY_FIELDS.equalsIgnoreCase(access.getType())) { Set fields = Optional.ofNullable(access.getConfig()) - .>map(conf -> new HashSet<>((Collection) conf.get("fields"))) - .orElseGet(HashSet::new); + .>map(conf -> new HashSet<>((Collection) conf.get("fields"))) + .orElseGet(HashSet::new); for (String field : fields) { filedAccessMap @@ -130,7 +161,7 @@ public class AuthorizationSettingDetail { for (FieldAccess access : fieldAccess) { for (String action : access.getAction()) { group.computeIfAbsent(action, r -> new HashSet<>()) - .add(access.name); + .add(access.name); } } for (Map.Entry> entry : group.entrySet()) { @@ -150,6 +181,12 @@ public class AuthorizationSettingDetail { entity.setDataAccesses(entities); } + public static PermissionInfo of(String id, Collection actions) { + PermissionInfo info = new PermissionInfo(); + info.setId(id); + info.setActions(new HashSet<>(actions)); + return info; + } } @@ -184,7 +221,7 @@ public class AuthorizationSettingDetail { } public List toEntity() { - if(CollectionUtils.isEmpty(actions)){ + if (CollectionUtils.isEmpty(actions)) { return Collections.emptyList(); } return actions diff --git a/jetlinks-manager/authentication-manager/src/main/java/org/jetlinks/community/auth/web/request/MenuGrantRequest.java b/jetlinks-manager/authentication-manager/src/main/java/org/jetlinks/community/auth/web/request/MenuGrantRequest.java new file mode 100644 index 00000000..fa010584 --- /dev/null +++ b/jetlinks-manager/authentication-manager/src/main/java/org/jetlinks/community/auth/web/request/MenuGrantRequest.java @@ -0,0 +1,97 @@ +package org.jetlinks.community.auth.web.request; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.apache.commons.collections4.CollectionUtils; +import org.hswebframework.web.api.crud.entity.TreeSupportEntity; +import org.hswebframework.web.id.IDGenerator; +import org.jetlinks.community.auth.entity.MenuView; +import org.jetlinks.community.auth.entity.MenuEntity; +import org.jetlinks.community.auth.entity.MenuView; +import org.jetlinks.community.auth.entity.PermissionInfo; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +public class MenuGrantRequest { + + + private String targetType; + + private String targetId; + + /** + * 冲突时是否合并 + */ + @Schema(description = "冲突时是否合并") + private boolean merge = true; + + /** + * 冲突时优先级 + */ + @Schema(description = "冲突时合并优先级") + private int priority = 10; + + @Schema(description = "授权的菜单信息") + private List menus; + + public AuthorizationSettingDetail toAuthorizationSettingDetail(List menuEntities) { + Map menuMap = menuEntities + .stream() + .collect(Collectors.toMap(MenuEntity::getId, Function.identity())); + AuthorizationSettingDetail detail = new AuthorizationSettingDetail(); + detail.setTargetType(targetType); + detail.setTargetId(targetId); + detail.setMerge(merge); + detail.setPriority(priority); + + List permissionInfos = new ArrayList<>(); + + for (MenuView menu : menus) { + //平铺 + List expand = TreeSupportEntity.expandTree2List(menu, IDGenerator.MD5); + for (MenuView menuView : expand) { + MenuEntity entity = menuMap.get(menuView.getId()); + if (entity == null) { + continue; + } + //自动持有配置的权限 + if (CollectionUtils.isNotEmpty(entity.getPermissions())) { + for (PermissionInfo permission : entity.getPermissions()) { + permissionInfos.add(AuthorizationSettingDetail.PermissionInfo.of(permission.getPermission(), permission.getActions())); + } + } + + if (CollectionUtils.isNotEmpty(menuView.getButtons())) { + for (MenuView.ButtonView button : menuView.getButtons()) { + entity.getButton(button.getId()) + .ifPresent(buttonInfo -> { + if (CollectionUtils.isNotEmpty(buttonInfo.getPermissions())) { + for (PermissionInfo permission : buttonInfo.getPermissions()) { + permissionInfos + .add(AuthorizationSettingDetail.PermissionInfo.of(permission.getPermission(), permission.getActions())); + } + + } + }); + } + } + } + } + detail.setPermissionList(permissionInfos); + + return detail; + } + + +}