package com.estate.expert.admin.utils.tree; import com.estate.expert.admin.enums.BizResultCode; import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import javax.persistence.Transient; import java.util.*; /** * 树根节点 */ @Getter @Setter @Slf4j public abstract class TreeRoot { // 保存所有的节点, 用于快速查找 @JsonIgnore @Transient private HashMap> nodeMap = new HashMap<>(); @JsonIgnore @Transient private HashMap> namePathMap = new HashMap<>(); /* * 获取树的根节点 * 数据放到具体的实现类中 * 例如DepartmentStore * 以便于可读性和字段控制 */ public abstract TreeNode root() ; public TreeNode getByNamePath(String namePath) { return namePathMap.get(namePath); } public TreeNode get(String path) { return get(path, true); } public TreeNode get(String path, boolean recursive) { var node = nodeMap.get(path); if (node == null) { return null; } if (recursive) { return node; } return node.ShadowNode(); } public void edit(String path, String name, T data) { var node = get(path); BizResultCode.HIERARCHY_NODE_NOT_FOUND.check(node == null); if(node.getParent()!= null) { for (TreeNode child : node.getParent().getChildren().values()) { BizResultCode.HIERARCHY_NODE_NAME_ALREADY_EXISTS.check(child.getName().equals(name) && !child.getId().equals(node.getId())); } } node.setName(name); node.setData(data); } public void remove(String path) { var node = get(path); if (node == null) { return; } nodeMap.remove(path); namePathMap.remove(node.getNamePath()); var parent = node.getParent(); if (parent == null) { return; } parent.getChildren().remove(node.getId()); } public TreeNode addChild(String parentPath, String name, T data) { var parent = get(parentPath); BizResultCode.HIERARCHY_PARENT_NOT_FOUND.check(parent == null); var child = parent.addChild(name, data); nodeMap.put(child.getPath(), child); namePathMap.put(child.getNamePath(), child); return child; } // copy节点 // public TreeNode copy(String path) { // var node = get(path); // BizResultCode.HIERARCHY_NODE_NOT_FOUND.check(node == null); // var parent = node.getParent(); // BizResultCode.HIERARCHY_PARENT_NOT_FOUND.check(parent == null); // //// TreeHelper.convertTree(node, ) // } /* * 设置树的父子关系 * 同时将所有的节点放入nodeMap中 * 便于快速查找 */ public TreeRoot buildTree() { nodeMap.clear(); if(root() == null) return this; root().buildPath(); nodeMap.put(root().getPath(), root()); namePathMap.clear(); namePathMap.put(root().getNamePath(), root()); setParent(root()); return this; } // 设置所有的节点的父节点引用, 并将节点放入nodeMap中 private void setParent(TreeNode node) { for (TreeNode child : node.getChildren().values()) { child.setParent(node); child.buildPath(); nodeMap.put(child.getPath(), child); namePathMap.put(child.getNamePath(), child); setParent(child); } } public List> children(String path){ return children(path, null); } public List> children(String path, String keyword) { var result = new ArrayList>(); var node = get(path); BizResultCode.HIERARCHY_NODE_NOT_FOUND.check(node == null); // 不包含子节点 for (var child : node.getChildren().values()) { if(StringUtils.isBlank(keyword) || child.getName().contains(keyword)) result.add(child.ShadowNode()); } return result; } public List findAllPaths(List hierarchyPaths) { var nodes = hierarchyPaths.stream() .map(h -> get(h, true)) .filter(Objects::nonNull) .toList(); // 归总并过滤掉相同的path var pathMap = new TreeSet(); nodes.forEach(n -> pathMap.addAll( n.allPaths())); return new ArrayList<>(pathMap); } }