递归实现前端多层级路由
问题描述
实现用户管理模块时,用户有不同角色和权限,根据用户所有的权限,实现前端多层级路由的实现,这里用循环嵌套调用方法,并封装了多个子级类,但当有更多子级时,就需要循环更多次,还要封装更多子级类,造成代码冗余。
@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 { private String id; private String title; private String icon; private String path; private String name; private Listchildren; } @Data @NoArgsConstructor @AllArgsConstructor @Builder public class LoginRespVo { 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; } @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);



