前端 static文件夹 index.js中,定义了baseUrl ,服务都会发送到网关,并且带api前缀。
网关中配置带api前缀的都路由到renren-fast模块,filter中进行了路径重写,将前缀api去掉。这样可以保证renren-fast模块可以正常访问
product微服务模块的网关配置:也是过滤掉了api,这个要放在renren-fast网关配置的前面。
前端:category.vue
1.查询:前端发送的请求
getMenus() {
this.$http({
url: this.$http.adornUrl("/gulimallproduct/category/list/tree"),
method: "get",
}).then(({ data }) => {
console.log("成功获取数据", data.data);
this.menus = data.data;
});
},
后端:Categorycontroller CategoryService CategoryEntity
接收请求
@RequestMapping("/list/tree")
public R list(){
//PageUtils page = categoryService.queryPage(params);
List<CategoryEntity> entities = categoryService.listWithTree();
return R.ok().put("data", entities);
}
创建一个CategoryEntity类型的List集合,存放查出来的所有分类数据
返回固定的数据 R类型,其实就是一个map, 有重载的ok方法,此处用了没有参数传入的ok方法,返回一个R类型,然后将查出的数据存到key为“data”的value中
ListWithTree方法:
@Override
public List<CategoryEntity> listWithTree() {
//1 查出所有分类 继承了serviceimpl 这个类中注入了baseMapper 所以此处可直接使用
List<CategoryEntity> entityList = baseMapper.selectList(null);
//2 组装成父子结构
//2.1 找到所有的一级分类
List<CategoryEntity> level1Menus = entityList.stream().filter((categoryEntity) -> {
//怎么找到一级分类? 就是先获取parentid为0的 过滤掉其他的
return categoryEntity.getParentCid() == 0;
}).map((menu)->{
//map方法类似一个迭代器,对调用这个Stream.map(**)的对象进行lambda表达式操作
//此处就是将一级分类的查找结果放入children属性中,再将二级分类的结果放入children集合中的children属性中,再三级。。。
//getChildrens就是通过一级分类再继续找二级分类,传入一级分类的结果,和总的查询结果
menu.setChildren(getChildrens(menu,entityList));
return menu;
//排序 menu1-menu2 是从小到大排序
}).sorted((menu1,menu2)->{
return menu1.getSort()==null?0:menu1.getSort()-(menu2.getSort()==null?0:menu2.getSort());
//collect:收集stream流的数据到集合中可以使list set 或者指定的集合
}).collect(Collectors.toList());
return level1Menus;
}
其中setChildren的children属性为附加属性,为了查询出子分类单独定义的,不在数据库表中,返回查询出来的分类列表,共包含三级分类
//这个属性不在数据库表中 所以加此注解
@JsonInclude(JsonInclude.Include.NON_EMPTY) //此注解表示数据为空时就不包含
@TableField(exist = false)
private List<CategoryEntity> children;
getChildrens方法:
private List<CategoryEntity> getChildrens(CategoryEntity root,List<CategoryEntity> all){
//遍历总的查询结果
List<CategoryEntity> chileren = all.stream().filter((categoryEntity) -> {
//找到parentid = 一级分类结果的id的条目 就相当于二级分类的结果,
return categoryEntity.getParentCid() == root.getCatId();
//这个传入的categoryEnties是二级分类的结果
}).map((categoryEntity) -> {
//然后再继续这样递归寻找三级结果 传入二级的结果和总的结果
categoryEntity.setChildren(getChildrens(categoryEntity, all));
return categoryEntity;
}).sorted((menu1, menu2) -> {
//menu1-menu2是从小到大排序
return menu1.getSort() == null ? 0 : menu1.getSort() - (menu2.getSort() == null ? 0 : menu2.getSort());
//collect:收集stream流的数据到集合中可以使list set 或者指定的集合
}).collect(Collectors.toList());
//查完二级分类的每个children就返回一次
return chileren;
}
返回查出的子分类
2.删除 前端发送的请求
url: this.$http.adornUrl("/gulimallproduct/category/delete"),
method: "post",
后端接收请求
@RequestMapping("/delete")
public R delete(@RequestBody Long[] catIds){
//categoryService.removeByIds(Arrays.asList(catIds));
//删除之前需要判断待删除的菜单那是否被别的地方所引用。
categoryService.removeMenuByIds(Arrays.asList(catIds));
return R.ok();
}
直接调用basemapper的deleteBatchIds方法进行批量删除,返回成功提示。
@Override
public void removeMenuByIds(List<Long> asList) {
//TODO 1.检查当前删除的菜单,是否被别的地方引用
baseMapper.deleteBatchIds(asList);
}
3.修改菜单顺序 前端发出的请求
url: this.$http.adornUrl("/gulimallproduct/category/update/sort"),
method: "post",
后端接收请求
@RequestMapping("/update/sort")
//@RequiresPermissions("product:category:update")
public R updateSort(@RequestBody CategoryEntity[] category){
categoryService.updateBatchById(Arrays.asList(category));
return R.ok();
}
直接调用basemapper的updateBatchById方法修改。
修改菜单属性,先调用根据id查询的方法进行数据回显,修改完调用根据id保存的方法
前端
/gulimallproduct/category/info/${data.catId}
后端
@RequestMapping("/info/{catId}")
public R info(@PathVariable("catId") Long catId){
CategoryEntity category = categoryService.getById(catId);
return R.ok().put("data", category);
}
getById为Iservice接口定义的方法
前端
url: this.$http.adornUrl("/gulimallproduct/category/update"),
后端
@RequestMapping("/update")
public R update(@RequestBody CategoryEntity category){
categoryService.updateById(category);
return R.ok();
}
updateById为Iservice接口定义的方法
添加三级分类及删除三级分类:略