package io.gisbi.utils; import io.gisbi.constant.SortConstants; import io.gisbi.model.*; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.util.Assert; import java.text.Collator; import java.util.*; import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Collectors; public class TreeUtils { public final static String DEFAULT_ROOT = "root"; public final static String SEPARATOR = "-de-"; private final static String I18N_PREFIX = "i18n_auth_menu."; public static List mergeTree(List list, Class tClass, boolean appendI18nPrefix) { AtomicBoolean rootExist = new AtomicBoolean(false); List modelList = list.stream().map(item -> { TreeModel treeModel = new TreeModel(item); if (isRoot(treeModel)) { rootExist.set(true); } return treeModel; }).toList(); List modelResult = new ArrayList<>(); Map> childMap = modelList.stream().collect(Collectors.groupingBy(TreeModel::getPid)); List existedList = new ArrayList<>(); modelList.forEach(po -> { List children = null; if (CollectionUtils.isNotEmpty(children = childMap.get(po.getId()))) { po.setChildren(children); existedList.addAll(children.stream().map(TreeModel::getId).toList()); } }); if (CollectionUtils.isEmpty(modelList)) { return null; } List floatingList = modelList.stream().filter(node -> !isRoot(node) && !existedList.contains(node.getId())).toList(); if (CollectionUtils.isNotEmpty(existedList)) { modelResult = modelList.stream().filter(node -> !existedList.contains(node.getId())).toList(); } else { modelResult = modelList; } if (rootExist.get() && CollectionUtils.isNotEmpty(floatingList)) { modelResult = modelResult.stream().filter(TreeUtils::isRoot).collect(Collectors.toList()); TreeModel root = modelResult.get(0); if (root.getChildren() == null) { root.setChildren(new ArrayList<>()); } root.getChildren().addAll(floatingList); } return convertTree(modelResult, tClass, appendI18nPrefix); } private static boolean isRoot(TreeModel node) { return node.getId().equals(0L) && (ObjectUtils.isEmpty(node.getPid()) || node.getPid().equals(-1L)); } public static List convertTree(List roots, Class tClass, boolean appendI18nPrefix) { List result = new ArrayList<>(); for (int i = 0; i < roots.size(); i++) { TreeModel node = roots.get(i); if (appendI18nPrefix) { node.getData().setName(I18N_PREFIX + node.getName()); } T instance = null; try { instance = tClass.newInstance(); } catch (InstantiationException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } T vo = BeanUtils.copyBean(instance, node.getData(), "children"); result.add(vo); List children = null; if (!CollectionUtils.isEmpty(children = node.getChildren())) { vo.setChildren(convertTree(children, tClass, appendI18nPrefix)); } } return result; } /** * Description: rootPid 是根节点PID */ public static List mergeTree(List tree, Long... rootPid) { Assert.notNull(rootPid, "Root Pid cannot be null"); if (CollectionUtils.isEmpty(tree)) { return null; } List result = new ArrayList<>(); // 构建id-节点map映射 Map treePidMap = tree.stream().collect(Collectors.toMap(T::getId, t -> t)); tree.stream().forEach(node -> { // 判断根节点 if (Arrays.asList(rootPid).contains(node.getPid())) { result.add(node); } else { //找到父元素 T parentNode = treePidMap.get(node.getPid()); if (parentNode == null) { // 可能出现 rootPid 更高的节点 这个操作相当于截断 return; } if (parentNode.getChildren() == null) { parentNode.setChildren(new ArrayList()); } parentNode.getChildren().add(node); } }); return result; } /** * Description: rootPid 是根节点PID 档期那默认是0 */ public static List mergeTree(List tree) { return mergeTree(tree, 0L); } public static List mergeDuplicateTree(List tree, Long... rootPid) { Assert.notNull(rootPid, "Root Pid cannot be null"); if (CollectionUtils.isEmpty(tree)) { return null; } List result = new ArrayList<>(); // 构建id-节点map映射 Map treePidMap = tree.stream().collect(Collectors.toMap(node -> node.getNodeType(), t -> t)); tree.stream().filter(item -> ObjectUtils.isNotEmpty(item.getId())).forEach(node -> { String nodeType = node.getNodeType(); String[] links = nodeType.split(SEPARATOR); int length = links.length; int level = Integer.parseInt(links[length - 1]); // 判断根节点 if (Arrays.asList(rootPid).contains(node.getPid()) && 0 == level) { result.add(node); } else { //找到父元素 String[] pLinks = new String[level]; System.arraycopy(links, 0, pLinks, 0, level); String parentType = Arrays.stream(pLinks).collect(Collectors.joining(SEPARATOR)) + TreeUtils.SEPARATOR + (level - 1); T parentNode = treePidMap.get(parentType); if (parentNode == null) { // 可能出现 rootPid 更高的节点 这个操作相当于截断 return; } if (parentNode.getChildren() == null) { parentNode.setChildren(new ArrayList()); } parentNode.getChildren().add(node); } }); return result; } public static List customSortVO(List list, String sortType) { Collator collator = Collator.getInstance(Locale.CHINA); if (StringUtils.equalsIgnoreCase(SortConstants.NAME_DESC, sortType)) { Set poSet = new TreeSet<>(Comparator.comparing(BusiNodeVO::getName, collator)); poSet.addAll(list); return poSet.stream().collect(Collectors.toList()); } else if (StringUtils.equalsIgnoreCase(SortConstants.NAME_ASC, sortType)) { Set poSet = new TreeSet<>(Comparator.comparing(BusiNodeVO::getName, collator).reversed()); poSet.addAll(list); return poSet.stream().collect(Collectors.toList()); } else if (StringUtils.equalsIgnoreCase(SortConstants.TIME_ASC, sortType)) { Collections.reverse(list); return list; } else { // 默认时间倒序 return list; } } }