SpringMVC+ZTree实现树形菜单权限配置
计划在开源项目里加入权限配置的功能,打算加入zTree实现树形结构。
Team的Github开源项目链接:https://github.com/u014427391/jeeplatform
欢迎star(收藏)
zTree 是一个依靠 jQuery 实现的多功能 “树插件”。优异的性能、灵活的配置、多种功能的组合是 zTree 最大优点。
zTree下载链接:http://www.treejs.cn/v3/main.php#_zTreeInfo
角色信息实体类:
package org.muses.jeeplatform.core.entity.admin;
import javax.persistence.*;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
/**
* @description 角色信息实体类
* @author Nicky
* @date 2017年3月16日
*/
@Table(name="sys_role")
@Entity
public class Role implements Serializable{
/** 角色Id**/
private int roleId;
/** 角色描述**/
private String roleDesc;
/** 角色名称**/
private String roleName;
/** 角色标志**/
private String role;
private Set<Permission> permissions = new HashSet<Permission>();
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
public int getRoleId() {
return roleId;
}
public void setRoleId(int roleId) {
this.roleId = roleId;
}
@Column(length=100)
public String getRoleDesc() {
return roleDesc;
}
public void setRoleDesc(String roleDesc) {
this.roleDesc = roleDesc;
}
@Column(length=100)
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
@Column(length=100)
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
//修改cascade策略为级联关系
@OneToMany(targetEntity=Permission.class,cascade=CascadeType.MERGE,fetch=FetchType.EAGER)
@JoinTable(name="sys_role_permission", joinColumns=@JoinColumn(name="roleId",referencedColumnName="roleId"), inverseJoinColumns=@JoinColumn(name="permissionId",referencedColumnName="id",unique=true))
public Set<Permission> getPermissions() {
return permissions;
}
public void setPermissions(Set<Permission> permissions) {
this.permissions = permissions;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Role) {
Role role = (Role) obj;
return this.roleId==(role.getRoleId())
&& this.roleName.equals(role.getRoleName())
&& this.roleDesc.equals(role.getRoleDesc())
&& this.role.equals(role.getRole());
}
return super.equals(obj);
}
}
权限信息实体类:
package org.muses.jeeplatform.core.entity.admin;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
/**
* @description 权限操作的Vo类
* @author Nicky
* @date 2017年3月6日
*/
@Table(name="sys_permission")
@Entity
public class Permission implements Serializable {
private int id;
private String pdesc;
private String name;
private static final long serialVersionUID = 1L;
private Menu menu;
private Set<Operation> operations = new HashSet<Operation>();
public Permission() {
super();
}
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
@Column(length=100)
public String getPdesc() {
return this.pdesc;
}
public void setPdesc(String pdesc) {
this.pdesc = pdesc;
}
@Column(length=100)
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
@OneToOne(targetEntity=Menu.class,cascade=CascadeType.REFRESH,fetch=FetchType.EAGER)
@JoinColumn(name="menuId",referencedColumnName="menuId")
public Menu getMenu() {
return menu;
}
public void setMenu(Menu menu) {
this.menu = menu;
}
@ManyToMany(targetEntity=Operation.class,cascade=CascadeType.MERGE,fetch=FetchType.EAGER)
@JoinTable(name="sys_permission_operation",joinColumns=@JoinColumn(name="permissionId",referencedColumnName="id"),inverseJoinColumns=@JoinColumn(name="operationId",referencedColumnName="id"))
public Set<Operation> getOperations() {
return operations;
}
public void setOperations(Set<Operation> operations) {
this.operations = operations;
}
}
实现菜单信息实体类,用JPA来实现
package org.muses.jeeplatform.core.entity.admin;
import javax.persistence.*;
import java.io.Serializable;
import java.util.List;
/**
* @description 菜单信息实体
* @author Nicky
* @date 2017年3月17日
*/
@Table(name="sys_menu")
@Entity
public class Menu implements Serializable {
/** 菜单Id**/
private int menuId;
/** 上级Id**/
private int parentId;
/** 菜单名称**/
private String menuName;
/** 菜单图标**/
private String menuIcon;
/** 菜单URL**/
private String menuUrl;
/** 菜单类型**/
private String menuType;
/** 菜单排序**/
private String menuOrder;
/**菜单状态**/
private String menuStatus;
private List<Menu> subMenu;
private String target;
private boolean hasSubMenu = false;
public Menu() {
super();
}
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
public int getMenuId() {
return this.menuId;
}
public void setMenuId(int menuId) {
this.menuId = menuId;
}
@Column(length=100)
public int getParentId() {
return parentId;
}
public void setParentId(int parentId) {
this.parentId = parentId;
}
@Column(length=100)
public String getMenuName() {
return this.menuName;
}
public void setMenuName(String menuName) {
this.menuName = menuName;
}
@Column(length=30)
public String getMenuIcon() {
return this.menuIcon;
}
public void setMenuIcon(String menuIcon) {
this.menuIcon = menuIcon;
}
@Column(length=100)
public String getMenuUrl() {
return this.menuUrl;
}
public void setMenuUrl(String menuUrl) {
this.menuUrl = menuUrl;
}
@Column(length=100)
public String getMenuType() {
return this.menuType;
}
public void setMenuType(String menuType) {
this.menuType = menuType;
}
@Column(length=10)
public String getMenuOrder() {
return menuOrder;
}
public void setMenuOrder(String menuOrder) {
this.menuOrder = menuOrder;
}
@Column(length=10)
public String getMenuStatus(){
return menuStatus;
}
public void setMenuStatus(String menuStatus){
this.menuStatus = menuStatus;
}
@Transient
public List<Menu> getSubMenu() {
return subMenu;
}
public void setSubMenu(List<Menu> subMenu) {
this.subMenu = subMenu;
}
public void setTarget(String target){
this.target = target;
}
@Transient
public String getTarget(){
return target;
}
public void setHasSubMenu(boolean hasSubMenu){
this.hasSubMenu = hasSubMenu;
}
@Transient
public boolean getHasSubMenu(){
return hasSubMenu;
}
}
实现JpaRepository接口
package org.muses.jeeplatform.core.dao.repository.admin;
import org.muses.jeeplatform.core.entity.admin.Role;
import org.springframework.data.jpa.repository.JpaRepository;
/**
* Created by Nicky on 2017/12/2.
*/
public interface RoleRepository extends JpaRepository<Role,Integer> {
}
实现JpaRepository接口
package org.muses.jeeplatform.core.dao.repository.admin;
import org.muses.jeeplatform.core.entity.admin.Menu;
import org.springframework.data.jpa.repository.JpaRepository;
/**
* Created by Nicky on 2017/6/17.
*/
public interface MenuTreeRepository extends JpaRepository<Menu,Integer>{
}
角色Service类:
package org.muses.jeeplatform.service;
import com.google.common.collect.Lists;
import org.muses.jeeplatform.core.dao.repository.admin.RolePageRepository;
import org.muses.jeeplatform.core.entity.admin.Role;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* Created by Nicky on 2017/7/30.
*/
@Service
public class RolePageService {
@Autowired
RolePageRepository roleRepository;
/**
* 构建PageRequest对象
* @param num
* @param size
* @param asc
* @param string
* @return
*/
private PageRequest buildPageRequest(int num, int size, Sort.Direction asc,
String string) {
return new PageRequest(num-1, size,null,string);
}
/**
* 获取所有的菜单信息并分页显示
* @param pageNo
* 当前页面数
* @param pageSize
* 每一页面的页数
* @return
*/
public Page<Role> findAll(int pageNo, int pageSize, Sort.Direction dir, String str){
PageRequest pageRequest = buildPageRequest(pageNo, pageSize, dir, str);
Page<Role> roles = roleRepository.findAll(pageRequest);
return roles;
}
public List<Role> findAllRole(){
Iterable<Role> roles = roleRepository.findAll();
List<Role> myList = Lists.newArrayList(roles);
return myList;
}
/**
* 根据角色id查找角色信息
* @param roleId
* @return
*/
public Role findByRoleId(String roleId){
return roleRepository.findOne(Integer.parseInt(roleId));
}
/**
* 保存角色信息
* @param role
*/
public void doSave(Role role){
roleRepository.save(role);
}
}
菜单Service类:
package org.muses.jeeplatform.service;
import org.muses.jeeplatform.annotation.RedisCache;
import org.muses.jeeplatform.common.RedisCacheNamespace;
import org.muses.jeeplatform.core.dao.repository.admin.MenuTreeRepository;
import org.muses.jeeplatform.core.entity.admin.Menu;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* Created by Nicky on 2017/6/17.
*/
@Service
public class MenuTreeService {
@Autowired
MenuTreeRepository menuTreeRepository;
/**
* 查询所有的菜单
* @return
*/
@Transactional
//@RedisCache
public List<Menu> findAll(){
return menuTreeRepository.findAll();
}
}
在Controller类里通过角色id获取该角色可以查看的菜单:
/**
* 跳转到角色授权页面
* @param roleId
* @param model
* @return
*/
@RequestMapping(value = "/goAuthorise" )
public String goAuth(@RequestParam String roleId, Model model){
List<Menu> menuList = menuTreeService.findAll();
Role role = roleService.findByRoleId(roleId);
Set<Permission> hasPermissions = null;
if(role != null){
hasPermissions = role.getPermissions();
}
for (Menu m : menuList) {
for(Permission p : hasPermissions){
if(p.getMenu().getMenuId()==m.getMenuId()){
m.setHasSubMenu(true);
}
}
}
model.addAttribute("roleId" , roleId);
JSONArray jsonArray = JSONArray.fromObject(menuList);
String json = jsonArray.toString();
json = json.replaceAll("menuId","id").replaceAll("parentId","pId").
replaceAll("menuName","name").replaceAll("hasSubMenu","checked");
model.addAttribute("menus",json);
return "admin/role/role_auth";
}
在前端通过zTree实现树形菜单展示,通过勾选然后实现角色授权:
<%@ page contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<base href="<%=basePath %>">
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Insert title here</title>
<!-- 引入JQuery库 start -->
<script type="text/javascript" src="${basePath}static/js/jquery-1.8.3.js"></script>
<!-- 引入JQuery库 end -->
<script type="text/javascript" src="<%=basePath%>plugins/zDialog/zDialog.js"></script>
<script type="text/javascript" src="<%=basePath%>plugins/zDialog/zDrag.js"></script>
<script type="text/javascript" src="<%=basePath%>plugins/zDialog/zProgress.js"></script>
<link rel="stylesheet" href="<%=basePath%>plugins/zTree/3.5/zTreeStyle.css" type="text/css">
<script type="text/javascript" src="<%=basePath%>plugins/zTree/3.5/jquery-1.4.4.min.js"></script>
<script type="text/javascript" src="<%=basePath%>plugins/zTree/3.5/jquery.ztree.core.js"></script>
<script type="text/javascript" src="<%=basePath%>plugins/zTree/3.5/jquery.ztree.excheck.js"></script>
<script type="text/javascript">
<!--
var setting = {
check: {
enable: true
},
data: {
simpleData: {
enable: true
}
},
callback:{
onClick: {
}
}
};
/*[
{ id:1, pId:0, name:"随意勾选 1", open:true},
{ id:11, pId:1, name:"随意勾选 1-1", open:true},
{ id:12, pId:1, name:"随意勾选 1-2", open:true}
];*/
var json = ${menus};
var zNodes = eval(json);
var code;
function setCheck() {
var zTree = $.fn.zTree.getZTreeObj("treeDemo"),
py = $("#py").attr("checked")? "p":"",
sy = $("#sy").attr("checked")? "s":"",
pn = $("#pn").attr("checked")? "p":"",
sn = $("#sn").attr("checked")? "s":"",
type = { "Y":py + sy, "N":pn + sn};
zTree.setting.check.chkboxType = type;
showCode('setting.check.chkboxType = { "Y" : "' + type.Y + '", "N" : "' + type.N + '" };');
}
function showCode(str) {
if (!code) code = $("#code");
code.empty();
code.append("<li>"+str+"</li>");
}
$(document).ready(function(){
$.fn.zTree.init($("#treeDemo"), setting, zNodes);
setCheck();
$("#py").bind("change", setCheck);
$("#sy").bind("change", setCheck);
$("#pn").bind("change", setCheck);
$("#sn").bind("change", setCheck);
});
//-->
function dialogClose()
{
parentDialog.close();
}
function doSave() {
var zTree = $.fn.zTree.getZTreeObj("treeDemo");
var nodes = zTree.getCheckedNodes();
var tmpNode;
var ids = "";
for(var i=0; i<nodes.length; i++){
tmpNode = nodes[i];
if(i!=nodes.length-1){
ids += tmpNode.id+",";
}else{
ids += tmpNode.id;
}
}
var roleId = ${roleId};
var params = roleId +";"+ids;
alert(ids);
$.ajax({
type: "POST",
url: 'role/authorise.do',
data: {params:params,tm:new Date().getTime()},
dataType:'json',
cache: false,
success: function(data){
if("success" == data.result){
alert('授权成功!请重新登录!');
parent.location.reload();
doDialogClose();
}else{
alert("授权失败!");
}
}
});
}
</script>
</head>
<body >
<div class="content_wrap">
<div class="zTreeDemoBackground left">
<ul id="treeDemo" class="ztree"></ul>
</div>
</div>
<input type="button" onClick="doSave()" value="保存" class="buttonStyle" />
<input onClick="dialogClose();" class="buttonStyle" type="button" value="关闭" />
</body>
</html>
Team的Github开源项目链接:https://github.com/u014427391/jeeplatform
欢迎star(收藏)
SpringMVC+ZTree实现树形菜单权限配置的更多相关文章
- 使用ztree展示树形菜单结构
官网:http://www.treejs.cn/v3/main.php#_zTreeInfo 一.功能简介 在权限系统中,实现给角色指定菜单权限的功能.主要包括以下几点: 读取全部菜单项,并以树形结构 ...
- zTree增加树形菜单格式
result为json字符串 //展示树形菜单 function showMenuTree(result) { console.log("页面展示函数:"+result); //属 ...
- C#winform菜单权限分配,与菜单同步的treeView树状菜单权限控制使用心得
在网上查了很多,发现没有讲述关于--C#winform菜单权限分配,与菜单同步的treeView树状菜单权限控制使用--的资料 自己研究了一个使用方法.下面来看看. 我有两个窗体:LOGINFRM,M ...
- 使用zTree插件构建树形菜单
zTree下载:https://github.com/zTree/zTree_v3 目录: 就我看来,zTree较为实用的有以下几点: zTree 是一个依靠 jQuery 实现的多功能 “树插件”. ...
- ztree树形菜单demo
阅读目录 zTree树形菜单 回到顶部 zTree树形菜单 树形菜单使用方式如下:HTML引入的方式如下: <!DOCTYPE html> <html> <head> ...
- ztree树形菜单的增加删除修改和换图标
首先需要注意一点,如果有研究过树形菜单,就会发现实现删除和修改功能特别简单,但是增加却有一点复杂.造成这个现象是ztree树形菜单的历史遗留问题.大概是之前的版本没有增加这个功能,后来的版本加上了这个 ...
- Ecshop :后台添加新功能 菜单及 管理权限 配置
需求:在<商品管理>下增加一项[商品推广管理]功能 一. 添加菜单项 打开 /admin/includes/inc_menu.php 文件(后台框架左边菜单),在最后添加一行如下: $mo ...
- zTree树形菜单交互选项卡效果实现
1. 添加自定义属性 page 2. 为 ztree 每个树形节点,添加点击事件 <!DOCTYPE html> <html> <head> <meta ch ...
- zTree树形菜单使用实例
在每个节点添加 id 和 pid, id 表示当前节点编号,pid 表示父节点编号 第一步:在页面显示菜单位置,添加 ul设置 class=”ztree” 第二步:开启简单数据格式支持 第三步:编写树 ...
随机推荐
- c#DES加密解密代码
//加密 public string DesEncrypt(string strText, string strEncrKey) { byte[] byKey=null; byte[ ...
- git如何忽略文件
偶尔有一些文件你不想让git提交到代码配置库上,这里有一些方法可以告诉git,有哪些文件可以忽略. 创建一个本地的.gitignore 如果你在你的git库(repository)中创建了一个名为.g ...
- 脱掉Golang的第一层衣裳 golang入坑系列
读前必读,博客园的文章并非最新,想看最新还是建议点击这里.博客园的文章是为了方便不能FQ的同学,同步而来的.不放在博客园,不是不支持国产,而是博客园的排版太难看了,太难看了,太难看了!而且还没有客户端 ...
- 完美解决--用VS中的Git做代码管理器,与他人共享代码
1.创建代码仓库,这里说一下为什么要创建仓库,Git不能够作为源代码管理器,vs中自带的也只能够在本地进行管理,要和他们共享的话必须要有服务器端去存储代码,类似于SVN,它就有客户端和服务器端,这里推 ...
- springboot整合shiro
请大家在看本文之前,先了解如下知识点: 1.Shiro 是什么?怎么用? 2.Cas 是什么?怎么用? 3.最好有Spring基础 可以先看看这两篇文章,按照这2篇文章的内容做一遍: Spring B ...
- java oop详解
近日来重温了一下java oop的知识.加深了对面向对象的理解.尤其时继承方面.故写一篇博客.记录一下自己的想法和心得 1.面向对象主要分为三大点(封装,继承,多态) 封装的思想促进了类的形成.相比于 ...
- python学习笔记——Day 1
python是一种什么语言? 编译与解释 编译器是把源程序的每一条语句都编译成机器语言,并保存成二进制文件,这样运行时计算机可以直接以机器语言来运行此程序,速度很快; 而解释器则是只在执行程序时,才一 ...
- VueJS引入css或者less文件的一些坑
我们在做Vue+webpack的时,难免会引入各种公共css样式文件,那么我们改如何引入呢?引入时会有那些坑呢? 首先,引入公共样式时,我们在“main.js”里使用AMD的方式引入,即 requir ...
- Python数据分析(二): Pandas技巧 (2)
Pandas的第一部分: http://www.cnblogs.com/cgzl/p/7681974.html github地址: https://github.com/solenovex/My-Ma ...
- 【机器学习】彻底搞懂CNN
之前通过各种博客视频学习CNN,总是对参数啊原理啊什么的懵懵懂懂..这次上课终于弄明白了,O(∩_∩)O~ 上世纪科学家们发现了几个视觉神经特点,视神经具有局部感受眼,一整张图的识别由多个局部识别点构 ...