尚筹网 —— 7、权限分配

目录

1、权限控制

2、给管理员分配 Role

2.1、目标

2.2、思路

2.3、代码

2.3.1、创建保存 Admin-Role 关联关系的数据库表

2.3.2、修改分配权限的按钮

2.3.2、创建 AssignHandle

2.3.3、完成 service 层方法

2.3.4、创建 assign-role.jsp.jsp 页面并显示已分配和未分配的角色信息

2.3.5、调整表单使其能够提交数据

2.3.6、角色列表左右移角色

2.3.7、完成保存分配角色信息的 handle 方法

2.3.8、完成保存角色信息的 service 层方法

2.3.9、给保存按钮绑定单击事件,使点击时选中所有要分配列表的option

3、给 Role 分配 Auth

3.1、思路

3.2、代码

3.2.1、创建权限表 t_auth

3.2.2、逆向工程:生成权限相关资源

3.2.3、创建获取所有权限的 方法

3.2.4、打开分配权限的模态框并显示 auth 树形结构

3.2.5、创建角色与权限之间关联关系的中间表

3.2.6、根据 role_id 查询 auth_id

3.2.7、执行分配


1、权限控制

ContextConfiguration

2、给管理员分配 Role

2.1、目标

通过页面操作把 Admin 和 Role 之间的关联关系保存到数据库。

2.2、思路

2.3、代码

2.3.1、创建保存 Admin-Role 关联关系的数据库表

CREATE TABLE `project_crowd`.`inner_admin_role` ( 
	`id` INT NOT NULL AUTO_INCREMENT, 
	`admin_id` INT, 
	`role_id` INT, 
	PRIMARY KEY (`id`) 
);

2.3.2、修改分配权限的按钮

admin-page.jsp 

<a href="assign/to/assign/role/page.html?adminId=${admin.id}&pageNum=${requestScope.pageInfo.pageNum}&keyword=${param.keyword}"
   class="btn btn-success btn-xs">
	<i class=" glyphicon glyphicon-check"></i>
</a>

2.3.2、创建 AssignHandle

package com.atguigu.crowd.mvc.handle;

import com.atguigu.crowd.entity.Role;
import com.atguigu.crowd.service.api.AdminService;
import com.atguigu.crowd.service.api.RoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.List;

/**
 * @Author zhang
 * @Date 2022/5/13 - 22:49
 * @Version 1.0
 */
@Controller
public class AssignHandle {

    @Autowired
    private AdminService adminService;

    @Autowired
    private RoleService roleService;

    /**
     * 跳转到分配角色页面
     * @param adminId 要分配的管理员的ID
     * @param modelMap
     * @return
     */
    @RequestMapping("/assign/to/assign/role/page.html")
    public String toAssignRolePage(
            @RequestParam("adminId") Integer adminId,
            ModelMap modelMap
    ){
        // 查询已分配的角色
        List<Role> assignedRoleList = roleService.getAssignedRole(adminId);

        // 查询未分配的角色
        List<Role> unAssignedRoleList = roleService.getUnAssignedRole(adminId);

        // 存入模型
        modelMap.addAttribute("assignedRoleList", assignedRoleList);
        modelMap.addAttribute("unAssignedRoleList", unAssignedRoleList);

        return "assign-role.jsp";
    }

}

2.3.3、完成 service 层方法

RoleService

    /**
     * 获取已分配的角色
     * @param adminId 要获取的管理员的ID
     * @return
     */
    List<Role> getAssignedRole(Integer adminId);

    /**
     * 获取未分配的角色
     * @param adminId 要获取的管理员的ID
     * @return
     */
    List<Role> getUnAssignedRole(Integer adminId);

RoleServiceImpl

    /**
     * 获取已分配的角色
     * @param adminId 要获取的管理员的ID
     * @return
     */
    @Override
    public List<Role> getAssignedRole(Integer adminId) {
        return roleMapper.getAssignedRole(adminId);
    }

    /**
     * 获取未分配的角色
     * @param adminId 要获取的管理员的ID
     * @return
     */
    @Override
    public List<Role> getUnAssignedRole(Integer adminId) {
        return roleMapper.getUnAssignedRole(adminId);
    }

RoleMapper.java

    /**
     * 获取已分配的角色
     * @param adminId 要获取的管理员的ID
     * @return
     */
    List<Role> getAssignedRole(Integer adminId);

    /**
     * 获取未分配的角色
     * @param adminId 要获取的管理员的ID
     * @return
     */
    List<Role> getUnAssignedRole(Integer adminId);

RoleMapper.xml

  <select id="getAssignedRole" resultMap="BaseResultMap">
    select id, name
    from t_role
    where id in (
        select role_id
        from inner_admin_role
        where admin_id = #{adminId}
      )
  </select>

  <select id="getUnAssignedRole" resultMap="BaseResultMap">
    select id, name
    from t_role
    where id not in (
      select role_id
      from inner_admin_role
      where admin_id = #{adminId}
    )
  </select>

2.3.4、创建 assign-role.jsp.jsp 页面并显示已分配和未分配的角色信息

option 标签的 value 属性在提交表单时会一起发送给 handle 方法

<c:forEach items="${requestScope.unAssignedRoleList}" var="role">
	<option value="${role.id}">${role.name}</option>
</c:forEach>

<c:forEach items="${requestScope.assignedRoleList}" var="role">
	<option value="${role.id}">${role.name}</option>
</c:forEach>

2.3.5、调整表单使其能够提交数据

assign-role.jsp

添加三个隐藏域,设置跳转地址及方法,已分配角色列表的 select 标签设置 name 属性,以便保存到数据库,添加保存按钮 

<form action="assign/do/role/assign.html" method="post" role="form" class="form-inline">
	<input type="hidden" name="adminId" value="${param.adminId}">
	<input type="hidden" name="pageNum" value="${param.pageNum}">
	<input type="hidden" name="keyword" value="${param.keyword}">
	<div class="form-group">
		<label for="exampleInputPassword1">未分配角色列表</label><br>
		<select class="form-control" multiple="" size="10" style="width:100px;overflow-y:auto;">
			<c:forEach items="${requestScope.unAssignedRoleList}" var="role">
				<option value="${role.id}">${role.name}</option>
			</c:forEach>
		</select>
	</div>
	<div class="form-group">
		<ul>
			<li class="btn btn-default glyphicon glyphicon-chevron-right"></li>
			<br>
			<li class="btn btn-default glyphicon glyphicon-chevron-left" style="margin-top:20px;"></li>
		</ul>
	</div>
	<div class="form-group" style="margin-left:40px;">
		<label for="exampleInputPassword1">已分配角色列表</label><br>
		<select name="roleIdList"
				class="form-control" multiple="multiple" size="10" style="width:100px;overflow-y:auto;">
			<c:forEach items="${requestScope.assignedRoleList}" var="role">
				<option value="${role.id}">${role.name}</option>
			</c:forEach>
		</select>
	</div>
	<button style="width:100px;margin:20px 100px" type="submit" class="btn btn-sm btn-success btn-block"> 保存</button>
</form>

2.3.6、角色列表左右移角色

 ① 给左移和右移按钮设置 id 属性

<div class="form-group">
	<ul>
		<li id="toRightBtn" class="btn btn-default glyphicon glyphicon-chevron-right"></li>
		<br>
		<li id="toLeftBtn" class="btn btn-default glyphicon glyphicon-chevron-left" style="margin-top:20px;"></li>
	</ul>
</div>

