day06【后台】两套分配

day06【后台】两套分配

1、权限控制

权限控制机制的本质就是“用钥匙开锁”

image-20200919191804412

2、给Admin分配Role

2.1、思路

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

image-20200919191842505

2.2、创建数据库中间表

  • 创建管理员与用户的关联表:inner_admin_role

image-20200615175237867

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.3.1、修改按钮超链接
  • admin-page.jsp页面中,修改【分配角色】按钮的超链接,附带上当前页码和关键词,因为等会还需要跳转回此页面

image-20200615180450548

image-20200615180826394

<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=" glyphiconglyphicon-check"></i></a>
2.3.2、创建AssignHandler
  • component工程下创建AssignHandler

image-20200615181123282

2.3.3、Handler代码
  • toAssignRolePage方法中,处理完业务逻辑,转发到assign-role,所以在该方法中无需取出当前页码和关键词,这些参数会随着转发请求被带到下一个页面
@Controller
public class AssignHandler {

	@Autowired
	private AdminService adminService;

	@Autowired
	private RoleService roleService;

	@RequestMapping("/assign/to/assign/role/page.html")
	public String toAssignRolePage(
			@RequestParam("adminId") Integer adminId, 
			ModelMap modelMap
		) {
		// 1.查询已分配角色
		List<Role> assignedRoleList = roleService.getAssignedRole(adminId);
		
		// 2.查询未分配角色
		List<Role> unAssignedRoleList = roleService.getUnAssignedRole(adminId);
		
		// 3.存入模型(本质上其实是: request.setAttribute("attrName",attrValue);
		modelMap.addAttribute("assignedRoleList", assignedRoleList);
		modelMap.addAttribute("unAssignedRoleList", unAssignedRoleList);
		
		return "assign-role";
	}
    
}
2.3.4、Service代码
  • Service层实现Handler层用到的方法
@Override
public List<Role> getAssignedRole(Integer adminId) {

    return roleMapper.selectAssignedRole(adminId);
}

@Override
public List<Role> getUnAssignedRole(Integer adminId) {
    return roleMapper.selectAssignedRole(adminId);
}
2.3.5、Mapper代码
  • Mapper接口中声明Service层中用到的方法
public interface RoleMapper {
   
    // ....
    
	List<Role> selectAssignedRole(Integer adminId);

	List<Role> selectUnAssignedRole(Integer adminId);
}
  • Mapper.xml映射文件中编写SQL
    • selectAssignedRole:根据adminId查询当前Admin已经被分配的角色
    • selectUnAssignedRole:根据adminId查询当前Admin未被分配的角色

image-20200615203059155

<select id="selectAssignedRole" 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="selectUnAssignedRole" 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.4、前端页面

2.4.1、新建角色分配页面
  • WEB-INF文件夹下添加assign-role.jsp页面,用于给管理员分配角色

image-20200615203644563

2.4.2、导入JSTL
  • 在导入assign-role.jsp页面中,导入JSTL
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
2.4.3、遍历生成option
  • 未分配的角色
<select
	class="form-control" multiple="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>
  • 已分配的角色
<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>
2.4.4、调整表单
  • 调整用于提交请求参数的表单
    • 修改提交的地址及提交方式
    • 添加隐藏域用于存储页面上不显示的数据
    • 由于需要获取【已分配角色列表】下拉列表中的值,给它设置一个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="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 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>
	<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 id="submitBtn" type="submit" style="width: 150px;" class="btn btn-lg btn-success btn-block">保存</button>
</form>
2.4.5、左右横跳
  • 思路

image-20200919192253360

  • 左跳右
$("#toRightBtn").click(function(){

    // select是标签选择器
    // :eq(0)表示选择页面上的第一个
    // :eq(1)表示选择页面上的第二个
    // “>”表示选择子元素
    // :selected表示选择“被选中的”option
    // appendTo()能够将jQuery对象追加到指定的位置
    $("select:eq(0)>option:selected").appendTo("select:eq(1)");

});
  • 右跳左
$("#toLeftBtn").click(function(){

    // select是标签选择器
    // :eq(0)表示选择页面上的第一个
    // :eq(1)表示选择页面上的第二个
    // “>”表示选择子元素
    // :selected表示选择“被选中的”option
    // appendTo()能够将jQuery对象追加到指定的位置
    $("select:eq(1)>option:selected").appendTo("select:eq(0)");

});
  • 左右横跳

image-20200615214344877

2.4.6、提交表单
  • 很遗憾,对于select标签来说,只会提交已经选中的选项
  • 为了能提交select标签中所有的选项,在提交表单时,选中select下所有的节点

image-20200919192310368

