目录

  • 1. 权限控制
  • 2. 给 Admin 分配 Role
    • 2.1 目标
    • 2.2 思路
    • 2.3 代码:前往分配页面
      • 2.3.1 创建保存 Admin-Role 关联关系的数据库表
      • 2.3.2 修改“分配”按钮
      • 2.3.3 创建 AssignHandler
      • 2.3.4 RoleService 中的方法
      • 2.3.5 SQL 语句
      • 2.3.6 在页面上显示角色数据
      • 2.3.7 调整表单让表单能够提交数据
      • 2.3.8 jQuery 代码
    • 2.4 代码:执行分配
      • 2.4.1 handler 方法
      • 2.4.2 Service 方法
      • 2.4.3 SQL 语句
      • 2.4.4 修正 Bug
  • 3. 给 Role 分配 Auth
    • 3.1 目标
    • 3.2 思路
    • 3.3 代码:t_auth 建表
      • 3.3.1 建表
    • 3.4 代码:打开模态框
      • 3.4.1 准备模态框
      • 3.4.2 给“✔”按钮绑定单击响应函数
      • 3.4.3 加入 zTree 的环境
      • 3.4.4 显示不正常分析
      • 3.4.5 函数 fillAuthTree()
      • 3.4.6 创建角色到权限之间关联关系的中间表
      • 3.4.7 根据 role_id 查询 auth_id
    • 3.5 代码:执行分配
      • 3.5.1 给“分配”按钮绑定单击响应函数
      • 3.5.2 后端执行分配,保存关联关系
  • 4. 给 Menu 分配 Auth

1. 权限控制

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

2. 给 Admin 分配 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 修改“分配”按钮

<%--<button type="button" class="btn btn-success btn-xs"><i class=" glyphicon glyphicon-check"></i></button>--%><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.3 创建 AssignHandler

@Controller
public class AssignHandler {@Autowiredprivate AdminService adminService;@Autowiredprivate RoleService roleService;@Autowiredprivate AuthService authService;@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 RoleService 中的方法

@Overridepublic List<Role> getUnAssignedRole(Integer adminId) {return roleMapper.selectUnAssignedRole(adminId);}

2.3.5 SQL 语句

<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.3.6 在页面上显示角色数据


对 option 标签进行说明:

<option value="将来在提交表单时一起发送给 handler 的值">在浏览器上让用户看到的数据</option>

实际显示角色信息时:

<option value="角色的 id">角色的名称</option>

举例:

<option value="5">市场部经理</option>

页面具体代码:

                     <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>

2.3.7 调整表单让表单能够提交数据

参考下面文件:

2.3.8 jQuery 代码

2.4 代码:执行分配

$(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)");});});

2.4.1 handler 方法

@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.4.2 Service 方法

