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