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();
}
}