SpringMVC+ZTree實現樹形菜單權限配置
阿新 • • 發佈:2017-12-27
true attr 前端 prefix fill body log cti tope
計劃在開源項目裏加入權限配置的功能,打算加入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實現樹形菜單權限配置