② 给左移和右移按钮绑定单击事件

        // 右移选中的角色
        $("#toRightBtn").click(function (){
            // 找到未分配列表中选中的角色
            // eq(0):第一个select标签
            // > :后代元素
            // appendTo:将元素追加到指定元素后,原本的位置消失
            $("select:eq(0)>option:selected").appendTo("select:eq(1)");
        });

        // 左移选中的角色
        $("#toLeftBtn").click(function (){
            // 找到未分配列表中选中的角色
            // eq(0):第一个select标签
            // > :后代元素
            // appendTo:将元素追加到指定元素后,原本的位置消失
            $("select:eq(1)>option:selected").appendTo("select:eq(0)");
        });

2.3.7、完成保存分配角色信息的 handle 方法

AssignHandle 

    /**
     * 将要分配的角色保存
     * @param adminId 要保存的管理员的id
     * @param pageNum 保存完后跳转页面的页数
     * @param keyword 保存完后跳转页面的关键词
     * @param roleIdList 要保存的角色id集合
     * @return
     */
    @RequestMapping("/assign/do/role/assign.html")
    public String saveRelationship(
            @RequestParam("adminId") Integer adminId,
            @RequestParam("pageNum") Integer pageNum,
            @RequestParam("keyword") String keyword,
            @RequestParam(value = "roleIdList", required = false) List<Integer> roleIdList
    ){
        adminService.saveRelationship(adminId, roleIdList);
        return "redirect:/admin/get/page.html?pageNum=" + pageNum + "&keyword=" + keyword;
    }

2.3.8、完成保存角色信息的 service 层方法

AdminService

    /**
     * 将roleIdList中对应的角色分配给adminId对应的管理员
     * @param adminId 要分配的管理员的id
     * @param roleIdList 要分配的角色的id集合
     */
    void saveRelationship(Integer adminId, List<Integer> roleIdList);

AdminServiceImpl 

    /**
     * 将roleIdList中对应的角色分配给adminId对应的管理员
     * @param adminId 要分配的管理员的id
     * @param roleIdList 要分配的角色的id集合
     */
    @Override
    public void saveRelationship(Integer adminId, List<Integer> roleIdList) {
        // 删除adminId的旧数据
        adminMapper.deleteRelationship(adminId);

        // 根据adminId和roleList保存新的关联关系
        if(roleIdList != null && roleIdList.size() > 0){
            adminMapper.insertNewRelationship(adminId, roleIdList);
        }
    }

AdminMapper.java

    /**
     * 删除adminId的角色信息
     * @param adminId
     */
    void deleteRelationship(Integer adminId);

    /**
     * 将roleIdList角色信息和adminId关联保存到数据库
     * @param adminId
     * @param roleIdList
     */
    void insertNewRelationship(@Param("adminId") int adminId, @Param("roleIdList") List<Integer> roleIdList);

