由于尚硅谷的视频是通过Eclipse软件来做的,其中有些操作与IDEA上有所区别,所以我在这里将IDEA区别于Eclipse的操作、操作过程中涉及的源码(与视频的源码略有出入)以及大家可能遇到的种种问题分享给大家,这些源码在我这里均是通过测试的,仅供参考!
1 @RestController注解
修改component\src\main\java\com\atguigu\crowd\mvc\handler\MenuHandler.java
@RestController
public class MenuHandler {...}
并注释掉所有@ResponseBody注解
同理AdminHandler与RoleHandler也可以做上述修改,并不必须修改,目的为了简洁
2 进入分配页面
2.1 后端部分
在SQLyog中配置inner_admin_role数据库表:
DROP TABLE IF EXISTS inner_admin_role;
CREATE TABLE `inner_admin_role` (
id INT NOT NULL AUTO_INCREMENT,
admin_id INT,
role_id INT,
PRIMARY KEY (id)
);
新建component\src\main\java\com\atguigu\crowd\mvc\handler\AssignHandler.java
package com.atguigu.crowd.mvc.handler;
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;
@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.存入模型
modelMap.addAttribute("assignedRoleList", assignedRoleList);
modelMap.addAttribute("unAssignedRoleList", unAssignedRoleList);
return "assign-role";
}
}
并新增getAssignedRole()与getUnAssignedRole()方法及实现类:
修改component\src\main\java\com\atguigu\crowd\service\impl\RoleServiceImpl.java
@Override
public List<Role> getAssignedRole(Integer adminId) {
return roleMapper.selectAssignedRole(adminId);
}
@Override
public List<Role> getUnAssignedRole(Integer adminId) {
return roleMapper.selectUnAssignedRole(adminId);
}
并新增getAssignedRole()与getUnAssignedRole()方法:
修改webui\src\main\resources\mybatis\mapper\RoleMapper.xml
<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.2 前端部分
分配按钮功能:修改webui\src\main\webapp\WEB-INF\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>
新建webui\src\main\webapp\WEB-INF\assign-role.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html lang="zh-CN">
<%@include file="include-head.jsp" %>
<script>
$(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(1)>option:selected").appendTo("select:eq(0)");
});
})
</script>
<body>
<%@include file="include-nav.jsp" %>
<div class="container-fluid">
<div class="row">
<%@include file="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>未分配角色列表</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 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>已分配角色列表</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>
<br/><br><br>
<button type="submit" style="width: 150px;" class="btn btn-lg btn-success btn-block">提交</button>
</form>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
2.3 测试
3 Admin分配Role
3.1 后端部分
修改component\src\main\java\com\atguigu\crowd\mvc\handler\AssignHandler.java
@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;
}
并新增saveAdminRoleRelationship()方法及实现类:
修改component\src\main\java\com\atguigu\crowd\service\impl\AdminServiceImpl.java
@Override
public void saveAdminRoleRelationship(Integer adminId, List<Integer> roleIdList) {
// 1. 根据adminId删除旧的关联关系数据
adminMapper.deleteOldRelationship(adminId);
// 2.根据roleIdList和adminId保存新的关联关系
if (roleIdList != null && roleIdList.size()>0) {
adminMapper.insertNewRelationship(adminId, roleIdList);
}
}
并新增deleteOldRelationship()与insertNewRelationship()方法:
修改webui\src\main\resources\mybatis\mapper\AdminMapper.xml
<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.2 前端部分
修改webui\src\main\webapp\WEB-INF\assign-role.jsp
$("#submitBtn").click(function () {
$("select:eq(1)>option").prop("selected","selected");
// 为了看到上面代码的效果, 暂时不让表单提交
// return false;
});
提交按钮功能:
<button id="submitBtn" type="submit" style="width: 150px;" class="btn btn-lg btn-success btn-block">提交</button>
4 Role分配Auth
4.1 配置数据库表
在SQLyog中配置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`)
);
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);
4.2 mybatis逆向工程
修改reverse\src\main\resources\generatorConfig.xml
<table tableName="t_auth" domainObjectName="Auth" />
在IDEA右侧的maven project找到mybatis-generator:generate并点击运行,生成文件
修改reverse\src\main\java\com\atguigu\crowd\entity\Auth.java
public Auth() {
}
public Auth(Integer id, String name, String title, Integer categoryId) {
this.id = id;
this.name = name;
this.title = title;
this.categoryId = categoryId;
}
@Override
public String toString() {
return "Auth{" +
"id=" + id +
", name='" + name + '\'' +
", title='" + title + '\'' +
", categoryId=" + categoryId +
'}';
}
将Auth.java与AuthExample.java放入entity\src\main\java\com\atguigu\crowd\entity中
将AuthMapper.java放入component\src\main\java\com\atguigu\crowd\mapper中
将AuthMapper.xml放入webui\src\main\resources\mybatis\mapper中
4.3 新建后端文件
新建component\src\main\java\com\atguigu\crowd\service\api\AuthService.java
新建component\src\main\java\com\atguigu\crowd\service\impl\AuthServiceImpl.java
修改component\src\main\java\com\atguigu\crowd\mvc\handler\AssignHandler.java
@Autowired
private AuthService authService;
4.4 显示树
4.4.1 前端部分
check按钮功能赋予:修改webui\src\main\webapp\crowd\my-role.js
var checkBtn = "<button id='" + roleId + "' type=\"button\" class=\"btn btn-success btn-xs checkBtn\"><i class=\" glyphicon glyphicon-check\"></i></button>";
新建webui\src\main\webapp\WEB-INF\modal-role-assign-auth.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<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>
修改webui\src\main\webapp\WEB-INF\role-page.jsp
<link rel="stylesheet" href="ztree/zTreeStyle.css">
<script type="text/javascript" src="ztree/jquery.ztree.all-3.5.min.js"></script>
// 13.给分配权限按钮绑定单击响应函数
$("#rolePageBody").on("click", ".checkBtn", function() {
window.roleId = this.id;
// 打开模态框
$("#assignModal").modal("show");
// 在模态框中装载Auth的树形结构数据
fillAuthTree();
});
<%@include file="/WEB-INF/modal-role-assign-auth.jsp"%>
修改webui\src\main\webapp\crowd\my-role.js
// 声明专门的函数用来在分配Auth的模态框中显示Auth的树形结构数据
function fillAuthTree(){
// 1.发送 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 ;
}
// 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.生成树形结构
$.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);
}
}
4.4.2 后端部分
修改component\src\main\java\com\atguigu\crowd\mvc\handler\AssignHandler.java
@ResponseBody
@RequestMapping("/assign/get/all/auth.json")
public ResultEntity<List<Auth>> getAllAuth() {
List<Auth> authList = authService.getAll();
return ResultEntity.successWithData(authList);
}
并新增getAll()方法及实现类:
修改component\src\main\java\com\atguigu\crowd\service\impl\AuthServiceImpl.java
@Override
public List<Auth> getAll() {
return authMapper.selectByExample(new AuthExample());
}
4.4.3 测试
如果无弹窗,可能是js文件在浏览器中无更新导致:Ctrl+F5强制刷新浏览器即可
4.5 勾选并执行分配
4.5.1 配置数据库表
在SQLyog中配置inner_role_auth数据库表:
DROP TABLE IF EXISTS inner_role_auth;
CREATE TABLE inner_role_auth
(
id INT AUTO_INCREMENT,
role_id INT NULL ,
auth_id INT NULL ,
PRIMARY KEY (id)
);
4.5.2 后端部分
修改component\src\main\java\com\atguigu\crowd\mvc\handler\AssignHandler.java
@ResponseBody
@RequestMapping("/assign/get/assigned/auth/id/by/role/id.json")
public ResultEntity<List<Integer>> getAssignAuthIdByRoleId(@RequestParam("roleId") Integer roleId) {
List<Integer> authIdList = authService.getAssignedAuthIdByRoleId(roleId);
return ResultEntity.successWithData(authIdList);
}
@ResponseBody
@RequestMapping("/assign/do/role/assign/auth.json")
public ResultEntity<String> saveRoleAuthRelathinship(@RequestBody Map<String, List<Integer>> map) {
authService.saveRoleAuthRelationship(map);
return ResultEntity.successWithoutData();
}
并新增getAssignedAuthIdByRoleId()与saveRoleAuthRelationship()方法及实现类:
修改component\src\main\java\com\atguigu\crowd\service\impl\AuthServiceImpl.java
@Override
public List<Integer> getAssignedAuthIdByRoleId(Integer roleId) {
return authMapper.selectAssignedAuthIdByRoleId(roleId);
}
@Override
public void saveRoleAuthRelationship(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);
}
}
并新增selectAssignedAuthIdByRoleId()、deleteOldRelationship()、insertNewRelationship()方法:
生成接口后,再修改component\src\main\java\com\atguigu\crowd\mapper\AuthMapper.java
void deleteOldRelationship(Integer roleId);
void insertNewRelationship(@Param("roleId") Integer roleId, @Param("authIdList") List<Integer> authIdList);
修改webui\src\main\resources\mybatis\mapper\AuthMapper.xml
<select id="selectAssignedAuthIdByRoleId" resultType="int">
select auth_id from inner_role_auth where role_id=#{roleId}
</select>
<delete id="deleteOldRelationship">
delete from inner_role_auth where role_id=#{roleId}
</delete>
<insert id="insertNewRelationship">
insert into inner_role_auth(role_id, auth_id) VALUES
<foreach collection="authIdList" item="authId" separator=",">(#{roleId}, #{authId})</foreach>
</insert>
4.5.3 前端部分
修改webui\src\main\webapp\WEB-INF\role-page.jsp
// 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");
});
4.5.4 测试