权限表只有一张(通常应该是两张),怎么封装导航菜单所需的数据格式

遇到的情况是:在做导航菜单那块时,发现数据库里将权限表设计成一张了,此时再改数据库会牵一发而动全身,如果直接用递归的方式将权限封装成树,那么会将增删查之类的权限也变成导航菜单的一部分,也就是说查出来的“删除用户”、“添加角色”等权限也会出现在children里。

解决方法:在递归时,将查出来的所有权限结果过滤,将增删改等子功能放在一个单独的list里(下文中的permitFunc中)。

具体做法:

  1. 给数据库的权限表增加字段isMenu,用来区别是否是导航菜单(1表示是导航菜单,0表示不能出现在导航菜单的权限功能),还是增删改等功能,如下(请忽略父子关系的不合理):

 2. 写sql语句,一个是用来查询某用户的导航菜单(即isMenu是1),另一个是用来查该用户的其他权限(即isMenu是0),如下:

3. 将用户的导航菜单全部查出来,并排序:

目前的menuList如下:

4. 按照前端所需的树结构存放,并将将查出来的所有权限结果过滤,将增删改等子功能放在一个单独的list(permitFunc)里:

findTree里是这样的:

  /**
     * 将数据库中查询到的菜单list转为菜单树list
     *
     * @param allMenu
     * @return
     */
    private Map<String, Object> findTree(List<Permission> allMenu,String userName) {
        Map<String, Object> data = new HashMap<String, Object>();
        try {//查询所有菜单
            //根节点
            List<NavigatMenuVo> rootMenu = new ArrayList<NavigatMenuVo>();
            for (Permission nav : allMenu) {
                NavigatMenuVo navigatMenuVo = new NavigatMenuVo();
                Integer ss = nav.getPid();
                if (nav.getPid() == 0) {//父节点是0的,为根节点。
                    navigatMenuVo.setChildren(nav.getChildren());
                    navigatMenuVo.setId(nav.getId());
                    navigatMenuVo.setLevel(nav.getLevel());
                    navigatMenuVo.setPermTag(nav.getPermTag());
                    navigatMenuVo.setTitle(nav.getPermName());
                    navigatMenuVo.setUrl(nav.getUrl());
                    rootMenu.add(navigatMenuVo);
                    break;
                }
            }
            //为根菜单设置子菜单,getClild是递归调用的
            for (NavigatMenuVo navigatMenuVo2 : rootMenu) {
                /* 获取根节点下的所有子节点 使用getChild方法*/
                List<NavigatMenuVo> childList = getChild(navigatMenuVo2.getId(), allMenu,userName);
                // 将查出来的所有权限结果过滤,将增删改等子功能放在一个单独的list里(permitFunc中)
                List<NavigatMenuVo> permitFuncs = userMapper.findFuncPermissionByUsername(navigatMenuVo2.getId(),userName);
                navigatMenuVo2.setPermitFunc(permitFuncs);
                navigatMenuVo2.setChildren(childList);//给根节点设置子节点
            }
            /**
             * 输出构建好的菜单数据。
             *
             */
            data.put("success", "true");
            data.put("list", rootMenu);
            return data;
        } catch (Exception e) {
            data.put("success", "false");
            data.put("list", new ArrayList());
            return data;
        }
    }

    private List<NavigatMenuVo> getChild(Integer id, List<Permission> allMenu,String userName) {
        //子菜单
        List<NavigatMenuVo> childList = new ArrayList<NavigatMenuVo>();
        List<NavigatMenuVo> permitList = new ArrayList<>();
        for (Permission nav : allMenu) {
            NavigatMenuVo navigatMenuVo = new NavigatMenuVo();
            // 遍历所有节点,将所有菜单的父id与传过来的根节点的id比较
            //相等说明:为该根节点的子节点。
            if (nav.getPid() == id) {
                navigatMenuVo.setChildren(nav.getChildren());
                navigatMenuVo.setId(nav.getId());
                navigatMenuVo.setLevel(nav.getLevel());
                navigatMenuVo.setPermTag(nav.getPermTag());
                navigatMenuVo.setTitle(nav.getPermName());
                navigatMenuVo.setUrl(nav.getUrl());
                // 下面注释掉的这行其实等同于再下面的这行
                // List<Permission> permitFuncs2 = allMenu.stream().filter(c->c.getIsMenu().equals(0) && c.getPid().equals(navigatMenuVo.getId())).collect(Collectors.toList());
                // 将查出来的所有权限结果过滤,将增删改等子功能放在一个单独的list里(permitFunc中)
                List<NavigatMenuVo> permitFuncs =  userMapper.findFuncPermissionByUsername(navigatMenuVo.getId(),userName);
                navigatMenuVo.setPermitFunc(permitFuncs);
                childList.add(navigatMenuVo);
            }
        }

        //递归
        for (NavigatMenuVo navigatMenuVo : childList) {
            navigatMenuVo.setChildren(getChild(navigatMenuVo.getId(), allMenu,userName));
        }
        //如果节点下没有子节点,返回一个空List(递归退出)
        if (childList.size() == 0) {
            return new ArrayList<NavigatMenuVo>();
        }
        return childList;
    }

