動態菜單樹加載過程


根據登錄的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;
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM