使用easyui的tree组件实现给角色快捷分配权限功能
这篇文章主要介绍怎么实现角色权限的快捷分配功能,不需要像大多数项目的授权一样,使用类似穿梭框的组件来授权。
具体实现:通过菜单树的勾选和取消勾选来给角色分配权限,在这之前,需要得到角色的菜单树,角色已有的权限对应树节点的选中状态为true,否则为false。
一、树的格式
首先简单了解一下easyui的tree组件的数据格式
官网截图
树的json数据格式
[{"id":1,"text":"Folder1","iconCls":"icon-save","children":[{"text":"File1","checked":true},{"text":"Books","state":"open","attributes":{"url":"/demo/book/abc","price":100},"children":[{"text":"PhotoShop","checked":true},{"id": 8,"text":"Sub Bookds","state":"closed"}]}]},{"text":"Languages","state":"closed","children":[{"text":"Java"},{"text":"C#"}]}]
二、创建实体类
根据这个格式,创建一个满足tree组件数据格式要求的实体类,其中attributes属性一般是用不到的,扩展了一个pxh字段,用于实现排序(本篇文章用不到)。
package cn.edu.sgu.www.authority.component;import lombok.Data;import java.util.List;/*** easyui树对象* @author heyunlin* @version 1.0*/
/*
树的数据格式每个节点可以包括下列属性:id:节点的 id,它对于加载远程数据很重要。text:要显示的节点文本。state:节点状态,'open' 或 'closed',默认是 'open'。当设置为 'closed' 时,该节点有子节点,并且将从远程站点加载它们。checked:指示节点是否被选中。attributes:给一个节点添加的自定义属性。children:定义了一些子节点的节点数组。
*/
@Data
public class Tree<T> {private String id;/*** 节点名称*/private String text;/*** 树节点的展开状态open/closed*/private String state;/*** 是否被选中*/private boolean checked;/*** 子树*/private List<Tree<T>> children;/*** 自定义属性*/T attributes;/*** 排序号*/private Integer pxh;
}
三、获取角色的菜单树
完成分配角色权限的功能之前,需要根据角色的权限生成一个权限树
第一步:查询所有系统权限;
第二步:根据角色ID查询角色拥有的权限;
第三步:遍历所有系统权限生成菜单树,角色拥有的权限,对应树节点选中状态checked属性设置为true;
因为实际保存的是系统中的子权限,即controller接口的所有方法对应的url地址,如:/user/login。
所以在生成树的时候,需要查询父级权限,把父权限的信息设置到树的根结点上。
package cn.edu.sgu.www.authority.service.impl;import cn.edu.sgu.www.authority.base.Pager;
import cn.edu.sgu.www.authority.component.Tree;
import cn.edu.sgu.www.authority.dto.PermissionTreeDTO;
import cn.edu.sgu.www.authority.entity.Permission;
import cn.edu.sgu.www.authority.entity.RolePermission;
import cn.edu.sgu.www.authority.enums.PermissionType;
import cn.edu.sgu.www.authority.exception.GlobalException;
import cn.edu.sgu.www.authority.mapper.PermissionMapper;
import cn.edu.sgu.www.authority.mapper.RolePermissionMapper;
import cn.edu.sgu.www.authority.pager.RolePermissionPager;
import cn.edu.sgu.www.authority.restful.ResponseCode;
import cn.edu.sgu.www.authority.service.RolePermissionService;
import cn.edu.sgu.www.authority.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.stereotype.Service;import java.util.*;/*** @author heyunlin* @version 1.0*/
@Service
public class RolePermissionServiceImpl implements RolePermissionService {private final PermissionMapper permissionMapper;private final RolePermissionMapper rolePermissionMapper;public RolePermissionServiceImpl(PermissionMapper permissionMapper, RolePermissionMapper rolePermissionMapper) {this.permissionMapper = permissionMapper;this.rolePermissionMapper = rolePermissionMapper;}@Overridepublic List<Tree<Void>> listTree(Integer roleId) {// 查询所有父级权限(权限类型为0),并生成权限ID和权限信息的mapMap<String, Permission> parentMap = new HashMap<>();List<Permission> parentPermissions = permissionMapper.selectByType(PermissionType.FQX.getValue());for (Permission permission : parentPermissions) {parentMap.put(permission.getId(), permission);}// 查询角色的权限List<Permission> permissions = rolePermissionMapper.selectByRoleId(roleId);// 查询全部二级权限(权限类型为1)List<Permission> subPermissions = permissionMapper.selectByType(PermissionType.ZQX.getValue());// 并根据父级权限ID分组存放到map中Map<String, List<Tree<Void>>> listHashMap = new HashMap<>();// 遍历,把查询出来的权限按照parentId存到map中for (Permission permission : subPermissions) {Tree<Void> children = new Tree<>();children.setId(permission.getId());children.setText(permission.getName());children.setChecked(permissions.contains(permission));String parentId = permission.getParentId();if (listHashMap.containsKey(parentId)) {listHashMap.get(parentId).add(children);} else {listHashMap.put(parentId, new ArrayList<>());}}// 构建返回结果对象List<Tree<Void>> trees = new ArrayList<>();// 遍历map,生成菜单树listHashMap.forEach((key, value) -> {Permission parent = parentMap.get(key);Tree<Void> tree = new Tree<>();tree.setState("open");tree.setChildren(value);tree.setId(parent.getId());tree.setText(parent.getName());trees.add(tree);});return trees;}}
四、分配权限功能实现
页面效果图
当我们勾选树的节点左边的复选框时,会把当前节点的ID添加到数组里,创建两个数组分别存放勾选和取消勾选的树的ID,不要求数组元素唯一,因为在后端去重了(List => Set)。
前端页面的js代码如下:当勾选和取消勾选的是非叶子节点,实际添加到数组中的是该节点下所有的叶子结点。点击对话框的【√确定】按钮时,会把数组的数据提交到后台,当没有选中或者取消选中树节点的时候不提交。
let insertIds = [];
let deleteIds = [];$(document).ready(function() {$("#tree").tree({dnd: true,animate: true,checkbox: true,onCheck: function (node, checked) {let children = node.children;// 父节点点击复选框if (children) {if (checked) {for (let i = 0; i < children.length; i++) {insertIds.push(children[i].id);}} else {for (let i = 0; i < children.length; i++) {deleteIds.push(children[i].id);}}} else {if (checked) {insertIds.push(node.id);} else {deleteIds.push(node.id);}}},onContextMenu: function(e, node){e.preventDefault();$("#tree").tree("select", node.target);$("#mm").menu("show", {left: e.pageX,top: e.pageY});}});$("#authorize_dialog").dialog({title: "分配角色权限",closed: true,closable: true,draggable: false,buttons: [{iconCls: "icon-ok",text: "确定",handler: function() {let row = $("#role_list").datalist("getSelected");if (row) {if (insertIds.length > 0 || deleteIds.length > 0) {let data = new FormData();data.append("roleId", row.id);if (insertIds.length > 0) {data.append("insertIds", insertIds);}if (deleteIds.length > 0) {data.append("deleteIds", deleteIds);}ajaxPost("/role_permission/distribute", data, function (res) {insertIds = [];deleteIds = [];showMsg(res.message);$("#tree").tree("reload");}, error);}}$("#authorize_dialog").dialog("close");}}, {iconCls: "icon-cancel",text: "取消",handler: function() {$("#authorize_dialog").dialog("close");}}]});});
好了,这篇文章就分享到这里了,完整代码可通过下方git地址获取,看完之后如果对你有所帮助,不要忘了点赞+收藏哦~
统一权限平台https://gitee.com/he-yunlin/authority.git
相关文章:

使用easyui的tree组件实现给角色快捷分配权限功能
这篇文章主要介绍怎么实现角色权限的快捷分配功能,不需要像大多数项目的授权一样,使用类似穿梭框的组件来授权。 具体实现:通过菜单树的勾选和取消勾选来给角色分配权限,在这之前,需要得到角色的菜单树,角色…...
Postman打不开/黄屏/一直转圈/Windows
环境背景 内网环境Postman-win64-8.11.1-Setup.exe 问题描述 电脑重启后,打开Postman后,出现加载弹窗:Preparing your workspaces…This might take a few minutes; 等待数分钟后,还是没有反应,于是关闭…...

使用SVM模型完成分类任务
SVM,即支持向量机(Support Vector Machine),是一种常见的机器学习算法,用于分类和回归分析。SVM的基本思想是将数据集映射到高维空间中,在该空间中找到一个最优的超平面,将不同类别的数据点分开…...

计算机毕设 深度学习实现行人重识别 - python opencv yolo Reid
文章目录 0 前言1 课题背景2 效果展示3 行人检测4 行人重识别5 其他工具6 最后 0 前言 🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉…...
开发经验分享之:import引入包和@Autowired注入类有什么区别
大家好,我是三叔,很高兴这期又和大家见面了,一个奋斗在互联网的打工人。 import 和 Autowired 想必大家在 Java 开发中使用频率最多的关键字之一了把,这篇博客将解释这两个概念的区别和作用,帮助你更好地理解它们在Ja…...

MySQL和Oracle区别
由于SQL Server不常用,所以这里只针对MySQL数据库和Oracle数据库的区别 (1) 对事务的提交 MySQL默认是自动提交,而Oracle默认不自动提交,需要用户手动提交,需要在写commit;指令或者点击commit按钮 (2) 分页查询 MySQL是直接在SQL…...

QT--day6(人脸识别、图像处理)
人脸识别: /***********************************************************************************头文件****************************************************************************************/#ifndef WIDGET_H #define WIDGET_H#include <QWidget>…...

深度学习:常用优化器Optimizer简介
深度学习:常用优化器Optimizer简介 随机梯度下降SGD带动量的随机梯度下降SGD-MomentumSGDWAdamAdamW 随机梯度下降SGD 梯度下降算法是使权重参数沿着整个训练集的梯度方向下降,但往往深度学习的训练集规模很大,计算整个训练集的梯度需要很大…...
【算法心得】二维dp的状态转移狂练
LCS: LCS变式:使两个字符串变成一样的,删除的和最小 https://leetcode.cn/problems/minimum-ascii-delete-sum-for-two-strings/ 建表 m ∗ n m*n m∗n or ( m 1 ) ∗ ( n 1 ) (m1)*(n1) (m1)∗(n1)? 感觉 ( m 1 ) ∗ ( n …...

JMeter常用内置对象:vars、ctx、prev
在前文 Beanshell Sampler 与 Beanshell 断言 中,初步阐述了JMeter beanshell的使用,接下来归集整理了JMeter beanshell 中常用的内置对象及其使用。 注:示例使用JMeter版本为5.1 1. vars 如 API 文档 所言,这是定义变量的类&a…...

【C++从0到王者】第十四站:list基本使用及其介绍
文章目录 一、list基本介绍二、list基本使用1.尾插头插接口使用2.insert接口使用3.查找某个值所在的位置4.erase接口使用以及迭代器失效5.reverse6.sort7.merge8.unique9.remove11.splice 三、list基本使用完整代码 一、list基本介绍 如下所示,是库里面对list的基本…...
正则表达式、常用的正则
文章目录 正则表达式字符含意义RegExp函数RegExp属性RegExp对象方法RegExp构造函数的第二个参数 常用的正则例子只包含数字(包括正数、负数、零)只包含中英文数字及键盘上的特殊字符校验密码是否符合规则的正则校验http或者https端口号的正则只校验端口号…...

ST官方基于米尔STM32MP135开发板培训课程(一)
本文将以Myirtech的MYD-YF13X以及STM32MP135F-DK为例,讲解如何使用STM32CubeMX结合Developer package实现最小系统启动。 1.开发准备 1.1 Developer package准备 a.Developer package下载: https://www.st.com/en/embedded-software/stm32mp1dev.ht…...

组件(lvs,keeplive,orm,mysql,分布式事务)
lvs LVS 已经集成到Linux内核系统中,ipvsadm 是 LVS 的命令行管理工具。 目前有三种 IP 负载均衡技术( VS/NAT 网络地址转换 、VS/TUN IP 隧道技术实现虚拟服务器 和 VS/DR 直接路由); 八种调度算法:轮询 …...
《视觉SLAM十四讲》报错信息和解决方案
文章目录 ch4-Sophus编译报错ch5/imageBasics安装opencv4.x报错ch5/joinMap/CMakeLists.txt编译报错ch5/joinMap-pcl_viewer map.pcd报错 ch4-Sophus编译报错 报错信息: error: lvalue required as left operand of assignmentunit_complex_.real() 1.;^~ error:…...
golang 设置http请求代理
tinypoxy 搭建http代理服务可参考:tinyproxy搭建http代理_wangxiaoangg的博客-CSDN博客 需求背景: 项目需要访问一国外服务接口,地址被墙。购买香港ecs服务器,并在上面搭建http代理服务。 一 使用http和https代理 func main() {pr…...

我的会议(会议通知)
前言: 我们在实现了发布会议功能,我的会议功能的基础上,继续来实现会议通知的功能。 4.1实现的特色功能: 当有会议要参加时,通过查询会议通知可以知道会议的内容,以及当前会议状态(未读) 4.2思路…...

css实现水平居中
代码示例 <div class"box"><div class"box1"></div> </div>1.弹性布局:(推荐) display:flex; 这些要添加在父级的,是父级的属性 //父级添加display:flex; //父级添加jus…...

c刷题(一)
目录 1.输出100以内3的倍数 2.将3个数从大到小输出 3.打印100~200素数 方法一 方法二 4.显示printf的返回值 最大公约数 试除法 辗转相除法 九九乘法表 求十个数的最大值 1.输出100以内3的倍数 法一: int n 0; while (n*3 < 100){printf("%d &q…...
webpack
文章目录 webpack概念打包的场景为什么要打包在打包之外 - 翻译在打包之外 - 小动作 课程重点模块化利用立即执行函数来改变 作用域模块化的优点模块化方案的进化史AMD(成型比较早,应用不是很广泛)COMMONJSES6 MODULE webpack 的打包机制webp…...
设计模式和设计原则回顾
设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...
java 实现excel文件转pdf | 无水印 | 无限制
文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...

华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...
土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等
🔍 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术,可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势,还能有效评价重大生态工程…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...

视觉slam十四讲实践部分记录——ch2、ch3
ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...

搭建DNS域名解析服务器(正向解析资源文件)
正向解析资源文件 1)准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2)服务端安装软件:bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...

Linux nano命令的基本使用
参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时,显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...