 @Overridepublic 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.4.3 SQL 语句


<delete id="deleteOLdRelationship">delete from inner_admin_role where admin_id=#{admin}</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.4.4 修正 Bug


$("#submitBtn").click(function () {// z爱提交表单前把"已分配"部分的option全部选中$("select:eq(1)>option").prop("selected","selected");/*// 为了看到上面代码的效果,暂时不让表单提交return false;*/});

3. 给 Role 分配 Auth

3.1 目标

把角色和权限的关联关系保存到数据库。

3.2 思路


3.3 代码: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)

name 字段:给资源分配权限或给角色分配权限时使用的具体值,将来做权限验证
也是使用 name 字段的值来进行比对。建议使用英文。
title 字段:在页面上显示,让用户便于查看的值。建议使用中文。
category_id 字段:关联到当前权限所属的分类。这个关联不是到其他表关联,而是
就在当前表内部进行关联,关联其他记录。所以说,t_auth 表中是依靠 category_id 字
段建立了“节点”之间的父子关系。

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

3.3.1 建表




+有(空)参+toString
归位

3.4 代码:打开模态框

3.4.1 准备模态框

<%@ 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">&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>

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

3.4.2 给“✔”按钮绑定单击响应函数

在 fillTableBody()函数中,修改 checkBtn

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

// 13.给分配权限按钮绑定单击响应函数$("#rolePageBody").on("click",".checkBtn",function () {// 把当前角色id存入全局变量window.roleId = this.id;// 打开模态框$("#assignModal").modal("show");// 在模态框中装载树 Auth 的形结构数据fillAuthTree();});

3.4.3 加入 zTree 的环境


注意:引入的时候 zTree 的 JavaScript 库文件要放在 my-role.js 的前面

3.4.4 显示不正常分析

3.4.5 函数 fillAuthTree()

// 声明专门的函数用来在分配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.生成树形结构$.fn.zTree.init($("#authTreeDemo"),setting,authList);// 获取zTreeObj对象var zTreeObj = $.fn.zTree.getZTreeObj("authTreeDemo");// 调用zTreeObj对象的方法,把节点展开zTreeObj.expandAll(true);// 5.查询已分配的Auth的id组成的ListajaxReturn = $.ajax({"url": "assign/get/assigned/auth/id/bu/role/id.json","type": "post","data":{"roleId": window.roleId},"dataType":"json","async": false});if (ajaxReturn.status != 200){layer.msg("请求处理出错!响应状态码是:"+ajaxReturn.status+"说明是:"+ajaxReturn.statusText);return ;}// 从响应结果中获取authIdArrayvar authIdArray = ajaxReturn.responseJSON.data;// 6.根据authIdArray把树形结构中对应的节点勾选上// 6.1 遍历authIdArrayfor (var i = 0; i < authIdArray.length ; i++) {var authId = authIdArray[i];// 6.2 根据id查询树形结构中对应的节点var treeNode =zTreeObj.getNodeByParam("id", authId);// 6.3 将treeNode设置位被勾选// checked设置为true表示节点勾选var checked = true;// checkTypeFlag设置为false,表示不"联动",不联动是为了避免把不该勾选的勾选上var checkTypeFlag = false;// 执行zTreeObj.checkNode(treeNode, checked, checkTypeFlag);}}

3.4.6 创建角色到权限之间关联关系的中间表

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

3.4.7 根据 role_id 查询 auth_id

@ResponseBody@RequestMapping("/assign/get/assigned/auth/id/bu/role/id.json")public ResultEntity<List<Integer>> getAssignedAuthIdByRoleId(@RequestParam("roleId") Integer roleId){List<Integer> authIdList = authService.getAssignedAuthIdByRoleId(roleId);return ResultEntity.successWithData(authIdList);}

@Service
public class AuthServiceImpl implements AuthService {@Autowiredprivate AuthMapper authMapper;@Overridepublic List<Auth> getAll() {return authMapper.selectByExample(new AuthExample());}@Overridepublic List<Integer> getAssignedAuthIdByRoleId(Integer roleId) {return authMapper.selectAssignedAuthIdByRoleId(roleId);}
}

<select id="selectAssignedAuthIdByRoleId" resultType="int">select auth_id from inner_role_auth where role_id=#{roleId}</select>


3.5 代码:执行分配

3.5.1 给“分配”按钮绑定单击响应函数

  // 14.给分配全选模态框中的“分配”按钮绑定单击响应函数$("#assignBtn").click(function () {// 14.1 收集树形结构的各个几点中被勾选的节点// [1]声明一个专门的数组存放idvar authIdArray = [];// [2]获取zTreeObj对象var zTreeObj = $.fn.zTree.getZTreeObj("authTreeDemo");// [3]获取全部被勾选的节点var checkedNodes = zTreeObj.getCheckedNodes();// [4]遍历checkedNodesfor (var i = 0; i < checkedNodes.length; i++) {var checkedNode = checkedNodes[i];var authId = checkedNode.id;authIdArray.push(authId);}// 14.2发送请求执行分配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.2 后端执行分配,保存关联关系

@ResponseBody@RequestMapping("/assign/do/role/assign/auth.json")public ResultEntity<String> saveRoleAuthRelathinship(@RequestBody Map<String, List<Integer>> map){authService.saveRoleAuthRelathinship(map);return ResultEntity.successWithoutData();}

@Overridepublic void saveRoleAuthRelathinship(Map<String, List<Integer>> map) {// 1.获取roleId的值List<Integer> roleIdList = map.get("roleId");Integer roleId = roleIdList.get(0);// 2.删除旧的关联关系数据authMapper.deleteOldRelathinship(roleId);// 3.获取authIdListList<Integer> authIdList = map.get("authIdArray");// 4.判断authIdList是否有效if (authIdList != null && authIdList.size() > 0){authMapper.insertNewRelathinship(roleId, authIdList);}}


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

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


4. 给 Menu 分配 Auth

众筹项目之后台管理系统-分配(八)相关推荐

  1. 众筹项目之后台管理系统-权限控制(九)

    目录 1. 项目中加入 SpringSecurity 1.1 加入 SpringSecurity 环境 2.1.1 依赖 1.1.2 在 web.xml 中配置 DelegatingFilterPro ...

  2. vue尚品汇商城项目-day00【项目介绍:此项目是基于vue2的前台电商项目和后台管理系统】

    文章目录 本人其他相关文章链接 项目介绍:此项目是基于vue2的前台电商项目和后台管理系统 此项目为在线电商Web App (SPA) 包括首页, 搜索列表, 商品详情, 购物车, 订单, 支付, 用 ...

  3. SSM项目-商城后台管理系统

    SSM项目-商城后台管理系统 开发说明 开发环境 项目界面演示 项目功能 具体的技术指标 开发过程 1.搭建SSM框架 1.1.建库建表 1.2.新建Maven工程 1.3.配置pom.xml 1.4 ...

  4. [ABP项目实战]-后台管理系统-目录

    学习ABP也有一段时间了,但是总是学习了后面的忘记了前面的,为了巩固所学到的知识以及记录所学到的东西,因此有了本系列的诞生. ABP ASP.NET Boilerplate Project(ABP.N ...

  5. Vue项目实战 —— 后台管理系统( pc端 ) 第三篇

    ​前期回顾    ​  Vue项目实战 -- 后台管理系统( pc端 ) 第二篇_0.活在风浪里的博客-CSDN博客前期回顾 Vue项目实战 -- 后台管理系统( pc端 ) 第一篇 _0.活在风浪里 ...

  6. Vue项目实战 —— 后台管理系统( pc端 ) 第一篇

    前期回顾     我只写注释 -- 让Ai写代码_0.活在风浪里的博客-CSDN博客前期回顾 Vue项目实战 -- 哔哩哔哩移动端开发-- 第二篇_0.活在风浪里的博客-CSDN博客https://b ...

  7. springboot+vue前后端分离项目(后台管理系统)

    学习笔记 学习资源来自于B站UP,up他讲的非常详细,对于熟悉两大框架很有用. 我的作业源代码在文章末尾,欢迎有需要的同学,学习参考使用,内置SQL文件,导入后,开启springboot和vue服务即 ...

  8. Vue项目实战 —— 后台管理系统( pc端 )

    前期回顾 我只写注释 -- 让Ai写代码_的博客-CSDN博客前期回顾 Vue项目实战 -- 哔哩哔哩移动端开发-- 第二篇_的博客-CSDN博客https://blog.csdn.net/m0_57 ...

  9. SSM 项目 --------- 小米商城后台管理系统

    目录 一.项目名称 二.使用技术 三.开发步骤 四.具体实现 1.创建数据库表 2.项目结构 3.配置文件 pom.xml db.properties applicationContext-dao.x ...

最新文章

  1. 加薪方式的真相!你是哪一种?
  2. 几款常用的编辑器介绍,给刚入门学Web前端的人
  3. 剑指offer(21)栈的压入、探出序列
  4. java中this_多学习才能多赚钱之:java中this什么用
  5. SQL常用日期处理函数(转)
  6. ssm框架整合_框架整合战斗压缩粮篇SpringCloud+SpringBoot+SSM
  7. 网页登陆注册(jsp实现)验证码
  8. 「leetcode」654.最大二叉树(详解)
  9. 周立功开发板安装linux,极速搭建周立功IMX283A ARM Linux开发环境(1)
  10. sendto函数深入理解
  11. leaflet 加载海量点位,点击marker 查看详情功能
  12. Lightdm简介和常用配置
  13. 不同手机型号图文预览_使用Adobe Preview 在手机上实时预览设计图
  14. 顶尖文案app_为了让你多读点书,这个APP请来了这些世界顶级“文案”
  15. 2020年煤矿安全监测监控新版试题及煤矿安全监测监控试题及答案
  16. redis实现高并发投票网站
  17. 秦王扫六合,虎视何雄哉
  18. 这应该是我见过最好的机房监控解决方案了!
  19. java数据结构 农夫过河,数据结构农夫过河
  20. 也碰到了刷新后再闪烁的问题

热门文章

  1. Unity切图命名参考
  2. 案例:模拟百度搜索框自动加载内容
  3. java中菜单的数据库_java将数据库中菜单表中内容转化成一个导航树
  4. ubuntu18.04重装R
  5. 国税怎么用计算机代码报税页面,增值税网上申报的详细步骤
  6. 变异系数法之python
  7. 我所了解的王坚院士 以及对云计算起源和未来的思考
  8. java星巴克,星巴克Starbucks 8大最好喝飲料...第一名真的名至實歸!
  9. 【3D视觉】PointNet解析
  10. java eden space_《深入理解Java虚拟机》(六)堆内存使用分析,垃圾收集器 GC 日志解读...