• 动态菜单树加载过程


    根据登录的userID查询出角色绑定的menucode,再查出所有菜单List<Module>

    去除List<Module>中没有绑定的菜单

    再将List<Module>建立成树形机构

    在将list转为json格式字符串返回到前端

    SysModule.java

    public class SysModule {
        private String moduleCode;
        private String moduleName;
        private String modulePath;
        private String parentCode;
        private String isLeaf;
        private String sortNumber;
    
        private List<SysModule> children = new ArrayList<SysModule>();   //子菜单
    
        public String getModuleCode() {
            return moduleCode;
        }
    
        public void setModuleCode(String moduleCode) {
            this.moduleCode = moduleCode;
        }
    
        public String getModuleName() {
            return moduleName;
        }
    
        public void setModuleName(String moduleName) {
            this.moduleName = moduleName;
        }
    
        public String getModulePath() {
            return modulePath;
        }
    
        public void setModulePath(String modulePath) {
            this.modulePath = modulePath;
        }
    
        public String getParentCode() {
            return parentCode;
        }
    
        public void setParentCode(String parentCode) {
            this.parentCode = parentCode;
        }
    
        public String getIsLeaf() {
            return isLeaf;
        }
    
        public void setIsLeaf(String isLeaf) {
            this.isLeaf = isLeaf;
        }
    
        public String getSortNumber() {
            return sortNumber;
        }
    
        public void setSortNumber(String sortNumber) {
            this.sortNumber = sortNumber;
        }
    }

    逻辑层

        /**
         * 根据用户id获取module列表
         * @param userId
         * @return
         * List<SysModule>
         */
        public List<SysModule> selectModuleByUserId(String userId){
            //最终的List<SysModule>集合
            List<SysModule> result=new ArrayList<SysModule>();
            //查询所有的List<SysModule>
            List<SysModule> modules=dao.queryForObjectList("select * from sys_module order by sortNumber asc", null,SysModule.class);
            if(modules==null){
                modules=new ArrayList<SysModule>();
            }
            //查询用户可以操作的模块编号String集合
            List<String> mids=dao.queryOneColumnForMoreRows("select distinct moduleCode from sys_role_module where roleCode in (select roleCode from sys_user_role where userCode=?)", new Object[]{userId}, String.class);
            if(mids==null){
                mids=new ArrayList<String>();
            }
            //去除没有权限的叶子节点
            clear(modules,mids);
            //建立模块层次结构
            for(int i=0;i<modules.size();i++){
                SysModule m=modules.get(i);
                if(m.getParentCode()!=null&&m.getParentCode().equals("0")){   //一级目录,父级code为0
                    resetModules2(m,modules);
                    result.add(m);
                }
            }
            return result;
        }
    /** * 根据mids去掉不存在的modules * @param modules 所有菜单List集合 * @param mids 绑定userid的菜单code * void */ private void clear(List<SysModule> modules,List<String> mids){ for(int i=0;i<modules.size();i++){ //遍历所有菜单 SysModule m=modules.get(i); if(m.getModulePath()!=null&&!m.getModulePath().trim().equals("")){ //当菜单路径不为空时,为空的菜单是文件夹,不允许删除. boolean bl=false; //假设不存在 for(int n=0;n<mids.size();n++){ //遍历所有存在的菜单code if(mids.get(n).toString().equals(m.getModuleCode())){ //遍历的菜单存在于绑定的权限中 bl=true; break; } } if(!bl){ //此菜单不存在,即在绑定userid的菜单code中找不到 modules.remove(i); //移除此菜单 i--; //移除后,i-1,下次遍历认为当前位置 } } } } /** * 为m设置子节点 * @param m 父节点 * @param ms 在ms中找到m的子节点 * void */ private void resetModules2(SysModule m,List<SysModule> ms){ for(int i=0;i<ms.size();i++){ //循环modules SysModule c=ms.get(i); //获取module if (c.getParentCode()!=null&&c.getParentCode()!="") { //当module的父code不为空时,即是子菜单 if(c.getParentCode().equals(m.getModuleCode())){ //如果module的的父code等于m的code,也就是遍历到的module是m的子菜单 if(c.getModulePath()==null||c.getModulePath().trim().equals("")){ //如果它的路径是空时,即这个module是个二级目录 resetModules2(c,ms); //继续找这个二级目录下的菜单. if(c.getChildren().size()>0){ //如果module的子菜单大于0时 m.getChildren().add(c); //把这个二级菜单c加入到m中 } }else if(c.getModulePath()!=null&&!c.getModulePath().trim().equals("")){ //当路径不为空时,即是m的子菜单. m.getChildren().add(c); //直接加入到m } } } } }

    前端

        //递归菜单
      function RecMenu(m){
          var result = '';
          
          result +="<li>";
          if(m.children!=null&&m.children.length>0){    //当菜单有子集时
              //菜单为文件夹
              result +='<a href="#"> <i class="fa fa-check"></i> <span class="nav-label">'+m.moduleName+'</span> <span class="fa arrow"></span></a>';
              result +='<ul class="nav nav-second-level">';
              //遍历子集
              for(var i=0,len=m.children.length;i<len;i++){
                  result+= RecMenu(m.children[i]);  //继续建立子集树形菜单
              }
              result +='</ul>';
          }else{
              result+= '<a class="J_menuItem" onclick="javascript:reloadMenu(this);" href="/${appName}/'+m.modulePath+'">'+m.moduleName+'</a>'
          }
          result +="</li>";
          
          return result;
      }
    
    $.ajax({
        url:'/${appName}/manager/LoginController/loadpermissions',
        type:'post',
        async: false,
        cache:false,
        data:{userId:userId},
        dataType:'json',
        success: function(data){   //返回的data为一级菜单集合
            for(var i=0,len=data.length;i<len;i++){   //遍历一级菜单
                var ps = data[i];   //一级菜单
                if(ps.children.length>0){   //如果一级菜单下有子菜单时
                    var result = RecMenu(ps);   //将菜单中的子菜单转为树形
                    $('#side-menu').append(result);
                }
            }
        },
        error: function (aa, ee, rr) {
          }
    });

     2018-07-17更新动态树加载

    SysModule.java

    public class SysModule {
        private String moduleCode;
        private String moduleName;
        private String modulePath;
        private String parentCode;
        private String isLeaf;
        private String sortNumber;
    
        private List<SysModule> children = new ArrayList<SysModule>();   //子菜单
    
       /*Getter & Setter方法*/
    }

    Mybatis层

    接口层

        /**
         * 根据用户id获取菜单权限(包括所有一级菜单)
         * @param uid 用户id
         * @return
         */
        List<SysModule> getModuleByUid(String uid);

    xml配置

      <!--根据用户id获取绑定的module菜单,以及所有的一级菜单,一级菜单parentCode为0-->
      <select id="getModuleByUid" resultType="com.autumn.pojo.SysModule">
        select * from sys_module as sm
        left join sys_role_module srm on sm.moduleCode=srm.moduleCode
        left join sys_role sr on sr.roleCode=srm.roleCode
        left join sys_user_role sur on sur.roleCode=sr.roleCode
        left join users u on u.id = sur.userCode
        where u.id = #{uid}  or parentCode = '0' order by sm.sortNumber
      </select>

    数据库中初始化数据

    Service层

        @Autowired
        public UsersMapper usersMapper;
    
        /**
         * 根据用户id获取菜单权限(包括所有一级菜单)
         * @param uid  用户id
         * @return
         */
        public List<SysModule> getModuleByUid(String uid){
            List<SysModule> modules = usersMapper.getModuleByUid(uid);
            return modules;
        }

    Controller层

        /**
         * 根据用户id获取菜单权限
         * @return
         */
        @RequestMapping("/loadpermissions")
        @ResponseBody
        List<SysModule> getModuleByUid(String uid, HttpServletRequest request, HttpServletResponse response){
            //所有绑定的菜单,以及包括
            List<SysModule> modules = loginService.getModuleByUid(uid);
            //最终的List<SysModule>集合,存储一级菜单
            List<SysModule> result=new ArrayList<SysModule>();
    
            //建立模块层次结构
            for(int i=0;i<modules.size();i++){
                SysModule m=modules.get(i);  //遍历模块
    
                if(m.getParentCode()!=null&&m.getParentCode().equals("0")&&(m.getModulePath()==null||m.getModulePath().isEmpty())){   //判断是否为一级目录,一级目录父级code为0
                    resetModules(m,modules);   //给一级目录添加子菜单
                    if (m.getChildren().size()>0){   //当一级目录中存在子菜单时
                        result.add(m);   //将一级目录添加到list中
                    }
                }else if(m.getParentCode()!=null&&m.getParentCode().equals("0")&&m.getModulePath()!=null&&!m.getModulePath().isEmpty()){
                    //当一级为菜单,不是目录时,直接添加
                    result.add(m);
                }
            }
            return result;
        }

    调用接口返回结果

    前端

    静态样式示例


    <
    li> <a href="#"> <i class="fa fa-home"></i> <span class="nav-label">一级菜单</span> <span class="fa arrow"></span> </a> <ul class="nav nav-second-level"> <li> <a class="J_menuItem" href="index_v1.html" data-index="0">菜单1</a> </li> <li> <a class="J_menuItem" href="index_v2.html">菜单2</a> </li> </ul> </li>

    动态添加菜单

    //递归菜单
    function RecMenu(m){
    var result = '';
    result +="<li>";
    if(m.children!=null&&m.children.length>0){  //当有子菜单时
        result +='<a href="#"> <i class="fa fa-check"></i> <span class="nav-label">'+m.moduleName+'</span> <span class="fa arrow"></span></a>';   //一级目录
        result +='<ul class="nav nav-second-level">';   //一级目录子菜单开始
        for(var i=0,len=m.children.length;i<len;i++){   //遍历子菜单
            result+= RecMenu(m.children[i]);   //递归多级菜单
        }
        result +='</ul>';   //一级目录子菜单结束
    }else{   //当无子菜单时,即是叶子菜单
        result+= '<a class="J_menuItem" onclick="javascript:reloadMenu(this);" href="/${appName}/'+m.modulePath+'">'+m.moduleName+'</a>'
    }
    result +="</li>";
    return result;
    }
    
    var userId="<%=((Users)session.getAttribute("user")).getId()%>";
    $.ajax({
        url:'/${appName}/manager/loginController/loadpermissions',
        type:'post',
        async: false,
        cache:false,
        data:{uid:userId},
        dataType:'json',
        success: function(data){
            for(var i=0,len=data.length;i<len;i++){
                var ps = data[i];
                if(ps.children.length>0){   //如果一级目录有子菜单
                    var result = RecMenu(ps);  //遍历添加这个一级目录中的菜单
                    $('#side-menu').append(result);   
                }else if(ps.modulePath!=null){   //如果一级是菜单,不是目录
                    var result = RecMenu(ps);
                    $('#side-menu').append(result);
                            }
            }
        },
        error: function (aa, ee, rr) {
            }
    });

    LayUI树生成

    Controller

        /**
         * 返回树形结构
         * @return
         * @throws Exception
         */
        @RequestMapping(value="/selectPermissionTree",method={RequestMethod.GET,RequestMethod.POST})
        @ResponseBody
        public List selectPermissionTree() throws Exception {
            return service.selectPermissionTree();
        }

    Service

        /**
         * 获取module的tree型目录
         * @return
         */
        public List<PermissionTreemodule> selectPermissionTree() throws Exception {
            List<PermissionTreemodule> result = new ArrayList<PermissionTreemodule>();
            //查询库中所有module的list
            String sql = PermissionConfig.getPermissionTree;
            List<PermissionTreemodule> modulelist = dao.queryForObjectList(sql,new Object[]{},PermissionTreemodule.class);
            /*设置根结点*/
            PermissionTreemodule root = new PermissionTreemodule();
            root.setId(0);
            root.setHref("");
            root.setTitle("模块设置");
            root.setSpread(true);
            root.setDisabled(true);
            //找到id为0的菜单的下级结点,并添加到root结点的children中
            if (modulelist != null) {
                for (int i = 0; i < modulelist.size(); i++) {
                    PermissionTreemodule m = modulelist.get(i);
                    if (m.getParentId()!=null && m.getParentId().equals(0)){  //如果是根结点
                        m.setSpread(true);
                        resetModules(m,modulelist);  //给m添加子结点
                        root.getChildren().add(m);
                    }
                }
            }else {
                throw new Exception("modulelist为空");
            }
            result.add(root);
            return result;
        }
    
        /**
         * 为m设置子节点
         * @param m  父节点
         * @param ms 在ms中找到m的子节点
         */
        private void resetModules(PermissionTreemodule m,List<PermissionTreemodule> ms){
            for(int i=0;i<ms.size();i++){   //循环modules
                PermissionTreemodule c=ms.get(i);    //获取module
                if (c.getParentId()!=null) {  //当module的父code不为空时,即是子菜单
                    if(c.getParentId().equals(m.getId())){   //如果module的的父code等于m的code,也就是遍历到的module是m的子菜单
                        m.getChildren().add(c);   //直接加入到m
                        resetModules(c,ms);    //把这个二级菜单c加入到m中
                    }
                }
            }
        }

    POJO

    package com.gmtx.platform.model;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class PermissionTreemodule {
    
        private String title;
        private Integer id;
        private Integer parentId;
        private String field;
        private String href;
        private Boolean checked;
        private Boolean spread;
        private Boolean disabled;
        private List<PermissionTreemodule> children = new ArrayList<PermissionTreemodule>();
    
        public String getTitle() {
            return title;
        }
    
        public void setTitle(String title) {
            this.title = title;
        }
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public Integer getParentId() {
            return parentId;
        }
    
        public void setParentId(Integer parentId) {
            this.parentId = parentId;
        }
    
        public String getField() {
            return field;
        }
    
        public void setField(String field) {
            this.field = field;
        }
    
        public String getHref() {
            return href;
        }
    
        public void setHref(String href) {
            this.href = href;
        }
    
        public Boolean getChecked() {
            return checked;
        }
    
        public void setChecked(Boolean checked) {
            this.checked = checked;
        }
    
        public Boolean getSpread() {
            return spread;
        }
    
        public void setSpread(Boolean spread) {
            this.spread = spread;
        }
    
        public Boolean getDisabled() {
            return disabled;
        }
    
        public void setDisabled(Boolean disabled) {
            this.disabled = disabled;
        }
    
        public List<PermissionTreemodule> getChildren() {
            return children;
        }
    
        public void setChildren(List<PermissionTreemodule> children) {
            this.children = children;
        }
    }
  • 相关阅读:
    Class Loading Deadlocks
    Find out your Java heap memory size
    ZookeeperGettingStarted
    ZooKeeper的Znode剖析
    nginx+iis实现负载均衡
    ubuntu 18.04下svn的安装与基本命令
    在ubuntu中如何向U盘复制粘贴文件 Read-only file system
    Ubuntu16.04下安装破解secureCRT和secureFX的操作记录
    securecrt8注册码
    Doris FE负载均衡配置
  • 原文地址:https://www.cnblogs.com/aeolian/p/9204524.html
Copyright © 2020-2023  润新知