【SaaS - Export项目】16 - 角色授权,更新角色权限(模块),zTree实现RBAC权限角色授权

效果图
在这里插入图片描述

Saas-Export项目的RBAC权限模型图

在这里插入图片描述
RABC权限模型的使用步骤

给用户授权的顺序

  1. 先给角色赋予权限
  2. 再将角色分配给用户
  3. 最后用户得到这些角色的所有权限

SaaS-Export角色授权

给角色添加权限,无非就是在中间表(角色模块表pe_role_module)中生成记录。
对应关系(一对多):一个角色(role)对应多个模块(moudle)

1)给角色添加权限
2)给角色修改权限
3)给用户指定角色
4)给用户更新角色

给角色分配权限

在这里插入图片描述

1. 编写测试给角色分配权限的sql语句

-- 先创建一个角色
INSERT INTO pe_role (role_id,NAME)VALUES('ac9b2814-51bc-40db-8628-6cb20b77e5e9','test role_moudle') 

-- 添加权限往中间表 pe_role_module(角色模块表) 添加用户权限(可以进入的模块) 参1:用户id	参2:模块id
INSERT INTO pe_role_module VALUES('ac9b2814-51bc-40db-8628-6cb20b77e5e9','201') -- 购销合同201
INSERT INTO pe_role_module VALUES('ac9b2814-51bc-40db-8628-6cb20b77e5e9','202') -- 出货表202
SELECT * FROM pe_role_module WHERE role_id='ac9b2814-51bc-40db-8628-6cb20b77e5e9'

-- 修改权限 (pe_role_module )先删除角色模块表的当前角色信息  参1:用户id	参2:模块id
DELETE FROM pe_role_module WHERE role_id='ac9b2814-51bc-40db-8628-6cb20b77e5e9'
INSERT INTO pe_role_module VALUES('ac9b2814-51bc-40db-8628-6cb20b77e5e9','201') -- 购销合同
INSERT INTO pe_role_module VALUES('ac9b2814-51bc-40db-8628-6cb20b77e5e9','202')-- 出货表
INSERT INTO pe_role_module VALUES('ac9b2814-51bc-40db-8628-6cb20b77e5e9','203')-- 合同管理

2. export_system_service子工程编写测试类测试角色授权

TestModuleService

    //测试查找所有的模块
    @Test
    public void test05(){

        List<Module> moduleList = iModuleService.findAllModules();
        l.info("模块数量"+ moduleList.size() +"moduleList = "+moduleList);
    }

    //测试通过角色id查询角色的权限
    @Test
    public void test06(){

        List<Module> myList = iModuleService.findModuleByRoleId("ac9b2814-51bc-40db-8628-6cb20b77e5e9");
        l.info("模块数量: "+myList.size()+"  \n角色的模块权限myList = "+myList);
    }

    //测试更新角色的权限(先删除、后更新)
    @Test
    public void test07(){
        //修改一个角色的权限,不仅仅是添加,也可能是减少
        String roleId="ac9b2814-51bc-40db-8628-6cb20b77e5e9";
        //String moduleIds="201,202";//减少指定角色的权限
        String moduleIds="201,202,203";//添加角色的权限
        iModuleService.updateRoleModule(roleId,moduleIds);
    }

3. export_system_service子工程的service接口和实现类

IModuleService

//查找所有模块
    List<Module> findAllModules();
    //通过角色查找从属于该角色的所有模块
    List<Module> findModuleByRoleId(String roleId);
    //通过角色id更新角色的模块信息(zTree树形,先删除该角色的所有模块权限,再添加)
    void updateRoleModule(String roleId, String moduleIds);

ModuleServiceImpl

