zoukankan      html  css  js  c++  java
  • java web简单权限管理设计

    一套最基本的权限管理包括用户、角色、资源。

    数据库设计

    我的设计如下:

    用户:user

    角色:role

    用户-角色:user_role

    资源:resource(包括上级菜单、子菜单、按钮等资源)

    角色-资源:role_resource

    标准的权限管理系统设计为以上5张表。

    注:用户、用户-角色我就不做说明了,这两个是很简单的两块,用户的crud,以及为用户分配角色(多对多的关系)稍微琢磨一下就清楚了,下面都是针对为角色分配权限的实现

    后台实现

    展示层采用ztree树
    <%@ page contentType="text/html;charset=UTF-8"%>
    <%@ include file="/views/back/include/taglib.jsp"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta name="decorator" content="back" />
    <script type="text/javaScript">
    //打开菜单窗口
    function openMenuDialog(){
        var selected = $("#list").datagrid('getSelected');
        if (selected != null) {
            $("#id").val(selected.id);
            queryMenus(selected.id);
            $("#menuWindow").window("open");
        } else {
            $.messager.alert('提示', "未选择数据!"); 
        }
    }
    //角色-菜单信息入库
    function ajaxSubmit(rid,idstr){
        $.post("${ctx}/roleMenu/save.jhtml",{"roleId":rid,"ids":idstr},function(obj){
            $.messager.alert('提示',obj.msg);
            $("#menuWindow").window('close');
        },'json');
    }
    </script>
    <!-- ztree -->
    <script type="text/javascript">
    var tree = "";
    var setting = {
        check : {
            chkboxType:{"Y":"ps","N":"s"},//勾选checkbox对于父子节点的关联关系,取消勾选时不关联父
            chkStyle:"checkbox",
            enable : true    //是否复选框
        },
        //数据
        data : {
            simpleData : {
                enable : true
            }
        }
    };
    //查询菜单信息
    function queryMenus(roleId){
        $.post('${ctx}/role/treedata.jhtml', {'roleId':roleId}, function(zNodes) {
            for (var i = 0; i < zNodes.length; i++) {
                if (zNodes[i].isParent) {
    
                } else {
                    //zNodes[i].icon = "${ctxStatic}/images/532.ico";//设置图标
                }
            }
            tree = $.fn.zTree.init($("#tree"), setting, zNodes);
            tree.expandAll(true);//全部展开
            //var nodes = treeObj.getNodes();
        }, 'json');
    }
    
    //获取选中节点
    function onCheck(){
         var rid = $("#id").val();
         var treeObj=$.fn.zTree.getZTreeObj("tree");
         var nodes=treeObj.getCheckedNodes(true);
         var ids = new Array();
         for(var i=0;i<nodes.length;i++){
            //获取选中节点的值
             ids.push(nodes[i].id);
            // v+=nodes[i].id + ",";
            //alert(nodes[i].id); 
         }
        ajaxSubmit(rid,ids);     
    }
    </script>
    </head>
    <body>
        <!-- 数据表格 -->
        <table id="list" url='${ctx}/role/list/page.jhtml' method='post'
            class="easyui-datagrid" style="100%;" fitcolumns="true" 
            toolbar='#tb' pagination='true' rownumbers='true' singleSelect='true'>
            <thead>
                <tr>
                    <th field='name' sortable='true' width='100'>角色名称</th>
                    <th field='description' width='200' align='right'>描述</th>
                    <th field='createTimeFormat' width='150' align='center'>创建时间</th>                
                </tr>
            </thead>
        </table>
        
        <!-- 编辑栏  -->
        <div id="tb" style="padding:5px 5px;">
            <div>
                <p2p:permission module="role" code="add"><a href="#" class="easyui-linkbutton" iconCls="icon-add" onclick="openCreateDialog();">新增</a></p2p:permission>
                <p2p:permission module="role" code="edit"><a href="#" class="easyui-linkbutton" iconCls="icon-edit" onclick="openUpdateDialog();">编辑</a></p2p:permission>
                <p2p:permission module="role" code="delete"><a href="#" class="easyui-linkbutton" iconCls="icon-remove" onclick="del();">删除</a></p2p:permission>
                <p2p:permission module="role" code="authority"><a href="#" class="easyui-linkbutton" iconCls="icon-edit" onclick="openMenuDialog();">设置权限</a></p2p:permission>
            </div>
            <!-- 搜索项 -->
            <div style="margin-top:5px;padding-left:5px">
                用户名:   <input id="query_name" class="easyui-textbox" type="text" style="110px" />
                创建日期: <input id="query_startDate" class="easyui-datebox" style="110px">
                至:        <input id="query_endDate" class="easyui-datebox" style="110px">
                <a onclick="reload();" href="#" class="easyui-linkbutton" iconCls="icon-search">查询</a>
            </div>
        </div>
        
        
        
        <!-- 权限窗口 -->
        <div id="menuWindow" class="easyui-window" title="配置权限" data-options="modal:true,iconCls:'icon-save',footer:'#menuWindowfooter'" style="350px;height:420px;padding:10px">
            <div id="tree" class="ztree" style="padding: 10px 20px;"></div>
        </div>
        <div id="menuWindowfooter" style="padding:5px;text-align:right;"> 
            <a href="#" onclick="onCheck();" class="easyui-linkbutton" data-options="iconCls:'icon-save'">提交</a>
        </div>
        
    </body>
    </html>

    action层
    RoleAction.java

    @RequestMapping(value = "/treedata.jhtml")
        @ResponseBody
        public String treedata(HttpServletRequest request, Model model) {
            DynamicParams params = new DynamicParams(request);
            List<Map<String, Object>> mapList = Lists.newArrayList();
    
            params.put("allMenu", "allMenu");
            List<Menu> list = authManager.findMenuList(params);
    
            List<RoleMenu> roleMenus = authManager.findRoleMenuList(params);
    
            for (int i = 0; i < list.size(); i++) {
                Menu e = list.get(i);
                Map<String, Object> map = Maps.newHashMap();
                map.put("id", e.getId());
                map.put("pId", e.getParentId() != null ? e.getParentId() : 0);
                map.put("name", e.getName());
                for (RoleMenu roleMenu : roleMenus) {
                    if (roleMenu.getMenuId() == e.getId()) {
                        map.put("checked", true);
                    }
                }
                mapList.add(map);
            }
    
            return toJson(mapList);
        }

    service层

    AuthManager.java

    // 菜单管理
    
        public List<Menu> findMenuList(DynamicParams params) {
            List<Menu> menus = new ArrayList<Menu>();
    
            if ("allMenu".equals(params.getString("allMenu"))) {
                menus = menuDao.findList(params);
            } else {
                // 通过用户查询角色
                List<UserRole> userRoles = userRoleDao.findList(params);
                // 通过角色查询菜单
                List<RoleMenu> roleMenus = new ArrayList<RoleMenu>();
                if (userRoles != null && userRoles.size() > 0) {
                    for (UserRole userRole : userRoles) {
                        params = new DynamicParams();
                        if (userRole != null) {
                            if (userRole.getRoleId().equals(params.getString("rid"))) {
                                break;
                            }
                            params.put("roleId", userRole.getRoleId().toString());
                            List<RoleMenu> rms = roleMenuDao.findList(params);
                            for (RoleMenu roleMenu : rms) {
                                roleMenus.add(roleMenu);
                            }
                        }
                    }
                }
    
                // 查询菜单信息
                for (RoleMenu roleMenu : roleMenus) {
                    if (roleMenu != null) {
                        Menu menu = menuDao.find(roleMenu.getMenuId());
                        if (menu != null) {
                            menus.add(menu);
                        }
                    }
                }
                menus = removeDuplicate(menus);
                Collections.sort(menus);
            }
            return menus;
        }
    /**
         * 去除菜单中重复项
         * 
         * @param list
         * @return
         */
        private List<Menu> removeDuplicate(List<Menu> list) {
            List<Menu> result = new ArrayList<Menu>();
            Set<Long> menuIds = new HashSet<Long>();
            for (int i = 0; i < list.size(); i++) {
                Menu m = list.get(i);
                if (m != null && menuIds.add(m.getId())) {
                    result.add(m);
                }
            }
            return result;
        }
    public List<RoleMenu> findRoleMenuList(DynamicParams params) {
            List<RoleMenu> roleMenus = roleMenuDao.findList(params);
            return roleMenus;
        }

    Dao层

    menuDao

    @Override
        protected void createQuery(DynamicParams params, StringBuffer sql, List<Object> args) {
            sql.append("select s.* from sys_menu s where 1=1 ");
    
            String parentId = params.getString("parentId");
            if (StringUtils.isNotBlank(parentId)) {
                sql.append(" and parent_id = ? ");
                args.add(parentId);
            }
    
            String sort = params.getString("sort");
            String order = params.getString("order");
    
            if (StringUtils.isNotBlank(sort)) {
                sql.append(" order by ").append(hump2underline(sort));
                if (StringUtils.isNotBlank(order)) {
                    sql.append(" " + order);
                } else {
                    sql.append(" desc ");
                }
            } else {
                sql.append("order by sort asc,id desc ");
            }
        }

    userRoleDao

    @Override
        protected void createQuery(DynamicParams params, StringBuffer sql, List<Object> args) {
            sql.append("select s.* from sys_user_role s where 1=1 ");
            Long adminId = params.getLong("adminId");
            if (adminId != null) {
                sql.append(" and s.user_id = ?");
                args.add(adminId);
            }
        }

    roleMenuDao

    @Override
        protected void createQuery(DynamicParams params, StringBuffer sql, List<Object> args) {
            sql.append("select s.* from ").append("sys_role_menu").append(" s where 1=1 ");
            Long adminId = params.getLong("roleId");
            if (adminId != null) {
                sql.append(" and s.role_id = ?");
                args.add(adminId);
            }
        }

    在WEB-INF目录下建立文件夹tlds 建立自定义标签文件shiros.tld,我们通过自定义标签实现页面按钮的控制。

    <span style="color:#333333;"><?xml version="1.0" encoding="UTF-8" ?>
    <taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
        version="2.0">
        <description>p2p permission taglib</description>
        <display-name>permission taglib</display-name>
        <tlib-version>1.0</tlib-version>
        <short-name>p2p_back</short-name>
        <uri>http://vanfon.p2p.cn/</uri>
    
        <tag>
            <description>权限校验标签,有权限就显示标签体的内容,否则不显示</description>
            <name>permission</name>
            <tag-class>com.vanfon.p2p.back.tag.PermissionTag</tag-class>
            <body-content>JSP</body-content>
            <attribute>
                <description></description>
                <name>module</name>
                <required>true</required>
                <rtexprvalue>false</rtexprvalue>
            </attribute>
            <attribute>
                <description></description>
                <name>code</name>
                <required>true</required>
                <rtexprvalue>false</rtexprvalue>
            </attribute>
        </tag>
    </taglib></span>

    自定义标签类

    package com.vanfon.p2p.back.tag;
    
    import java.util.List;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.jsp.JspException;
    import javax.servlet.jsp.tagext.TagSupport;
    
    import com.vanfon.p2p.entity.system.Admin;
    import com.vanfon.p2p.entity.system.Menu;
    import com.vanfon.p2p.manager.system.AuthManager;
    import com.vanfon.p2p.utils.DynamicParams;
    import com.vanfon.p2p.utils.SpringContextHolder;
    
    /**
     * 权限控制标签
     * 
     * @author zhangwx
     * @date 2015-2-5
     */
    public class PermissionTag extends TagSupport {
    
        /**
         * 
         */
        private static final long serialVersionUID = 4592227792811389132L;
    
        private String module;// 属性名必须与JSP自定义标签的属性名一样
    
        private String code;
    
        public String getModule() {
            return module;
        }
    
        public void setModule(String module) {
            this.module = module;
        }
    
        public String getCode() {
            return code;
        }
    
        public void setCode(String code) {
            this.code = code;
        }
    
        @Override
        public int doStartTag() throws JspException {
            boolean result = false;
            HttpServletRequest request = (HttpServletRequest) this.pageContext.getRequest();// 通过成员变量获取HttpServletRequest对象
            Admin admin = (Admin) request.getSession().getAttribute("admin");// 获取登录到系统的用户
            if (admin != null) {
                if ("1".equals(String.valueOf(admin.getIfsuper()))) {// 超级管理员
                    result = true;
                } else {
                    DynamicParams params = new DynamicParams();
                    params.put("id", String.valueOf(admin.getId()));
                    params.put("module", this.module);
                    params.put("code", this.code);
                    AuthManager authManager = SpringContextHolder.getBean(AuthManager.class);
                    List<Menu> userRoleAuths = authManager.findUserRoleAuthList(params);
                    if (userRoleAuths != null && userRoleAuths.size() > 0) {
                        result = true;
                    }
                }
            }
            return result ? EVAL_BODY_INCLUDE : SKIP_BODY;
        }
    }

    以上就是该权限管理中权限树(为角色分配权限)的大体实现。

  • 相关阅读:
    仿照京东做的一个鼠标移上去的图片文字说明效果
    js 之 复制一段代码
    自己练习了一个弹出框
    用jq 做了一个排序
    做了一个类似天猫鼠标经过icon的动画,记录一下
    一行代码写一个轮播,想了好久,感觉这样可以。
    一个小例子,全选复选框
    仿照淘宝首页做的一个高度伪对齐demo
    《挑战程序设计竞赛》2.2 贪心法-区间 POJ2376 POJ1328 POJ3190
    《挑战程序设计竞赛》2.1 穷竭搜索 POJ2718 POJ3187 POJ3050 AOJ0525
  • 原文地址:https://www.cnblogs.com/jinzhiming/p/5011245.html
Copyright © 2011-2022 走看看