diff --git a/src/main/java/com/cczsa/xinghe/codegen/controller/RoleController.java b/src/main/java/com/cczsa/xinghe/codegen/controller/RoleController.java index 0bc6520..9101cb3 100644 --- a/src/main/java/com/cczsa/xinghe/codegen/controller/RoleController.java +++ b/src/main/java/com/cczsa/xinghe/codegen/controller/RoleController.java @@ -3,7 +3,9 @@ package com.cczsa.xinghe.codegen.controller; import com.cczsa.xinghe.codegen.entity.req.role.RoleAddReq; import com.cczsa.xinghe.codegen.entity.req.role.RoleBindFunReq; import com.cczsa.xinghe.codegen.entity.req.role.RoleEditReq; +import com.cczsa.xinghe.codegen.entity.req.role.RoleQueryFunReq; import com.cczsa.xinghe.codegen.entity.req.role.RoleQueryReq; +import com.cczsa.xinghe.codegen.entity.res.role.RoleQueryFunRes; import com.cczsa.xinghe.codegen.entity.res.role.RoleQueryRes; import com.cczsa.xinghe.codegen.service.RoleService; import com.cczsa.xinghe.codegen.util.XResult; @@ -72,5 +74,11 @@ public class RoleController { return roleService.deleteFun(roleBindFunId); } + @Operation(summary = "获取角色功能权限配置", description = "获取角色功能权限配置") + @PostMapping("/query/fun") + public XResult> queryRoleFun(@RequestBody @Valid RoleQueryFunReq req) { + return roleService.queryRoleFun(req); + } + } \ No newline at end of file diff --git a/src/main/java/com/cczsa/xinghe/codegen/entity/req/role/RoleQueryFunReq.java b/src/main/java/com/cczsa/xinghe/codegen/entity/req/role/RoleQueryFunReq.java new file mode 100644 index 0000000..3a4a938 --- /dev/null +++ b/src/main/java/com/cczsa/xinghe/codegen/entity/req/role/RoleQueryFunReq.java @@ -0,0 +1,33 @@ +package com.cczsa.xinghe.codegen.entity.req.role; + +import com.cczsa.xinghe.codegen.entity.enums.ClientTypeEnum; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.Getter; +import lombok.Setter; + +import java.io.Serial; +import java.io.Serializable; + +/** + * 获取角色功能权限配置 请求参数 + * @author xia + * @version 0.0.1 + */ +@Getter +@Setter +@Schema(description = "获取角色功能权限配置-参数") +public class RoleQueryFunReq implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + @NotNull(message = "角色id不能为空") + @Schema(description = "角色id") + private Long roleId; + + @NotNull(message = "客户端类型不能为空") + @Schema(description = "客户端类型:0 PC端,1 小程序端,2 H5端") + private ClientTypeEnum clientType; + +} diff --git a/src/main/java/com/cczsa/xinghe/codegen/entity/res/role/MenuFunListRes.java b/src/main/java/com/cczsa/xinghe/codegen/entity/res/role/MenuFunListRes.java new file mode 100644 index 0000000..7d0136c --- /dev/null +++ b/src/main/java/com/cczsa/xinghe/codegen/entity/res/role/MenuFunListRes.java @@ -0,0 +1,65 @@ +package com.cczsa.xinghe.codegen.entity.res.role; + +import com.cczsa.xinghe.codegen.entity.enums.UsableConfigEnum; +import com.cczsa.xinghe.codegen.handler.PostgreSQLJsonTypeHandler; +import com.mybatisflex.annotation.Column; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; + +import java.io.Serial; +import java.io.Serializable; +import java.util.List; + +/** + * 菜单功能列表 响应参数 + * + * @author xia + * @version 0.0.1 + */ +@Getter +@Setter +@Schema(description = "菜单功能列表-响应") +public class MenuFunListRes implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + @Schema(description = "权限id") + private Long id; + + @Schema(description = "操作名称") + private String funName; + + @Schema(description = "可配置数据类型") + @Column(typeHandler = PostgreSQLJsonTypeHandler.class) + private List usableConfig; + + @Schema(description = "可配置字段") + @Column(typeHandler = PostgreSQLJsonTypeHandler.class) + private List fieldConfig; + + @Schema(description = "排序") + private Integer sortOrder; + + @Schema(description = "说明") + private String describe; + + @Schema(description = "是否已选择") + private Boolean isSelect = false; + + @Schema(description = "角色权限绑定的id") + private Long funBindId; + + @Schema(description = "数据权限") + private UsableConfigEnum dataScope; + + @Schema(description = "指定的数据权限范围") + @Column(typeHandler = PostgreSQLJsonTypeHandler.class) + private List assignDataScope; + + @Schema(description = "排除的字段") + @Column(typeHandler = PostgreSQLJsonTypeHandler.class) + private List excludeField; + +} diff --git a/src/main/java/com/cczsa/xinghe/codegen/entity/res/role/RoleQueryFunRes.java b/src/main/java/com/cczsa/xinghe/codegen/entity/res/role/RoleQueryFunRes.java new file mode 100644 index 0000000..507208a --- /dev/null +++ b/src/main/java/com/cczsa/xinghe/codegen/entity/res/role/RoleQueryFunRes.java @@ -0,0 +1,60 @@ +package com.cczsa.xinghe.codegen.entity.res.role; + +import com.cczsa.xinghe.codegen.entity.enums.ClientTypeEnum; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; + +import java.io.Serial; +import java.io.Serializable; +import java.util.List; + +/** + * 获取角色功能权限配置 响应参数 + * + * @author xia + * @version 0.0.1 + */ +@Getter +@Setter +@Schema(description = "获取角色功能权限配置-响应") +public class RoleQueryFunRes implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + @Schema(description = "菜单ID") + private Long id; + + @Schema(description = "客户端类型:0 PC端,1 小程序端,2 H5端") + private ClientTypeEnum clientType; + + @Schema(description = "菜单名称") + private String menuName; + + @Schema(description = "父菜单ID") + private Long parentId = 0L; + + @Schema(description = "路由路径") + private String path; + + @Schema(description = "菜单图标") + private String icon; + + @Schema(description = "是否租户") + private Boolean isTenant; + + @Schema(description = "是否隐藏") + private Boolean isHide; + + @Schema(description = "排序") + private Integer sortOrder; + + @Schema(description = "菜单功能列表") + private List menuFunList; + + @Schema(description = "子菜单") + private List children; + + +} diff --git a/src/main/java/com/cczsa/xinghe/codegen/service/RoleService.java b/src/main/java/com/cczsa/xinghe/codegen/service/RoleService.java index d2e69f6..d627569 100644 --- a/src/main/java/com/cczsa/xinghe/codegen/service/RoleService.java +++ b/src/main/java/com/cczsa/xinghe/codegen/service/RoleService.java @@ -3,7 +3,9 @@ package com.cczsa.xinghe.codegen.service; import com.cczsa.xinghe.codegen.entity.req.role.RoleAddReq; import com.cczsa.xinghe.codegen.entity.req.role.RoleBindFunReq; import com.cczsa.xinghe.codegen.entity.req.role.RoleEditReq; +import com.cczsa.xinghe.codegen.entity.req.role.RoleQueryFunReq; import com.cczsa.xinghe.codegen.entity.req.role.RoleQueryReq; +import com.cczsa.xinghe.codegen.entity.res.role.RoleQueryFunRes; import com.cczsa.xinghe.codegen.entity.res.role.RoleQueryRes; import com.cczsa.xinghe.codegen.util.XResult; @@ -48,4 +50,9 @@ public interface RoleService { XResult deleteFun(Long roleBindFunId); + /** + * 获取角色功能权限配置 + */ + XResult> queryRoleFun(RoleQueryFunReq req); + } \ No newline at end of file diff --git a/src/main/java/com/cczsa/xinghe/codegen/service/impl/RoleServiceImpl.java b/src/main/java/com/cczsa/xinghe/codegen/service/impl/RoleServiceImpl.java index d766ddd..360cf4a 100644 --- a/src/main/java/com/cczsa/xinghe/codegen/service/impl/RoleServiceImpl.java +++ b/src/main/java/com/cczsa/xinghe/codegen/service/impl/RoleServiceImpl.java @@ -1,17 +1,27 @@ package com.cczsa.xinghe.codegen.service.impl; import com.cczsa.xinghe.codegen.entity.FunOperationEntity; +import com.cczsa.xinghe.codegen.entity.MenuBindFunEntity; +import com.cczsa.xinghe.codegen.entity.MenuEntity; import com.cczsa.xinghe.codegen.entity.RoleEntity; import com.cczsa.xinghe.codegen.entity.RoleFunEntity; import com.cczsa.xinghe.codegen.entity.enums.UsableConfigEnum; import com.cczsa.xinghe.codegen.entity.req.role.RoleAddReq; import com.cczsa.xinghe.codegen.entity.req.role.RoleBindFunReq; import com.cczsa.xinghe.codegen.entity.req.role.RoleEditReq; +import com.cczsa.xinghe.codegen.entity.req.role.RoleQueryFunReq; import com.cczsa.xinghe.codegen.entity.req.role.RoleQueryReq; +import com.cczsa.xinghe.codegen.entity.res.role.MenuFunListRes; +import com.cczsa.xinghe.codegen.entity.res.role.RoleQueryFunRes; import com.cczsa.xinghe.codegen.entity.res.role.RoleQueryRes; import com.cczsa.xinghe.codegen.mapper.FunOperationMapper; +import com.cczsa.xinghe.codegen.mapper.MenuBindFunMapper; +import com.cczsa.xinghe.codegen.mapper.MenuMapper; import com.cczsa.xinghe.codegen.mapper.RoleFunMapper; import com.cczsa.xinghe.codegen.mapper.RoleMapper; +import com.cczsa.xinghe.codegen.mapper.def.FunOperationDef; +import com.cczsa.xinghe.codegen.mapper.def.MenuBindFunDef; +import com.cczsa.xinghe.codegen.mapper.def.MenuDef; import com.cczsa.xinghe.codegen.mapper.def.RoleDef; import com.cczsa.xinghe.codegen.mapper.def.RoleFunDef; import com.cczsa.xinghe.codegen.service.RoleService; @@ -24,7 +34,9 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * 角色管理 服务层实现。 @@ -39,6 +51,8 @@ public class RoleServiceImpl implements RoleService { private final RoleMapper roleMapper; private final RoleFunMapper roleFunMapper; private final FunOperationMapper funOperationMapper; + private final MenuMapper menuMapper; + private final MenuBindFunMapper menuBindFunMapper; /** @@ -202,4 +216,100 @@ public class RoleServiceImpl implements RoleService { return XResult.ok(); } + /** + * 获取角色功能权限配置 + */ + @Override + public XResult> queryRoleFun(RoleQueryFunReq req) { + // 获取菜单 + MenuDef menuDef = MenuDef.MENU_ENTITY; + QueryWrapper queryMenu = new QueryWrapper(); + queryMenu.select(menuDef.ALL_COLUMNS) + .from(menuDef) + .eq(MenuEntity::getClientType, req.getClientType()); + List roleQueryFunList = menuMapper.selectListByQueryAs(queryMenu, RoleQueryFunRes.class); + // 获取角色功能权限 + RoleFunDef roleFunDef = RoleFunDef.ROLE_FUN_ENTITY; + QueryWrapper queryRoleFun = new QueryWrapper(); + queryRoleFun.select(roleFunDef.ALL_COLUMNS) + .from(roleFunDef) + .eq(RoleFunEntity::getRoleId, req.getRoleId()); + List roleFunEntities = roleFunMapper.selectListByQuery(queryRoleFun); + for (RoleQueryFunRes roleQueryFunRes : roleQueryFunList) { + // 获取菜单功能 + FunOperationDef funOperationDef = FunOperationDef.FUN_OPERATION_ENTITY; + MenuBindFunDef menuBindFunDef = MenuBindFunDef.MENU_BIND_FUN_ENTITY; + QueryWrapper queryMenuBindFun = new QueryWrapper(); + queryMenuBindFun.select( + funOperationDef.ID, + funOperationDef.FUN_NAME, + funOperationDef.USABLE_CONFIG, + funOperationDef.FIELD_CONFIG, + funOperationDef.SORT_ORDER, + funOperationDef.DESCRIBE + ) + .from(menuBindFunDef) + .leftJoin(funOperationDef).on(funOperationDef.ID.eq(menuBindFunDef.FUN_ID)) + .eq(MenuBindFunEntity::getMenuId, roleQueryFunRes.getId()); + List menuFunList = menuBindFunMapper.selectListByQueryAs(queryMenuBindFun, MenuFunListRes.class); + for (MenuFunListRes menuFunListRes : menuFunList) { + // 在roleFunEntities中查找匹配的功能权限 + RoleFunEntity roleFunEntity = roleFunEntities.stream() + .filter(entity -> entity.getFunId().equals(menuFunListRes.getId())) + .findFirst() + .orElse(null); + if (roleFunEntity != null) { + // 设置角色权限配置 + menuFunListRes.setDataScope(roleFunEntity.getDataScope()); + menuFunListRes.setExcludeField(roleFunEntity.getExcludeField()); + menuFunListRes.setAssignDataScope(roleFunEntity.getAssignDataScope()); + menuFunListRes.setIsSelect(true); + menuFunListRes.setFunBindId(roleFunEntity.getId()); + } else { + // 如果角色没有此功能的权限,设置默认值 + menuFunListRes.setDataScope(null); + menuFunListRes.setExcludeField(new ArrayList<>()); + menuFunListRes.setAssignDataScope(new ArrayList<>()); + } + } + roleQueryFunRes.setMenuFunList(menuFunList); + } + // 构建树形结构 + List treeList = buildMenuTree(roleQueryFunList); + return XResult.ok(treeList); + } + + /** + * 构建树形结构 + */ + private List buildMenuTree(List roleQueryFunList) { + // 创建一个Map用于快速查找分组 + Map menuMap = new HashMap<>(); + for (RoleQueryFunRes menu : roleQueryFunList) { + menuMap.put(menu.getId(), menu); + } + // 构建树形结构 + List rootMenuList = new ArrayList<>(); + for (RoleQueryFunRes menu : roleQueryFunList) { + Long parentId = menu.getParentId(); + if (parentId == 0) { + // 根分组 + rootMenuList.add(menu); + } else { + // 如果父节点在结果中,则挂到父节点下 + RoleQueryFunRes parentMenu = menuMap.get(parentId); + if (parentMenu != null) { + if (parentMenu.getChildren() == null) { + parentMenu.setChildren(new ArrayList<>()); + } + parentMenu.getChildren().add(menu); + } else { + // 如果父节点不在结果中,则将该节点作为根节点处理 + rootMenuList.add(menu); + } + } + } + return rootMenuList; + } + } \ No newline at end of file