假设要构建一个菜单,可以实现智慧库房,菜单的样子如下:
智慧库房
|- RFID
|- 智慧大屏
|- 智能密集架
|- 环境管控
那这种结构如何保存在数据库中呢?一般是这样的:
每条数据根据parentId
相互关联并表示层级关系,parentId
在这里也叫外键
id | parentId | name |
---|---|---|
1 | 0 | 智慧库房 |
2 | 1 | RFID |
3 | 1 | 智慧大屏 |
4 | 1 | 智能密集架 |
5 | 1 | 环境管控 |
使用步骤:
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.16</version>
</dependency>
我这里使用的是枚举:(大家可以使用数据将需要封装成树形结构的数据,查询封装成一个List)
package com.hy.archive.supervision.enums;
/**
* @description: 智慧库房功能
*/
public enum SmartWarehouseFunctionEnum {
SMART_WAREHOUSE("1", "智慧库房", "0"),
RFID("2", "RFID", "1"),
SMART_LARGE_SCREEN("3", "智慧大屏", "1"),
INTELLIGENT_DENSE_RACK("4", "智能密集架", "1"),
ENVIRONMENTAL_CONTROL("5", "环境管控", "1");
private String id;
private String name;
private String pid;
SmartWarehouseFunctionEnum(String id, String name, String pid) {
this.id = id;
this.name = name;
this.pid = pid;
}
public String getId() {
return id;
}
public String getName() {
return name;
}
public String getPid() {
return pid;
}
public static SmartWarehouseFunctionEnum fromCode(String id) {
for (SmartWarehouseFunctionEnum DispatchTypeEnum : SmartWarehouseFunctionEnum.values()) {
if (DispatchTypeEnum.getId().equals(id)) {
return DispatchTypeEnum;
}
}
return null;
}
}
package com.js.hutool.controller;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNode;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import com.js.hutool.enums.SmartWarehouseFunctionEnum;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.List;
@RestController
@RequestMapping("/frid")
public class FridFunctionController {
/**
* @description: 使用htool工具生成树形递归结构
* @author: js
* @date: 2023/8/4 15:36
* @param:
* @return:
**/
@GetMapping("/function")
public List<Tree<String>> obtainAllFunctionsOfTheSmartWarehouse() {
List<TreeNode> nodeList = CollUtil.newArrayList();
int i=0;
for (SmartWarehouseFunctionEnum value : SmartWarehouseFunctionEnum.values()) {
//1.将数据库中的数据一次性查询出来封装到List中
//2.在这里将从数据库查询的所有数据List中id,pid(父级id),name 依次次封装到longTreeNode中
TreeNode<String> longTreeNode = new TreeNode<>(value.getId(), value.getPid(), value.getName(), 0);
// 如果还需要给树形添加其他字段,返回给前端,需使用map进行封装
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("返回给前端的字段1", i++);// 返回给前端的字段:open_function
hashMap.put("返回给前端的字段2",i+1);
longTreeNode.setExtra(hashMap);
nodeList.add(longTreeNode);
}
//配置
TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
// 自定义属性名 都要默认值的
//设置权重对应的名称
treeNodeConfig.setWeightKey("order");
//设置ID对应的名称
treeNodeConfig.setIdKey("id");//如果返回给前端的id不叫id,可以修改这里的值
// 最大递归深度
treeNodeConfig.setDeep(3);//这个是设置树形结构的层级
//转换器 (含义:找出父节点为字符串零的所有子节点, 并递归查找对应的子节点, 深度最多为 3)
// 0表示最顶层的id是0,即最高的父级id为多少
List<Tree<String>> build = TreeUtil.<TreeNode, String>build(nodeList, "0", treeNodeConfig,
(treeNode, tree) -> {
tree.setId((String) treeNode.getId());
tree.setParentId((String) treeNode.getParentId());
tree.setName(treeNode.getName());
//这里的putAll与put的区别:put将之前需要给前端的其他字段封装成Map,进行多嵌套了一成
tree.putAll(treeNode.getExtra());
//tree.put("open_function",treeNode.getExtra());
});
return build;
}
}