根据登录的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; } }