This commit is contained in:
2023-05-12 17:21:44 +08:00
parent 101e515922
commit 77a83cee8b
13 changed files with 539 additions and 3 deletions

View File

@ -0,0 +1,68 @@
package com.qiaoba.api.system.entity.vo;
import cn.hutool.http.HttpUtil;
import lombok.Getter;
import lombok.Setter;
/**
* 路由显示信息
*
* @author ailanyin
* @version 1.0
* @since 2022-09-22 04:20:28
*/
@Getter
@Setter
public class MetaVo {
/**
* 设置该路由在侧边栏和面包屑中展示的名字
*/
private String title;
/**
* 设置该路由的图标对应路径src/assets/icons/svg
*/
private String icon;
/**
* 设置为true则不会被 <keep-alive>缓存
*/
private boolean noCache;
/**
* 内链地址http(s)://开头)
*/
private String link;
public MetaVo() {
}
public MetaVo(String title, String icon) {
this.title = title;
this.icon = icon;
}
public MetaVo(String title, String icon, boolean noCache) {
this.title = title;
this.icon = icon;
this.noCache = noCache;
}
public MetaVo(String title, String icon, String link) {
this.title = title;
this.icon = icon;
if (HttpUtil.isHttp(link) || HttpUtil.isHttps(link)) {
this.link = link;
}
}
public MetaVo(String title, String icon, boolean noCache, String link) {
this.title = title;
this.icon = icon;
this.noCache = noCache;
if (HttpUtil.isHttp(link) || HttpUtil.isHttps(link)) {
this.link = link;
}
}
}

View File

@ -0,0 +1,66 @@
package com.qiaoba.api.system.entity.vo;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
/**
* 路由配置信息
*
* @author ailanyin
* @version 1.0
* @since 2022-09-22 04:20:28
*/
@JsonInclude(JsonInclude.Include.NON_EMPTY)
@Getter
@Setter
public class RouterVo {
/**
* 路由名字
*/
private String name;
/**
* 路由地址
*/
private String path;
/**
* 是否隐藏路由,当设置 true 的时候该路由不会再侧边栏出现
*/
private boolean hidden;
/**
* 重定向地址,当设置 noRedirect 的时候该路由在面包屑导航中不可被点击
*/
private String redirect;
/**
* 组件地址
*/
private String component;
/**
* 路由参数:如 {"id": 1, "name": "ry"}
*/
private String query;
/**
* 当你一个路由下面的 children 声明的路由大于1个时自动会变成嵌套的模式--如组件页面
*/
private Boolean alwaysShow;
/**
* 其他元素
*/
private MetaVo meta;
/**
* 子路由
*/
private List<RouterVo> children;
}

View File