$("#submitBtn").click(function(){
    // 在提交表单前把“已分配”部分的option全部选中
    $("select:eq(1)>option").prop("selected","selected");

    // 为了看到上面代码的效果,暂时不让表单提交
    // return false;
});
2.4.7、完整代码
  • assign-role.jsp页面的完整代码如下
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html lang="zh-CN">
<%@include file="/WEB-INF/include-head.jsp"%>
<script type="text/javascript">
	$(function(){
		$("#toRightBtn").click(function(){
			
			// select是标签选择器
			// :eq(0)表示选择页面上的第一个
			// :eq(1)表示选择页面上的第二个
			// “>”表示选择子元素
			// :selected表示选择“被选中的”option
			// appendTo()能够将jQuery对象追加到指定的位置
			$("select:eq(0)>option:selected").appendTo("select:eq(1)");
			
		});
		
		$("#toLeftBtn").click(function(){
			
			// select是标签选择器
			// :eq(0)表示选择页面上的第一个
			// :eq(1)表示选择页面上的第二个
			// “>”表示选择子元素
			// :selected表示选择“被选中的”option
			// appendTo()能够将jQuery对象追加到指定的位置
			$("select:eq(1)>option:selected").appendTo("select:eq(0)");
			
		});
		
		$("#submitBtn").click(function(){
			// 在提交表单前把“已分配”部分的option全部选中
			$("select:eq(1)>option").prop("selected","selected");
			
			// 为了看到上面代码的效果,暂时不让表单提交
			// return false;
		});
	});
</script>
<body>

	<%@ include file="/WEB-INF/include-nav.jsp"%>
	<div class="container-fluid">
		<div class="row">
			<%@ include file="/WEB-INF/include-sidebar.jsp"%>
			<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
				<ol class="breadcrumb">
					<li><a href="#">首页</a></li>
					<li><a href="#">数据列表</a></li>
					<li class="active">分配角色</li>
				</ol>
				<div class="panel panel-default">
					<div class="panel-body">
						<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="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 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>
							<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 id="submitBtn" type="submit" style="width: 150px;" class="btn btn-lg btn-success btn-block">保存</button>
						</form>
					</div>
				</div>
			</div>
		</div>
	</div>
</body>
</html>

2.5、后端代码

2.5.1、Handler代码
  • AssignHandler中保存给管理员分配的角色,重定向至分页页面
@RequestMapping("/assign/do/role/assign.html")
public String saveAdminRoleRelationship(
    @RequestParam("adminId") Integer adminId,
    @RequestParam("pageNum") Integer pageNum,
    @RequestParam("keyword") String keyword,
    // 我们允许用户在页面上取消所有已分配角色再提交表单,所以可以不提供roleIdList请求参数
    // 设置required=false表示这个请求参数不是必须的
    @RequestParam(value="roleIdList", required=false) List<Integer> roleIdList
) {
    adminService.saveAdminRoleRelationship(adminId, roleIdList);
    return "redirect:/admin/get/page.html?pageNum="+pageNum+"&keyword="+keyword;
}
2.5.2、Service代码
  • AdminService层实现上述代码
@Override
public void saveAdminRoleRelationship(Integer adminId, List<Integer> roleIdList) {

    // 旧数据如下:
    // adminId	roleId
    // 1		1(要删除)
    // 1		2(要删除)
    // 1		3
    // 1		4
    // 1		5
    // 新数据如下:
    // adminId	roleId
    // 1		3(本来就有)
    // 1		4(本来就有)
    // 1		5(本来就有)
    // 1		6(新)
    // 1		7(新)
    // 为了简化操作:先根据adminId删除旧的数据,再根据roleIdList保存全部新的数据

    // 1.根据adminId删除旧的关联关系数据
    adminMapper.deleteOldRelationship(adminId);

    // 2.根据roleIdList和adminId保存新的关联关系
    if(roleIdList != null && roleIdList.size() > 0) {
        adminMapper.insertNewRelationship(adminId, roleIdList);
    }
}
2.5.3、Mapper代码
  • Mapper接口中声明方法,注意:如果参数超过两个,需要使用@Param注解指定参数名称
public interface AdminMapper {

    //...

	void deleteOldRelationship(Integer adminId);

	void insertNewRelationship(@Param("adminId") Integer adminId, @Param("roleIdList") List<Integer> roleIdList);

}
  • AdminMapper层编写对应的SQL语句
<!-- 删除【admin_id=#{adminId}】的管理员所拥有的角色信息 -->
<delete id="deleteOldRelationship">
    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>

3、给Role分配Auth

3.1、思路

image-20200919192323868

3.2、创建数据库表