这里需要注意,再做更新角色权限(模块)的时候,先删除该角色的所有权限,然后进行更新,更新需要判断页面传来的参数是否有值(null或""空子字符串)如果是无值的,name就不进行saveRoleModule保存角色权限,否则会抛出InvocationTargetException异常。
也就是如果没有传过来模块参数就不需要进行保存,也就是情况角色的权限(更新的时候先删除了角色的所有权限)

 @Override
    public List<Module> findAllModules() {
        return iModuleDao.findAll();
    }

    @Override
    public List<Module> findModuleByRoleId(String roleId) {
        return iModuleDao.findByRoleId(roleId);
    }

    //更新角色的模块信息
    @Override
    public void updateRoleModule(String roleId, String moduleIds) {
        //先做删除,删除角色在中间表(角色模块表)中的记录
        iModuleDao.deleteRoleModule(roleId);
        // zTree获取所有的模块id,按,逗号分开  moduleIds 202,203
        //判断该角色权限是否清空(该角色还有模块的情况,否则会抛出InvocationTargetException异常)
        if(moduleIds!=null && moduleIds != ""){
            String[] mids = moduleIds.split(",");
            //更新角色模块
            if (mids.length > 0) { //判断选择模块权限是否>0,再操作
                //再作添加,将模块赋予给角色(角色模块表添加记录)
                for (String mid : mids) {
                    iModuleDao.saveRoleModule(roleId, mid);
                }
            }
        }else{
            System.out.println("updateRoleModule 该用户没有任何权限了");
        }
    }

4. export_dao子工程写dao接口及其映射

IModuleDao

 //通过角色id查询角色的模块权限
    List<Module> findByRoleId(String roleId);
    //删除指定角色的所有模块权限
    void deleteRoleModule(String roleId);
    //给角色添加模块(权限)
    void saveRoleModule(String roleId, String mid);

