一、应用场景
权限菜单
商品分类
需要返回类似数据结构
{
"data": [
{
"id": 1,
"parentId": 0,
"name": "根节点",
"children": [
{
"id": 2,
"parentId": 1,
"name": "王二"
},
{
"id": 3,
"parentId": 1,
"name": "王1二"
}
]
},
{
"id": 4,
"parentId": 0,
"name": "一级目"
},
{
"id": 5,
"parentId": 0,
"name": "一级目2",
"children": [
{
"id": 6,
"parentId": 5,
"name": "一级目2"
}
]
}
]
}
?二、推荐工具
使用hutool工具的树结构工具-TreeUtil
电梯:Hutool参考文档
导入依赖
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.7.22</version>
</dependency>
三、数据准备
层级数据表一般会涉及三个必填字段:数据->id,父级ID->pid,数据排序->sort;
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for system_classification
-- ----------------------------
DROP TABLE IF EXISTS `system_classification`;
CREATE TABLE `system_classification` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '分类id',
`name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '分类名称',
`parent_id` bigint(20) NULL DEFAULT 0 COMMENT '父分类id',
`sort` int(11) NOT NULL DEFAULT 0 COMMENT '显示顺序',
`level` int(11) NULL DEFAULT NULL COMMENT '层级',
`status` tinyint(4) NOT NULL DEFAULT 0 COMMENT '分类状态(0正常 1停用)',
`deth` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '纵深',
`creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者',
`create_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间',
`updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者',
`update_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
`tenant_id` bigint(20) NOT NULL DEFAULT 0 COMMENT '租户编号',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 8 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '部门表' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of system_classification
-- ----------------------------
INSERT INTO `system_classification` VALUES (1, '根节点', 0, 0, 1, 0, '1', 'admin', '2021-01-05 17:03:47', '1', '2022-03-22 10:18:56', b'0', 1);
INSERT INTO `system_classification` VALUES (2, '王二', 1, 1024, 2, 0, '1', '1', '2022-03-18 11:35:43', '1', '2022-03-22 10:19:00', b'0', 1);
INSERT INTO `system_classification` VALUES (3, '王1二', 1, 1024, 2, 0, '1', '1', '2022-03-18 11:38:05', '1', '2022-03-22 10:19:02', b'0', 1);
INSERT INTO `system_classification` VALUES (4, '一级目', 0, 1, 1, 0, NULL, '1', '2022-03-22 10:09:25', '1', '2022-03-22 10:09:25', b'0', 1);
INSERT INTO `system_classification` VALUES (5, '一级目2', 0, 1, 1, 0, NULL, '1', '2022-03-22 10:09:32', '1', '2022-03-22 10:09:32', b'0', 1);
INSERT INTO `system_classification` VALUES (6, '二级目2', 5, 1, 2, 0, '5', '1', '2022-03-22 10:09:40', '1', '2022-03-22 10:14:17', b'0', 1);
INSERT INTO `system_classification` VALUES (7, 'san级目2', 6, 1, 3, 0, '5,6', '1', '2022-03-22 10:19:28', '1', '2022-03-22 10:19:28', b'0', 1);
SET FOREIGN_KEY_CHECKS = 1;
?数据对应实体类
?
public class ClassificationDO {
/**
* 分级ID
*/
@TableId
private Long id;
/**
* 分级名称
*/
private String name;
/**
* 父分级ID
*
* 关联 {@link #id}
*/
private Long parentId;
/**
* 显示顺序
*/
private Integer sort;
/**
* 层级
*/
private Integer level;
/**
* 纵深
*
*/
private String deth;
/**
* 分级状态
*
* 枚举 {@link CommonStatusEnum}
*/
private Integer status;
/**
* 多租户编号
*/
private Long tenantId;
}
?
四、实现细节
根据pid与id的逻辑关系构建tree;
public CommonResult<List<Tree<Integer>>> listClassificationsChildren() {
//返回的业务数据
List<ClassificationDO> list = classificationService.getSimpleClassifications();
log.info(JSON.toJSONString(list));
//配置
TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
// 自定义属性名 都要默认值的
//数据ID
treeNodeConfig.setIdKey("id");
// 父级id字段
treeNodeConfig.setParentIdKey("parentId");
// 排序字段,这个字段不能是null,不然会报错,默认最好是数字
treeNodeConfig.setWeightKey("sort");
// 最大递归深度
//treeNodeConfig.setDeep(3);
//转换器
List<Tree<Integer>> build = TreeUtil.build(list, 0, treeNodeConfig, ((object, treeNode) -> {
treeNode.setId(object.getId().intValue());//id
treeNode.setParentId(object.getParentId().intValue());//父id
treeNode.putExtra("name", object.getName());
treeNode.putExtra("sort", object.getSort());
treeNode.putExtra("level", object.getLevel());
treeNode.putExtra("status", object.getStatus());
}));
log.info(JSON.toJSONString(build));
return success(build);
}
查询返回的数据
[{"createTime":1647574543000,"creator":"1","deleted":false,"deth":"1","id":2,"level":2,"name":"王二","parentId":1,"sort":1024,"status":0,"tenantId":1,"updateTime":1647915540000,"updater":"1"},{"createTime":1647917632000,"creator":"1","deleted":false,"id":8,"level":1,"name":"测试1","parentId":0,"sort":5,"status":0,"tenantId":1,"updateTime":1647917638000,"updater":"1"},{"createTime":1647917993000,"creator":"1","deleted":false,"deth":"1,1","id":10,"level":2,"name":"张三","parentId":1,"sort":2,"status":0,"tenantId":1,"updateTime":1647917993000,"updater":"1"},{"createTime":1647918003000,"creator":"1","deleted":false,"deth":"1,1,10","id":11,"level":3,"name":"张小三","parentId":10,"sort":1,"status":0,"tenantId":1,"updateTime":1647918003000,"updater":"1"},{"createTime":1647917776000,"creator":"1","deleted":false,"id":9,"level":1,"name":"小王","parentId":0,"sort":1,"status":0,"tenantId":1,"updateTime":1647917776000,"updater":"1"},{"createTime":1647915568000,"creator":"1","deleted":false,"deth":"5,6","id":7,"level":3,"name":"san级目2","parentId":6,"sort":1,"status":0,"tenantId":1,"updateTime":1647915568000,"updater":"1"},{"createTime":1647914980000,"creator":"1","deleted":false,"deth":"5","id":6,"level":2,"name":"二级目2","parentId":5,"sort":1,"status":0,"tenantId":1,"updateTime":1647915257000,"updater":"1"},{"createTime":1647914972000,"creator":"1","deleted":false,"id":5,"level":1,"name":"一级目2","parentId":0,"sort":1,"status":0,"tenantId":1,"updateTime":1647914972000,"updater":"1"},{"createTime":1647914965000,"creator":"1","deleted":false,"id":4,"level":1,"name":"一级目","parentId":0,"sort":1,"status":0,"tenantId":1,"updateTime":1647914965000,"updater":"1"},{"createTime":1609837427000,"creator":"admin","deleted":false,"deth":"1","id":1,"level":1,"name":"根节点","parentId":0,"sort":0,"status":0,"tenantId":1,"updateTime":1647915536000,"updater":"1"}]
排序后的数据
[{"id":1,"parentId":0,"name":"根节点","sort":0,"level":1,"status":0,"children":[{"id":10,"parentId":1,"name":"张三","sort":2,"level":2,"status":0,"children":[{"id":11,"parentId":10,"name":"张小三","sort":1,"level":3,"status":0}]},{"id":2,"parentId":1,"name":"王二","sort":1024,"level":2,"status":0}]},{"id":9,"parentId":0,"name":"小王","sort":1,"level":1,"status":0},{"id":5,"parentId":0,"name":"一级目2","sort":1,"level":1,"status":0,"children":[{"id":6,"parentId":5,"name":"二级目2","sort":1,"level":2,"status":0,"children":[{"id":7,"parentId":6,"name":"san级目2","sort":1,"level":3,"status":0}]}]},{"id":4,"parentId":0,"name":"一级目","sort":1,"level":1,"status":0},{"id":8,"parentId":0,"name":"测试1","sort":5,"level":1,"status":0}]
接口返回的数据
{
"code": 0,
"data": [
{
"id": 1,
"parentId": 0,
"name": "根节点",
"sort": 0,
"level": 1,
"status": 0,
"children": [
{
"id": 10,
"parentId": 1,
"name": "张三",
"sort": 2,
"level": 2,
"status": 0,
"children": [
{
"id": 11,
"parentId": 10,
"name": "张小三",
"sort": 1,
"level": 3,
"status": 0
}
]
},
{
"id": 2,
"parentId": 1,
"name": "王二",
"sort": 1024,
"level": 2,
"status": 0
}
]
},
{
"id": 9,
"parentId": 0,
"name": "小王",
"sort": 1,
"level": 1,
"status": 0
},
{
"id": 5,
"parentId": 0,
"name": "一级目2",
"sort": 1,
"level": 1,
"status": 0,
"children": [
{
"id": 6,
"parentId": 5,
"name": "二级目2",
"sort": 1,
"level": 2,
"status": 0,
"children": [
{
"id": 7,
"parentId": 6,
"name": "san级目2",
"sort": 1,
"level": 3,
"status": 0
}
]
}
]
},
{
"id": 4,
"parentId": 0,
"name": "一级目",
"sort": 1,
"level": 1,
"status": 0
},
{
"id": 8,
"parentId": 0,
"name": "测试1",
"sort": 5,
"level": 1,
"status": 0
}
],
"msg": ""
}
|