最后得到的结果如下:

{
    "rtnCode": 200,
    "msg": "success",
    "data": [
        {           
            "id": 1,
            "title": "权限管理",
            "level": 0,
            "permitFunc": [
                {     
                    "id": 19,
                    "title": "添加计划信息",
                    "level": 1,
                    "permitFunc": null,
                    "children": null
                },
                {   
                    "id": 20,
                    "title": "计划信息excel文件上传",
                    "level": 1,
                    "permitFunc": null,
                    "children": null
                },
                {
                    "id": 21,
                    "title": "根据token获取用户信息",
                    "level": 1,
                    "permitFunc": null,
                    "children": null
                },
                {
                    "id": 22,
                    "title": "根据token获取任务统计信息",
                    "level": 1,
                    "permitFunc": null,
                    "children": null
                },
                {
                    "id": 23,
                    "title": "添加日程日志",
                    "level": 1,
                    "permitFunc": null,
                    "children": null
                },
                {
                    "id": 24,
                    "title": "更新日程退出时间",
                    "level": 1,
                    "permitFunc": null,
                    "children": null
                },
                {
                    "id": 25,
                    "title": "查询日程日志",
                    "level": 1,
                    "permitFunc": null,
                    "children": null
                }
            ],
            "children": [
                {
                    "id": 2,
                    "title": "用户管理",
                    "level": 1,
                    "permitFunc": [
                        {
                            "id": 6,
                            "title": "添加用户",
                            "level": 2,
                            "permitFunc": null,
                            "children": null
                        },
                        {  
                            "id": 7,
                            "title": "修改用户",
                            "level": 2,
                            "permitFunc": null,
                            "children": null
                        },
                        {   
                            "id": 8,
                            "title": "删除用户",
                            "level": 2,
                            "permitFunc": null,
                            "children": null
                        }
                    ],
                    "children": []
                },
                {   
                    "id": 3,
                    "title": "角色管理",
                    "level": 1,
                    "permitFunc": [
                        {  
                            "id": 10,
                            "title": "添加角色",
                            "level": 2,
                            "permitFunc": null,
                            "children": null
                        },
                        {  
                            "id": 11,
                            "title": "修改角色",
                            "level": 2,
                            "permitFunc": null,
                            "children": null
                        },
                        {       
                            "id": 12,
                            "title": "删除角色",
                            "level": 2,
                            "permitFunc": null,
                            "children": null
                        }
                    ],
                    "children": []
                },
                {    
                    "id": 4,
                    "title": "菜单管理",
                    "level": 1,
                    "permitFunc": [
                        {     
                            "id": 14,
                            "title": "添加菜单",
                            "level": 2,
                            "permitFunc": null,
                            "children": null
                        },
                        {      
                            "id": 15,
                            "title": "修改菜单",
                            "level": 2,
                            "permitFunc": null,
                            "children": null
                        },
                        {      
                            "id": 16,
                            "title": "删除菜单",
                            "level": 2,
                            "permitFunc": null,
                            "children": null
                        }
                    ],
                    "children": []
                }
            ]
        }
    ]
}

总结:其实这种解决方法还是很笨拙,可以进一步优化,比如用sql查询时就是直接封装好,再比如只用写一个sql,然后在利用

stream().filter()过滤查询结果。不过总的来说,在设计数据库表的时候就应该考虑到这点,将权限表拆分成两张表,一张存放导航里要显示的权限,另一张来存放其他权限。编程之路很辛苦,还请各位多多指教!
发布了26 篇原创文章 · 获赞 4 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/y_onghuming/article/details/102694808