day06【后台】两套分配
1、权限控制
权限控制机制的本质就是“用钥匙开锁”
2、给Admin分配Role
2.1、思路
通过页面操作把 Admin 和 Role 之间的关联关系保存到数据库
2.2、创建数据库中间表
- 创建管理员与用户的关联表:
inner_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.3.1、修改按钮超链接
- 在
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=" glyphiconglyphicon-check"></i></a>
2.3.2、创建AssignHandler
- 在
component
工程下创建AssignHandler
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
未被分配的角色
<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
页面,用于给管理员分配角色
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、左右横跳
- 思路
- 左跳右
$("#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)");
});
- 左右横跳
2.4.6、提交表单
- 很遗憾,对于
select
标签来说,只会提交已经选中的选项 - 为了能提交
select
标签中所有的选项,在提交表单时,选中select
下所有的节点
$("#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、思路
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);
- 表结构:自关联表
表字段含义解释
-
name 字段: 给资源分配权限或给角色分配权限时使用的具体值, 将来做权限验证也是使用 name 字段的值来进行比对。 建议使用英文
-
title 字段: 在页面上显示, 让用户便于查看的值。 建议使用中文
-
category_id 字段: 关联到当前权限所属的分类。 这个关联不是到其他表关联, 而是就在当前表内部进行关联, 关联其他记录。 所以说, t_auth 表中是依靠 category_id 字段建立了“节点” 之间的父子关系
-
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`)
) ;
- 表结构
3.3、逆向工程
3.3.1、修改逆向工程配置文件
- 修改
generatorConfig.xml
逆向工程配置文件,修改表名和实体类名
<table tableName="t_auth" domainObjectName="Auth" />
<?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
3.3.3、资源归位
- 将实体类归位至
entity
工程下
- 将
Mapper
接口归位至component
工程下
- 将
Mapper.xml
映射文件归位至webui
工程下
3.4、创建组件
- 创建
AuthService
组件,
- 为什么没有创建
AuthHandler
?因为直接就在AssignHandler
中编写业务逻辑啦~
3.5、前段代码
3.5.1、准备模态框
- 在
WEB-INF
文件夹下,添加modal-role-assign-auth.jsp
模态框:给角色分配权限时弹框
<%@ 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">×</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
页面中引入上述模态框
<%@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
前面哟
<link rel="stylesheet" href="ztree/zTreeStyle.css"/>
<script type="text/javascript" src="ztree/jquery.ztree.all-3.5.min.js"></script>
3.5.4、按钮属性的调整
- 给按钮添加
id
和class
属性,这样才能使用jQuery
找到它
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
返回给浏览器,用于模态框的回显
@ResponseBody
@RequestMapping("/assgin/get/all/auth.json")
public ResultEntity<List<Auth>> getAllAuth() {
List<Auth> authList = authService.getAll();
return ResultEntity.successWithData(authList);
}
Service
代码:new AuthExample()
表示查询数据库表中的所有字段
@Override
public List<Auth> getAll() {
return authMapper.selectByExample(new AuthExample());
}
3.6.2、查询角色所拥有的权限
Handler
代码:通过roleId
查询当前角色所拥有的权限(权限id
)
@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
)
@Override
public List<Integer> getAssignedAuthIdByRoleId(Integer roleId) {
return authMapper.selectAssignedAuthIdByRoleId(roleId);
}
Mapper
代码:编写SQL
语句从中间表中查询角色所拥有的权限
<select id="selectAssignedAuthIdByRoleId" resultType="int">
select auth_id from inner_role_auth where role_id=#{roleId}
</select>
3.6.3、保存角色的权限
Handler
代码:调用AuthService
层的方法保存角色所拥有的权限
@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
代码:- 先删除旧的关联关系(角色所拥有的权限)
- 再将角色所拥有的权限保存至数据库表
@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、测试
- 乌拉~
4、JavaScript Debug
- 在
Chrome
中Debug JavaScript
代码