@ -45,6 +45,11 @@ public class SysMenuVo implements Serializable {
*/
private String component;
/**
* 路由参数
*/
private String query;
/**
* 显示状态0隐藏 1显示
*/
@ -55,11 +60,31 @@ public class SysMenuVo implements Serializable {
*/
private String perms;
/**
* 路由地址
*/
private String path;
/**
* 菜单图标
*/
private String icon;
/**
* 是否为外链0否 1是
*/
private String isFrame;
/**
* 是否缓存0不缓存 1缓存
*/
private String isCache;
/**
* 类型M目录 C菜单 F按钮
*/
private String menuType;
/**
* 创建时间
*/

View File

@ -28,4 +28,14 @@ public class BaseConstant {
* 默认的父ID = 0
*/
public static final String DEFAULT_PARENT_ID_VALUE = "0";
/**
* http请求
*/
public static final String HTTP = "http://";
/**
* https请求
*/
public static final String HTTPS = "https://";
}

View File

@ -0,0 +1,56 @@
package com.qiaoba.common.base.constants;
/**
* 菜单常量
*
* @author ailanyin
* @version 1.0
* @since 2023-04-23 15:37:43
*/
public class MenuConstant {
/**
* 是否菜单外链(是)
*/
public static final String YES_FRAME = "1";
/**
* 是否菜单外链(否)
*/
public static final String NO_FRAME = "0";
/**
* 菜单类型(目录)
*/
public static final String TYPE_DIR = "M";
/**
* 菜单类型(菜单)
*/
public static final String TYPE_MENU = "C";
/**
* 菜单类型(按钮)
*/
public static final String TYPE_BUTTON = "F";
/**
* Layout组件标识
*/
public final static String LAYOUT = "Layout";
/**
* ParentView组件标识
*/
public final static String PARENT_VIEW = "ParentView";
/**
* InnerLink组件标识
*/
public final static String INNER_LINK = "InnerLink";
/**
* 不重定向
*/
public final static String NO_REDIRECT = "noRedirect";
}

View File

@ -1,10 +1,16 @@
package com.qiaoba.module.system.controller;
import com.qiaoba.api.system.entity.SysMenu;
import com.qiaoba.api.system.entity.vo.SysMenuVo;
import com.qiaoba.common.base.result.AjaxResult;
import com.qiaoba.module.system.service.SysMenuService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* 登录
*
@ -13,8 +19,12 @@ import org.springframework.web.bind.annotation.RestController;
* @since 2023/5/5 9:43
*/
@RestController
@RequiredArgsConstructor
public class SysLoginController {
private final SysMenuService sysMenuService;
@PostMapping("/login")
public String login() {
return "{\"msg\":\"操作成功\",\"code\":200,\"token\":\"eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6IjhhNjY4MGY1LTI0OTAtNDUyYi1hYzQ1LWE5YWI0MzQ0YTRlYyJ9.mTZr7TN1Jk2-_7zbeUbOBuHijVLiqY2QSbhcAIfWuX4oF22xGw_DpxOz3I2_-TLeYlJN4y2Gm1qmw6ricqCBqw\"}";
@ -26,8 +36,10 @@ public class SysLoginController {
}
@GetMapping("/getRouters")
public String getRouters() {
return "{\"msg\":\"操作成功\",\"code\":200,\"data\":[{\"name\":\"System\",\"path\":\"/system\",\"hidden\":false,\"redirect\":\"noRedirect\",\"component\":\"Layout\",\"alwaysShow\":true,\"meta\":{\"title\":\"系统管理\",\"icon\":\"system\",\"noCache\":false,\"link\":null},\"children\":[{\"name\":\"User\",\"path\":\"user\",\"hidden\":false,\"component\":\"system/user/index\",\"meta\":{\"title\":\"用户管理\",\"icon\":\"user\",\"noCache\":false,\"link\":null}},{\"name\":\"Role\",\"path\":\"role\",\"hidden\":false,\"component\":\"system/role/index\",\"meta\":{\"title\":\"角色管理\",\"icon\":\"peoples\",\"noCache\":false,\"link\":null}},{\"name\":\"Menu\",\"path\":\"menu\",\"hidden\":false,\"component\":\"system/menu/index\",\"meta\":{\"title\":\"菜单管理\",\"icon\":\"tree-table\",\"noCache\":false,\"link\":null}},{\"name\":\"Dept\",\"path\":\"dept\",\"hidden\":false,\"component\":\"system/dept/index\",\"meta\":{\"title\":\"部门管理\",\"icon\":\"tree\",\"noCache\":false,\"link\":null}},{\"name\":\"Post\",\"path\":\"post\",\"hidden\":false,\"component\":\"system/post/index\",\"meta\":{\"title\":\"岗位管理\",\"icon\":\"post\",\"noCache\":false,\"link\":null}},{\"name\":\"Dict\",\"path\":\"dict\",\"hidden\":false,\"component\":\"system/dict/index\",\"meta\":{\"title\":\"字典管理\",\"icon\":\"dict\",\"noCache\":false,\"link\":null}},{\"name\":\"Config\",\"path\":\"config\",\"hidden\":false,\"component\":\"system/config/index\",\"meta\":{\"title\":\"参数设置\",\"icon\":\"edit\",\"noCache\":false,\"link\":null}},{\"name\":\"Notice\",\"path\":\"notice\",\"hidden\":false,\"component\":\"system/notice/index\",\"meta\":{\"title\":\"通知公告\",\"icon\":\"message\",\"noCache\":false,\"link\":null}},{\"name\":\"Log\",\"path\":\"log\",\"hidden\":false,\"redirect\":\"noRedirect\",\"component\":\"ParentView\",\"alwaysShow\":true,\"meta\":{\"title\":\"日志管理\",\"icon\":\"log\",\"noCache\":false,\"link\":null},\"children\":[{\"name\":\"Operlog\",\"path\":\"operlog\",\"hidden\":false,\"component\":\"monitor/operlog/index\",\"meta\":{\"title\":\"操作日志\",\"icon\":\"form\",\"noCache\":false,\"link\":null}},{\"name\":\"Logininfor\",\"path\":\"logininfor\",\"hidden\":false,\"component\":\"monitor/logininfor/index\",\"meta\":{\"title\":\"登录日志\",\"icon\":\"logininfor\",\"noCache\":false,\"link\":null}}]}]},{\"name\":\"Monitor\",\"path\":\"/monitor\",\"hidden\":false,\"redirect\":\"noRedirect\",\"component\":\"Layout\",\"alwaysShow\":true,\"meta\":{\"title\":\"系统监控\",\"icon\":\"monitor\",\"noCache\":false,\"link\":null},\"children\":[{\"name\":\"Online\",\"path\":\"online\",\"hidden\":false,\"component\":\"monitor/online/index\",\"meta\":{\"title\":\"在线用户\",\"icon\":\"online\",\"noCache\":false,\"link\":null}},{\"name\":\"Job\",\"path\":\"job\",\"hidden\":false,\"component\":\"monitor/job/index\",\"meta\":{\"title\":\"定时任务\",\"icon\":\"job\",\"noCache\":false,\"link\":null}},{\"name\":\"Druid\",\"path\":\"druid\",\"hidden\":false,\"component\":\"monitor/druid/index\",\"meta\":{\"title\":\"数据监控\",\"icon\":\"druid\",\"noCache\":false,\"link\":null}},{\"name\":\"Server\",\"path\":\"server\",\"hidden\":false,\"component\":\"monitor/server/index\",\"meta\":{\"title\":\"服务监控\",\"icon\":\"server\",\"noCache\":false,\"link\":null}},{\"name\":\"Cache\",\"path\":\"cache\",\"hidden\":false,\"component\":\"monitor/cache/index\",\"meta\":{\"title\":\"缓存监控\",\"icon\":\"redis\",\"noCache\":false,\"link\":null}},{\"name\":\"CacheList\",\"path\":\"cacheList\",\"hidden\":false,\"component\":\"monitor/cache/list\",\"meta\":{\"title\":\"缓存列表\",\"icon\":\"redis-list\",\"noCache\":false,\"link\":null}}]},{\"name\":\"Tool\",\"path\":\"/tool\",\"hidden\":false,\"redirect\":\"noRedirect\",\"component\":\"Layout\",\"alwaysShow\":true,\"meta\":{\"title\":\"系统工具\",\"icon\":\"tool\",\"noCache\":false,\"link\":null},\"children\":[{\"name\":\"Build\",\"path\":\"build\",\"hidden\":false,\"component\":\"tool/build/index\",\"meta\":{\"title\":\"表单构建\",\"icon\":\"build\",\"noCache\":false,\"link\":null}},{\"name\":\"Gen\",\"path\":\"gen\",\"hidden\":false,\"component\":\"tool/gen/index\",\"meta\":{\"title\":\"代码生成\",\"icon\":\"code\",\"noCache\":false,\"link\":null}},{\"name\":\"Swagger\",\"path\":\"swagger\",\"hidden\":false,\"component\":\"tool/swagger/index\",\"meta\":{\"title\":\"系统接口\",\"icon\":\"swagger\",\"noCache\":false,\"link\":null}}]},{\"name\":\"Http://ruoyi.vip\",\"path\":\"http://ruoyi.vip\",\"hidden\":false,\"component\":\"Layout\",\"meta\":{\"title\":\"若依官网\",\"icon\":\"guide\",\"noCache\":false,\"link\":\"http://ruoyi.vip\"}}]}";
public Object getRouters() {
List<SysMenuVo> sysMenuVos = sysMenuService.selectByUserId("1650123803828019202");
return AjaxResult.success(sysMenuService.menusToRouters(sysMenuVos));
//return "{\"msg\":\"操作成功\",\"code\":200,\"data\":[{\"name\":\"System\",\"path\":\"/system\",\"hidden\":false,\"redirect\":\"noRedirect\",\"component\":\"Layout\",\"alwaysShow\":true,\"meta\":{\"title\":\"系统管理\",\"icon\":\"system\",\"noCache\":false,\"link\":null},\"children\":[{\"name\":\"User\",\"path\":\"user\",\"hidden\":false,\"component\":\"system/user/index\",\"meta\":{\"title\":\"用户管理\",\"icon\":\"user\",\"noCache\":false,\"link\":null}},{\"name\":\"Role\",\"path\":\"role\",\"hidden\":false,\"component\":\"system/role/index\",\"meta\":{\"title\":\"角色管理\",\"icon\":\"peoples\",\"noCache\":false,\"link\":null}},{\"name\":\"Menu\",\"path\":\"menu\",\"hidden\":false,\"component\":\"system/menu/index\",\"meta\":{\"title\":\"菜单管理\",\"icon\":\"tree-table\",\"noCache\":false,\"link\":null}},{\"name\":\"Dept\",\"path\":\"dept\",\"hidden\":false,\"component\":\"system/dept/index\",\"meta\":{\"title\":\"部门管理\",\"icon\":\"tree\",\"noCache\":false,\"link\":null}},{\"name\":\"Post\",\"path\":\"post\",\"hidden\":false,\"component\":\"system/post/index\",\"meta\":{\"title\":\"岗位管理\",\"icon\":\"post\",\"noCache\":false,\"link\":null}},{\"name\":\"Dict\",\"path\":\"dict\",\"hidden\":false,\"component\":\"system/dict/index\",\"meta\":{\"title\":\"字典管理\",\"icon\":\"dict\",\"noCache\":false,\"link\":null}},{\"name\":\"Config\",\"path\":\"config\",\"hidden\":false,\"component\":\"system/config/index\",\"meta\":{\"title\":\"参数设置\",\"icon\":\"edit\",\"noCache\":false,\"link\":null}},{\"name\":\"Notice\",\"path\":\"notice\",\"hidden\":false,\"component\":\"system/notice/index\",\"meta\":{\"title\":\"通知公告\",\"icon\":\"message\",\"noCache\":false,\"link\":null}},{\"name\":\"Log\",\"path\":\"log\",\"hidden\":false,\"redirect\":\"noRedirect\",\"component\":\"ParentView\",\"alwaysShow\":true,\"meta\":{\"title\":\"日志管理\",\"icon\":\"log\",\"noCache\":false,\"link\":null},\"children\":[{\"name\":\"Operlog\",\"path\":\"operlog\",\"hidden\":false,\"component\":\"monitor/operlog/index\",\"meta\":{\"title\":\"操作日志\",\"icon\":\"form\",\"noCache\":false,\"link\":null}},{\"name\":\"Logininfor\",\"path\":\"logininfor\",\"hidden\":false,\"component\":\"monitor/logininfor/index\",\"meta\":{\"title\":\"登录日志\",\"icon\":\"logininfor\",\"noCache\":false,\"link\":null}}]}]},{\"name\":\"Monitor\",\"path\":\"/monitor\",\"hidden\":false,\"redirect\":\"noRedirect\",\"component\":\"Layout\",\"alwaysShow\":true,\"meta\":{\"title\":\"系统监控\",\"icon\":\"monitor\",\"noCache\":false,\"link\":null},\"children\":[{\"name\":\"Online\",\"path\":\"online\",\"hidden\":false,\"component\":\"monitor/online/index\",\"meta\":{\"title\":\"在线用户\",\"icon\":\"online\",\"noCache\":false,\"link\":null}},{\"name\":\"Job\",\"path\":\"job\",\"hidden\":false,\"component\":\"monitor/job/index\",\"meta\":{\"title\":\"定时任务\",\"icon\":\"job\",\"noCache\":false,\"link\":null}},{\"name\":\"Druid\",\"path\":\"druid\",\"hidden\":false,\"component\":\"monitor/druid/index\",\"meta\":{\"title\":\"数据监控\",\"icon\":\"druid\",\"noCache\":false,\"link\":null}},{\"name\":\"Server\",\"path\":\"server\",\"hidden\":false,\"component\":\"monitor/server/index\",\"meta\":{\"title\":\"服务监控\",\"icon\":\"server\",\"noCache\":false,\"link\":null}},{\"name\":\"Cache\",\"path\":\"cache\",\"hidden\":false,\"component\":\"monitor/cache/index\",\"meta\":{\"title\":\"缓存监控\",\"icon\":\"redis\",\"noCache\":false,\"link\":null}},{\"name\":\"CacheList\",\"path\":\"cacheList\",\"hidden\":false,\"component\":\"monitor/cache/list\",\"meta\":{\"title\":\"缓存列表\",\"icon\":\"redis-list\",\"noCache\":false,\"link\":null}}]},{\"name\":\"Tool\",\"path\":\"/tool\",\"hidden\":false,\"redirect\":\"noRedirect\",\"component\":\"Layout\",\"alwaysShow\":true,\"meta\":{\"title\":\"系统工具\",\"icon\":\"tool\",\"noCache\":false,\"link\":null},\"children\":[{\"name\":\"Build\",\"path\":\"build\",\"hidden\":false,\"component\":\"tool/build/index\",\"meta\":{\"title\":\"表单构建\",\"icon\":\"build\",\"noCache\":false,\"link\":null}},{\"name\":\"Gen\",\"path\":\"gen\",\"hidden\":false,\"component\":\"tool/gen/index\",\"meta\":{\"title\":\"代码生成\",\"icon\":\"code\",\"noCache\":false,\"link\":null}},{\"name\":\"Swagger\",\"path\":\"swagger\",\"hidden\":false,\"component\":\"tool/swagger/index\",\"meta\":{\"title\":\"系统接口\",\"icon\":\"swagger\",\"noCache\":false,\"link\":null}}]},{\"name\":\"Http://ruoyi.vip\",\"path\":\"http://ruoyi.vip\",\"hidden\":false,\"component\":\"Layout\",\"meta\":{\"title\":\"若依官网\",\"icon\":\"guide\",\"noCache\":false,\"link\":\"http://ruoyi.vip\"}}]}";
}
@PostMapping("/logout")

View File

@ -4,7 +4,6 @@ import com.qiaoba.api.system.entity.SysMenu;
import com.qiaoba.api.system.entity.param.SysMenuParam;
import com.qiaoba.api.system.entity.vo.SysMenuVo;
import com.qiaoba.common.base.result.AjaxResult;
import com.qiaoba.common.security.utils.SecurityUtil;
import com.qiaoba.module.system.service.SysMenuService;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;

View File

@ -30,4 +30,12 @@ public interface SysMenuMapper extends BaseMapperPlus<SysMenuMapper, SysMenu, Sy
* @return 选中菜单ID列表
*/
List<String> selectMenuIdsByRoleId(String roleId);
/**
* 通过 userId 查询目录和菜单
*
* @param userId userId
* @return list
*/
List<SysMenuVo> selectByUserId(String userId);
}

View File

@ -1,6 +1,8 @@
package com.qiaoba.module.system.service;
import cn.hutool.core.lang.tree.Tree;
import com.qiaoba.api.system.entity.SysMenu;
import com.qiaoba.api.system.entity.vo.RouterVo;
import com.qiaoba.api.system.entity.vo.SysMenuVo;
import com.qiaoba.api.system.service.SysMenuApiService;
@ -31,4 +33,19 @@ public interface SysMenuService extends SysMenuApiService {
* @return 选中菜单ID列表
*/
List<String> selectMenuIdsByRoleId(String roleId);
/**
* 通过 userId 查询目录和菜单
* @param userId userId
* @return list
*/
List<SysMenuVo> selectByUserId(String userId);
/**
* 菜单转路由
*
* @param menus 菜单列表
* @return 路由列表
*/
List<RouterVo> menusToRouters(List<SysMenuVo> menus);
}

View File

@ -7,11 +7,13 @@ import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.qiaoba.api.system.entity.SysMenu;
import com.qiaoba.api.system.entity.param.SysMenuParam;
import com.qiaoba.api.system.entity.vo.RouterVo;
import com.qiaoba.api.system.entity.vo.SysMenuVo;
import com.qiaoba.common.base.constants.BaseConstant;
import com.qiaoba.common.base.exceptions.ServiceException;
import com.qiaoba.module.system.mapper.SysMenuMapper;
import com.qiaoba.module.system.service.SysMenuService;
import com.qiaoba.module.system.utils.MenuUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@ -87,7 +89,20 @@ public class SysMenuServiceImpl implements SysMenuService {
return sysMenuMapper.selectMenuIdsByRoleId(roleId);
}
@Override
public List<SysMenuVo> selectByUserId(String userId) {
return sysMenuMapper.selectByUserId(userId);
}
@Override
public List<RouterVo> menusToRouters(List<SysMenuVo> menus) {
return MenuUtil.menusToRouters(menus);
}
private boolean checkMenuNameNotUnique(SysMenu menu) {
return sysMenuMapper.checkMenuNameUnique(menu) > 0;
}
}

View File

@ -0,0 +1,166 @@
package com.qiaoba.module.system.utils;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.qiaoba.api.system.entity.vo.MetaVo;
import com.qiaoba.api.system.entity.vo.RouterVo;
import com.qiaoba.api.system.entity.vo.SysMenuVo;
import com.qiaoba.common.base.constants.BaseConstant;
import com.qiaoba.common.base.constants.MenuConstant;
import com.qiaoba.common.base.enums.BaseEnum;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
/**
* 菜单工具类
*
* @author ailanyin
* @version 1.0
* @since 2023/5/12 10:33
*/
public class MenuUtil {
public static List<RouterVo> menusToRouters(List<SysMenuVo> menus) {
List<SysMenuVo> tree = TreeUtil.buildTree(menus, SysMenuVo.class, "menuId", "parentId", "children");
List<RouterVo> routers = new LinkedList<RouterVo>();
for (SysMenuVo menu : tree) {
RouterVo router = new RouterVo();
router.setHidden(StrUtil.equals(BaseEnum.NO.getCode(), menu.getIsVisible()));
router.setName(MenuUtil.getRouteName(menu));
router.setPath(MenuUtil.getRouterPath(menu));
router.setComponent(MenuUtil.getComponent(menu));
router.setQuery(menu.getQuery());
router.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), StrUtil.equals(BaseEnum.NO.getCode(), menu.getIsCache()), menu.getPath()));
List<SysMenuVo> cMenus = menu.getChildren();
if (CollUtil.isNotEmpty(cMenus) && MenuConstant.TYPE_DIR.equals(menu.getMenuType())) {
router.setAlwaysShow(true);
router.setRedirect(MenuConstant.NO_REDIRECT);
router.setChildren(menusToRouters(cMenus));
} else if (MenuUtil.isMenuFrame(menu)) {
router.setMeta(null);
List<RouterVo> childrenList = new ArrayList<RouterVo>();
RouterVo children = new RouterVo();
children.setPath(menu.getPath());
children.setComponent(menu.getComponent());
children.setName(StrUtil.upperFirst(menu.getPath()));
children.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), StrUtil.equals(BaseEnum.NO.getCode(), menu.getIsCache()), menu.getPath()));
children.setQuery(menu.getQuery());
childrenList.add(children);
router.setChildren(childrenList);
} else if (BaseConstant.DEFAULT_PARENT_ID_VALUE.equals(menu.getParentId()) && MenuUtil.isInnerLink(menu.getIsFrame(), menu.getPath())) {
router.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon()));
router.setPath("/");
List<RouterVo> childrenList = new ArrayList<RouterVo>();
RouterVo children = new RouterVo();
String routerPath = MenuUtil.innerLinkReplaceEach(menu.getPath());
children.setPath(routerPath);
children.setComponent(MenuConstant.INNER_LINK);
children.setName(StrUtil.upperFirst(routerPath));
children.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), menu.getPath()));
childrenList.add(children);
router.setChildren(childrenList);
}
routers.add(router);
}
return routers;
}
/**
* 获取路由名称
*
* @param menuVo 菜单信息
* @return 路由名称
*/
private static String getRouteName(SysMenuVo menuVo) {
// 首字母大写
String routerName = StrUtil.upperFirst(menuVo.getPath());
// 非外链并且是一级目录(类型为目录)
return isMenuFrame(menuVo) ? StrUtil.EMPTY : routerName;
}
/**
* 是否为菜单内部跳转
*
* @param menuVo 菜单信息
* @return 结果
*/
private static boolean isMenuFrame(SysMenuVo menuVo) {
return BaseConstant.DEFAULT_PARENT_ID_VALUE.equals(menuVo.getParentId()) && MenuConstant.TYPE_MENU.equals(menuVo.getMenuType())
&& menuVo.getIsFrame().equals(MenuConstant.NO_FRAME);
}
/**
* 获取路由地址
*
* @param menuVo 菜单信息
* @return 路由地址
*/
private static String getRouterPath(SysMenuVo menuVo) {
String routerPath = menuVo.getPath();
// 内链打开外网方式
if (!BaseConstant.DEFAULT_PARENT_ID_VALUE.equals(menuVo.getParentId()) && isInnerLink(menuVo.getIsFrame(), menuVo.getPath())) {
routerPath = innerLinkReplaceEach(routerPath);
}
// 非外链并且是一级目录(类型为目录)
if (BaseConstant.DEFAULT_PARENT_ID_VALUE.equals(menuVo.getParentId()) && MenuConstant.TYPE_DIR.equals(menuVo.getMenuType())
&& MenuConstant.NO_FRAME.equals(menuVo.getIsFrame())) {
routerPath = "/" + menuVo.getPath();
}
// 非外链并且是一级目录(类型为菜单)
else if (isMenuFrame(menuVo)) {
routerPath = "/";
}
return routerPath;
}
/**
* 获取组件信息
*
* @param menuVo 菜单信息
* @return 组件信息
*/
private static String getComponent(SysMenuVo menuVo) {
String component = MenuConstant.LAYOUT;
if (StrUtil.isNotEmpty(menuVo.getComponent()) && !isMenuFrame(menuVo)) {
component = menuVo.getComponent();
} else if (StrUtil.isEmpty(menuVo.getComponent()) && !BaseConstant.DEFAULT_PARENT_ID_VALUE.equals(menuVo.getParentId()) && isInnerLink(menuVo.getIsFrame(), menuVo.getPath())) {
component = MenuConstant.INNER_LINK;
} else if (StrUtil.isEmpty(menuVo.getComponent()) && isParentView(menuVo.getParentId(), menuVo.getMenuType())) {
component = MenuConstant.PARENT_VIEW;
}
return component;
}
/**
* 是否为内链组件
*
* @param isFrame isFrame
* @param path path
* @return 结果
*/
private static boolean isInnerLink(String isFrame, String path) {
return MenuConstant.NO_FRAME.equals(isFrame) && (HttpUtil.isHttp(path) || HttpUtil.isHttps(path));
}
/**
* 内链域名特殊字符替换
*/
private static String innerLinkReplaceEach(String path) {
return path.replaceAll(BaseConstant.HTTP, "").replaceAll(BaseConstant.HTTPS, "");
}
/**
* 是否为parent_view组件
*
* @param parentId parentId
* @param menuType menuType
* @return 结果
*/
private static boolean isParentView(String parentId, String menuType) {
return !BaseConstant.DEFAULT_PARENT_ID_VALUE.equals(parentId) && MenuConstant.TYPE_DIR.equals(menuType);
}
}

