1.递归查询树形结构
@Override
public List<CategoryEntity> listWithTree() {
//1.查出所有分类
List<CategoryEntity> all = this.list();
//2.组装成父子的属性结构
List<CategoryEntity> level1Menus = all
.stream()
.filter(c -> c.getParentCid().equals(0L))
.map(categoryEntity -> categoryEntity.setChildren(getChildrenCategory(all,categoryEntity.getCatId())))
//大于放后面 升序
.sorted(Comparator.comparing(CategoryEntity::getSort))
.collect(Collectors.toList());
return level1Menus;
}
private List<CategoryEntity> getChildrenCategory(List<CategoryEntity> allList, long pCatId) {
List<CategoryEntity> collect = allList.stream()
.filter(a -> a.getParentCid() == pCatId)
.sorted(Comparator.comparing(CategoryEntity::getSort))
.collect(Collectors.toList());
if (collect.isEmpty()) {
return new ArrayList<>();
} else {
for (CategoryEntity categoryEntity : collect) {
Long catId = categoryEntity.getCatId();
List<CategoryEntity> childrenCategory = getChildrenCategory(allList, catId);
categoryEntity.setChildren(childrenCategory);
}
return collect;
}
}
2.网关统一配置跨域问题
2.1添加 网关过滤器
package com.jmj.gulimall.gateway.config;
import org.springframework.context.annotation.Bean;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.reactive.CorsWebFilter;
@Configuration
public class GulimallCorsConfiguration {
//网关gateway是使用webflex 进行编程的 响应式 所以用的都是reactive 包下
@Bean
public CorsWebFilter corsWebFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration corsConfiguration = new CorsConfiguration();
//1.配置跨域
corsConfiguration.addAllowedHeader("*");//允许哪些头跨域
corsConfiguration.addAllowedMethod("*");//允许哪些请求跨域
corsConfiguration.addAllowedOrigin("*");//允许哪些请求来源 跨域
corsConfiguration.setAllowCredentials(true);//是否允许携带cookie进行跨域 允许 否则跨域请求将会丢失一些相关cookie信息
source.registerCorsConfiguration("/**", corsConfiguration);
return new CorsWebFilter(source);
}
}
但是我们发现还是出现了问题
这是因为网关配置了跨域,而网关转发的微服务也配置了跨域,所以返回了两个响应头被允许,
但是浏览器只希望有一个,所以报错,这时,我们只需要去把微服务的跨域注释掉就好了。
这是人人fast 服务的跨域配置,也是Spring MVC的 配置
/**
* Copyright (c) 2016-2019 人人开源 All rights reserved.
* <p>
* https://www.renren.io
* <p>
* 版权所有,侵权必究!
*/
package io.renren.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowCredentials(true)
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.maxAge(3600);
}
}
这是网关的路由,是有优先级的,从上优先级最高,如果匹配不上就会依次遍历。
如果不调换优先级,路径会被网关转发到 renrenfast 服务当中,导致没有token 返回invalid token
spring:
cloud:
gateway:
routes:
- id: test_route
uri: http://www.baidu.com
predicates:
#访问的路径就是 如果是/hello?url=baidu 就转发到 https://www.baidu.com/hello?url=baidu
- Query=url,baidu
- id: test1_route
uri: http://www.hao123.com
predicates:
- Query=url,hao123
- id: product_rout
uri: lb://gulimall-product
predicates:
- Path=/api/product/**
filters:
- RewritePath=/api/(?<segment>.*),/$\{segment}
- id: admin_route
uri: lb://renren-fast
predicates:
- Path=/api/**
filters:
- RewritePath=/api/(?<segment>.*),/renren-fast/$\{segment}
##前端项目,/api
3.拖拽修改前端代码
<!-- -->
<template>
<div>
<el-switch v-model="isDraggable" active-text="开启拖拽" inactive-text="关闭拖拽">
</el-switch>
<el-tree
:data="menus"
:props="defaultProps"
show-checkbox
node-key="catId"
:expand-on-click-node="false"
:default-expanded-keys="expandedkey"
@node-expand="expend"
@node-collapse="nodeClose"
:draggable="isDraggable"
:allow-drop="allowDrop"
@node-drop="handleDrop"
>
<span class="custom-tree-node" slot-scope="{ node, data }">
<!-- 插槽,代替了原来的 label 里所显示的内容 将插槽内容显示在原来的每个结点上面 -->
<span>{{ node.label }}</span>
<span>
<el-button
v-if="node.level <= 2"
type="text"
size="mini"
@click="() => append(data)"
>
Append
</el-button>
<el-button type="text" size="mini" @click="edit(data)">
Edit
</el-button>
<el-button
v-if="node.childNodes.length == 0"
type="text"
size="mini"
@click="() => remove(node, data)"
>
Delete
</el-button>
</span>
</span>
</el-tree>
<el-dialog
:title="submitTitle"
:visible.sync="dialogVisible"
:close-on-click-modal="false"
width="30%"
>
<el-form :model="category">
<el-form-item label="分类名称">
<el-input v-model="category.name" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="图标">
<el-input v-model="category.icon" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="计量单位">
<el-input
v-model="category.productUnit"
autocomplete="off"
></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="cancelForm">取 消</el-button>
<el-button type="primary" @click="submitForm">确 定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
//这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
//例如:import 《组件名称》 from '《组件路径》';
class UpdateCategoryData {
constructor(catId, parentCid, sort, catLevel) {
this.catId = catId;
this.parentCid = parentCid;
this.sort = sort;
this.catLevel = catLevel;
}
}
export default {
//import引入的组件需要注入到对象中才能使用
components: {},
props: {},
data() {
return {
isDraggable: false,
submitType: "",
submitTitle: "",
dialogVisible: false,
menus: [],
defaultProps: {
children: "children",
label: "name",
},
expandedkey: [],
copyCategory: {},
category: {
catId: null,
name: "",
parentCid: 0,
catLevel: 0,
showStatus: 1,
productUnit: "",
icon: "",
sort: 0,
},
};
},
//监听属性 类似于data概念
computed: {},
//监控data中的数据变化
watch: {},
//方法集合
methods: {
/**
*
* @param {*} draggingNode 拖拽的节点
* @param {*} dropNode 拖拽到的哪个节点
* @param {*} dropType 拖拽类型, 前后或者 内部
* @param {*} event 事件对象
*/
handleDrop(draggingNode, dropNode, dropType, event) {
console.log(draggingNode, dropNode, dropType);
//1.当前节点最新的父节点Id,
let updateArray = new Array();
let draggingNodeLevel = draggingNode.level;
if (dropType == "inner") {
let dropNodeId = dropNode.data.catId;
let dropNodeLevel = dropNode.level;
let childrenNew = dropNode.data.children;
for (const index in childrenNew) {
let { catId } = childrenNew[index];
let updateCategoryData = new UpdateCategoryData(
catId,
dropNodeId,
index,
dropNodeLevel + 1
);
updateArray.push(updateCategoryData);
}
let div = dropNodeLevel + 1 - draggingNodeLevel;
//递归把子节点都遍历完
if (div != 0) {
this.recursivelyTraverseChildNodes(
draggingNode.data.children,
div,
updateArray
);
}
} else {
//往前插入节点或者后插入节点
let parentLevel = dropNode.parent.level;
console.log(parentLevel);
let parentChildrenArr = {};
if (parentLevel == 0) {
parentChildrenArr = dropNode.parent.data;
} else {
parentChildrenArr = dropNode.parent.data.children;
}
let parentCid = dropNode.data.parentCid;
for (const index in parentChildrenArr) {
let { catId } = parentChildrenArr[index];
let updateCategoryData = new UpdateCategoryData(
catId,
parentCid,
index,
parentLevel + 1
);
updateArray.push(updateCategoryData);
}
let div = parentLevel + 1 - draggingNodeLevel;
console.log("parentLevel", parentLevel);
console.log("draggingNodeLevel", draggingNodeLevel);
//递归把子节点都遍历完
if (div != 0) {
this.recursivelyTraverseChildNodes(
draggingNode.data.children,
div,
updateArray
);
}
}
console.log(updateArray);
//发送http请求修改
this.$http({
url: this.$http.adornUrl("/product/category/updateList"),
method: "post",
data: this.$http.adornData(updateArray, false),
}).then(({ data }) => {
this.success("修改位置与排序成功");
this.getMenus();
});
},
recursivelyTraverseChildNodes(children, div, arr) {
if (children == null || children.length == 0) {
//没有子节点了
return;
} else {
for (const child of children) {
let updateCategoryData = new UpdateCategoryData(
child.catId,
child.parentCid,
child.sort,
child.catLevel + div
);
arr.push(updateCategoryData);
this.recursivelyTraverseChildNodes(child.children, div, arr);
}
}
},
allowDrop(draggingNode, dropNode, type) {
//1、被拖动的当前节点以及所在的父节点总层数不能大于3
console.log("allowDrop", draggingNode, dropNode, type);
let level = this.countNodeLevel(
draggingNode.data,
draggingNode.data.catLevel
);
if (type == "inner") {
if (dropNode.level + level <= 3) {
return true;
} else {
return false;
}
}
if (type == "next") {
if (dropNode.parent.level + level <= 3) {
return true;
} else {
return false;
}
}
if (type == "prev") {
if (dropNode.parent.level + level <= 3) {
return true;
} else {
return false;
}
}
//1)被拖动的当前节点总层数
return false;
},
//递归查找该节点加上子类最深层级一共有几层;包含自己算
countNodeLevel(node, l) {
let children = node.children;
let levelMax = 0;
if (children.length == 0) {
return node.catLevel - l + 1;
} else {
for (let child of children) {
let level = this.countNodeLevel(child, l);
if (level > levelMax) {
levelMax = level;
}
}
}
return levelMax;
},
resetCategory() {
Object.assign(this.category, this.copyCategory);
//如果你希望在 console.log 输出的时候看到对象的当前状态,
//你可以在赋值操作之前进行 console.log,或者使用对象解构等方法创建一个新的对象进行输出,以确保输出的是当前状态的副本而不是对象的引用。
let categoryre = {};
Object.assign(categoryre, this.category);
console.log("执行了重置", categoryre);
},
submitForm() {
if (this.submitType == "add") {
this.addCategory();
}
if (this.submitType == "edit") {
this.updateCategory();
}
},
updateCategory() {
this.$http({
url: this.$http.adornUrl("/product/category/update"),
method: "post",
data: this.$http.adornData(this.category, false),
}).then(({ data }) => {
this.success("修改成功");
this.getMenus();
this.resetCategory();
this.dialogVisible = false;
});
},
edit(data) {
this.submitType = "edit";
this.submitTitle = "修改分类菜单";
console.log("正在修改数据", data);
this.dialogVisible = true;
//发送http请求获取回显数据
this.$http({
url: this.$http.adornUrl(`/product/category/info/${data.catId}`),
method: "get",
}).then(({ data }) => {
let categoryEdit = data.data;
console.log("回显数据", categoryEdit);
this.category.catId = categoryEdit.catId;
this.category.name = categoryEdit.name;
this.category.parentCid = categoryEdit.parentCid;
this.category.catLevel = categoryEdit.catLevel;
this.category.showStatus = categoryEdit.showStatus;
this.category.productUnit = categoryEdit.productUnit;
this.category.icon = categoryEdit.icon;
this.category.sort = categoryEdit.sort;
console.log("category被回显数据", this.category);
});
},
cancelForm() {
this.resetCategory();
this.dialogVisible = false;
},
append(data) {
this.resetCategory();
console.log("append", this.category);
this.category.parentCid = data.catId;
this.category.catLevel = data.catLevel + 1;
this.category.showStatus = 1;
this.category.sort = 0;
this.dialogVisible = true;
this.submitType = "add";
this.submitTitle = "添加分类菜单";
},
addCategory() {
console.log("提交三级分类的数据", this.category);
this.$http({
url: this.$http.adornUrl("/product/category/save"),
method: "post",
data: this.$http.adornData(this.category, false),
}).then(({ data }) => {
this.success("添加分类成功");
this.getMenus();
});
this.resetCategory();
this.dialogVisible = false;
},
remove(node, data) {
console.log("remove", node, data);
let ids = [data.catId];
// console.log(this); //vue
this.$confirm(`是否删除【${data.name}】菜单`, "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
// console.log(this); //vue
this.$http({
url: this.$http.adornUrl("/product/category/delete"),
method: "post",
data: this.$http.adornData(ids, false),
}).then(({ data }) => {
// console.log(this); //vue
this.$message({
message: "菜单删除成功",
type: "success",
});
// node.visible = false;
this.getMenus();
//设置需要默认展开的菜单
});
})
.catch(() => {
this.$message({
message: "取消了删除",
type: "warning",
});
});
},
expend(data, node, _) {
console.log("展开了", node.data.catId);
this.expandedkey.push(node.data.catId);
},
nodeClose(data, node, _) {
let id = node.data.catId;
console.log("收起了", id);
let index = this.expandedkey.indexOf(id);
this.expandedkey.splice(index, 1);
},
getMenus() {
this.$http({
url: this.$http.adornUrl("/product/category/list/tree"),
method: "get",
}).then(({ data }) => {
console.log("成功获取到菜单数据:", data.data);
this.menus = data.data;
});
},
success(msg) {
this.$message({
message: msg,
type: "success",
});
},
error(msg) {
this.$message({
message: msg,
type: "warning",
});
},
},
//生命周期 - 创建完成(可以访问当前this实例)
created() {
this.getMenus();
Object.assign(this.copyCategory, this.category);
},
//生命周期 - 挂载完成(可以访问DOM元素)
mounted() {},
beforeCreate() {}, //生命周期 - 创建之前
beforeMount() {}, //生命周期 - 挂载之前
beforeUpdate() {}, //生命周期 - 更新之前
updated() {}, //生命周期 - 更新之后
beforeDestroy() {}, //生命周期 - 销毁之前
destroyed() {}, //生命周期 - 销毁完成
activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
};
</script>
<style scoped>
</style>
4.批量删除
封装复用方法 闭包
<!-- -->
<template>
<div>
<el-switch
v-model="isDraggable"
active-text="开启拖拽"
inactive-text="关闭拖拽"
>
</el-switch>
<el-button type="danger" round @click="batchDelete">批量删除</el-button>
<el-tree
:data="menus"
:props="defaultProps"
show-checkbox
node-key="catId"
:expand-on-click-node="false"
:default-expanded-keys="expandedkey"
@node-expand="expend"
@node-collapse="nodeClose"
:draggable="isDraggable"
:allow-drop="allowDrop"
@node-drop="handleDrop"
ref="menuTree"
>
<span class="custom-tree-node" slot-scope="{ node, data }">
<!-- 插槽,代替了原来的 label 里所显示的内容 将插槽内容显示在原来的每个结点上面 -->
<span>{{ node.label }}</span>
<span>
<el-button
v-if="node.level <= 2"
type="text"
size="mini"
@click="() => append(data)"
>
Append
</el-button>
<el-button type="text" size="mini" @click="edit(data)">
Edit
</el-button>
<el-button
v-if="node.childNodes.length == 0"
type="text"
size="mini"
@click="() => remove(node, data)"
>
Delete
</el-button>
</span>
</span>
</el-tree>
<el-dialog
:title="submitTitle"
:visible.sync="dialogVisible"
:close-on-click-modal="false"
width="30%"
>
<el-form :model="category">
<el-form-item label="分类名称">
<el-input v-model="category.name" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="图标">
<el-input v-model="category.icon" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="计量单位">
<el-input
v-model="category.productUnit"
autocomplete="off"
></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="cancelForm">取 消</el-button>
<el-button type="primary" @click="submitForm">确 定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
//这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
//例如:import 《组件名称》 from '《组件路径》';
class UpdateCategoryData {
constructor(catId, parentCid, sort, catLevel) {
this.catId = catId;
this.parentCid = parentCid;
this.sort = sort;
this.catLevel = catLevel;
}
}
export default {
//import引入的组件需要注入到对象中才能使用
components: {},
props: {},
data() {
return {
isDraggable: false,
submitType: "",
submitTitle: "",
dialogVisible: false,
menus: [],
defaultProps: {
children: "children",
label: "name",
},
expandedkey: [],
copyCategory: {},
category: {
catId: null,
name: "",
parentCid: 0,
catLevel: 0,
showStatus: 1,
productUnit: "",
icon: "",
sort: 0,
},
};
},
//监听属性 类似于data概念
computed: {},
//监控data中的数据变化
watch: {},
//方法集合
methods: {
confirm(msg,success,error){
this.$confirm(msg, "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}).then(() => {
success();
}).catch(()=>{
error();
});
},
batchDelete() {
let deleteArray = this.$refs.menuTree.getCheckedNodes();
console.log("被选中的元素", deleteArray);
let ids = deleteArray.map((c) => {
return c.catId;
});
console.log("被选中的Id", ids);
// this.$confirm(`是否批量删除`, "提示", {
// 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.success("批量删除成功");
// this.getMenus();
// });
// }).catch((error)=>{
// this.error("取消批量删除");
// });
this.confirm("是否批量删除",()=>{
this.$http({
url: this.$http.adornUrl("/product/category/delete"),
method: "post",
data: this.$http.adornData(ids, false),
}).then(({ data }) => {
this.success("批量删除成功");
this.getMenus();
});
},()=>{
this.error("取消批量删除");
})
},
/**
*
* @param {*} draggingNode 拖拽的节点
* @param {*} dropNode 拖拽到的哪个节点
* @param {*} dropType 拖拽类型, 前后或者 内部
* @param {*} event 事件对象
*/
handleDrop(draggingNode, dropNode, dropType, event) {
console.log(draggingNode, dropNode, dropType);
//1.当前节点最新的父节点Id,
let updateArray = new Array();
let draggingNodeLevel = draggingNode.level;
if (dropType == "inner") {
let dropNodeId = dropNode.data.catId;
let dropNodeLevel = dropNode.level;
let childrenNew = dropNode.data.children;
for (const index in childrenNew) {
let { catId } = childrenNew[index];
let updateCategoryData = new UpdateCategoryData(
catId,
dropNodeId,
index,
dropNodeLevel + 1
);
updateArray.push(updateCategoryData);
}
let div = dropNodeLevel + 1 - draggingNodeLevel;
//递归把子节点都遍历完
if (div != 0) {
this.recursivelyTraverseChildNodes(
draggingNode.data.children,
div,
updateArray
);
}
} else {
//往前插入节点或者后插入节点
let parentLevel = dropNode.parent.level;
console.log(parentLevel);
let parentChildrenArr = {};
if (parentLevel == 0) {
parentChildrenArr = dropNode.parent.data;
} else {
parentChildrenArr = dropNode.parent.data.children;
}
let parentCid = dropNode.data.parentCid;
for (const index in parentChildrenArr) {
let { catId } = parentChildrenArr[index];
let updateCategoryData = new UpdateCategoryData(
catId,
parentCid,
index,
parentLevel + 1
);
updateArray.push(updateCategoryData);
}
let div = parentLevel + 1 - draggingNodeLevel;
console.log("parentLevel", parentLevel);
console.log("draggingNodeLevel", draggingNodeLevel);
//递归把子节点都遍历完
if (div != 0) {
this.recursivelyTraverseChildNodes(
draggingNode.data.children,
div,
updateArray
);
}
}
console.log(updateArray);
//发送http请求修改
this.$http({
url: this.$http.adornUrl("/product/category/updateList"),
method: "post",
data: this.$http.adornData(updateArray, false),
}).then(({ data }) => {
this.success("修改位置与排序成功");
this.getMenus();
});
},
recursivelyTraverseChildNodes(children, div, arr) {
if (children == null || children.length == 0) {
//没有子节点了
return;
} else {
for (const child of children) {
let updateCategoryData = new UpdateCategoryData(
child.catId,
child.parentCid,
child.sort,
child.catLevel + div
);
arr.push(updateCategoryData);
this.recursivelyTraverseChildNodes(child.children, div, arr);
}
}
},
allowDrop(draggingNode, dropNode, type) {
//1、被拖动的当前节点以及所在的父节点总层数不能大于3
console.log("allowDrop", draggingNode, dropNode, type);
let level = this.countNodeLevel(
draggingNode.data,
draggingNode.data.catLevel
);
if (type == "inner") {
if (dropNode.level + level <= 3) {
return true;
} else {
return false;
}
}
if (type == "next") {
if (dropNode.parent.level + level <= 3) {
return true;
} else {
return false;
}
}
if (type == "prev") {
if (dropNode.parent.level + level <= 3) {
return true;
} else {
return false;
}
}
//1)被拖动的当前节点总层数
return false;
},
//递归查找该节点加上子类最深层级一共有几层;包含自己算
countNodeLevel(node, l) {
let children = node.children;
let levelMax = 0;
if (children.length == 0) {
return node.catLevel - l + 1;
} else {
for (let child of children) {
let level = this.countNodeLevel(child, l);
if (level > levelMax) {
levelMax = level;
}
}
}
return levelMax;
},
resetCategory() {
Object.assign(this.category, this.copyCategory);
//如果你希望在 console.log 输出的时候看到对象的当前状态,
//你可以在赋值操作之前进行 console.log,或者使用对象解构等方法创建一个新的对象进行输出,以确保输出的是当前状态的副本而不是对象的引用。
let categoryre = {};
Object.assign(categoryre, this.category);
console.log("执行了重置", categoryre);
},
submitForm() {
if (this.submitType == "add") {
this.addCategory();
}
if (this.submitType == "edit") {
this.updateCategory();
}
},
updateCategory() {
this.$http({
url: this.$http.adornUrl("/product/category/update"),
method: "post",
data: this.$http.adornData(this.category, false),
}).then(({ data }) => {
this.success("修改成功");
this.getMenus();
this.resetCategory();
this.dialogVisible = false;
});
},
edit(data) {
this.submitType = "edit";
this.submitTitle = "修改分类菜单";
console.log("正在修改数据", data);
this.dialogVisible = true;
//发送http请求获取回显数据
this.$http({
url: this.$http.adornUrl(`/product/category/info/${data.catId}`),
method: "get",
}).then(({ data }) => {
let categoryEdit = data.data;
console.log("回显数据", categoryEdit);
this.category.catId = categoryEdit.catId;
this.category.name = categoryEdit.name;
this.category.parentCid = categoryEdit.parentCid;
this.category.catLevel = categoryEdit.catLevel;
this.category.showStatus = categoryEdit.showStatus;
this.category.productUnit = categoryEdit.productUnit;
this.category.icon = categoryEdit.icon;
this.category.sort = categoryEdit.sort;
console.log("category被回显数据", this.category);
});
},
cancelForm() {
this.resetCategory();
this.dialogVisible = false;
},
append(data) {
this.resetCategory();
console.log("append", this.category);
this.category.parentCid = data.catId;
this.category.catLevel = data.catLevel + 1;
this.category.showStatus = 1;
this.category.sort = 0;
this.dialogVisible = true;
this.submitType = "add";
this.submitTitle = "添加分类菜单";
},
addCategory() {
console.log("提交三级分类的数据", this.category);
this.$http({
url: this.$http.adornUrl("/product/category/save"),
method: "post",
data: this.$http.adornData(this.category, false),
}).then(({ data }) => {
this.success("添加分类成功");
this.getMenus();
});
this.resetCategory();
this.dialogVisible = false;
},
remove(node, data) {
console.log("remove", node, data);
let ids = [data.catId];
// console.log(this); //vue
this.$confirm(`是否删除【${data.name}】菜单`, "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
// console.log(this); //vue
this.$http({
url: this.$http.adornUrl("/product/category/delete"),
method: "post",
data: this.$http.adornData(ids, false),
}).then(({ data }) => {
// console.log(this); //vue
this.$message({
message: "菜单删除成功",
type: "success",
});
// node.visible = false;
this.getMenus();
//设置需要默认展开的菜单
});
})
.catch(() => {
this.$message({
message: "取消了删除",
type: "warning",
});
});
},
expend(data, node, _) {
console.log("展开了", node.data.catId);
this.expandedkey.push(node.data.catId);
},
nodeClose(data, node, _) {
let id = node.data.catId;
console.log("收起了", id);
let index = this.expandedkey.indexOf(id);
this.expandedkey.splice(index, 1);
},
getMenus() {
this.$http({
url: this.$http.adornUrl("/product/category/list/tree"),
method: "get",
}).then(({ data }) => {
console.log("成功获取到菜单数据:", data.data);
this.menus = data.data;
});
},
success(msg) {
this.$message({
message: msg,
type: "success",
});
},
error(msg) {
this.$message({
message: msg,
type: "warning",
});
},
},
//生命周期 - 创建完成(可以访问当前this实例)
created() {
this.getMenus();
Object.assign(this.copyCategory, this.category);
},
//生命周期 - 挂载完成(可以访问DOM元素)
mounted() {},
beforeCreate() {}, //生命周期 - 创建之前
beforeMount() {}, //生命周期 - 挂载之前
beforeUpdate() {}, //生命周期 - 更新之前
updated() {}, //生命周期 - 更新之后
beforeDestroy() {}, //生命周期 - 销毁之前
destroyed() {}, //生命周期 - 销毁完成
activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
};
</script>
<style scoped>
</style>