天天看點

java父子分類樹建構工具類

java父子分類樹建構工具類

  • 傳入根節點和所有分類樹節點,傳回封裝好的父子分類樹圖
@UtilityClass
public class TreeUtil {
    /**
     * 兩層循環實作建樹
     *
     * @param treeNodes 傳入的樹節點清單
     */
    public <T extends TreeNode> List<T> build(List<T> treeNodes, Object root) {

        List<T> trees = new ArrayList<>();

        for (T treeNode : treeNodes) {

            if (root.equals(treeNode.getParentId())) {
                trees.add(treeNode);
            }

            for (T it : treeNodes) {
                if (it.getParentId() == treeNode.getId()) {
                    if (treeNode.getChildren() == null) {
                        treeNode.setChildren(new ArrayList<>());
                    }
                    treeNode.add(it);
                }
            }
        }
        return trees;
    }

    /**
     * 使用遞歸方法建樹
     */
    public <T extends TreeNode> List<T> buildByRecursive(List<T> treeNodes, Object root) {
        List<T> trees = new ArrayList<>();
        for (T treeNode : treeNodes) {
            if (root.equals(treeNode.getParentId())) {
                trees.add(findChildren(treeNode, treeNodes));
            }
        }
        return trees;
    }

    /**
     * 遞歸查找子節點
     */
    public <T extends TreeNode> T findChildren(T treeNode, List<T> treeNodes) {
        for (T it : treeNodes) {
            if (treeNode.getId() == it.getParentId()) {
                if (treeNode.getChildren() == null) {
                    treeNode.setChildren(new ArrayList<>());
                }
                treeNode.add(findChildren(it, treeNodes));
            }
        }
        return treeNode;
    }

    /**
     * 通過sysMenu建立樹形節點
     */
    public List<MenuTree> buildTree(List<SysMenu> menus, int root) {
        List<MenuTree> trees = new ArrayList<>();
        MenuTree node;
        for (SysMenu menu : menus) {
            node = new MenuTree();
            node.setId(menu.getMenuId());
            node.setParentId(menu.getParentId());
            node.setName(menu.getName());
            node.setPath(menu.getPath());
            node.setCode(menu.getPermission());
            node.setLabel(menu.getName());
            node.setIcon(menu.getIcon());
            node.setKeepAlive(menu.getKeepAlive());
            node.setType(menu.getType());
            node.setSort(menu.getSort());
            node.setCreateTime(menu.getCreateTime());
            node.setUpdateTime(menu.getUpdateTime());
            node.setDelFlag(menu.getDelFlag());
            node.setTenantId(menu.getTenantId());
            trees.add(node);
        }
        return TreeUtil.build(trees, root);
    }

    /**
     * 通過sysMenu建立樹形節點
     */
    public List<MenuTree> buildMenuVoTree(List<MenuVO> menus, int root) {
        List<MenuTree> trees = new ArrayList<>();
        MenuTree node;
        for (MenuVO menu : menus) {
            node = new MenuTree();
            node.setId(menu.getMenuId());
            node.setParentId(menu.getParentId());
            node.setName(menu.getName());
            node.setPath(menu.getPath());
            node.setCode(menu.getPermission());
            node.setLabel(menu.getName());
            node.setIcon(menu.getIcon());
            node.setKeepAlive(menu.getKeepAlive());
            node.setType(menu.getType());
            node.setSort(menu.getSort());
            node.setCreateTime(menu.getCreateTime());
            node.setUpdateTime(menu.getUpdateTime());
            node.setDelFlag(menu.getDelFlag());
            trees.add(node);
        }
        return TreeUtil.build(trees, root);
    }

    /**
     * 省市區樹形節點
     *
     * @param treeNodes 省市區所有節點
     * @param root      根節點
     * @return 省市區樹
     */
    public List<ProvinceTree> bulidProvince(List<ProvinceTree> treeNodes, Object root) {

        List<ProvinceTree> trees = new ArrayList<>();

        for (ProvinceTree treeNode : treeNodes) {
            if (root.equals(treeNode.getParentId())) {
                trees.add(treeNode);
            }

            for (ProvinceTree it : treeNodes) {
                if (it.getParentId() == treeNode.getId() && it.getLevel().equals(treeNode.getLevel() + 1)) {
                    treeNode.add(it);
                }
            }
        }
        return trees;
    }

    /**
     * 根據id 查找節點
     *
     * @param treeNodes 樹形結構資料
     * @param id        節點id
     * @return 查到的節點
     */
    public TreeNode findById(List<? extends TreeNode> treeNodes, Object id) {
        for (TreeNode treeNode : treeNodes) {
            if (id.equals(treeNode.getId())) {
                return treeNode;
            }
            if (CollUtil.isNotEmpty(treeNode.getChildren())) {
                TreeNode result = findById(treeNode.getChildren(), id);
                if (result != null) {
                    return result;
                }
            }
        }
        return null;
    }

    /**
     * 擷取所有的id
     *
     * @param treeNodes  樹形結構資料
     * @param collection 要存入的集合
     */
    public void getAllId(List<? extends TreeNode> treeNodes, Collection<Integer> collection) {
        for (TreeNode treeNode : treeNodes) {
            if (treeNode != null) {
                collection.add(treeNode.getId());
                if (CollUtil.isNotEmpty(treeNode.getChildren())) {
                    getAllId(treeNode.getChildren(), collection);
                }
            }
        }
    }


    /**
     * 根據節點id遞歸擷取父節點清單
     *
     * @param treeNodes 樹形結構資料
     * @param id        節點id
     * @param nodeList  節點清單
     */
    public List<Integer> getRecursionParent(List<? extends TreeNode> treeNodes, Integer id, List<Integer> nodeList, Integer rootId) {
        TreeNode node = TreeUtil.findById(treeNodes, id);
        if (node != null) {
            nodeList.add(node.getId());
            if (node.getParentId() == rootId) {
                return nodeList;
            }
            return getRecursionParent(treeNodes, node.getParentId(), nodeList,rootId);
        }
        return Lists.newArrayList();
    }


}
           
@Data
@ApiModel(value = "樹形節點")
public class TreeNode implements Serializable {
    @ApiModelProperty(value = "目前節點id")
    protected int id;
    @ApiModelProperty(value = "目前節點代碼")
    protected String code;
    @ApiModelProperty(value = "父節點id")
    protected int parentId;
    @ApiModelProperty(value = "子節點清單")
    protected List<TreeNode> children = new ArrayList<>();

    public void add(TreeNode node) {
        children.add(node);
    }
}
           
@Data
@ApiModel(value = "菜單樹")
@EqualsAndHashCode(callSuper = true)
public class MenuTree extends TreeNode {
    /**
     * 菜單圖示
     */
    @ApiModelProperty(value = "菜單圖示")
    private String icon;
    /**
     * 菜單名稱
     */
    @ApiModelProperty(value = "菜單名稱")
    private String name;
    private boolean spread = false;
    /**
     * 前端路由辨別路徑
     */
    @ApiModelProperty(value = "前端路由辨別路徑")
    private String path;
    /**
     * 路由緩沖
     */
    @ApiModelProperty(value = "路由緩沖")
    private String keepAlive;
    /**
     * 權限編碼
     */
    @ApiModelProperty(value = "權限編碼")
    private String code;
    /**
     * 菜單類型 (0菜單 1按鈕)
     */
    @ApiModelProperty(value = "菜單類型,0:菜單 1:按鈕")
    private String type;
    /**
     * 菜單标簽
     */
    @ApiModelProperty(value = "菜單标簽")
    private String label;
    /**
     * 排序值
     */
    @ApiModelProperty(value = "排序值")
    private Integer sort;

    /**
     * 建立時間
     */
    @ApiModelProperty(value = "建立時間")
    private LocalDateTime createTime;
    /**
     * 更新時間
     */
    @ApiModelProperty(value = "更新時間")
    private LocalDateTime updateTime;

    @ApiModelProperty(value = "删除标記,1:已删除,0:正常")
    private String delFlag;

    @ApiModelProperty(value = "租戶ID")
    private Integer tenantId;

    public MenuTree() {
    }

    public MenuTree(int id, String name, int parentId) {
        this.id = id;
        this.parentId = parentId;
        this.name = name;
        this.label = name;
    }

    public MenuTree(int id, String name, MenuTree parent) {
        this.id = id;
        this.parentId = parent.getId();
        this.name = name;
        this.label = name;
    }

    public MenuTree(MenuVO menuVo) {
        this.id = menuVo.getMenuId();
        this.parentId = menuVo.getParentId();
        this.icon = menuVo.getIcon();
        this.name = menuVo.getName();
        this.path = menuVo.getPath();
        this.type = menuVo.getType();
        this.label = menuVo.getName();
        this.sort = menuVo.getSort();
        this.keepAlive = menuVo.getKeepAlive();
    }
}
           
@Getter
@Setter
public class ProvinceTree extends TreeNode implements Serializable {

    private static final long serialVersionUID = -205356155648510053L;
    
    private String name;

    private Integer level;

    /**
     * 是否最後一級(葉子節點)
     */
    private Boolean leaf;

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        ProvinceTree that = (ProvinceTree) o;
        return Objects.equals(id, that.id) && Objects.equals(name, that.name);
    }

    @Override
    public int hashCode() {
        return super.hashCode();
    }
}