@Override
public List<DashMenuTreeNodeVO> listProjectVOSForFeishu() {
List<ProjectDashboardTabChartVO> projectDashboardTabChartVOList = dashboardMapper.listProjectDashboardTabChart(true);
if (CollectionUtils.isEmpty(projectDashboardTabChartVOList)) {
return Collections.emptyList();
}
DashMenuTreeNodeVO root = new DashMenuTreeNodeVO();
for (int i = 0; i < projectDashboardTabChartVOList.size(); i++) {
ProjectDashboardTabChartVO vo = projectDashboardTabChartVOList.get(i);
root.add(vo);
}
return new LinkedList<>(root.getChildren());
}
DashMenuTreeNodeVO:
package com.soyoung.ztdata.bi.core.vo.report;
import com.soyoung.ztdata.bi.core.enums.DashMenuTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import java.util.*;
/**
*/
@Slf4j
public class DashMenuTreeNodeVO {
private String id;
private String name;
/**
* 当前节点类型
*/
String type;
/**
* 排序字段
*/
private Integer sortNum;
/**
* 是否可编辑
*/
private Boolean edit = false;
/**
* 是否可删除
*/
private Boolean del = false;
/**
* 子节点
*/
private Set<DashMenuTreeNodeVO> children = new TreeSet<>((o1, o2) -> {
if (null == o1.sortNum || null == o2.sortNum) {
return -1;
}
if (Objects.equals(o1.sortNum, o2.sortNum)) {
if (Objects.equals(o1.getId(), o2.getId())) {
return -1;
}
return o1.getId().compareTo(o2.getId());
}
return o1.sortNum.compareTo(o2.sortNum);
});
public DashMenuTreeNodeVO() {
}
public DashMenuTreeNodeVO(String type) {
this.type = type;
}
private static final ThreadLocal<Finder> finder = new ThreadLocal<>();
/**
* 状态模式
* type == null, // 说明是 根 root 节点, 获取菜单探测器探测结果(DashMenuTreeNodeVO),探测结果作为 子树 root 继续添加节点(node)
* <p>
* type == project("文件夹") && level == 0, // 说明是第一级菜单, 不可能出现此状态(type == null时,已经把level = 0 和 level = 1 两级节点关联了)
* <p>
* type == project("文件夹") && level == 1, // 说明是第二级菜单, 获取仪表盘探测器探测结果(DashMenuTreeNodeVO),探测结果作为root继续添加节点(node)
* <p>
* // type == dashboard("看板"), // 说明是看板节点,从页签探测器中获取页签引用,作为 子树 root 继续添加节点(node)
* <p>
* // type == tab("页签"), // 说明是页签节点,从图表探测器中获取图表引用,作为 子树 root 继续添加节点(node)
* <p>
* // type == chart("图表"); // 说明是图表节点(叶子节点),将 子树集合 置为 null
*
* @param node
*/
public void add(ProjectDashboardTabChartVO node) {
if (null == finder.get() || (null == type && this.children.size() == 0)) {
finder.set(new Finder());
}
DashMenuTreeNodeVO root;
String uniquePId = uniquePId(node);
String uniqueProjId = uniqueProjId(node);
String uniqueDashId = uniqueDashId(node);
String uniqueTabId = uniqueTabId(node);
String uniqueChartId = uniqueChartId(node);
if (null == type) { // this == root
if (Objects.equals("0", uniquePId)) { // node == 一级
root = finder.get().getProjectFinder().computeIfAbsent(uniqueProjId,
key -> {
DashMenuTreeNodeVO dashMenuTreeNodeVO = new DashMenuTreeNodeVO(DashMenuTypeEnum.project.name()).setId(node.getProjId()).setName(node.getProjName()).setSortNum(node.getProjectSortNum());
this.children.add(dashMenuTreeNodeVO);
return dashMenuTreeNodeVO;
});
root.add(node);
} else { // node == 二级
// pid
DashMenuTreeNodeVO rootPid = finder.get().getProjectFinder().computeIfAbsent(uniquePId,
key -> {
DashMenuTreeNodeVO dashMenuTreeNodeVO = new DashMenuTreeNodeVO(DashMenuTypeEnum.project.name()).setId(node.getPid()).setName(node.getPname()).setSortNum(node.getPSortNum());
this.children.add(dashMenuTreeNodeVO);
return dashMenuTreeNodeVO;
});
// projId
root = finder.get().getProjectFinder().computeIfAbsent(uniqueProjId,
key -> {
final DashMenuTreeNodeVO dashMenuTreeNodeVO = new DashMenuTreeNodeVO(DashMenuTypeEnum.project.name()).setId(node.getProjId()).setName(node.getProjName()).setSortNum(node.getProjectSortNum());
rootPid.getChildren().add(dashMenuTreeNodeVO);
return dashMenuTreeNodeVO;
});
root.add(node);
}
} else if (Objects.equals(DashMenuTypeEnum.project.name(), this.type)) {
root = finder.get().getDashboardFinder().computeIfAbsent(uniqueDashId,
key -> {
final DashMenuTreeNodeVO dashMenuTreeNodeVO = new DashMenuTreeNodeVO(DashMenuTypeEnum.dashboard.name()).setId(node.getDashId()).setName(node.getDashName()).setSortNum(node.getDashSortNum());
this.children.add(dashMenuTreeNodeVO);
return dashMenuTreeNodeVO;
});
root.add(node);
} else if (Objects.equals(DashMenuTypeEnum.dashboard.name(), this.type)) {
root = finder.get().getTabFinder().computeIfAbsent(uniqueTabId,
key -> {
final DashMenuTreeNodeVO dashMenuTreeNodeVO = new DashMenuTreeNodeVO(DashMenuTypeEnum.tab.name()).setId(node.getTabId()).setName(node.getTabName());
this.children.add(dashMenuTreeNodeVO);
return dashMenuTreeNodeVO;
});
root.add(node);
} else if (Objects.equals(DashMenuTypeEnum.tab.name(), this.type)) {
if (StringUtils.isBlank(uniqueChartId)) {
this.children = null;
return;
}
root = finder.get().getChartFinder().computeIfAbsent(uniqueChartId,
key -> {
final DashMenuTreeNodeVO dashMenuTreeNodeVO = new DashMenuTreeNodeVO(DashMenuTypeEnum.chart.name()).setId(node.getChartId()).setName(node.getChartName());
this.children.add(dashMenuTreeNodeVO);
return dashMenuTreeNodeVO;
});
root.add(node);
} else if (Objects.equals(DashMenuTypeEnum.chart.name(), this.type)) {
this.children = null;
}
}
private String uniqueChartId(ProjectDashboardTabChartVO node) {
return node.getChartId();
}
private String uniqueTabId(ProjectDashboardTabChartVO node) {
return uniqueDashId(node) + ":" + node.getTabId();
}
private String uniquePId(ProjectDashboardTabChartVO node) {
return node.getPid();
}
private String uniqueDashId(ProjectDashboardTabChartVO node) {
return node.getDashId();
}
private String uniqueProjId(ProjectDashboardTabChartVO node) {
return node.getProjId();
}
public String getId() {
return id;
}
public DashMenuTreeNodeVO setId(String id) {
this.id = id;
return this;
}
public String getName() {
return name;
}
public DashMenuTreeNodeVO setName(String name) {
this.name = name;
return this;
}
public String getType() {
return type;
}
public DashMenuTreeNodeVO setType(String type) {
this.type = type;
return this;
}
public Boolean getEdit() {
return edit;
}
public void setEdit(Boolean edit) {
this.edit = edit;
}
public Boolean getDel() {
return del;
}
public void setDel(Boolean del) {
this.del = del;
}
public Integer getSortNum() {
return sortNum;
}
public DashMenuTreeNodeVO setSortNum(Integer sortNum) {
this.sortNum = sortNum;
return this;
}
public Set<DashMenuTreeNodeVO> getChildren() {
return children;
}
public void setChildren(Set<DashMenuTreeNodeVO> children) {
this.children = children;
}
private static final class Finder {
Map<String, DashMenuTreeNodeVO> projectFinder = new HashMap<>();
Map<String, DashMenuTreeNodeVO> dashboardFinder = new HashMap<>();
Map<String, DashMenuTreeNodeVO> tabFinder = new HashMap<>();
Map<String, DashMenuTreeNodeVO> chartFinder = new HashMap<>();
public Map<String, DashMenuTreeNodeVO> getProjectFinder() {
return projectFinder;
}
public Map<String, DashMenuTreeNodeVO> getDashboardFinder() {
return dashboardFinder;
}
public Map<String, DashMenuTreeNodeVO> getTabFinder() {
return tabFinder;
}
public Map<String, DashMenuTreeNodeVO> getChartFinder() {
return chartFinder;
}
}
}