3.2.1、创建权限表
  • 执行如下SQL语句,创建权限表,并插入测试数据
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`)
) ;

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);
  • 表结构:自关联表

image-20200615231357912

表字段含义解释

  1. name 字段: 给资源分配权限或给角色分配权限时使用的具体值, 将来做权限验证也是使用 name 字段的值来进行比对。 建议使用英文

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

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

    image-20200919192648559

  4. name 字段中值的格式: 中间的“:” 没有任何特殊含义。 不论是我们自己写的代码还是将来使用的框架都不会解析“:”。 如果不用“:”, 用“%、 @、 &、 *、 -” 等等这样的符号也都是可以的

3.2.2、创建中间表
  • 创建角色与权限的中间表
CREATE TABLE `project_crowd`.`inner_role_auth` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `role_id` INT,
  `auth_id` INT,
  PRIMARY KEY (`id`)
) ;
  • 表结构

image-20200616112603695

3.3、逆向工程

3.3.1、修改逆向工程配置文件
  • 修改generatorConfig.xml逆向工程配置文件,修改表名和实体类名
<table tableName="t_auth" domainObjectName="Auth" />

image-20200615231643805

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
	<!-- mybatis-generator:generate -->
	<context id="atguiguTables" targetRuntime="MyBatis3">
		<commentGenerator>
			<!-- 是否去除自动生成的注释 true:是;false:否 -->
			<property name="suppressAllComments" value="true" />
		</commentGenerator>
		<!--数据库连接的信息: 驱动类、 连接地址、 用户名、 密码 -->
		<jdbcConnection driverClass="com.mysql.jdbc.Driver"
			connectionURL="jdbc:mysql://localhost:3306/project_crowd"
			userId="root" password="101713">
		</jdbcConnection>
		<!-- 默认 false, 把 JDBC DECIMAL 和 NUMERIC 类型解析为 Integer, 为 true 时把 JDBC DECIMAL 
			和 NUMERIC 类型解析为 java.math.BigDecimal -->
		<javaTypeResolver>
			<property name="forceBigDecimals" value="false" />
		</javaTypeResolver>
		<!-- targetProject:生成 Entity 类的路径 -->
		<javaModelGenerator targetProject=".\src\main\java"
			targetPackage="com.atguigu.crowd.entity">
			<!-- enableSubPackages:是否让 schema 作为包的后缀 -->
			<property name="enableSubPackages" value="false" />
			<!-- 从数据库返回的值被清理前后的空格 -->
			<property name="trimStrings" value="true" />
		</javaModelGenerator>
		<!-- targetProject:XxxMapper.xml 映射文件生成的路径 -->
		<sqlMapGenerator targetProject=".\src\main\java"
			targetPackage="com.atguigu.crowd.mapper">
			<!-- enableSubPackages:是否让 schema 作为包的后缀 -->
			<property name="enableSubPackages" value="false" />
		</sqlMapGenerator>
		<!-- targetPackage: Mapper 接口生成的位置 -->
		<javaClientGenerator type="XMLMAPPER"
			targetProject=".\src\main\java"
			targetPackage="com.atguigu.crowd.mapper">
			<!-- enableSubPackages:是否让 schema 作为包的后缀 -->
			<property name="enableSubPackages" value="false" />
		</javaClientGenerator>
		<!-- 数据库表名字和我们的 entity 类对应的映射指定 -->
		<table tableName="t_auth" domainObjectName="Auth" />
	</context>
</generatorConfiguration>
3.3.2、执行Maven命令
  • 执行Maven命令:mybatis-generator:generate

image-20200615231542998

3.3.3、资源归位
  • 将实体类归位至entity工程下

image-20200615232052478

  • Mapper接口归位至component工程下

image-20200615232132989

  • Mapper.xml映射文件归位至webui工程下

image-20200615232158376

3.4、创建组件

  • 创建AuthService组件,

image-20200615232302638

  • 为什么没有创建AuthHandler?因为直接就在AssignHandler中编写业务逻辑啦~

image-20200615181123282

3.5、前段代码

3.5.1、准备模态框
  • WEB-INF文件夹下,添加modal-role-assign-auth.jsp模态框:给角色分配权限时弹框

image-20200616101634549

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<div id="assignModal" class="modal fade" tabindex="-1" role="dialog">
	<div class="modal-dialog" role="document">
		<div class="modal-content">
			<div class="modal-header">
				<button type="button" class="close" data-dismiss="modal"
					aria-label="Close">
					<span aria-hidden="true">&times;</span>
				</button>
				<h4 class="modal-title">尚筹网系统弹窗</h4>
			</div>
			<div class="modal-body">
				<ul id="authTreeDemo" class="ztree"></ul>
			</div>
			<div class="modal-footer">
				<button id="assignBtn" type="button" class="btn btn-primary">好的,我设置好了!执行分配!</button>
			</div>
		</div>
	</div>
</div>
3.5.2、引入模态框
  • modal-role-assign-auth.jsp页面中引入上述模态框

image-20200616102041776

<%@include file="/WEB-INF/modal-role-assign-auth.jsp"%>
3.5.3、引入zTree环境
  • 因为my-role.js中需要用到zTree,而role-page.jsp页面中包含了my-role.js库,所以需要在role-page.jsp页面中添加zTree环境;注意:需要放在my-role.js前面哟

image-20200616104724322

<link rel="stylesheet" href="ztree/zTreeStyle.css"/>
<script type="text/javascript" src="ztree/jquery.ztree.all-3.5.min.js"></script>
3.5.4、按钮属性的调整
  • 给按钮添加idclass属性,这样才能使用jQuery找到它

image-20200616102421129

var checkBtn = "<button id='"+roleId+"' type='button' class='btn btn-success btn-xs checkBtn'><i class=' glyphicon glyphicon-check'></i></button>";
3.5.5、绑定单击响应函数
  • 给分配角色按钮绑定单击响应函数
// 13.给分配权限按钮绑定单击响应函数
$("#rolePageBody").on("click",".checkBtn",function(){

    // 把当前角色id存入全局变量
    window.roleId = this.id;

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

    // 在模态框中装载树Auth的形结构数据
    fillAuthTree();
});
3.5.6、生成权限树形结构
  • fillAuthTree用于发送Ajax请求,生成权限树形结构
    • 发送Ajax请求获取所有的权限信息
    • 生成权限树形结构
    • 查询已经为角色分配的权限信息,选中已经为角色分配的权限(回显)
//声明专门的函数用来在分配Auth的模态框中显示Auth的树形结构数据
function fillAuthTree() {
	
	// 1.发送Ajax请求查询Auth数据
	var ajaxReturn = $.ajax({
		"url":"assgin/get/all/auth.json",
		"type":"post",
		"dataType":"json",
		"async":false
	});
	
	if(ajaxReturn.status != 200) {
		layer.msg("请求处理出错!响应状态码是:"+ajaxReturn.status+" 说明是:"+ajaxReturn.statusText);
		return ;
	}
	
	// 2.从响应结果中获取Auth的JSON数据
	// 从服务器端查询到的list不需要组装成树形结构,这里我们交给zTree去组装
	var authList = ajaxReturn.responseJSON.data;
	
	// 3.准备对zTree进行设置的JSON对象
	var setting = {
		"data": {
			"simpleData": {
				
				// 开启简单JSON功能
				"enable": true,
				
				// 使用categoryId属性关联父节点,不用默认的pId了
				"pIdKey": "categoryId"
			},
			"key": {
				// 使用title属性显示节点名称,不用默认的name作为属性名了
				"name": "title"
			}
		},
		"check": {
			"enable": true
		}
	};
	
	// 4.生成树形结构
	// <ul id="authTreeDemo" class="ztree"></ul>
	$.fn.zTree.init($("#authTreeDemo"), setting, authList);

	// 获取zTreeObj对象
	var zTreeObj = $.fn.zTree.getZTreeObj("authTreeDemo");
	
	// 调用zTreeObj对象的方法,把节点展开
	zTreeObj.expandAll(true);
	
	// 5.查询已分配的Auth的id组成的数组
	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("请求处理出错!响应状态码是:"+ajaxReturn.status+" 说明是:"+ajaxReturn.statusText);
		return ;
	}
	
	// 从响应结果中获取authIdArray
	var authIdArray = ajaxReturn.responseJSON.data;
	
	// 6.根据authIdArray把树形结构中对应的节点勾选上
	// ①遍历authIdArray
	for(var i = 0; i < authIdArray.length; i++) {
		var authId = authIdArray[i];
		
		// ②根据id查询树形结构中对应的节点
		var treeNode = zTreeObj.getNodeByParam("id", authId);
		
		// ③将treeNode设置为被勾选
		
		// checked设置为true表示节点勾选
		var checked = true;
		
		// checkTypeFlag设置为false,表示不“联动”,不联动是为了避免把不该勾选的勾选上
		var checkTypeFlag = false;
		
		// 执行
		zTreeObj.checkNode(treeNode, checked, checkTypeFlag);
	}
	
}
3.5.7、发送权限更新请求
  • 给模态框中的保存按钮绑定单击响应函数:
    • 获取选中的节点,进而获取选中的权限id
    • 通过Ajax发送权限更新请求至后端
    • 显示相应的提示信息,并关闭模态框
// 14.给分配权限模态框中的“分配”按钮绑定单击响应函数
$("#assignBtn").click(function(){

    // ①收集树形结构的各个节点中被勾选的节点
    // [1]声明一个专门的数组存放id
    var authIdArray = [];

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

    // [3]获取全部被勾选的节点
    var checkedNodes = zTreeObj.getCheckedNodes();

    // [4]遍历checkedNodes
    for(var i = 0; i < checkedNodes.length; i++) {
        var checkedNode = checkedNodes[i];

        var authId = checkedNode.id;

        authIdArray.push(authId);
    }

    // ②发送请求执行分配
    var requestBody = {
        "authIdArray":authIdArray,

        // 为了服务器端handler方法能够统一使用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.message);
            }
        },
        "error":function(response) {
            layer.msg(response.status+" "+response.statusText);
        }
    });

    $("#assignModal").modal("hide");
});
3.5.8、浏览器缓存问题
  • Ctrl+F5强制刷新

3.6、后端代码

3.6.1、查询所有权限信息
  • Handler代码:查询所有的权限信息,并通过json返回给浏览器,用于模态框的回显

image-20200615181123282

@ResponseBody
@RequestMapping("/assgin/get/all/auth.json")
public ResultEntity<List<Auth>> getAllAuth() {
    List<Auth> authList = authService.getAll();	
    return ResultEntity.successWithData(authList);
}
  • Service代码:new AuthExample()表示查询数据库表中的所有字段

image-20200615232302638

@Override
public List<Auth> getAll() {
    return authMapper.selectByExample(new AuthExample());
}
3.6.2、查询角色所拥有的权限
  • Handler代码:通过roleId查询当前角色所拥有的权限(权限id

image-20200615181123282

@ResponseBody
@RequestMapping("/assign/get/assigned/auth/id/by/role/id.json")
public ResultEntity<List<Integer>> getAssignedAuthIdByRoleId(
    @RequestParam("roleId") Integer roleId) {	
    List<Integer> authIdList = authService.getAssignedAuthIdByRoleId(roleId);	
    return ResultEntity.successWithData(authIdList);
}
  • Service代码:通过roleId查询当前角色所拥有的权限(权限id

image-20200615232302638

@Override
public List<Integer> getAssignedAuthIdByRoleId(Integer roleId) {
    return authMapper.selectAssignedAuthIdByRoleId(roleId);
}
  • Mapper代码:编写SQL语句从中间表中查询角色所拥有的权限

image-20200615232158376

<select id="selectAssignedAuthIdByRoleId" resultType="int">
    select auth_id from inner_role_auth where role_id=#{roleId}
</select>
3.6.3、保存角色的权限
  • Handler代码:调用AuthService层的方法保存角色所拥有的权限

image-20200615181123282

@ResponseBody
@RequestMapping("/assign/do/role/assign/auth.json")
public ResultEntity<String> saveRoleAuthRelathinship(
    @RequestBody Map<String, List<Integer>> map) {	
    authService.saveRoleAuthRelathinship(map);
    return ResultEntity.successWithoutData();
}
  • Service代码:
    • 先删除旧的关联关系(角色所拥有的权限)
    • 再将角色所拥有的权限保存至数据库表

image-20200615232302638

@Override
public void saveRoleAuthRelathinship(Map<String, List<Integer>> map) {

    // 1.获取roleId的值
    List<Integer> roleIdList = map.get("roleId");
    Integer roleId = roleIdList.get(0);

    // 2.删除旧关联关系数据
    authMapper.deleteOldRelationship(roleId);

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

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

}
  • Mapper代码:在Mapper接口中声明方法,在Mapper.xml中编写SQL语句
// Mapper接口
public interface AuthMapper {

    //...

    // 删除旧的关联关系(角色所拥有的权限)
	void deleteOldRelationship(Integer roleId);

    //保存新的关联关系(角色所拥有的权限)
	void insertNewRelationship(@Param("roleId") Integer roleId, @Param("authIdList") List<Integer> authIdList);

}
<delete id="deleteOldRelationship">
    delete from inner_role_auth where role_id=#{roleId}
</delete>

<insert id="insertNewRelationship">
    insert into inner_role_auth(auth_id,role_id) values
    <foreach collection="authIdList" item="authId" separator=",">(#{authId},#{roleId})</foreach>
</insert>

3.7、测试

  • 乌拉~

image-20200616144244812

4、JavaScript Debug

  • ChromeDebug JavaScript代码

image-20200616145023248

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值