在需要使用树形菜单的时候,z-tree是可以直接传数据父级id 对应子集pid自动生成树形结构,但z-tree这个框架毕竟年级较大了大家都知道年纪大的人都长得丑毕竟像我这么年轻才能天下第一帅,在使用很多树形控件时候需要的数据格式是固定的也就是子集需要在父级的一个集合属性里。(好了,可能是我们的前端太菜了不会写,非逼着我转结构)
比如
这样就需要我们在后台将数据处理成指定格式在转成json了比如我们要查一个省的数据,河南省下面有郑州市、开封市、洛阳市、驻马店市、等等,然后郑州市下面还有金水区、惠济区、二七区等等,我们可以用递归查询查询出河南省下所有的地方,但是我们查询出来的是一个结果集要怎么才能转换成这样的数据
package com.synergy.util;
import cn.hutool.core.collection.IterUtil;
import cn.hutool.core.util.StrUtil;
import java.util.*;
/**
* 将查询的pageData转换成树形结构
* 父级id为pid 本级id
*/
public class PageToTreeUtil {
/**
* 工具类不允许实例化
*/
private PageToTreeUtil() {
}
static List<PageData> returnList = new ArrayList<>();
/**
* 根据父节点的ID获取所有子节点
*
* @param list 需要转换的数据
* @param sort 排序码的名称
* @param lowerName 子集名称
* @param superId 一级id
*/
public static List<PageData> getChildPerms(List<PageData> list, String sort, String lowerName, String superId) {
if (list == null) {
return null;
}
List<PageData> childList = getChildList(list, sort, superId);
for (int i = 0; i < list.size(); i++) {
if (list.get(i).get("id").equals(superId)) {
PageData remove = list.remove(i);
if (StrUtil.isBlank(lowerName)) {
remove.put("list", childList);
} else {
remove.put(lowerName, childList);
}
returnList.add(remove);
break;//找到一级跳出循环
}
}
for (PageData pageData : childList) {
if (IterUtil.isEmpty(list)) {
break;
}
recursionFn(list, sort, lowerName, pageData);
}
return returnList;
}
/**
* 递归出所有的子集菜单
* @param list 查询的结果集
* @param sort 排序列名
* @param lowerName 子集name
* @param superdata 相对一级
*/
private static void recursionFn(List<PageData> list, String sort, String lowerName, PageData superdata) {
List<PageData> list1 = getChildList(list, sort, superdata.get("id").toString());
if (IterUtil.isNotEmpty(list1)) {
if (StrUtil.isBlank(lowerName)) {
superdata.put("list", list1);// 未定义子集名称使用list
} else {
superdata.put(lowerName, list1);
}
for (PageData pageData : list1) {
if (IterUtil.isEmpty(list)) {
break;
}
recursionFn(list, sort, lowerName, pageData);
}
}
}
/**
* 得到子节点列表
*/
private static List<PageData> getChildList(List<PageData> list, String sort, String superId) {
List<PageData> tlist = new ArrayList<>();
Iterator<PageData> it = list.iterator();
for (int i = 0; i < list.size(); i++) {
if (list.get(i).get("pid").equals(superId)) {
tlist.add(list.remove(i));
i--;
}
}
try {
if (StrUtil.isNotBlank(sort)) {
Collections.sort(tlist, new Comparator<PageData>() {
@Override
public int compare(PageData o1, PageData o2) {
return Integer.valueOf(o1.get(superId).toString()) - Integer.valueOf(o2.get(superId).toString());
}
});
}
} catch (Exception e) {//排序码为字符了无法排序
e.printStackTrace();
}
return tlist;
}
}
我的代码里使用了hutool来做了一些判断,你们如果不想加hutool的工具包也可以改一下,但是我强烈推荐hutool。我的pageData是封装的一个map对象你们查询的时候直接返回map就可以
好了,写好没测,谁用谁测,反正坑的不是我
2021年更新,果然还是没眼看自己以前的代码,转Tree是没有必要用递归的。
/**
* 将列表转换成tree
*
* @param list 菜单集合
* @return Tree形菜单
*/
@Override
public List<Menu> buildTree(List<Menu> list) {
List<Menu> trees = new ArrayList<>();
for (Menu menuDTO : list) {
if (SysConstants.MAXMENUPID.equals(menuDTO.getPid())) {
trees.add(menuDTO);
}
for (Menu it : list) {
if (menuDTO.getId().equals(it.getPid())) {
if (menuDTO.getChildren() == null) {
menuDTO.setChildren(new ArrayList<>());
}
menuDTO.getChildren().add(it);
}
}
// 按照排序码进行排序
List<Menu> children = menuDTO.getChildren();
if (IterUtil.isNotEmpty(children)) {
children.sort(Comparator.comparingInt(Menu::getSortid));
}
}
// 排序
trees.sort(Comparator.comparingInt(Menu::getSortid));
return trees;
}