AdminMapper.xml

  <delete id="deleteRelationship">
    delete from inner_admin_role where admin_id = #{adminId}
  </delete>

  <insert id="insertNewRelationship">
    insert into inner_admin_role(admin_id, role_id) values
    <foreach collection="roleIdList" item="roleId" separator=",">
      (#{adminId}, #{roleId})
    </foreach>
  </insert>

2.3.9、给保存按钮绑定单击事件,使点击时选中所有要分配列表的option

此时,当点击保存时,程序只保存已分配角色列表选中的角色,而不是所有角色 

① 给保存按钮设定 id 属性

<button id="submitBtn" style="width:100px;margin:20px 100px" type="submit" class="btn btn-sm btn-success btn-block">
	保存
</button>

② 给保存按钮绑定单击事件

        // 给保存按钮绑定单击事件
        $("#submitBtn").click(function (){
            // 使要分配的列表的所有option选中
            $("select:eq(1)>option").prop("selected", "selected");
            // return false;
        });

3、给 Role 分配 Auth

3.1、思路

3.2、代码

3.2.1、创建权限表 t_auth

创建表

CREATE TABLE `t_auth` (
	`id` INT(11) NOT NULL AUTO_INCREMENT, 
	`name` VARCHAR(200) DEFAULT NULL, 
	`title` VARCHAR(200) DEFAULT NULL,
	`category_id` INT(11) DEFAULT NULL, PRIMARY KEY (`id`)
);

表属性解释:

  • name 字段:给资源分配权限或给角色分配权限时使用的具体值,将来做权限验证也是使用 name 字段的值来进行比对。建议使用英文。name 字段中值的格式中间的“:”没有任何特殊含义。不论是我们自己写的代码还是将来使用的框架都不会解析“:”。如果不用“:”,用“%、@、&、*、-”等等这样的符号也都是可以的。

  • title 字段:在页面上显示,让用户便于查看的值。建议使用中文。

  • category_id 字段:关联到当前权限所属的分类。这个关联不是到其他表关联,而是就在当前表内部进行关联,关联其他记录。所以说,t_auth 表中是依靠 category_id 字段建立了“节点”之间的父子关系。

插入数据

INSERT INTO t_auth(id,`name`,title,category_id) VALUES(1,'','用户模块',NULL);
INSERT INTO t_auth(id,`name`,title,category_id) VALUES(2,'user:delete','删除',1);
INSERT INTO t_auth(id,`name`,title,category_id) VALUES(3,'user:get','查询',1);
INSERT INTO t_auth(id,`name`,title,category_id) VALUES(4,'','角色模块',NULL);
INSERT INTO t_auth(id,`name`,title,category_id) VALUES(5,'role:delete','删除',4);
INSERT INTO t_auth(id,`name`,title,category_id) VALUES(6,'role:get','查询',4);
INSERT INTO t_auth(id,`name`,title,category_id) VALUES(7,'role:add','新增',4);

3.2.2、逆向工程:生成权限相关资源

① 修改逆向工程的配置文件:atcrowdfunding06-common-reverse 模块的 generatorConfig.xml

<table tableName="t_auth" domainObjectName="Auth" />

② 执行 maven 指令

③ 给 Auth 类添加无参构造器、有参构造器 

④ 将生成的资源归位

3.2.3、创建获取所有权限的 方法

AuthService

public interface AuthService {
    /**
     * 获取所有权限
     * @return
     */
    List<Auth> getAll();
}

AuthServiceImpl

@Service
public class AuthServiceImpl implements AuthService {

    @Autowired
    private AuthMapper authMapper;

    /**
     * 获取所有权限
     * @return
     */
    @Override
    public List<Auth> getAll() {
        authMapper.selectByExample(new AuthExample());
        return null;
    }
}

AssignHandle

    /**
     * 获取所有权限
     * @return
     */
    @ResponseBody
    @RequestMapping("/assign/get/all/auth.json")
    public ResultEntity<List<Auth>> getAllAuth(){
        List<Auth> authList = authService.getAll();
        return ResultEntity.successWithData(authList);
    }

3.2.4、打开分配权限的模态框并显示 auth 树形结构

① 准备模态框页面,位置:atcrowdfunding01-admin-parent\atcrowdfunding02-admin-webui\src\main\webapp\WEB-INF\modal-role-assign-auth.jsp 

② 在 role-page.jsp 引入模态框页面

<%@include file="/WEB-INF/modal-role-assign-auth.jsp"%> 

③ 修改打开模态框的按钮

my-role.js 的 fillTableBody 函数

添加 id 属性和 class 属性 

var checkBtn = "<button id='" + roleId + "' type='button' class='btn btn-success btn-xs checkBtn'><i class=' glyphicon glyphicon-check'></i></button>";

④ 引入 zTree,注意放在引入 my-role.js 的前面

role-page.jsp

<%-- 引入zTree环境 --%>
<link rel="stylesheet" href="ztree/zTreeStyle.css">
<script type="text/javascript" src="ztree/jquery.ztree.all-3.5.min.js"></script>

⑤ 定义专门用来生成 auth 树形结构的函数

my-role.js 

// 专门用来在分配auth的模态框中显示Auth的树形结构的函数
function fillAuthThree(){
    // 发送Ajax请求查询Auth数据
    var ajaxReturn = $.ajax({
        "url" : "assign/get/all/auth.json",
        "type" : "post",
        "dataType" : "json",
        "async" : false, // 设置同步
    });

    if(ajaxReturn.status != 200){
        layer.msg("请求处理出错!响应状态码:" + ajaxReturn.status + " 说明:" + ajaxReturn.statusText);
        return;
    }

    // 从响应结果获取auth的JSON数据
    var authList = ajaxReturn.responseJSON.data;

    // 准备对zTree进行设置的JSON对象
    var setting = {
        "data":{
            "simpleData":{
                // 开启简单JSON生成树功能
                "enable":true,
                //
                "pIdKey" : "categoryId"
            },
            "key" : {
                // 使用title属性显示节点名称,不用默认的name值作为属性名
                "name" : "title"
            }
        },
        "check":{
            "enable" : true // 在图标前显示复选框
        }
    };

    // 生成树形结构
    $.fn.zTree.init($("#authTreeDemo"), setting, authList);

    // 获取zTreeObj对象
    var zTreeObj = $.fn.zTree.getZTreeObj("authTreeDemo");

    // 调用zTreeObj对象方法,把节点展开
    zTreeObj.expandAll(true);

    // 查询已分配的auth的id组成的List
    ajaxReturn = $.ajax({
        "url" : "assign/get/assigned/auth/id/by/role/id.json",
        "type" : "post",
        "data" : {
            "roleId" : window.roleId
        },
        "dataType":"json",
        "async" : false
    });
    if(ajaxReturn.status != 200){
        layer.msg("服务器端成勋调用失败!响应状态码是" + statusCode + "说明信息:" + ajaxResult.statusText);
        return null;
    }

    // 从响应结果获取authIdArray
    var authIdArray = ajaxReturn.responseJSON.data;
    // console.log(authIdArray);

    // 根据authIdArray把树形结构中对应的节点勾选上
    for(var i = 0; i < authIdArray.length; i++){
        var authId = authIdArray[i];

        // 根据id查询树形结构中对应的节点
        var treeNode = zTreeObj.getNodeByParam("id", authId);

        // 将对应的treeNode设置为被勾选
        var checked = true; // 选中状态
        var checkTypeFlag = false; // 是否与父节点的勾选状态进行联动(类似全选)
        zTreeObj.checkNode(treeNode, checked, checkTypeFlag);
    }
}

④ 给打开分配权限模态框的按钮绑定单击事件

role-page.jsp

        // 给分配权限按钮绑定单击事件
        $("#rolePageBody").on("click", ".checkBtn", function (){
            // 把当前角色id存入全局变量
            window.roleId = this.id;

            // 打开模态框
            $("#assignModal").modal("show");

            // 在模态框中装载Auth的树形结构
            fillAuthThree();
        });

3.2.5、创建角色与权限之间关联关系的中间表

CREATE TABLE `project_crowd`.`inner_role_auth`( 
	`id` INT NOT NULL AUTO_INCREMENT, 
	`role_id` INT, 
	`auth_id` INT, 
	PRIMARY KEY (`id`) 
); 

3.2.6、根据 role_id 查询 auth_id

① 在 AuthMapper.xml 创建 SQL 语句

  <!-- 根据roleId查询已分配的权限 -->
  <select id="selectAssignedAuthIdBtRoleId" resultType="int">
    select auth_id from inner_role_auth where role_id = #{roleId}
  </select>

② AuthMapper

    /**
     * 根据roleId查询已分配的权限
     * @param roleId
     * @return
     */
    List<Integer> selectAssignedAuthIdBtRoleId(Integer roleId);

③ AuthService

    /**
     * 根据roleId查询已分配的权限
     * @param roleId
     * @return
     */
    List<Integer> getAssignedAuthIdBtRoleId(Integer roleId);

④ AuthServiceImpl

    /**
     * 根据roleId查询已分配的权限
     * @param roleId
     * @return
     */
    @Override
    public List<Integer> getAssignedAuthIdBtRoleId(Integer roleId) {
        return authMapper.selectAssignedAuthIdBtRoleId(roleId);
    }

3.2.7、执行分配

① 给分配按钮绑定单击事件

role-page.jsp

        // 给分配权限的按钮绑定单击事件,保存修改结果
        $("#assignBtn").click(function (){
            // 收集树形结构被勾选的节点
            var authIdArray = [];
            var zTreeObj = $.fn.zTree.getZTreeObj("authTreeDemo"); // 获取zTreeObj对象
            var checkedNodes = zTreeObj.getCheckedNodes(true); // 获取被勾选的节点
            for(var i = 0; i < checkedNodes.length; i++){
                var chenkedNode = checkedNodes[i];
                var authId = chenkedNode.id;
                authIdArray.push(authId);
            }
            //alert(authIdArray);

            // 发送请求执行分配
            var requestBody = {
                "authIdArray":authIdArray,
                // 为了方便后端handle方法使用List<Integer>方式接收参数,roleId也存入数组
                "roleId":[window.roleId]
            }

            requestBody = JSON.stringify(requestBody);

            $.ajax({
                "url":"assign/do/role/assign/auth.json",
                "type":"post",
                "data":requestBody,
                "contentType":"application/json;charset=UTF-8",
                "dataType":"json",
                "success":function (response){
                    var result = response.result;
                    if(result == "SUCCESS"){
                        layer.msg("操作成功!");
                    }
                    if(result == "FAILED"){
                        layer.msg("操作失败!" + " " + response.statusText);
                    }
                },
                "error":function (response){
                    layer.msg(response.status + " " +response.statusText)
                }
            });

            // 关闭模态框
            $("#assignModal").modal("hide");
        });

② 执行分配的service层代码

AuthHandle

    /**
     * 修改roleId的权限
     * @param map
     * @return
     */
    @ResponseBody
    @RequestMapping("/assign/do/role/assign/auth.json")
    public ResultEntity<String> saveRoleAuthRelationship(@RequestBody Map<String, List<Integer>> map){
        authService.saveRoleAuthRelationship(map);
        return ResultEntity.successWithoutData();
    }

AuthService

    /**
     * 修改角色与权限的关系
     * @param map
     */
    void saveRoleAuthRelationship(Map<String, List<Integer>> map);

AuthServiceImpl

    /**
     * 修改角色与权限的关系
     * @param map
     */
    @Override
    public void saveRoleAuthRelationship(Map<String, List<Integer>> map) {
        // 获取roleId
        List<Integer> roleIdList = map.get("roleId");
        Integer roleId = roleIdList.get(0);

        // 删除旧关联关系
        authMapper.deleteOleRelationship(roleId);

        // 获取authIdList
        List<Integer> authIdList = map.get("authIdArray");

        // 判断authIdList是否有效
        if(authIdList != null && authIdList.size() > 0){
            authMapper.insertNewRelationship(roleId, authIdList);
        }
    }

AuthMapper

    /**
     * 删除roleId的权限关系
     * @param roleId
     */
    void deleteOleRelationship(Integer roleId);

    /**
     * 为roleId添加权限关系
     * @param roleId
     * @param authIdList
     */
    void insertNewRelationship(@Param("roleId") Integer roleId, @Param("authIdList") List<Integer> authIdList);

AuthMapper.xml

  <!-- 删除roleId的权限关系 -->
  <delete id="deleteOleRelationship">
    delete from inner_role_auth where role_id = #{roleId}
  </delete>

  <!-- 为roleId添加权限关系 -->
  <insert id="insertNewRelationship">
    insert into inner_role_auth(auth_id, role_id) values
    <foreach collection="authIdList" item="authId" separator=",">
      (#{authId}, #{roleId})
    </foreach>
  </insert>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值