三级分类功能 递归树形结构数据获取
1.技术全览
- 后端采用的技术是SpringBoot+MybatisPlus+Hutool(可选)
- 前端采用的技术是VUE +ElementUI
2.后端实现
2.1 依赖
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.3</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
</dependency>
2.2 application.yml配置文件
spring:
datasource:
username: root
password: root
url: jdbc:mysql://192.168.14.155:3306/gulimall_pms
driver-class-name: com.mysql.jdbc.Driver
application:
name: gulimall-product
mybatis-plus:
mapper-locations: classpath*:/mapper/**/*.xml
global-config:
db-config:
id-type: auto
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
server:
port: 10000
2.3 实体类
@Data
@TableName("pms_category")
public class CategoryEntity implements Serializable {
private static final long serialVersionUID = 1L;
@TableId
private Long catId;
private String name;
private Long parentCid;
private Integer catLevel;
private Integer showStatus;
private Integer sort;
private String icon;
private String productUnit;
private Integer productCount;
@TableField(exist = false)
private List<CategoryEntity> children;
}
2.4 DAO层
@Mapper
public interface CategoryDao extends BaseMapper<CategoryEntity> {}
2.5 service
public interface CategoryService extends IService<CategoryEntity> {
List<CategoryEntity> listWithTree();
}
2.6 serviceImpl
@Service("categoryService")
public class CategoryServiceImpl extends ServiceImpl<CategoryDao, CategoryEntity> implements CategoryService {
@Override
public List<CategoryEntity> listWithTree() {
List<CategoryEntity> entities = baseMapper.selectList(null);
List<CategoryEntity> level1Menus = entities.stream().filter(categoryEntity ->
categoryEntity.getParentCid() == 0
).map(menu -> {
menu.setChildren(getChildrens(menu, entities));
return menu;
}).sorted((category1, category2) -> {
return (category1.getSort() == null ? 0 : category1.getSort()) - (category2.getSort() == null ? 0 : category2.getSort());
}
).collect(Collectors.toList());
return level1Menus;
}
public List<CategoryEntity> getChildrens(CategoryEntity root, List<CategoryEntity> all) {
List<CategoryEntity> childrens = all.stream().filter(categoryEntity -> {
return categoryEntity.getParentCid().equals(root.getCatId());
}).map((category) -> {
category.setChildren(getChildrens(category, all));
return category;
})
.sorted((category1, category2) -> {
return (category1.getSort() == null ? 0 : category1.getSort()) - (category2.getSort() == null ? 0 : category2.getSort());
}).collect(Collectors.toList());
return childrens;
}
}
2.7 controller
@RestController
@RequestMapping("product/category")
public class CategoryController {
@Autowired
private CategoryService categoryService;
@RequestMapping("/list/tree")
public R list() {
List<CategoryEntity> entities = categoryService.listWithTree();
return R.ok().put("data", entities);
}
@RequestMapping("/list/tree1")
public R list1() {
List<CategoryEntity> nodeList = categoryService.list();
TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
treeNodeConfig.setDeep(3);
List<Tree<String>> treeNodes = TreeUtil.build(nodeList,"0", treeNodeConfig,
(treeNode, tree) -> {
tree.setId(treeNode.getCatId().toString());
tree.setParentId(treeNode.getParentCid().toString());
tree.setWeight(treeNode.getSort());
tree.setName(treeNode.getName());
tree.putExtra("catId", treeNode.getCatId());
tree.putExtra("name", treeNode.getName());
tree.putExtra("parentCid", treeNode.getParentCid());
tree.putExtra("catLevel", treeNode.getCatLevel());
tree.putExtra("showStatus", treeNode.getShowStatus());
tree.putExtra("sort", treeNode.getSort());
tree.putExtra("icon", treeNode.getIcon());
tree.putExtra("productUnit", treeNode.getProductUnit());
tree.putExtra("productCount", treeNode.getProductCount());
});
return R.ok().put("data", treeNodes);
}
}
3.前端vue实现
<template>
<el-tree :data="menus" :props="defaultProps" @node-click="handleNodeClick"></el-tree>
</template>
<script>
export default {
data() {
return {
menus: [],
defaultProps: {
children: 'children',
label: 'name'
}
};
},
methods: {
handleNodeClick(data) {
console.log(data);
},
getMenus() {
this.$http({
url: this.$http.adornUrl('/product/category/list/tree'),
method: 'get'
}).then(
({data}) => {
this.menus = data.data;
console.log("成功获取到数据!", data.data)
}
)
},
},
created() {
this.getMenus();
}
};
</script>
4.效果展示