From 099df97db4765b1b31641a5d77a69a9f9f19b2b1 Mon Sep 17 00:00:00 2001 From: super_liu <396572590@qq.com> Date: Mon, 21 Feb 2022 12:26:24 +0800 Subject: [PATCH] feat: There is no way the, tree --- .../slrs/sarResource/entity/TsResource.java | 4 + .../service/impl/TsResourceServiceImpl.java | 2 + .../entity/SarStandardsInfoEOPage.java | 3 + .../impl/SarStandardsInfoServiceImpl.java | 30 ++- .../SarStandardsInfoMapper.xml | 8 + .../entity/SarMenuStandard.java | 5 + .../service/ISarMenuStandardService.java | 2 + .../impl/SarMenuStandardServiceImpl.java | 20 ++ .../java/com/adc/da/sys/util/tree/ITree.java | 32 +++ .../com/adc/da/sys/util/tree/ITreeNode.java | 43 ++++ .../java/com/adc/da/sys/util/tree/Tree.java | 133 ++++++++++++ .../com/adc/da/sys/util/tree/TreeNode.java | 187 ++++++++++++++++ .../sys/util/treetool/OrdNamComparator.java | 21 ++ .../com/adc/da/sys/util/treetool/Tree.java | 179 ++++++++++++++++ .../adc/da/sys/util/treetool/TreeNode.java | 202 ++++++++++++++++++ .../util/treetool/annotation/TreeNodeId.java | 12 ++ .../treetool/annotation/TreeNodeLevel.java | 12 ++ .../treetool/annotation/TreeNodeName.java | 12 ++ .../treetool/annotation/TreeNodeOrder.java | 12 ++ .../treetool/annotation/TreeNodeParentId.java | 12 ++ 20 files changed, 929 insertions(+), 2 deletions(-) create mode 100644 adc-da-sys/src/main/java/com/adc/da/sys/util/tree/ITree.java create mode 100644 adc-da-sys/src/main/java/com/adc/da/sys/util/tree/ITreeNode.java create mode 100644 adc-da-sys/src/main/java/com/adc/da/sys/util/tree/Tree.java create mode 100644 adc-da-sys/src/main/java/com/adc/da/sys/util/tree/TreeNode.java create mode 100644 adc-da-sys/src/main/java/com/adc/da/sys/util/treetool/OrdNamComparator.java create mode 100644 adc-da-sys/src/main/java/com/adc/da/sys/util/treetool/Tree.java create mode 100644 adc-da-sys/src/main/java/com/adc/da/sys/util/treetool/TreeNode.java create mode 100644 adc-da-sys/src/main/java/com/adc/da/sys/util/treetool/annotation/TreeNodeId.java create mode 100644 adc-da-sys/src/main/java/com/adc/da/sys/util/treetool/annotation/TreeNodeLevel.java create mode 100644 adc-da-sys/src/main/java/com/adc/da/sys/util/treetool/annotation/TreeNodeName.java create mode 100644 adc-da-sys/src/main/java/com/adc/da/sys/util/treetool/annotation/TreeNodeOrder.java create mode 100644 adc-da-sys/src/main/java/com/adc/da/sys/util/treetool/annotation/TreeNodeParentId.java diff --git a/adc-da-slrs/src/main/java/com/adc/da/slrs/sarResource/entity/TsResource.java b/adc-da-slrs/src/main/java/com/adc/da/slrs/sarResource/entity/TsResource.java index d0232950..84d1bcbc 100644 --- a/adc-da-slrs/src/main/java/com/adc/da/slrs/sarResource/entity/TsResource.java +++ b/adc-da-slrs/src/main/java/com/adc/da/slrs/sarResource/entity/TsResource.java @@ -103,4 +103,8 @@ public class TsResource extends BaseEntity { @TableField(exist = false) private String isFlow; + @ApiModelProperty(value = "树结构数据 区分 类型: 标准数据 tsr 技术系列 sarMs") + @TableField(exist = false) + private String treeType; + } diff --git a/adc-da-slrs/src/main/java/com/adc/da/slrs/sarResource/service/impl/TsResourceServiceImpl.java b/adc-da-slrs/src/main/java/com/adc/da/slrs/sarResource/service/impl/TsResourceServiceImpl.java index b1ba6be4..bf67d117 100644 --- a/adc-da-slrs/src/main/java/com/adc/da/slrs/sarResource/service/impl/TsResourceServiceImpl.java +++ b/adc-da-slrs/src/main/java/com/adc/da/slrs/sarResource/service/impl/TsResourceServiceImpl.java @@ -220,6 +220,7 @@ public class TsResourceServiceImpl extends ServiceImpl TsResourceQueryWrapper=new QueryWrapper<>(); TsResourceQueryWrapper.like("PARENT_IDS",resource.getId()); TsResourceQueryWrapper.orderByAsc("DISPLAY_SEQ"); @@ -343,6 +344,7 @@ public class TsResourceServiceImpl extends ServiceImpl resource1.getDisplaySeq())).collect(Collectors.toList()); tsResources.forEach(resource1 -> { + resource1.setTreeType("tsr"); resource1.setChildren(recursionGetListChildrenStand((resource1),(children))); }); } diff --git a/adc-da-slrs/src/main/java/com/adc/da/slrs/sarStandardsInfo/entity/SarStandardsInfoEOPage.java b/adc-da-slrs/src/main/java/com/adc/da/slrs/sarStandardsInfo/entity/SarStandardsInfoEOPage.java index 99d9d949..4afc427c 100644 --- a/adc-da-slrs/src/main/java/com/adc/da/slrs/sarStandardsInfo/entity/SarStandardsInfoEOPage.java +++ b/adc-da-slrs/src/main/java/com/adc/da/slrs/sarStandardsInfo/entity/SarStandardsInfoEOPage.java @@ -66,6 +66,9 @@ public class SarStandardsInfoEOPage extends BasePage { private List menuRoleList; //有权限的目录 private String[] idlist; //多个id private String menuId; //目录ID + private String treeType; // 树结构数据 区分 类型: 标准数据 tsr 技术系列 sarMs + private String sarMsType; // 树结构数据 技术系列 sarMs 过滤此目录之外数据 + private String sarMsMenuId; private String rootMenuId; private String attrSearchStr; private String advanceSearchStr; diff --git a/adc-da-slrs/src/main/java/com/adc/da/slrs/sarStandardsInfo/service/impl/SarStandardsInfoServiceImpl.java b/adc-da-slrs/src/main/java/com/adc/da/slrs/sarStandardsInfo/service/impl/SarStandardsInfoServiceImpl.java index 0640bbec..f0cdf011 100644 --- a/adc-da-slrs/src/main/java/com/adc/da/slrs/sarStandardsInfo/service/impl/SarStandardsInfoServiceImpl.java +++ b/adc-da-slrs/src/main/java/com/adc/da/slrs/sarStandardsInfo/service/impl/SarStandardsInfoServiceImpl.java @@ -221,6 +221,9 @@ public class SarStandardsInfoServiceImpl extends ServiceImpl getSarStandardsInfoPage(SarStandardsInfoEOPage page) throws Exception { //查询当前登录人角色拥有权限的菜单 if(page.getMenuId() != null && page.getUserId() != null && StringUtils.isNotBlank(page.getUserId())){ - QueryWrapper qw = new QueryWrapper<>(); + String treeType = page.getTreeType(); + QueryWrapper qw = new QueryWrapper<>(); qw.eq("ID",page.getMenuId()); qw.isNull("PARENT_ID"); List children = iTsResourceService.list(qw); - if(children.isEmpty() && !page.getMenuId().equals("nomenu")){ + if(children.isEmpty() && !page.getMenuId().equals("nomenu") && StringUtils.isNotBlank(treeType) && "tsr".equals(treeType)){ List getMenuIdList = tsUserService.getResourceUserId(page.getUserId()); if (getMenuIdList != null && !getMenuIdList.isEmpty()) { page.setMenuRoleList(getMenuIdList); @@ -314,6 +318,28 @@ public class SarStandardsInfoServiceImpl extends ServiceImpl getMenuIdList = tsUserService.getResourceUserId(page.getUserId()); + if (getMenuIdList != null && !getMenuIdList.isEmpty()) { + page.setMenuRoleList(getMenuIdList); + } else { + page.setMenuRoleList(null); + } + List ids = iSarMenuStandardService.getChildMenuList(page.getMenuId()); + if (ids != null && !ids.isEmpty()) { + page.setMenuAllChildrenIdList(ids); + } + }else if(page.getMenuId().equals("nomenu") && StringUtils.isNotBlank(page.getSarMsType()) && "filterSarMsMenu".equals(page.getSarMsType())){ + List getMenuIdList = tsUserService.getResourceUserId(page.getUserId()); + if (getMenuIdList != null && !getMenuIdList.isEmpty()) { + page.setMenuRoleList(getMenuIdList); + } else { + page.setMenuRoleList(null); + } + List ids = iSarMenuStandardService.getChildMenuList(page.getSarMsMenuId()); + if (ids != null && !ids.isEmpty()) { + page.setMenuAllChildrenIdList(ids); + } } } Integer rowCount = dao.getSarStandardsInfoCount(page); diff --git a/adc-da-slrs/src/main/resources/mybatis/mapper/sarStandardsInfo/SarStandardsInfoMapper.xml b/adc-da-slrs/src/main/resources/mybatis/mapper/sarStandardsInfo/SarStandardsInfoMapper.xml index 4a7f892f..dab4871e 100644 --- a/adc-da-slrs/src/main/resources/mybatis/mapper/sarStandardsInfo/SarStandardsInfoMapper.xml +++ b/adc-da-slrs/src/main/resources/mybatis/mapper/sarStandardsInfo/SarStandardsInfoMapper.xml @@ -1030,6 +1030,14 @@ #{item} + + + + and SAR_STAND_MENU.MENU_ID not in + + #{item} + + diff --git a/adc-da-sys/src/main/java/com/adc/da/sys/sarMenuStandard/entity/SarMenuStandard.java b/adc-da-sys/src/main/java/com/adc/da/sys/sarMenuStandard/entity/SarMenuStandard.java index 36ee728a..7cea639d 100644 --- a/adc-da-sys/src/main/java/com/adc/da/sys/sarMenuStandard/entity/SarMenuStandard.java +++ b/adc-da-sys/src/main/java/com/adc/da/sys/sarMenuStandard/entity/SarMenuStandard.java @@ -1,6 +1,7 @@ package com.adc.da.sys.sarMenuStandard.entity; import com.adc.da.base.entity.BaseEntity; +import com.adc.da.sys.utils.treetool.annotation.TreeNodeId; import com.adc.da.sys.utils.treetool.annotation.TreeNodeName; import com.adc.da.sys.utils.treetool.annotation.TreeNodeParentId; import com.baomidou.mybatisplus.annotation.IdType; @@ -35,6 +36,7 @@ public class SarMenuStandard extends BaseEntity { private static final long serialVersionUID = 1L; + @TreeNodeId @NotNull(message = "id不能为空",groups = {update.class}) @ApiModelProperty(value = "主键") @TableId(value = "ID",type = IdType.UUID) @@ -101,5 +103,8 @@ public class SarMenuStandard extends BaseEntity { @TableField(exist=false) private String parentIdsName; + @ApiModelProperty(value = "树结构数据 区分 类型: 标准数据 tsr 技术系列 sarMs") + @TableField(exist = false) + private String treeType; } diff --git a/adc-da-sys/src/main/java/com/adc/da/sys/sarMenuStandard/service/ISarMenuStandardService.java b/adc-da-sys/src/main/java/com/adc/da/sys/sarMenuStandard/service/ISarMenuStandardService.java index ec36a862..63ff3208 100644 --- a/adc-da-sys/src/main/java/com/adc/da/sys/sarMenuStandard/service/ISarMenuStandardService.java +++ b/adc-da-sys/src/main/java/com/adc/da/sys/sarMenuStandard/service/ISarMenuStandardService.java @@ -16,6 +16,8 @@ import java.util.List; */ public interface ISarMenuStandardService extends IService { + List getChildMenuList(String menuId); + /** * 查询所有菜单 */ diff --git a/adc-da-sys/src/main/java/com/adc/da/sys/sarMenuStandard/service/impl/SarMenuStandardServiceImpl.java b/adc-da-sys/src/main/java/com/adc/da/sys/sarMenuStandard/service/impl/SarMenuStandardServiceImpl.java index 2992aa20..1ac03e29 100644 --- a/adc-da-sys/src/main/java/com/adc/da/sys/sarMenuStandard/service/impl/SarMenuStandardServiceImpl.java +++ b/adc-da-sys/src/main/java/com/adc/da/sys/sarMenuStandard/service/impl/SarMenuStandardServiceImpl.java @@ -5,6 +5,8 @@ import com.adc.da.http.Result; import com.adc.da.sys.sarMenuStandard.dao.SarMenuStandardDao; import com.adc.da.sys.sarMenuStandard.entity.SarMenuStandard; import com.adc.da.sys.sarMenuStandard.service.ISarMenuStandardService; +import com.adc.da.sys.util.treetool.Tree; +import com.adc.da.sys.util.treetool.TreeNode; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.apache.commons.lang3.StringUtils; @@ -36,6 +38,22 @@ public class SarMenuStandardServiceImpl extends ServiceImpl getChildMenuList (String menuId) { + List menuIds = new ArrayList<>(); + if (StringUtils.isNotEmpty(menuId)) { + List SarMenuList = dao.selectList(new QueryWrapper<>()); + Tree tree = new Tree(SarMenuList); + TreeNode treeNode = tree.getTreeNode(menuId); + if (treeNode != null) { + menuIds.add(treeNode.getNodeId()); + for (TreeNode node : treeNode.getAllChildren()) { + menuIds.add(node.getNodeId()); + } + } + } + return menuIds; + } + /** * 查询有权限菜单 * @param sarMenuStandard @@ -57,6 +75,7 @@ public class SarMenuStandardServiceImpl extends ServiceImpl TsResourceQueryWrapper=new QueryWrapper<>(); TsResourceQueryWrapper.like("PARENT_IDS",resource.getId()); TsResourceQueryWrapper.orderByAsc("DISPLAY_SEQ"); @@ -78,6 +97,7 @@ public class SarMenuStandardServiceImpl extends ServiceImpl resource1.getDisplaySeq())).collect(Collectors.toList()); tsResources.forEach(resource1 -> { + resource1.setTreeType("sarMs"); resource1.setChildren(recursionGetListChildrenStand((resource1),(children))); }); } diff --git a/adc-da-sys/src/main/java/com/adc/da/sys/util/tree/ITree.java b/adc-da-sys/src/main/java/com/adc/da/sys/util/tree/ITree.java new file mode 100644 index 00000000..8ad5afe8 --- /dev/null +++ b/adc-da-sys/src/main/java/com/adc/da/sys/util/tree/ITree.java @@ -0,0 +1,32 @@ +package com.adc.da.sys.util.tree; + +import java.util.List; + +/** + * 操作树的接口类 + * + */ +public interface ITree { + /** + * 获取构建数的list,因为根节点可能不止一个,所有返回List + * 获取的结构与getRoot基本一致,但是后边增加了另外的数据,不建议调用 + * + * @return + */ + List getTree(); + + /** + * 获取根节点树结构,因为根节点可能不止一个,所有返回List + * + * @return + */ + List getRoot(); + + /** + * 获取指定节点数据 + * + * @param nodeId + * @return + */ + TreeNode getTreeNode(String nodeId); +} diff --git a/adc-da-sys/src/main/java/com/adc/da/sys/util/tree/ITreeNode.java b/adc-da-sys/src/main/java/com/adc/da/sys/util/tree/ITreeNode.java new file mode 100644 index 00000000..7ee144a4 --- /dev/null +++ b/adc-da-sys/src/main/java/com/adc/da/sys/util/tree/ITreeNode.java @@ -0,0 +1,43 @@ +package com.adc.da.sys.util.tree; + +/** + * 需要实现树的实体类需要实现的接口,获取关键数据 + * + */ +public interface ITreeNode { + /** + * TreeNode获取nodeId + * + * @return + */ + String getNodeId(); + + /** + * TreeNode获取nodeName + * + * @return + */ + String getNodeName(); + + /** + * TreeNode获取nodeParentId(父id) + * + * @return + */ + String getNodeParentId(); + + /** + * TreeNode获取orderNum(排序字段用于排序) + * + * @return + */ + Integer getOrderNum(); + + /** + * TreeNode获取nodeLevel(当前属于第几层级) + * + * @return + */ + Integer getNodeLevel(); + +} diff --git a/adc-da-sys/src/main/java/com/adc/da/sys/util/tree/Tree.java b/adc-da-sys/src/main/java/com/adc/da/sys/util/tree/Tree.java new file mode 100644 index 00000000..9ac1d670 --- /dev/null +++ b/adc-da-sys/src/main/java/com/adc/da/sys/util/tree/Tree.java @@ -0,0 +1,133 @@ +package com.adc.da.sys.util.tree; + +import com.adc.da.sys.sarMenuStandard.entity.SarMenuStandard; +import org.apache.commons.lang3.StringUtils; + +import java.util.*; + +/** + * 构建树形建构 + */ +public class Tree implements ITree { + /** + * 用于存放treeNode的Map + */ + private LinkedHashMap treeNodesMap = new LinkedHashMap<>(); + /** + * 用于存放treeNode的list + */ + private List treeNodesList = new ArrayList<>(); + + /** + * 构造方法 + * + * @param list + */ + public Tree(List list) { + initTreeNodeMap(list); + initTreeNodeList(); + } + + /** + * 将List对象数据转为TreeNodeMap + * + * @param list + */ + private void initTreeNodeMap(List list) { + TreeNode treeNode; + for (ITreeNode item : list) { + treeNode = new TreeNode(item); + treeNode.setLastNodeNum(1); + treeNodesMap.put(treeNode.getNodeId(), treeNode); + } + Iterator iterator = treeNodesMap.values().iterator(); + TreeNode parentTreeNode; + while (iterator.hasNext()) { + treeNode = iterator.next(); + if (StringUtils.isEmpty(treeNode.getParentNodeId())) { + continue; + } + parentTreeNode = treeNodesMap.get(treeNode.getParentNodeId()); + if (parentTreeNode != null) { + treeNode.setParent(parentTreeNode); + parentTreeNode.addChild(treeNode); + // 按照orderNum排序 + Collections.sort(parentTreeNode.getChildren(), new OrdNamComparator()); + // 判断这个节点是否是最子节点 + if (treeNode.getChildren().size() == 0) { + treeNode.setLastNode(true); + } + // 计算每一个节点的最子节点的数量 + List children = parentTreeNode.getChildren(); + if (children.size() > 0) { + int sum = 0; + for (TreeNode treeNode2 : children) { + sum += treeNode2.getLastNodeNum(); + } + parentTreeNode.setLastNodeNum(sum); + } + } + } + } + + /** + * 根据treeNodesMap转为treeNodesList + */ + private void initTreeNodeList() { + if (treeNodesList.size() > 0) { + return; + } + if (treeNodesMap.size() == 0) { + return; + } + Iterator iterator = treeNodesMap.values().iterator(); + TreeNode treeNode; + while (iterator.hasNext()) { + treeNode = iterator.next(); + if (treeNode.getParent() == null) { + this.treeNodesList.add(treeNode); + this.treeNodesList.addAll(treeNode.getAllChildren()); + } + } + } + + @Override + public List getTree() { + return this.treeNodesList; + } + + @Override + public List getRoot() { + List rootList = new ArrayList<>(); + if (this.treeNodesList.size() > 0) { + for (TreeNode node : treeNodesList) { + if (node.getParent() == null) { + rootList.add(node); + Collections.sort(rootList, new OrdNamComparator()); + } + } + } + return rootList; + } + + @Override + public TreeNode getTreeNode(String nodeId) { + return this.treeNodesMap.get(nodeId); + } +} + +/** + * 自定义排序,按照orderNum排序 + */ +class OrdNamComparator implements Comparator { + @Override + public int compare(TreeNode t1, TreeNode t2) { + if (t1.getOrderNum() > t2.getOrderNum()) { + return 1; + } + if (t1.getOrderNum() < t2.getOrderNum()) { + return -1; + } + return t1.getNodeName().compareTo(t2.getNodeName()); + } +} \ No newline at end of file diff --git a/adc-da-sys/src/main/java/com/adc/da/sys/util/tree/TreeNode.java b/adc-da-sys/src/main/java/com/adc/da/sys/util/tree/TreeNode.java new file mode 100644 index 00000000..7bc15e30 --- /dev/null +++ b/adc-da-sys/src/main/java/com/adc/da/sys/util/tree/TreeNode.java @@ -0,0 +1,187 @@ +package com.adc.da.sys.util.tree; + +import com.alibaba.fastjson.annotation.JSONField; + +import java.util.ArrayList; +import java.util.List; + +public class TreeNode { + + /** + * 树节点ID + */ + @JSONField(ordinal = 1) + private String nodeId; + /** + * 树节点名称 + */ + @JSONField(ordinal = 2) + private String nodeName; + /** + * 父节点ID + */ + @JSONField(ordinal = 3) + private String parentNodeId; + /** + * 节点在树中的排序号 + */ + @JSONField(ordinal = 4) + private int orderNum; + /** + * 节点所在的层级 + */ + @JSONField(ordinal = 5) + private int level; + /** + * 最子节点的数量 + */ + @JSONField(ordinal = 6) + private int lastNodeNum; + + /** + * 是否是最子节点 + */ + @JSONField(ordinal = 7) + private boolean lastNode; + + /** + * 当前节点的儿子节点 + */ + @JSONField(ordinal = 8) + private List children = new ArrayList<>(); + + /** + * 当前节点的完整路径 + */ + @JSONField(ordinal = 9) + private String completeName; + + /** + * 当前节点的父级节点 + * 转json的时候忽略此属性,因为此属性到前端无作用 + */ + @JSONField(serialize = false) + private TreeNode parent; + + /** + * 当前节点的子孙节点 + * 转json的时候忽略此属性,因为此属性到前端无作用 + */ + @JSONField(serialize = false) + private List allChildren = new ArrayList<>(); + + public TreeNode(ITreeNode obj) { + this.nodeId = obj.getNodeId(); + this.nodeName = obj.getNodeName(); + this.parentNodeId = obj.getNodeParentId(); + this.orderNum = obj.getOrderNum(); + this.level = obj.getNodeLevel(); + } + + public TreeNode(TreeNode obj) { + this.orderNum = obj.getOrderNum(); + this.level = obj.getLevel(); + this.lastNodeNum = obj.getLastNodeNum(); + } + + public TreeNode() { + } + + public void addChild(TreeNode treeNode) { + this.children.add(treeNode); + } + + public void removeChild(TreeNode treeNode) { + this.children.remove(treeNode); + } + + public String getNodeId() { + return nodeId; + } + + public void setNodeId(String nodeId) { + this.nodeId = nodeId; + } + + public String getNodeName() { + return nodeName; + } + + public void setNodeName(String nodeName) { + this.nodeName = nodeName; + } + + public String getParentNodeId() { + return parentNodeId; + } + + public void setParentNodeId(String parentNodeId) { + this.parentNodeId = parentNodeId; + } + + public int getLevel() { + return level; + } + + public void setLevel(int level) { + this.level = level; + } + + public TreeNode getParent() { + return parent; + } + + public void setParent(TreeNode parent) { + this.parent = parent; + } + + public List getChildren() { + return children; + } + + public void setChildren(List children) { + this.children = children; + } + + public int getOrderNum() { + return orderNum; + } + + public void setOrderNum(int orderNum) { + this.orderNum = orderNum; + } + + public int getLastNodeNum() { + return lastNodeNum; + } + + public void setLastNodeNum(int lastNodeNum) { + this.lastNodeNum = lastNodeNum; + } + + public boolean isLastNode() { + return lastNode; + } + + public void setLastNode(boolean lastNode) { + this.lastNode = lastNode; + } + + public List getAllChildren() { + if (this.allChildren.isEmpty()) { + for (TreeNode treeNode : this.children) { + this.allChildren.add(treeNode); + this.allChildren.addAll(treeNode.getAllChildren()); + } + } + return this.allChildren; + } + + public String getCompleteName() { + return completeName; + } + + public void setCompleteName(String completeName) { + this.completeName = completeName; + } +} \ No newline at end of file diff --git a/adc-da-sys/src/main/java/com/adc/da/sys/util/treetool/OrdNamComparator.java b/adc-da-sys/src/main/java/com/adc/da/sys/util/treetool/OrdNamComparator.java new file mode 100644 index 00000000..324f1e68 --- /dev/null +++ b/adc-da-sys/src/main/java/com/adc/da/sys/util/treetool/OrdNamComparator.java @@ -0,0 +1,21 @@ +package com.adc.da.sys.util.treetool; + +import java.util.Comparator; + +/** + * List 排序 Comparator + * @author david + */ +public class OrdNamComparator implements Comparator { + + @Override + public int compare(TreeNode t1, TreeNode t2) { + if (t1.getOrderNum() > t2.getOrderNum()) { + return 1; + } + if (t1.getOrderNum() < t2.getOrderNum()) { + return -1; + } + return t1.getNodeName().compareTo(t2.getNodeName()); + } +} diff --git a/adc-da-sys/src/main/java/com/adc/da/sys/util/treetool/Tree.java b/adc-da-sys/src/main/java/com/adc/da/sys/util/treetool/Tree.java new file mode 100644 index 00000000..7538fa61 --- /dev/null +++ b/adc-da-sys/src/main/java/com/adc/da/sys/util/treetool/Tree.java @@ -0,0 +1,179 @@ +package com.adc.da.sys.util.treetool; + +import com.adc.da.sys.utils.treetool.annotation.*; +import org.apache.commons.lang3.StringUtils; + +import java.lang.reflect.Field; +import java.util.*; + +//import group.ipp.tree.util.annotation.TreeNodeLevel; +//import group.ipp.tree.util.annotation.TreeNodeName; +//import group.ipp.tree.util.annotation.TreeNodeOrder; +//import group.ipp.tree.util.annotation.TreeNodeParentId; + +/** + * 构建树形建构 + * + * @author David + */ +public class Tree { + /** + * 用于存放treeNode的Map + */ + private LinkedHashMap treeNodesMap = new LinkedHashMap<>(); + /** + * 用于存放treeNode的list + */ + private List treeNodesList = new ArrayList<>(); + + /** + * 构造方法 + * + * @param list + */ + public Tree(List list) { + initTreeNodeMap(list); + initTreeNodeList(); + } + + /** + * 将List对象数据转为TreeNodeMap + * + * @param list + */ + private void initTreeNodeMap(List list) { + TreeNode treeNode; + for (Object item : list) { + treeNode = new TreeNode(); + treeNode.setNodeId(getFieldValue(item, "TreeNodeId")); + treeNode.setNodeName(getFieldValue(item, "TreeNodeName")); + treeNode.setParentNodeId(getFieldValue(item, "TreeNodeParentId")); + if(StringUtils.isEmpty(getFieldValue(item, "TreeNodeLevel"))) { + treeNode.setLevel(0); + } else { + treeNode.setLevel(Integer.parseInt(getFieldValue(item, "TreeNodeLevel"))); + } + if(StringUtils.isEmpty(getFieldValue(item, "TreeNodeOrder"))) { + treeNode.setOrderNum(0); + } else { + treeNode.setOrderNum(Integer.parseInt(getFieldValue(item, "TreeNodeOrder"))); + } + treeNode.setLastNodeNum(1); + treeNode.setData(item); + treeNodesMap.put(treeNode.getNodeId(), treeNode); + } + Iterator iterator = treeNodesMap.values().iterator(); + TreeNode parentTreeNode; + while (iterator.hasNext()) { + treeNode = iterator.next(); + if (StringUtils.isEmpty(treeNode.getParentNodeId())) { + continue; + } + parentTreeNode = treeNodesMap.get(treeNode.getParentNodeId()); + if (parentTreeNode != null) { + treeNode.setParent(parentTreeNode); + parentTreeNode.addChild(treeNode); + // 按照orderNum排序 + Collections.sort(parentTreeNode.getChildren(), new OrdNamComparator()); + // 判断这个节点是否是最子节点 + if (treeNode.getChildren().size() == 0) { + treeNode.setLastNode(true); + } + // 计算每一个节点的最子节点的数量 + List children = parentTreeNode.getChildren(); + if (children.size() > 0) { + int sum = 0; + for (TreeNode treeNode2 : children) { + sum += treeNode2.getLastNodeNum(); + } + parentTreeNode.setLastNodeNum(sum); + } + } + } + } + + private String getFieldValue(Object obj, String type) { + Class clz = obj.getClass(); + Field[] fields = clz.getDeclaredFields(); + String value = null; + try { + for(Field field : fields){ + field.setAccessible(true); + switch (type){ + case "TreeNodeId": + if(field.isAnnotationPresent(TreeNodeId.class)) { + value = String.valueOf(field.get(obj)); + } + break; + case "TreeNodeParentId": + if(field.isAnnotationPresent(TreeNodeParentId.class)) { + value = String.valueOf(field.get(obj)); + } + break; + case "TreeNodeName": + if(field.isAnnotationPresent(TreeNodeName.class)) { + value = String.valueOf(field.get(obj)); + } + break; + case "TreeNodeOrder": + if(field.isAnnotationPresent(TreeNodeOrder.class)) { + value = String.valueOf(field.get(obj)); + } + break; + case "TreeNodeLevel": + if(field.isAnnotationPresent(TreeNodeLevel.class)) { + value = String.valueOf(field.get(obj)); + } + break; + default: + break; + } + } + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + return value; + } + + /** + * 根据treeNodesMap转为treeNodesList + */ + private void initTreeNodeList() { + if (treeNodesList.size() > 0) { + return; + } + if (treeNodesMap.size() == 0) { + return; + } + Iterator iterator = treeNodesMap.values().iterator(); + TreeNode treeNode; + while (iterator.hasNext()) { + treeNode = iterator.next(); + if (treeNode.getParent() == null) { + this.treeNodesList.add(treeNode); + this.treeNodesList.addAll(treeNode.getAllChildren()); + } + } + } + + public List getTree() { + return this.treeNodesList; + } + + public List getRoot() { + List rootList = new ArrayList<>(); + if (this.treeNodesList.size() > 0) { + for (TreeNode node : treeNodesList) { + if (node.getParent() == null) { + rootList.add(node); + Collections.sort(rootList, new OrdNamComparator()); + } + } + } + return rootList; + } + + public TreeNode getTreeNode(String nodeId) { + return this.treeNodesMap.get(nodeId); + } +} \ No newline at end of file diff --git a/adc-da-sys/src/main/java/com/adc/da/sys/util/treetool/TreeNode.java b/adc-da-sys/src/main/java/com/adc/da/sys/util/treetool/TreeNode.java new file mode 100644 index 00000000..a978a5b3 --- /dev/null +++ b/adc-da-sys/src/main/java/com/adc/da/sys/util/treetool/TreeNode.java @@ -0,0 +1,202 @@ +package com.adc.da.sys.util.treetool; + +import com.alibaba.fastjson.annotation.JSONField; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author David + */ +public class TreeNode { + + /** + * 树节点ID + */ + @JSONField(ordinal = 1) + private String nodeId; + /** + * 树节点名称 + */ + @JSONField(ordinal = 2) + private String nodeName; + /** + * 父节点ID + */ + @JSONField(ordinal = 3) + private String parentNodeId; + /** + * 节点在树中的排序号 + */ + @JSONField(ordinal = 4) + private int orderNum; + /** + * 节点所在的层级 + */ + @JSONField(ordinal = 5) + private int level; + /** + * 最子节点的数量 + */ + @JSONField(ordinal = 6) + private int lastNodeNum; + + /** + * 是否是最子节点 + */ + @JSONField(ordinal = 7) + private boolean lastNode; + + private Object data; + + /** + * 当前节点的儿子节点 + */ + @JSONField(ordinal = 8) + private List children = new ArrayList<>(); + + /** + * 当前节点的完整路径 + */ + @JSONField(ordinal = 9) + private String completeName; + + /** + * 当前节点的父级节点 + * 转json的时候忽略此属性,因为此属性到前端无作用 + */ + @JSONField(serialize = false) + private TreeNode parent; + + /** + * 当前节点的子孙节点 + * 转json的时候忽略此属性,因为此属性到前端无作用 + */ + @JSONField(serialize = false) + private List allChildren = new ArrayList<>(); + + private int standFlag; + + public TreeNode(TreeNode obj) { + this.orderNum = obj.getOrderNum(); + this.level = obj.getLevel(); + this.lastNodeNum = obj.getLastNodeNum(); + } + + public TreeNode() { + } + + public void addChild(TreeNode treeNode) { + this.children.add(treeNode); + } + + public void removeChild(TreeNode treeNode) { + this.children.remove(treeNode); + } + + public String getNodeId() { + return nodeId; + } + + public void setNodeId(String nodeId) { + this.nodeId = nodeId; + } + + public String getNodeName() { + return nodeName; + } + + public void setNodeName(String nodeName) { + this.nodeName = nodeName; + } + + public String getParentNodeId() { + return parentNodeId; + } + + public void setParentNodeId(String parentNodeId) { + this.parentNodeId = parentNodeId; + } + + public int getLevel() { + return level; + } + + public void setLevel(int level) { + this.level = level; + } + + public TreeNode getParent() { + return parent; + } + + public void setParent(TreeNode parent) { + this.parent = parent; + } + + public List getChildren() { + return children; + } + + public void setChildren(List children) { + this.children = children; + } + + public int getOrderNum() { + return orderNum; + } + + public void setOrderNum(int orderNum) { + this.orderNum = orderNum; + } + + public int getLastNodeNum() { + return lastNodeNum; + } + + public void setLastNodeNum(int lastNodeNum) { + this.lastNodeNum = lastNodeNum; + } + + public boolean isLastNode() { + return lastNode; + } + + public void setLastNode(boolean lastNode) { + this.lastNode = lastNode; + } + + public List getAllChildren() { + if (this.allChildren.isEmpty()) { + for (TreeNode treeNode : this.children) { + this.allChildren.add(treeNode); + this.allChildren.addAll(treeNode.getAllChildren()); + } + } + return this.allChildren; + } + + public String getCompleteName() { + return completeName; + } + + public void setCompleteName(String completeName) { + this.completeName = completeName; + } + + public Object getData() { + return data; + } + + public void setData(Object data) { + this.data = data; + } + + public int getStandFlag() { + return standFlag; + } + + public void setStandFlag(int standFlag) { + this.standFlag = standFlag; + } +} \ No newline at end of file diff --git a/adc-da-sys/src/main/java/com/adc/da/sys/util/treetool/annotation/TreeNodeId.java b/adc-da-sys/src/main/java/com/adc/da/sys/util/treetool/annotation/TreeNodeId.java new file mode 100644 index 00000000..c8b1b2df --- /dev/null +++ b/adc-da-sys/src/main/java/com/adc/da/sys/util/treetool/annotation/TreeNodeId.java @@ -0,0 +1,12 @@ +package com.adc.da.sys.util.treetool.annotation; + +import java.lang.annotation.*; + +/** + * @author david + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.FIELD}) +@Documented +public @interface TreeNodeId { +} diff --git a/adc-da-sys/src/main/java/com/adc/da/sys/util/treetool/annotation/TreeNodeLevel.java b/adc-da-sys/src/main/java/com/adc/da/sys/util/treetool/annotation/TreeNodeLevel.java new file mode 100644 index 00000000..caf33377 --- /dev/null +++ b/adc-da-sys/src/main/java/com/adc/da/sys/util/treetool/annotation/TreeNodeLevel.java @@ -0,0 +1,12 @@ +package com.adc.da.sys.util.treetool.annotation; + +import java.lang.annotation.*; + +/** + * @author david + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.FIELD}) +@Documented +public @interface TreeNodeLevel { +} diff --git a/adc-da-sys/src/main/java/com/adc/da/sys/util/treetool/annotation/TreeNodeName.java b/adc-da-sys/src/main/java/com/adc/da/sys/util/treetool/annotation/TreeNodeName.java new file mode 100644 index 00000000..7d5dd96c --- /dev/null +++ b/adc-da-sys/src/main/java/com/adc/da/sys/util/treetool/annotation/TreeNodeName.java @@ -0,0 +1,12 @@ +package com.adc.da.sys.util.treetool.annotation; + +import java.lang.annotation.*; + +/** + * @author david + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.FIELD}) +@Documented +public @interface TreeNodeName { +} diff --git a/adc-da-sys/src/main/java/com/adc/da/sys/util/treetool/annotation/TreeNodeOrder.java b/adc-da-sys/src/main/java/com/adc/da/sys/util/treetool/annotation/TreeNodeOrder.java new file mode 100644 index 00000000..270b719b --- /dev/null +++ b/adc-da-sys/src/main/java/com/adc/da/sys/util/treetool/annotation/TreeNodeOrder.java @@ -0,0 +1,12 @@ +package com.adc.da.sys.util.treetool.annotation; + +import java.lang.annotation.*; + +/** + * @author david + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.FIELD}) +@Documented +public @interface TreeNodeOrder { +} diff --git a/adc-da-sys/src/main/java/com/adc/da/sys/util/treetool/annotation/TreeNodeParentId.java b/adc-da-sys/src/main/java/com/adc/da/sys/util/treetool/annotation/TreeNodeParentId.java new file mode 100644 index 00000000..a3a07750 --- /dev/null +++ b/adc-da-sys/src/main/java/com/adc/da/sys/util/treetool/annotation/TreeNodeParentId.java @@ -0,0 +1,12 @@ +package com.adc.da.sys.util.treetool.annotation; + +import java.lang.annotation.*; + +/** + * @author david + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.FIELD}) +@Documented +public @interface TreeNodeParentId { +}