View File

@ -0,0 +1,83 @@
package com.qiaoba.module.system.utils;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import java.util.ArrayList;
import java.util.List;
/**
* 树工具类 遍历子节点
*
* @author ailanyin
* @version 1.0
* @since 2021-08-31
*/
public class TreeUtil {
public static <T> List<T> buildTree(List<T> trees, Class<T> clazz, String idFieldName, String parentIdFieldName, String childIdFieldName) {
List<T> returnList = new ArrayList<>();
List<Object> tempList = new ArrayList<>();
for (T tree : trees) {
tempList.add(ReflectUtil.getFieldValue(tree, ReflectUtil.getField(clazz, idFieldName)));
}
for (T tree : trees) {
// 如果是顶级节点, 遍历该父节点的所有子节点
if (!tempList.contains(ReflectUtil.getFieldValue(tree, ReflectUtil.getField(clazz, parentIdFieldName)))) {
recursionFn(trees, clazz, tree, idFieldName, parentIdFieldName, childIdFieldName);
returnList.add(tree);
}
}
if (returnList.isEmpty()) {
returnList = trees;
}
return returnList;
}
/**
* 递归列表
*/
private static <T> void recursionFn(List<T> list, Class<T> clazz, T t, String idFieldName, String parentIdFieldName, String childIdFieldName) {
// 得到子节点列表
List<T> childList = getChildList(list, t, clazz, idFieldName, parentIdFieldName);
ReflectUtil.invoke(t, ReflectUtil.getMethodByName(clazz, getSetMethodName(childIdFieldName)), childList);
for (T tChild : childList) {
if (hasChild(list, tChild, clazz, idFieldName, parentIdFieldName)) {
recursionFn(list, clazz, tChild, idFieldName, parentIdFieldName, childIdFieldName);
}
}
}
private static String getSetMethodName(String field) {
return "set" + StrUtil.upperFirst(field);
}
/**
* 得到子节点列表
*/
private static <T> List<T> getChildList(List<T> list, T t, Class<T> clazz, String idFieldName, String parentIdFieldName) {
List<T> childList = new ArrayList<>();
for (T n : list) {
Object parentId = ReflectUtil.getFieldValue(n, ReflectUtil.getField(clazz, parentIdFieldName));
Object id = ReflectUtil.getFieldValue(t, ReflectUtil.getField(clazz, idFieldName));
if (ObjectUtil.isNotEmpty(parentId) && ObjectUtil.isNotEmpty(id) && parentId.toString().equals(id.toString())) {
childList.add(n);
}
}
return childList;
}
/**
* 判断是否有子节点
*/
private static <T> boolean hasChild(List<T> list, T t, Class<T> clazz, String idFieldName, String parentIdFieldName) {
return getChildList(list, t, clazz, idFieldName, parentIdFieldName).size() > 0;
}
}

View File

@ -20,4 +20,15 @@
where rm.role_id = #{roleId}
order by m.parent_id, m.order_num
</select>
<select id="selectByUserId" resultType="com.qiaoba.api.system.entity.vo.SysMenuVo">
select distinct t1.menu_id, t1.parent_id, t1.menu_name, t1.path, t1.component, t1.`query`, t1.is_visible, t1.perms, t1.is_frame, t1.is_cache, t1.menu_type, t1.icon, t1.order_num, t1.create_time
from sys_menu t1
left join sys_role_menu t2 on t1.menu_id = t2.menu_id
left join sys_user_role t3 on t2.role_id = t3.role_id
left join sys_role t4 on t3.role_id = t4.role_id
left join sys_user t5 on t3.user_id = t5.user_id
where t5.user_id = #{userId} and t1.menu_type in ('M', 'C') AND t4.status = '1'
order by t1.parent_id, t1.order_num
</select>
</mapper>