IModuleDao.xml

    <!-- 通过角色id查询角色的模块权限 -->
    <select id="findByRoleId" parameterType="string" resultMap="moduleMap" >
        select m.*
        from pe_role_module rm
        inner join ss_module m
        on rm.module_id = m.module_id
        where rm.role_id=#{roleId}
    </select>

    <!-- 删除指定角色的所有模块权限 -->
    <delete id="deleteRoleModule" parameterType="string">
        delete from pe_role_module where role_id=#{roleId}
    </delete>

    <!-- 给角色添加模块(权限)  void saveRoleModule(String roleId, String mid);-->
    <!-- 保存角色模块有两个参数,第一个参数是:角色id(roleId)第二个参数是:模块id(moduleId) 
            可以通过arg0、arg1...来接收
            或者通过param1、param2...来接收
    -->
    <insert id="saveRoleModule">
            insert into pe_role_module values(#{arg0},#{arg1})
    </insert>
    <!-- 
     <insert id="saveRoleModule" >
             insert into pe_role_module values(#{param1},#{param2})
     </insert>
     -->

5. export_web_manager子工程编写controller

RoleControllerController

    // 去角色的模块表(需要角色的id,查找该角色的模块) location.href="${path}/system/role/toRoleModule?roleId="+id;
    @RequestMapping(path="/toRoleModule",method ={ RequestMethod.GET, RequestMethod.POST})
    public String toRoleModule(String roleId){//接收页面提交的roleId
        //当前授权页面需要显示 角色名称
        l.info("toRoleModule roleId=" + roleId);
        //查找角色信息
        Role role = iRoleService.findById(roleId);

        //数据转发到页面
        request.setAttribute("role",role);
        return "system/role/role-module";
    }

    // 给role-module页面的zTree的树形角色模块菜单赋值(有权限的选中)  $.get('${path}/role/getZtreeData?roleId=${role.roleId}',fn,'json')
    @RequestMapping(path="/getZtreeData",method ={ RequestMethod.GET, RequestMethod.POST})
    public @ResponseBody Object getZtreeData(String roleId) {//接收页面提交的roleId
        //所有的权限(模块)查询出来
        List<Module> all = iModuleService.findAllModules();
        //根据roleId查询该角色的权限(有权限的模块打钩)
        List<Module> myList = iModuleService.findModuleByRoleId(roleId);

        //将list转换成 List<Map<String,Object>>  { id:1, pId:0, name:"Sass管理", open:true},
        List<Map<String,Object>> list = new ArrayList<>();
        //返回给页面
        for(Module m:all){
            //生成一个集合 Map<String,Object> 表示一节点
            Map<String,Object> node = new HashMap<String,Object>();
            node.put("id",m.getModuleId());
            node.put("pId",m.getParentId());    //菜单等级
            node.put("name",m.getName());
            node.put("open",true);              //是否展开该菜单
            //比较所有模块(权限)和当前角色拥有的模块是否相同
            if(isInMyList(m,myList)){
                node.put("checked",true);//当前角色拥有该权限,选中状态,有打勾就表示有这个权限,否则就是没有
            }
            //添加到集合中
            list.add(node);
        }
        return list;    //@ResponseBody将list转成json
    }

    //定义方法判断当前模块是否在该角色的模块列表用
    //需要判断m是否在myList里面,如果在表示该角色有这个权限,否则没有
    private boolean isInMyList(Module m, List<Module> myList) {
        for(Module my:myList){
            if(m.getModuleId().equals(my.getModuleId())){
                l.info("isInMyList  moduleId1  "+m.getModuleId()+" "+m.getName());
                l.info("isInMyList  moduleId2  "+my.getModuleId()+" "+my.getName());
                return true;
            }
        }
        return false;
    }

    //更新角色的模块(先全部删除,再根据选中的模块进行赋值到中间表角色模块表中)  ${path}/system/role/updateRoleModule
    @RequestMapping(path="/updateRoleModule",method ={ RequestMethod.GET, RequestMethod.POST})
    public String updateRoleModule(String roleId,String moduleIds){//接收了页面提交的参数
        l.info("updateRoleModule roleId="+roleId);
        l.info("updateRoleModule moduleIds="+moduleIds);
        //roleId=ac9b2814-51bc-40db-8628-6cb20b77e5e9
        //更新角色的模块权限  moduleIds=202,203,204
        iModuleService.updateRoleModule(roleId,moduleIds);

        return "redirect:/system/role/toList";
    }

6. export_web_manager子工程编写jsp页面

role-list
页面权限按钮
在这里插入图片描述

<button type="button" class="btn btn-default" title="权限" onclick="findModuleByRoleId()"><i class="fa fa-users"></i> 权限</button>

绑定js进行跳转

//查找选中角色的所有权限
    function findModuleByRoleId(){
        var roleId = getCheckId();
        if(roleId) {
            //去角色模块列表
            location.href="${path}/system/role/toRoleModule?roleId="+roleId;
        }else{
            alert("请勾选待处理的记录,且每次只能勾选一个")
        }
    }

role-module.jsp

<%-- 角色(通过roleid)-的模块权限 --%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ include file="../../base.jsp" %>
<!DOCTYPE html>
<html>

<head>

    <!-- 页面meta -->
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>SaaS-Export 角色的模块树</title>
    <meta name="description" content="SaaS-Export 角色的模块树">
    <meta name="keywords" content="SaaS-Export module tree">
    <!-- Tell the browser to be responsive to screen width -->
    <meta content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" name="viewport">
    <!-- 页面meta /-->

    <%--步骤:
         第一步:拷贝zTree的css/js文件到项目中
         第二步:拷贝js导入到当前页面
         第三步:页面定义显示树的区域
    --%>
    <%--拷贝zTree的js脚本、css样式导入到当前页面--%>
    <link rel="stylesheet" type="text/css" href="${path}/plugins/ztree/css/zTreeStyle/zTreeStyle.css">
    <script type="text/javascript" src="${path}/plugins/ztree/js/jquery-1.4.4.min.js"></script>
    <script type="text/javascript" src="${path}/plugins/ztree/js/jquery.ztree.all-3.5.min.js"></script>

    <script type="text/javascript">

        //当前的配置信息
        var setting = {
            check: {
                enable: true
            },
            data: {
                simpleData: {
                    enable: true
                }
            }
        };
        //zTree的数据(模拟数据)
        //pId是树形菜单的等级(0最高) open:true,就是菜单是打开的(显示子菜单)
        //checked:true 默认选中
        /*var zNodes =[
            { id:1, pId:0, name:"Sass管理", open:true},
            { id:11, pId:1, name:"企业管理", open:true,checked:true},
            { id:111, pId:1, name:"模块管理"},
            { id:112, pId:1, name:"用户管理"},
            { id:113, pId:1, name:"角色管理"}
        ];*/
        $(document).ready(function(){
            var fn =function(data){
                //菜单的初始化
                //参1 显示的标签  参2 设置的参数 比如支持复选 check enable = true  参3 数据
                $.fn.zTree.init($("#treeDemo"), setting, data);
            }
            //通过角色的id(roleId)来获取角色的模块权限信息
            $.get('${path}/system/role/getZtreeData?roleId=${role.roleId}',fn,'json')
        });
    </script>
</head>

<body style="overflow: visible;">
<div id="frameContent" class="content-wrapper" style="margin-left:0px;height: 1200px" >
    <section class="content-header">
        <h1>
            菜单管理
            <small>菜单列表 - 角色模块</small>
        </h1>
        <ol class="breadcrumb">
            <li><a href="all-admin-index.html"><i class="fa fa-dashboard"></i> 首页</a></li>
        </ol>
    </section>
    <!-- 内容头部 /-->

    <!-- 正文区域 -->
    <section class="content">

        <!-- .box-body -->
        <div class="box box-primary">
            <div class="box-header with-border">
                <h3 class="box-title">角色 [ ${role.name} ] 权限(模块)列表</h3>
            </div>

            <div class="box-body">

                <!-- 数据表格 -->
                <div class="table-box">
                    <!--工具栏-->
                    <div class="box-tools text-left">
                        <button type="button" class="btn bg-maroon" onclick="submitCheckedNodes();">保存</button>
                        <button type="button" class="btn bg-default" onclick="history.back(-1);">返回</button>
                    </div>
                    <!--工具栏/-->
                    <!-- 树菜单 -->
                    <script type="text/javascript">
                        function submitCheckedNodes() {
                            //先读取树状菜单的moduleId,再拼接成 201,202,203 赋值给隐藏框
                            var tree= $.fn.zTree.getZTreeObj("treeDemo");
                            //再获取选中的moduleId
                            //tree.getCheckedNodes(true); 返回被选中的节点,放在一个数组中
                            var nodes = tree.getCheckedNodes(true);
                            var moduleIds = ''
                            for(var i = 0;i<nodes.length;i++){
                                console.info(nodes[i])
                                var moduleId = nodes[i].id
                                moduleIds += moduleId
                                //201,202,203 如果是最后一个元素,不需要拼接,
                                if(i != nodes.length-1){
                                    moduleIds += ','
                                }//end if

                            }//end for
                            console.info("moduleIds = "+moduleIds)
                            //将得到的moduleIds 设置给隐藏输入框,方便提交到后台控制器
                            $('#moduleIds').val(moduleIds)
                            //提交表单
                            $('#icform').submit()
                        }
                    </script>

                    <%-- zTree角色权限树,打钩就是拥有权限 --%>
                    <form id="icform" method="post" action="${path}/system/role/updateRoleModule">
                        <%-- 隐藏域角色id,后台需要根据id对角色权限进行更新 --%>
                        <input type="hidden" name="roleId" value="${role.roleId}"/>
                        <!-- 先读取树状菜单的moduleId,再拼接成 201,202,203 赋值给隐藏框-->
                        <input type="hidden" id="moduleIds" name="moduleIds" value=""/>
                        <div class="content_wrap">
                            <div class="zTreeDemoBackground left" style="overflow: visible">
                                <%-- 将模块显示出来 --%>
                                <ul id="treeDemo" class="ztree"></ul>
                            </div>
                        </div>

                    </form>
                    <!-- 树菜单 /-->

                </div>
                <!-- /数据表格 -->

            </div>
            <!-- /.box-body -->
        </div>
    </section>
</div>
</body>
</html>
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值