一、参照1
这里主要介绍controller封装ztree参数,具体业务以实际为准,这里controller里封装的数据最好写在service层。
1.前台返回数据的格式
var zNodes =[
{ name:"父节点1 - 展开", open:true,
children: [
{ name:"父节点11 - 折叠",
children: [
{ name:"叶子节点111"},
{ name:"叶子节点112"},
{ name:"叶子节点113"},
{ name:"叶子节点114"}
]},
{ name:"父节点12 - 折叠",
children: [
{ name:"叶子节点121"},
{ name:"叶子节点122"},
{ name:"叶子节点123"},
{ name:"叶子节点124"}
]},
{ name:"父节点13 - 没有子节点", isParent:true}
]},
{ name:"父节点2 - 折叠",
children: [
{ name:"父节点21 - 展开", open:true,
children: [
{ name:"叶子节点211"},
{ name:"叶子节点212"},
{ name:"叶子节点213"},
{ name:"叶子节点214"}
]},
{ name:"父节点22 - 折叠",
children: [
{ name:"叶子节点221"},
{ name:"叶子节点222"},
{ name:"叶子节点223"},
{ name:"叶子节点224"}
]},
{ name:"父节点23 - 折叠",
children: [
{ name:"叶子节点231"},
{ name:"叶子节点232"},
{ name:"叶子节点233"},
{ name:"叶子节点234"}
]}
]},
{ name:"父节点3 - 没有子节点", isParent:true}
];
<c:forEach items="${sessionScope.permissionRoot.children }" var="permission">
<c:if test="${empty permission.children}">
<li class="list-group-item tree-closed" >
<a href="${APP_PATH }/${permission.url }"><i class="${permission.icon}"></i> ${permission.name }</a>
</li>
</c:if>
<c:if test="${not empty permission.children}" >
<li class="list-group-item tree-closed">
<span><i class="${permission.icon}"></i> ${permission.name } <span class="badge" style="float:right">${fn:length(permission.children)} <%-- ${permission.children.size() } --%></span></span>
<ul style="margin-top:10px;display:none;">
<c:forEach items="${permission.children }" var="innerPermission">
<li style="height:30px;">
<a href="${APP_PATH }/${innerPermission.url}"><i class="${innerPermission.icon }"></i> ${innerPermission.name }</a>
</li>
</c:forEach>
</ul>
</li>
</c:if>
</c:forEach>
2.封装的类
package com.stuwork.crowdfunding.bean;
import java.util.ArrayList;
import java.util.List;
public class Permission {
private Integer id;
private Integer pid;
private String name;
private String icon;
private String url;
private boolean open;
private boolean checked;
private List<Permission> children = new ArrayList<Permission>();
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getPid() {
return pid;
}
public void setPid(Integer pid) {
this.pid = pid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name == null ? null : name.trim();
}
public String getIcon() {
return icon;
}
public void setIcon(String icon) {
this.icon = icon == null ? null : icon.trim();
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url == null ? null : url.trim();
}
public boolean isOpen() {
return open;
}
public void setOpen(boolean open) {
this.open = open;
}
public List<Permission> getChildren() {
return children;
}
public void setChildren(List<Permission> children) {
this.children = children;
}
public boolean isChecked() {
return checked;
}
public void setChecked(boolean checked) {
this.checked = checked;
}
}
package com.stuwork.crowdfunding.util;
public class AjaxResult {
private boolean success;
private String message;
private Page page;
private Object data;
public Page getPage() {
return page;
}
public void setPage(Page page) {
this.page = page;
}
public boolean getSuccess() {
return success;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public void setSuccess(boolean success) {
this.success = success;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
3.controller几种返回数据格式封装和优化
package com.stuwork.crowdfunding.manager.controller;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.stuwork.crowdfunding.bean.Permission;
import com.stuwork.crowdfunding.manager.service.PermissionService;
import com.stuwork.crowdfunding.util.AjaxResult;
@Controller
@RequestMapping("/permission")
public class PermissionController {
@Autowired
private PermissionService permissionService;
//最终版方式1
//最终优化版,减少循环的次数
@ResponseBody
@RequestMapping("/loadData")
public Object loadData(){
AjaxResult result = new AjaxResult();
try {
List<Permission> root = new ArrayList<Permission>();
List<Permission> permissionList = permissionService.getAllPermission();//根菜单
Map<Integer,Permission> map = new HashMap<Integer,Permission>();
for(Permission bean :permissionList){
map.put(bean.getId(), bean);
}
for(Permission bean :permissionList){
Permission children = bean;
if(bean.getPid() == 0){
root.add(bean);
}else{
Permission parent = map.get(children.getPid());
parent.getChildren().add(children);
}
}
result.setData(root);
result.setSuccess(true);
} catch (Exception e) {
result.setSuccess(false);
result.setMessage("许可树加载失败");
e.printStackTrace();
}
return result;
}
//方式2
@ResponseBody //递归优化
@RequestMapping("/loadData")
public Object loadData(){
AjaxResult result = new AjaxResult();
try {
List<Permission> root = new ArrayList<Permission>();
List<Permission> permissionList = permissionService.getAllPermission();//根菜单
for(Permission bean :permissionList){
Permission children = bean;//子菜单
if(children.getPid() == 0){
root.add(bean);
}else{
for(Permission innerPermission:permissionList){
if(children.getPid() == innerPermission.getId()){
innerPermission.getChildren().add(children);
break;
}
}
}
}
result.setData(root);
result.setSuccess(true);
} catch (Exception e) {
result.setSuccess(false);
result.setMessage("许可树加载失败");
e.printStackTrace();
}
return result;
}
//方式3
//递归,解决多个层次 //效率低,多次调用数据库
@ResponseBody
@RequestMapping("/loadData")
public Object loadData(){
AjaxResult result = new AjaxResult();
try {
List<Permission> root = new ArrayList<Permission>();
Permission permission = permissionService.getRootPermission();//根菜单
root.add(permission);
getPermissionChildern(permission);
result.setData(root);
result.setSuccess(true);
} catch (Exception e) {
result.setSuccess(false);
result.setMessage("许可树加载失败");
e.printStackTrace();
}
return result;
}
/**
* 递归使用注意事项
* 1.调用自身
* 2.范围要不断缩小
* 3.要有跳出条件
* @param permission
*/
private void getPermissionChildern(Permission permission){
List<Permission> childrenList = permissionService.getChildrenPermissionByPid(permission.getId());
permission.setChildren(childrenList);
for(Permission bean:childrenList){
getPermissionChildern(bean);
}
}
//方式4(这个是demo,没从数据库取数据)
@ResponseBody
@RequestMapping("/loadData")
public Object loadData(){
AjaxResult result = new AjaxResult();
try {
Permission permission = new Permission();//父菜单
Permission permission1 = new Permission();//子菜单
Permission permission2 = new Permission();//子菜单
List<Permission> list = new ArrayList<Permission>();//子菜单
List<Permission> root = new ArrayList<Permission>();//根菜单
permission.setName("系统权限菜单");
permission.setOpen(true);
permission1.setName("控制面板");
permission2.setName("权限管理");
list.add(permission1);
list.add(permission2);
permission.setChildren(list);
root.add(permission);
result.setData(root);
result.setSuccess(true);
} catch (Exception e) {
result.setSuccess(false);
result.setMessage("许可树加载失败");
e.printStackTrace();
}
return result;
}
//方式5
@ResponseBody
@RequestMapping("/loadData")
public Object loadData(){
AjaxResult result = new AjaxResult();
try {
List<Permission> root = new ArrayList<Permission>();
Permission permission = permissionService.getRootPermission();//根菜单
permission.setOpen(true);
root.add(permission);
List<Permission> childrenList = permissionService.getChildrenPermissionByPid(permission.getId());
permission.setChildren(childrenList);
for(Permission bean :childrenList){
bean.setOpen(true);
List<Permission> innerChildrenList = permissionService.getChildrenPermissionByPid(bean.getId());
bean.setChildren(innerChildrenList);
}
result.setData(root);
result.setSuccess(true);
} catch (Exception e) {
result.setSuccess(false);
result.setMessage("许可树加载失败");
e.printStackTrace();
}
return result;
}
}
4.mapper文件方法
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.stuwork.crowdfunding.manager.dao.PermissionMapper">
<resultMap id="BaseResultMap" type="Permission">
<id column="id" jdbcType="INTEGER" property="id" />
<result column="pid" jdbcType="INTEGER" property="pid" />
<result column="name" jdbcType="VARCHAR" property="name" />
<result column="icon" jdbcType="VARCHAR" property="icon" />
<result column="url" jdbcType="VARCHAR" property="url" />
</resultMap>
<select id="getPermissionByRoleId" resultType="int">
SELECT permissionid
FROM t_role_permission
WHERE roleid = #{roleid}
</select>
<select id="getRootPermission" resultMap="BaseResultMap">
SELECT id,pid,icon,url,name
FROM t_permission
WHERE pid = 0
</select>
<select id="getChildrenPermissionByPid" resultMap="BaseResultMap">
SELECT id,pid,icon,url,name
FROM t_permission
WHERE pid = #{id}
</select>
<select id="getAlltPermission" resultMap="BaseResultMap">
SELECT id,pid,icon,url,name
FROM t_permission
</select>
</mapper>
5.数据库表数据
二、参照2
1、实体类
package com.stu.aclservice.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import java.util.List;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
* 权限
* </p>
*
* @author testjava
* @since 2020-01-12
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("acl_permission")
@ApiModel(value="Permission对象", description="权限")
public class Permission implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "编号")
@TableId(value = "id", type = IdType.ID_WORKER_STR)
private String id;
@ApiModelProperty(value = "所属上级")
private String pid;
@ApiModelProperty(value = "名称")
private String name;
@ApiModelProperty(value = "类型(1:菜单,2:按钮)")
private Integer type;
@ApiModelProperty(value = "权限值")
private String permissionValue;
@ApiModelProperty(value = "访问路径")
private String path;
@ApiModelProperty(value = "组件路径")
private String component;
@ApiModelProperty(value = "图标")
private String icon;
@ApiModelProperty(value = "状态(0:禁止,1:正常)")
private Integer status;
@ApiModelProperty(value = "层级")
@TableField(exist = false)
private Integer level;
@ApiModelProperty(value = "下级")
@TableField(exist = false)
private List<Permission> children;
@ApiModelProperty(value = "是否选中")
@TableField(exist = false)
private boolean isSelect;
@ApiModelProperty(value = "逻辑删除 1(true)已删除, 0(false)未删除")
private Boolean isDeleted;
@ApiModelProperty(value = "创建时间")
private Date gmtCreate;
@ApiModelProperty(value = "更新时间")
private Date gmtModified;
}
2、业务类
package com.stu.aclservice.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.stu.aclservice.entity.Permission;
import com.stu.aclservice.entity.RolePermission;
import com.stu.aclservice.entity.User;
import com.stu.aclservice.helper.MemuHelper;
import com.stu.aclservice.helper.PermissionHelper;
import com.stu.aclservice.mapper.PermissionMapper;
import com.stu.aclservice.service.PermissionService;
import com.stu.aclservice.service.RolePermissionService;
import com.stu.aclservice.service.UserService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* <p>
* 权限 服务实现类
* </p>
*
* @author testjava
* @since 2020-01-12
*/
@Service
public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permission> implements PermissionService {
@Autowired
private RolePermissionService rolePermissionService;
@Autowired
private UserService userService;
//获取全部菜单
@Override
public List<Permission> queryAllMenu() {
QueryWrapper<Permission> wrapper = new QueryWrapper<>();
wrapper.orderByDesc("id");
List<Permission> permissionList = baseMapper.selectList(wrapper);
List<Permission> result = bulid(permissionList);
return result;
}
//根据角色获取菜单
@Override
public List<Permission> selectAllMenu(String roleId) {
List<Permission> allPermissionList = baseMapper.selectList(new QueryWrapper<Permission>().orderByAsc("CAST(id AS SIGNED)"));
//根据角色id获取角色权限
List<RolePermission> rolePermissionList = rolePermissionService.list(new QueryWrapper<RolePermission>().eq("role_id",roleId));
//转换给角色id与角色权限对应Map对象
// List<String> permissionIdList = rolePermissionList.stream().map(e -> e.getPermissionId()).collect(Collectors.toList());
// allPermissionList.forEach(permission -> {
// if(permissionIdList.contains(permission.getId())) {
// permission.setSelect(true);
// } else {
// permission.setSelect(false);
// }
// });
for (int i = 0; i < allPermissionList.size(); i++) {
Permission permission = allPermissionList.get(i);
for (int m = 0; m < rolePermissionList.size(); m++) {
RolePermission rolePermission = rolePermissionList.get(m);
if(rolePermission.getPermissionId().equals(permission.getId())) {
permission.setSelect(true);
}
}
}
List<Permission> permissionList = bulid(allPermissionList);
return permissionList;
}
//给角色分配权限
@Override
public void saveRolePermissionRealtionShip(String roleId, String[] permissionIds) {
rolePermissionService.remove(new QueryWrapper<RolePermission>().eq("role_id", roleId));
List<RolePermission> rolePermissionList = new ArrayList<>();
for(String permissionId : permissionIds) {
if(StringUtils.isEmpty(permissionId)) continue;
RolePermission rolePermission = new RolePermission();
rolePermission.setRoleId(roleId);
rolePermission.setPermissionId(permissionId);
rolePermissionList.add(rolePermission);
}
rolePermissionService.saveBatch(rolePermissionList);
}
//递归删除菜单
@Override
public void removeChildById(String id) {
List<String> idList = new ArrayList<>();
this.selectChildListById(id, idList);
idList.add(id);
baseMapper.deleteBatchIds(idList);
}
//根据用户id获取用户菜单
@Override
public List<String> selectPermissionValueByUserId(String id) {
List<String> selectPermissionValueList = null;
if(this.isSysAdmin(id)) {
//如果是系统管理员,获取所有权限
selectPermissionValueList = baseMapper.selectAllPermissionValue();
} else {
selectPermissionValueList = baseMapper.selectPermissionValueByUserId(id);
}
return selectPermissionValueList;
}
@Override
public List<JSONObject> selectPermissionByUserId(String userId) {
List<Permission> selectPermissionList = null;
if(this.isSysAdmin(userId)) {
//如果是超级管理员,获取所有菜单
selectPermissionList = baseMapper.selectList(null);
} else {
selectPermissionList = baseMapper.selectPermissionByUserId(userId);
}
List<Permission> permissionList = PermissionHelper.bulid(selectPermissionList);
List<JSONObject> result = MemuHelper.bulid(permissionList);
return result;
}
/**
* 判断用户是否系统管理员
* @param userId
* @return
*/
private boolean isSysAdmin(String userId) {
User user = userService.getById(userId);
if(null != user && "admin".equals(user.getUsername())) {
return true;
}
return false;
}
/**
* 递归获取子节点
* @param id
* @param idList
*/
private void selectChildListById(String id, List<String> idList) {
List<Permission> childList = baseMapper.selectList(new QueryWrapper<Permission>().eq("pid", id).select("id"));
childList.stream().forEach(item -> {
idList.add(item.getId());
this.selectChildListById(item.getId(), idList);
});
}
/**
* 使用递归方法建菜单
* @param treeNodes
* @return
*/
private static List<Permission> bulid(List<Permission> treeNodes) {
List<Permission> trees = new ArrayList<>();
for (Permission treeNode : treeNodes) {
if ("0".equals(treeNode.getPid())) {
treeNode.setLevel(1);
trees.add(findChildren(treeNode,treeNodes));
}
}
return trees;
}
/**
* 递归查找子节点
* @param treeNodes
* @return
*/
private static Permission findChildren(Permission treeNode,List<Permission> treeNodes) {
treeNode.setChildren(new ArrayList<Permission>());
for (Permission it : treeNo