使用easyui的tree组件实现给角色快捷分配权限功能

这篇具有很好参考价值的文章主要介绍了使用easyui的tree组件实现给角色快捷分配权限功能。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

这篇文章主要介绍怎么实现角色权限的快捷分配功能,不需要像大多数项目的授权一样,使用类似穿梭框的组件来授权。

具体实现:通过菜单树的勾选和取消勾选来给角色分配权限,在这之前,需要得到角色的菜单树,角色已有的权限对应树节点的选中状态为true,否则为false。

一、树的格式

首先简单了解一下easyui的tree组件的数据格式

官网截图

使用easyui的tree组件实现给角色快捷分配权限功能,easyui前端框架,easyui,前端,javascript

 树的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;
    }
    
    @Override
    public List<Tree<Void>> listTree(Integer roleId) {
        // 查询所有父级权限(权限类型为0),并生成权限ID和权限信息的map
        Map<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;
    }

}

四、分配权限功能实现

页面效果图

使用easyui的tree组件实现给角色快捷分配权限功能,easyui前端框架,easyui,前端,javascript

当我们勾选树的节点左边的复选框时,会把当前节点的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");
			}
		}]
	});

});

后端代码:

接收前端请求数据的dto对象

package cn.edu.sgu.www.authority.dto;

import lombok.Data;

import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.List;

/**
 * @author heyunlin
 * @version 1.0
 */
@Data
public class PermissionTreeDTO implements Serializable {
    private static final long serialVersionUID = 18L;

    /**
     * 角色ID
     */
    @NotNull(message = "角色ID不能为空")
    private Integer roleId;

    /**
     * 待添加权限
     */
    private List<String> insertIds;

    /**
     * 待删除权限
     */
    private List<String> deleteIds;
}

 控制器类代码

package cn.edu.sgu.www.authority.controller;

import cn.edu.sgu.www.authority.dto.PermissionTreeDTO;
import cn.edu.sgu.www.authority.restful.JsonResult;
import cn.edu.sgu.www.authority.service.RolePermissionService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author heyunlin
 * @version 1.0
 */
@RestController
@Api(tags = "角色权限控制器类")
@RequestMapping(path = "/role_permission", produces = "application/json;charset=utf-8")
public class RolePermissionController {
    private final RolePermissionService service;

    @Autowired
    public RolePermissionController(RolePermissionService service) {
        this.service = service;
    }

    @ApiOperation("为角色分配权限")
    @RequestMapping(value = "/distribute", method = RequestMethod.POST)
    public JsonResult<Void> distribute(@Validated PermissionTreeDTO permissionTreeDTO) {
        service.distribute(permissionTreeDTO);

        return JsonResult.success("操作成功");
    }

}

service层代码

service接口

在service的接口上使用@Transactional(rollbackFor = Exception.class)注解开启事务

package cn.edu.sgu.www.authority.service;

import cn.edu.sgu.www.authority.dto.PermissionTreeDTO;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author heyunlin
 * @version 1.0
 */
public interface RolePermissionService {

	/**
	 * 为角色分配权限
	 * @param permissionTreeDTO 权限信息
	 */
	@Transactional(rollbackFor = Exception.class)
    void distribute(PermissionTreeDTO permissionTreeDTO);
}
 serviceImpl

在这里分了三种情况来处理

package cn.edu.sgu.www.authority.service.impl;

import cn.edu.sgu.www.authority.dto.PermissionTreeDTO;
import cn.edu.sgu.www.authority.entity.RolePermission;
import cn.edu.sgu.www.authority.mapper.PermissionMapper;
import cn.edu.sgu.www.authority.mapper.RolePermissionMapper;
import cn.edu.sgu.www.authority.service.RolePermissionService;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import org.springframework.stereotype.Service;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @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;
    }

    @Override
    public void distribute(PermissionTreeDTO permissionTreeDTO) {
        // 获取前端传来的数据
        List<String> insertIds = permissionTreeDTO.getInsertIds();
        List<String> deleteIds = permissionTreeDTO.getDeleteIds();
        Integer roleId = permissionTreeDTO.getRoleId();

        UpdateWrapper<RolePermission> wrapper;

        if (insertIds != null && deleteIds != null) {
            Set<String> insert = new HashSet<>(insertIds);
            Set<String> delete = new HashSet<>(deleteIds);

            System.out.println("insert:" + insert);
            System.out.println("delete:" + delete);

            // 求交集
            Set<String> inter;
            inter = new HashSet<>(insertIds);
            inter.retainAll(delete);

            // 删除交集
            insert.removeAll(inter);
            delete.removeAll(inter);

            if (!delete.isEmpty()) {
                for (String deleteId : delete) {
                    wrapper = new UpdateWrapper<>();

                    wrapper.eq("permission_id", deleteId);
                    wrapper.eq("role_id", roleId);

                    rolePermissionMapper.delete(wrapper);
                }
            }

            if (!insert.isEmpty()) {
                for (String insertId : insert) {
                    RolePermission permission = new RolePermission();

                    permission.setId(null);
                    permission.setRoleId(roleId);
                    permission.setPermissionId(insertId);

                    rolePermissionMapper.insert(permission);
                }
            }
        } else if (deleteIds != null) {
            for (String deleteId : deleteIds) {
                wrapper = new UpdateWrapper<>();

                wrapper.eq("permission_id", deleteId);
                wrapper.eq("role_id", roleId);

                rolePermissionMapper.delete(wrapper);
            }
        } else if (insertIds != null) {
            for (String insertId : insertIds) {
                RolePermission permission = new RolePermission();

                permission.setId(null);
                permission.setRoleId(roleId);
                permission.setPermissionId(insertId);

                rolePermissionMapper.insert(permission);
            }
        }
    }

}

好了,这篇文章就分享到这里了,需要完整的代码可通过下方git地址获取,看完之后如果对你有所帮助,不要忘了点赞+收藏哦~

统一权限平台https://gitee.com/he-yunlin/authority.git文章来源地址https://www.toymoban.com/news/detail-620802.html

到了这里,关于使用easyui的tree组件实现给角色快捷分配权限功能的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包