Fork me on GitHub

用户动态权限菜单管理简单实现方式

1.说明

根据用户角色的权限进行菜单管理,根据拥有的权限访问范围内的菜单

2.数据库表设计

 

2.1用户表

CREATE TABLE `sys_user` (
  `uid` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户Id',
  `username` varchar(100) NOT NULL COMMENT '用户名',
  `password` varchar(100) NOT NULL COMMENT '密码',
  `phone` varchar(11) DEFAULT NULL COMMENT '手机',
  `email` varchar(100) DEFAULT NULL COMMENT '邮箱',
  `locked` int(1) DEFAULT NULL COMMENT '账号是否被锁定',
  PRIMARY KEY (`uid`),
  UNIQUE KEY `uk_u_1` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8

2.2角色表

Create Table

CREATE TABLE `sys_role` (
  `roleId` int(11) NOT NULL AUTO_INCREMENT COMMENT '角色Id',
  `roleName` varchar(100) DEFAULT NULL COMMENT '角色名称',
  `roleDesc` varchar(100) DEFAULT NULL COMMENT '角色描述',
  `role` varchar(100) DEFAULT NULL COMMENT '角色标志',
  PRIMARY KEY (`roleId`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8

2.3权限表

Create Table

CREATE TABLE `sys_permission` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '权限Id',
  `pdesc` varchar(100) DEFAULT NULL COMMENT '权限描述',
  `name` varchar(100) DEFAULT NULL COMMENT '权限名称',
  `menuId` int(11) DEFAULT NULL COMMENT '菜单Id',
  PRIMARY KEY (`id`),
  KEY `p_fk_1` (`menuId`),
  CONSTRAINT `p_fk_1` FOREIGN KEY (`menuId`) REFERENCES `sys_menu` (`menuId`)
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8

2.4菜单表

CREATE TABLE `sys_menu` (
  `menuId` int(11) NOT NULL AUTO_INCREMENT COMMENT '菜单Id',
  `parentId` int(11) DEFAULT NULL COMMENT '上级Id',
  `menuName` varchar(100) DEFAULT NULL COMMENT '菜单名称',
  `menuUrl` varchar(100) DEFAULT NULL COMMENT '菜单链接',
  `menuStatus` varchar(10) DEFAULT NULL COMMENT '菜单状态',
  `level` int(4) NOT NULL COMMENT '菜单等级',
  PRIMARY KEY (`menuId`)
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8

 

3.代码

3.1设计思路

本次菜单只有两级,所有采用hashmap方式解决,Map<String, List<SysMenu>>,key值为父菜单,value为子菜单集合.

dao层:根据用户登录的session值取到用户id,根据用户id关联查询出所有菜单列表(包括父子菜单)

service层:双层for循环,判断menuById.get(I).getParentid() == 0且menuById.get(I).getMenuid() == menuById.get(J).getParentid();这样就可以得到父菜单及其子菜单,

将子菜单对象放在list集合中,在将父菜单的name作为key,子菜单的集合作为value存入map中;如图可以看出端倪:

 

 servlet层:获取登陆后session中保存的uid,调用service方法.返回主页面;

前端:el表达式,双重foreach,动态展示各父菜单及子菜单

3.2.dao层


QueryRunner queryRunner = new QueryRunner(ComboPooledDataSourceUtil.getDataSourceByxml());
List<Object> param = new ArrayList<>();
StringBuffer buffer = new StringBuffer();
 @Override
    public  List<SysMenu>  findMenuById(Integer uid) {
        //清空list和stringbuffer
        delListAndStringBuf();
        buffer.append("SELECT m.*");
        buffer.append(" FROM `sys_user` u");
        buffer.append(" INNER JOIN `sys_user_role` ur");
        buffer.append(" ON u.`uid`=ur.`userId`");
        buffer.append(" INNER JOIN `sys_role` r");
        buffer.append(" ON ur.`roleId`=r.`roleId`");
        buffer.append(" INNER JOIN `sys_role_permission` rp");
        buffer.append(" ON r.`roleId`=rp.`roleId`");
        buffer.append(" INNER JOIN `sys_permission` p");
        buffer.append(" ON rp.`permissionId`=p.`id`");
        buffer.append(" JOIN`sys_menu` m");
        buffer.append(" ON m.`menuId`=p.`menuId`");
        buffer.append(" WHERE m.`menuStatus`=0");
        buffer.append(" AND  u.`locked`=0");
        buffer.append(" AND u.`uid`=?");
        param.add(uid);
        //list集合转化为数组
        Object[] objects = param.toArray();
        List<SysMenu> menu =null;
        //
        try {
           menu = queryRunner.query(buffer.toString(), new BeanListHandler<SysMenu>(SysMenu.class), objects);
        } catch (SQLException e) {

        }
        return menu;
    }
//清空list和stringbuffer
public void delListAndStringBuf(){
param.clear();
buffer.delete(0,buffer.length());
}

3.3.service层

   @Override
    public Map<String, List<SysMenu>> menus(Integer uid) {
        //key为父菜单,value为父菜单下的子菜单集合
        Map<String, List<SysMenu>> menus = new HashMap<>();
        //父子菜单集合
        List<SysMenu> menuById = permissionMenuDao.findMenuById(uid);
        for (int i = 0; i < menuById.size(); i++) {
            //子菜单集合,外层循环时为另外一个父菜单的子菜单
            List<SysMenu> childMenu = new ArrayList<>();
            for (int j = 0; j < menuById.size(); j++) {
                //SysMenu创建对象,二次循环时为同父菜单下的另外一个子菜单对象
                SysMenu sm = new SysMenu();
                if (menuById.get(i).getParentid() == 0
                        & menuById.get(i).getMenuid() == menuById.get(j).getParentid()) {
                    sm.setMenuname(menuById.get(j).getMenuname());
                    sm.setMenuurl(menuById.get(j).getMenuurl());
                    sm.setMenuid(menuById.get(j).getMenuid());
                    // childMenu对象
                    childMenu.add(sm);
                    //将父菜单以及对应的子菜单集合封装在map里面
                    menus.put(menuById.get(i).getMenuname(), childMenu);
                }
            }
        }
        return menus;
    }

3.4servlet层

@WebServlet("/main/")
public class PermissionMenuServlet extends BaseServlet {
    PermissionMenuService service=new PermissionMenuServiceImpl();
    public String  index (HttpServletRequest request, HttpServletResponse response){
        HttpSession session = request.getSession();
        SysUser user= (SysUser) session.getAttribute("user");
        System.out.println("user:"+user.getUid());
        Map<String, List<SysMenu>> menus = service.menus(user.getUid());
        request.setAttribute("menus",menus);
        return "/WEB-INF/views/main/mainpage.jsp";
    }
}

4.0 前端

<aside class="Hui-aside">
        <div class="menu_dropdown bk_2">
            <%--父菜单--%>
            <c:forEach items="${requestScope.menus}" var="mainMenu">
            <dl id="menu-article">
                <dt><i class="Hui-iconfont">&#xe616;</i> ${mainMenu.key}<i
                        class="Hui-iconfont menu_dropdown-arrow">&#xe6d5;</i></dt>
                    <dd>
                        <%--子菜单--%>
                        <c:forEach items="${mainMenu.value}" var="childMenu">
                        <ul>
                            <li><a data-href=${childMenu.menuurl} data-title=${childMenu.menuname}
                                   href="javascript:void(0)">${childMenu.menuname}</a></li>
                        </ul>
                        </c:forEach>
                    </dd>
            </dl>
            </c:forEach>
        </div>
</aside>

 

备注:登录的service层需加入在session中加入uid

 request.getSession().setAttribute("user",user);

 

 

 

 

 


 

posted @ 2020-07-06 20:27  亲爸爸  阅读(1580)  评论(0编辑  收藏  举报