From 8db4f0c8f7044c49c48d991dd9e860c857aa98a8 Mon Sep 17 00:00:00 2001 From: Rootrl Date: Thu, 8 Dec 2022 14:45:53 +0800 Subject: [PATCH] =?UTF-8?q?=E9=80=9A=E7=94=A8=E6=A0=91=E5=BD=A2=E8=8F=9C?= =?UTF-8?q?=E5=8D=95=E7=94=9F=E6=88=90=E5=B7=A5=E5=85=B7=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ruoyi/common/core/utils/trees/Tree.java | 136 ++++++++++++++++++ .../common/core/utils/trees/TreeNode.java | 30 ++++ 2 files changed, 166 insertions(+) create mode 100755 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/trees/Tree.java create mode 100755 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/trees/TreeNode.java diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/trees/Tree.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/trees/Tree.java new file mode 100755 index 00000000..514a5122 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/trees/Tree.java @@ -0,0 +1,136 @@ +package com.ruoyi.common.core.utils.trees; + +import java.util.ArrayList; +import java.util.List; + +/** + * 树形菜单生成工具类 + * @param + */ +public class Tree { + + /** + * 扁平化的树形结构 + */ + protected List flatTrees = new ArrayList<>(); + + /** + * 所有根节点 + */ + public List rootTrees = new ArrayList<>(); + + /** + * Id key标识 + */ + protected String idFlag; + + /** + * pid key标识 + */ + protected String pidFlag; + + /** + * name key标识 + */ + protected String nameFlag; + + /** + * 使用默认属性名 + */ + public Tree() { + this("MenuId", "ParentId", "MenuName"); + } + + /** + * 自定义修改属性名 + * @param idFlag + * @param pidFlag + * @param nameFlag + */ + public Tree(String idFlag, String pidFlag, String nameFlag) { + this.idFlag = idFlag; + this.pidFlag = pidFlag; + this.nameFlag = nameFlag; + } + + /** + * 生成树形菜单 + * @return + */ + public List generateTrees(List anyTrees) throws Exception { + + // 处理给定的树形结构 + screenTrees(anyTrees); + + // 找到父节点下面所有子节点 - 递归 + generateRecursionTrees(); + + return rootTrees; + } + + /** + * 从任意扁平树结构中生成待处理的扁平化的树形结构 以及 根节点 + * @param anyTrees + * @return + */ + protected void screenTrees(List anyTrees) throws Exception { + for (T anyTree: anyTrees) { + TreeNode treeNode = new TreeNode(); + + try { + treeNode.id = (Long) anyTree.getClass().getMethod("get" + idFlag).invoke(anyTree); + treeNode.pid = (Long) anyTree.getClass().getMethod("get" + pidFlag).invoke(anyTree); + treeNode.label = (String) anyTree.getClass().getMethod("get" + nameFlag).invoke(anyTree); + } catch (Exception e) { + throw new Exception(e.getMessage()); + } + + // 提取root节点和子节点 + if (treeNode.pid == 0L) { + this.rootTrees.add(treeNode); + } else { + this.flatTrees.add(treeNode); + } + } + } + + /** + * 使用递归方式生成树形结构 + */ + protected void generateRecursionTrees() { + for (TreeNode rootTreeNode : rootTrees) { + recursionFunction(rootTreeNode); + } + } + + /** + * 递归函数 + * @param rootTreeNode + */ + protected void recursionFunction(TreeNode rootTreeNode) { + + List usedTreeNode = new ArrayList<>(); + + for(TreeNode treeNode : flatTrees) { + if (treeNode.pid == rootTreeNode.id) { + rootTreeNode.children.add(treeNode); + // 标记使用过的node + usedTreeNode.add(treeNode); + } + } + + // 删除标记的node + flatTrees.removeAll(usedTreeNode); + + // 终止条件 + if (usedTreeNode.size() == 0) { + return; + } + + // 递归 + for (TreeNode treeNode: usedTreeNode) { + recursionFunction(treeNode); + } + } + +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/trees/TreeNode.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/trees/TreeNode.java new file mode 100755 index 00000000..6ddde44d --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/trees/TreeNode.java @@ -0,0 +1,30 @@ +package com.ruoyi.common.core.utils.trees; + +import java.util.ArrayList; +import java.util.List; + +/** + * Tree node + */ +public class TreeNode { + + /** + * ID + */ + public Long id; + + /** + * parentId + */ + public Long pid; + + /** + * Node name + */ + public String label; + + /** + * Child nodes + */ + public List children = new ArrayList<>(); +} \ No newline at end of file