文章目录
商品服务-分类管理
查出所有分类以及子分类
后端编写
1、定义接口查询所有数据:gulimall-product的com.liu.gulimall.product.controller.CategoryController添加如下方法
/**
* 商品三级分类
*
* @author liujianyu
* @email [email protected]
* @date 2021-12-09 19:15:00
*/
@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);
}
}
2、在service层中创建方法 listWithTree
/**
* 商品三级分类
*
* @author liujianyu
* @email [email protected]
* @date 2021-12-09 18:29:39
*/
public interface CategoryService extends IService<CategoryEntity> {
PageUtils queryPage(Map<String, Object> params);
/**
* 将数据以树形分类,分出三级
* @return
*/
List<CategoryEntity> listWithTree();
}
3、在service层的Impl中实现方法
- 最重要的是商品实体中需要多一个字段,children,为了放此分类的子分类
- 先把所有商品查出来然后根据数据库字段父id查出,没有父id的一级商品,然后在递归找子分类
- 主要理解流式编程:filter、map、sorted、collect
- 一级分类有二级,二级有三级,所以是一个递归的方式
@Service("categoryService")
public class CategoryServiceImpl extends ServiceImpl<CategoryDao, CategoryEntity> implements CategoryService {
// @Autowired
// private CategoryDao categoryDao;
// ServiceImpl<CategoryDao, CategoryEntity>已经帮我们注入了dao,就不用自己注入了
@Override
public List<CategoryEntity> listWithTree() {
// 1 查出所有分类
List<CategoryEntity> entities = baseMapper.selectList(null);
// 2 组装成父子的树形结构
List<CategoryEntity> level1Menus = entities.stream().filter((categoryEntity) ->{
// 过滤
// long类型的比较不要直接使用==,要用到longValue()来比较
return categoryEntity.getParentCid().longValue() == 0;} // 过滤只要父id等于0的数据,也就是一级分类
).map((categoryEntity)->{
// 为过滤后的一级分类的每一个数据设置他的子分类
categoryEntity.setChildren(getChildrens(categoryEntity,entities));
return categoryEntity;}
).sorted((categoryEntity1,categoryEntity2)->{
// 升序排序根据字段sort来让sort小的的排前面 由于categoryEntity1可能已经为空null了,所以先判断
return (categoryEntity1.getSort() == null? 0: categoryEntity1.getSort())
-
(categoryEntity2.getSort() == null?0:categoryEntity2.getSort());
}).collect(Collectors.toList()); // 将过滤的数据收集成数组
return level1Menus;
}
// 递归查找所有菜单的子菜单,把当前分类,和总分类传进来
private List<CategoryEntity> getChildrens(CategoryEntity root, List<CategoryEntity> all) {
List<CategoryEntity> children = all.stream().filter(categoryEntity -> {
// 过滤取出父id等于当前分类的数据
return categoryEntity.getParentCid().longValue() == root.getCatId().longValue();
}).map(categoryEntity -> {
// 每一个子分类还有可能有子分类
// 1 找到子菜单
categoryEntity.setChildren(getChildrens(categoryEntity, all));
return categoryEntity;
}).sorted((menu1, menu2) -> {
// 2 菜单的排序 由于menu可能已经为空null了,所以先判断
return (menu1.getSort() == null?0:menu1.getSort()) - (menu2.getSort() == null?0:menu2.getSort());
}).collect(Collectors.toList());
return children;
}
}
前端展示
1、创建商品系统的目录,以及内容转发的路由
数据库同步数据
2、根据人人开源策略,根据路由product/category
来请求product-category,比如sys-role具体的视图在renren-fast-vue/views/modules/sys/role.vue 所以要自定义我们的product/category视图的话,就是创建mudules/product/category.vue,根据策略创建product文件,在文件下创建category.vue组件,这样请求路由就会跳转到这个组件中,
3、编写category.vue组件
- 可以模仿人人开源的组件方式,包括里面怎么转发,怎么数据交互等。
- 采用Element UI来开发,采用树形控件来管理三级数据
<template>
<el-tree
:data="data"
:props="defaultProps"
@node-click="handleNodeClick"
></el-tree>
</template>
<script>
export default {
data() {
return {
data: [],
defaultProps: {
children: "children",
label: "label",
},
};
},
methods: {
handleNodeClick(data) {
console.log(data);
},
getMenus(data) {
// 自定义方法
this.$http({
// htpp请求
url: this.$http.adornUrl("/product/category/list/tree"), // 请求后端的接口
method: "get",
}).then((data) => {
// 成功了之后的操作
console.log("请求数据," + data);
});
},
},
created() {
// 加载组件的时候就调用改方法
this.getMenus();
},
};
</script>
<style lang="scss" scoped>
</style>
4、我们的数据肯定是从后端取出来,所以要请求gulimall-product服务后端的接口,但是现在请求的是:人人开源的接口,所以修改前端配置:renren-fast-vue\static\config\index.js中修改,但是我们gulimall-product服务可能在很多服务器上,所以每次都要修改端口很麻烦,直接交给网关来做,让网关跟我们去请求服务器
由于我们想要访问的是:http://localhost:10000/product/category/list/tree这个请求,而且这里面的10000端口也存在多服务问题,所以采用网关来转发请求。http://localhost:88/product/category/list/tree