# 如下的配置在nacos中也进行了配置(从spring 到 port: 88),可以进行注释掉
# 当一个请求过来的时候,会交给网关进行处理,通过一系列的预言,如果预言为真,会转到指定的服务,转到指定服务的时候,会经过一系列的过滤器
spring:
# application:
# name: gulimall-gateway
# cloud:
# nacos:
# discovery:
# server-addr: 127.0.0.1:8848
#server:
# port: 88
cloud:
gateway:
routes:
# 测试网关的功能
- id: test_route1
uri: http://localhost:7001
predicates:
- Path=/coupon/coupon/nacos/config/simple/**
# 商品服务网关配置(注意需要把product_route放在admin_route前面)
# http://localhost:88/api/product/category/list/tree
# http://localhost:10000/product/category/list/tree
- id: product_route
uri: lb://gulimall-product
predicates:
- Path=/api/product/**
filters:
- RewritePath=/api/(?>/?.*), /$\{segment}
- id: admin_route
uri: lb://renren-fast
predicates:
- Path=/api/**
filters:
- RewritePath=/api/(?>/?.*), /renren-fast/$\{segment}
# 前端项目 /api
# http://localhost:88/api/captcha.jpg?uuid=72b9da67-0130-4d1d-8dda-6bfe4b5f7935
# http://renren-fast:8080/renren-fast/captcha.jpg
@RestController
@RequestMapping("product/category")
public class CategoryController {
@Autowired
private CategoryService categoryService;
/**
* 查出所有分类、以及子分类,以树形结构组装起来
*/
@RequestMapping("/list/tree")
//@RequiresPermissions("product:category:list")
public R list(){
List<CategoryEntity> entities = categoryService.listWithTree();
return R.ok().put("data", entities);
}
}
@Override
public List<CategoryEntity> listWithTree() {
//1、查出所有分类
List<CategoryEntity> entities = baseMapper.selectList(null);
//2、组装成父子的树形结构
//2.1)、找到所有的一级分类
List<CategoryEntity> level1Menus = entities.stream().filter(categoryEntity ->
categoryEntity.getParentCid() == 0
).map((menu)->{
menu.setChildren(getChildrens(menu,entities));
return menu;
}).sorted((menu1,menu2)->{
return (menu1.getSort()==null?0:menu1.getSort()) - (menu2.getSort()==null?0:menu2.getSort());
}).collect(Collectors.toList());
return level1Menus;
}
//递归查找所有菜单的子菜单
private List<CategoryEntity> getChildrens(CategoryEntity root,List<CategoryEntity> all){
List<CategoryEntity> children = all.stream().filter(categoryEntity -> {
return categoryEntity.getParentCid() == root.getCatId();
}).map(categoryEntity -> {
//1、找到子菜单
categoryEntity.setChildren(getChildrens(categoryEntity,all));
return categoryEntity;
}).sorted((menu1,menu2)->{
//2、菜单的排序
return (menu1.getSort()==null?0:menu1.getSort()) - (menu2.getSort()==null?0:menu2.getSort());
}).collect(Collectors.toList());
return children;
}
@Data
@TableName("pms_category")
public class CategoryEntity implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 分类id
*/
@TableId
private Long catId;
/**
* 分类名称
*/
private String name;
/**
* 父分类id
*/
private Long parentCid;
/**
* 层级
*/
private Integer catLevel;
/**
* 是否显示[0-不显示,1显示]
*/
@TableLogic(value = "1",delval = "0")
private Integer showStatus;
/**
* 排序
*/
private Integer sort;
/**
* 图标地址
*/
private String icon;
/**
* 计量单位
*/
private String productUnit;
/**
* 商品数量
*/
private Integer productCount;
@TableField(exist = false)
private List<CategoryEntity>children;
}
<template>
<div class="">
<el-tree
:data="menus"
:props="defaultProps"
@node-click="handleNodeClick"
>el-tree>
div>
template>
<script>
//这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
//例如:import 《组件名称》 from '《组件路径》';
export default {
//import引入的组件需要注入到对象中才能使用
components: {},
data() {
//这里存放数据
return {};
},
//监听属性 类似于data概念
computed: {},
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 }) => {
if (data && data.code === 0) {
this.menus = data.data;
}
});
}
},
//生命周期 - 创建完成(可以访问当前this实例)
created() {
this.getMenus();
},
//生命周期 - 挂载完成(可以访问DOM元素)
mounted() {}
};
script>
<style scoped>style>
/**
* 删除
* @RequestBody:获取请求体,只有post请求才会有请求体,必须发送post请求
* springMvc自动将请求体的数据(JSON)转为对应的对象
*/
@RequestMapping("/delete")
//@RequiresPermissions("product:category:delete")
public R delete(@RequestBody Long[] catIds){
//1. 检查当前删除菜单,是否被别的地方引用
categoryService.removeMenuByIds(Arrays.asList(catIds));
return R.ok();
}
③. 使用postman发送删除的逻辑
④. 前端代码如下所示
<template>
<div class="">
<el-tree
:data="menus"
:props="defaultProps"
show-checkbox
node-key="catId"
:expand-on-click-node="false"
:default-expanded-keys="expandedkey"
>
<span class="custom-tree-node" slot-scope="{ node, data }">
<span>{{ node.label }}span>
<span>
<el-button
type="text"
size="mini"
v-if="node.level <= 2"
@click="() => append(data)"
>
Append
el-button>
<el-button
v-if="node.level == 3"
type="text"
size="mini"
@click="() => remove(node, data)"
>
Delete
el-button>
span>
span>
el-tree>
div>
template>
<script>
//这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
//例如:import 《组件名称》 from '《组件路径》';
export default {
//import引入的组件需要注入到对象中才能使用
components: {},
data() {
//这里存放数据
return {};
},
//监听属性 类似于data概念
computed: {},
data() {
return {
menus: [],
expandedkey: [],
defaultProps: {
children: "children",
label: "name"
}
};
},
methods: {
getMenus() {
this.$http({
url: this.$http.adornUrl("/product/category/list/tree"),
method: "get"
}).then(({ data }) => {
if (data && data.code === 0) {
this.menus = data.data;
}
});
},
append(data) {
console.log("data", data);
},
remove(node, data) {
var ids = [data.catId];
this.$confirm(`是否删除${data.name}菜单`, "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
this.$http({
url: this.$http.adornUrl("/product/category/delete"),
method: "post",
data: this.$http.adornData(ids, false)
}).then(({ data }) => {
this.$message({
message: "菜单删除成功",
type: "success"
});
//刷新新的菜单
this.getMenus();
//设置默认需要展开的菜单(找到当前删除节点的父节点id)
this.expandedkey = [node.parent.data.catId];
});
})
.catch(() => {});
}
},
//生命周期 - 创建完成(可以访问当前this实例)
created() {
this.getMenus();
},
//生命周期 - 挂载完成(可以访问DOM元素)
mounted() {}
};
script>
<style scoped>style>
修改和删除等后续有时间再补充