
递归实现前端多层级路由
问题描述
实现用户管理模块时,用户有不同角色和权限,根据用户所有的权限,实现前端多层级路由的实现,这里用循环嵌套调用方法,并封装了多个子级类,但当有更多子级时,就需要循环更多次,还要封装更多子级类,造成代码冗余。
/**
* 一级目录
*/
@Data
public class OneMenu {
private String id;
private String title;
private String icon;
private String path;
private String name;
private List children;
}
/**
* 二级目录
*/
@Data
public class TwoMenu {
private String id;
private String title;
private String icon;
private String path;
private String name;
/**
* 三级目录集合
*/
//private List children;
}
//2.1查询权限表数据
//1.查询所有一级分类
QueryWrapper wrapper = new QueryWrapper<>();
wrapper.eq("pid", "0");
List fatherList = sysPermissionService.list(wrapper);
//2.查询所有二级分类
QueryWrapper wrapper1 = new QueryWrapper<>();
wrapper1.ne("pid", "0");
List sonList = sysPermissionService.list(wrapper1);
//创建list集合,用于封装最终封装数据
List finalFatherList = new ArrayList<>();
//封装一级分类
for (SysPermission father : fatherList) {
OneMenu oneMenu = new OneMenu();
BeanUtils.copyProperties(father, oneMenu);
finalFatherList.add(oneMenu);
List finalSonList = new ArrayList<>();
for (SysPermission son : sonList) {
//判断二级分类pid和一级分类的id是否一样
if (son.getPid().equals(father.getId())) {
TwoMenu twoMenu = new TwoMenu();
BeanUtils.copyProperties(son, twoMenu);
finalSonList.add(twoMenu);
}
}
oneMenu.setChildren(finalSonList);
}
解决方案:
在业务层新建一个getTree方法, 使用递归来实现子级路由的获得,组装权限目录树。在主业务层调用getTree方法,然后封装给响应对象响应给前端。
/** * 封装权限树的对象 */ @Data @NoArgsConstructor @AllArgsConstructor @Builder public class PermissionRespNodeVo { /** * 角色ID */ private String id; /** * 角色标题 */ private String title; /** * 角色图标 */ private String icon; /** * 路由地址URL */ private String path; /** * 路由名称 */ private String name; /** * 菜单树结构 */ private Listchildren; } /** * 响应给前端的对象 */ @Data @NoArgsConstructor @AllArgsConstructor @Builder public class LoginRespVo { /** * 用户ID */ private String id; /** * 用户名 */ private String username; /** * 电话 */ private String phone; /** * 昵称 */ private String nickName; /** * 真实名称 */ private String realName; /** * 性别 */ private Integer sex; /** * 装填 */ private Integer status; /** * 邮件 */ private String email; /** * 权限树 */ private Listmenus; /** * 权限按钮集合 */ private List permissions; } /** * 组装权限树 * * @param permissions 用户所有的权限 * @param pid "0"为顶级权限 * @param isOnlyMenuType 按钮权限 * @return {@link List}<{@link PermissionRespNodeVo}> */ @Override public ListgetTree(List permissions, String pid, boolean isOnlyMenuType) { //构建权限树集合 if (CollectionUtils.isEmpty(permissions)) { return null; } //组装权限树 List infos = permissions.stream() .filter(p -> p.getPid().equals(pid) && (p.getType() != 3 || !isOnlyMenuType)) .map(p -> { PermissionRespNodeVo prnv = PermissionRespNodeVo.builder().id(p.getId()).title(p.getTitle()) .icon(p.getIcon()).path(p.getUrl()).name(p.getName()) //这里使用递归!!! .children(getTree(permissions, p.getId(), isOnlyMenuType)) .build(); return prnv; }).collect(Collectors.toList()); return infos; } 最后将得到的数据封装好返回给前端
//添加权限树和权限按钮集合 //获取当前用户拥有的权限集合 Listpermissions = sysPermissionService.getPermissionByUserId(userInfo.getId()); //组装权限树 顶级权限的pid约定为0 List tree = sysPermissionService.getTree(permissions, "0", true); //获取菜单按钮集合 List authBtnPerms = permissions.stream().filter(p -> p.getType() == 3).map(SysPermission::getCode).collect(Collectors.toList()); loginRespVo.setMenus(tree); loginRespVo.setPermissions(authBtnPerms); //5.组装响应对象来响应前端 return R.ok(loginRespVo);
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)