最近要開發一個選單介面,結構是父選單下面有子選單,子選單下面還有子選單,要實作樹形結構返給前端,
資料表設計
CREATE TABLE `platform_menu` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '選單id',
`menu_name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '選單名稱',
`menu_value` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '選單值(前端路由)',
`parent_id` bigint NULL DEFAULT NULL COMMENT '上級選單id',
`parent_path` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '選單全路徑(用/隔開)',
`func_type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '功能型別(0選單1按鈕2區塊)',
`order_num` int NULL DEFAULT NULL COMMENT '排序',
`icon` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '圖示',
`created_by` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '創建人',
`created_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '創建時間',
`updated_by` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '更新人',
`updated_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新時間',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 21 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '選單資訊 ' ROW_FORMAT = Dynamic;
創建樹形結構工具類
import cn.hutool.core.collection.CollUtil;
import org.apache.commons.compress.utils.Lists;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* @author ws
* @date 2021/9/5
*/
public class BaseTreeHelper {
/**
* @param <T> 節點型別
* @param <E> 節點id的型別
* @return 樹形結構串列
* @author ws
* @date 2021/9/5
* 根據所有樹節點串列,生成含有所有樹形結構的串列
**/
public static <T extends TreeNode<E, T>, E> List<T> generateTrees(List<T> data) {
if (CollUtil.isEmpty(data)) {
return Lists.newArrayList();
}
//將集合中所有資料按照父Id進行分組,放入Map中,Map<parntId, List<T>>
Map<String, List<T>> groupByParentIdMap = data.stream().collect(Collectors.groupingBy(item -> item.root() ? "" : Objects.toString(item.getPid())));
//將集合中所有資料以資料Id為key,放入Map中,Map<id,T>
Map<String, T> dataMap = data.stream().collect(Collectors.toMap(item -> item.getId().toString(), t -> t));
List<T> resp = Lists.newArrayList();
//遍歷資料,將子節點放入對應父節點Children屬性中
groupByParentIdMap.forEach((parentId, values) -> {
if (dataMap.containsKey(parentId)) {
List<T> child = dataMap.get(parentId).getChildren();
if (CollUtil.isEmpty(child)) {
child = Lists.newArrayList();
}
child.addAll(values);
dataMap.get(parentId).setChildren(child);
} else {
resp.addAll(values);
}
});
return resp;
}
/**
* @param parent 父節點
* @param <T> 實際節點型別
* @return 葉子節點
* @author ws
* @date 2021/9/5
* 獲取指定樹節點下的所有葉子節點
**/
public static <T extends TreeNode<E, T>, E> List<T> getLeafs(T parent) {
List<T> leafs = new ArrayList<>();
fillLeaf(parent, leafs);
return leafs;
}
/**
* @param parent 父節點
* @param leafs 葉子節點串列
* @param <T> 實際節點型別
* @author ws
* @date 2021/9/5
* 將parent的所有葉子節點填充至leafs串列中
**/
private static <T extends TreeNode<E, T>, E> void fillLeaf(T parent, List<T> leafs) {
List<T> children = parent.getChildren();
// 如果節點沒有子節點則說明為葉子節點
if (CollUtil.isEmpty(children)) {
leafs.add(parent);
return;
}
// 遞回呼叫子節點,查找葉子節點
for (T child : children) {
fillLeaf(child, leafs);
}
}
}
創建UserMenusVo物件,里面可以只寫需要回傳的屬性欄位就行,
import com.knight.common.core.utils.tree.TreeNode;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* @author ws
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class UserMenusVo implements TreeNode<Long, UserMenusVo> {
private static final long serialVersionUID = 1L;
/**
* id
*/
@ApiModelProperty("選單id")
private Long id;
/**
* 選單名稱
*/
@ApiModelProperty("選單名稱")
private String name;
/**
* 選單值(前端路由)
*/
@ApiModelProperty("選單值")
private String menuValue;
/**
* 上級選單id
*/
@ApiModelProperty("上級選單")
private Long pid;
/**
* 選單全路徑(用/隔開)
*/
@ApiModelProperty("選單全路徑")
private String parentPath;
/**
* 功能型別(0選單1按鈕2區塊)
*/
@ApiModelProperty("功能型別")
private String funcType;
/**
* 排序
*/
@ApiModelProperty("排序")
private Integer orderNum;
/**
* 圖示
*/
@ApiModelProperty("圖示")
private String icon;
@ApiModelProperty("子選單")
private List<UserMenusVo> children;
@Override
@ApiModelProperty("父節點")
public Boolean root() {
return pid == null;
}
}
controller,回傳的pid就是parentId,
public Result<List<UserMenusVo>> listMenuAll() {
//查詢所有選單
List<UserMenusVo> menus = this.listMenuAll();
//回傳樹形結構
return Result.ok(BaseTreeHelper.generateTrees(menus));
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/297896.html
標籤:區塊鏈
上一篇:前 10 個 NFT 專案
下一篇:2021-09-05
