100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > 谷粒商城之商品服务-三级分类(展示与删除)

谷粒商城之商品服务-三级分类(展示与删除)

时间:2022-11-16 17:25:08

相关推荐

谷粒商城之商品服务-三级分类(展示与删除)

目录

三级类目查询后台代码实现

后台管理系统的菜单创建

配置网关和路径重写

网关统一配置跨域

三级类目后台管理系统的页面显示

三级分类删除页面效果的编写

​三级分类逻辑删除后台实现

三级类目删除功能的前后联调

三级类目查询后台代码实现

catagory表的表结构,首先一级类目的parent_cid为0,二级类目以及三级类目的parent_cid为cid,sort字段用于排序

baseMapper等价于catagoryDao

代码实现:

/*** 三级分类查询,以树状结构呈现* @return*/@Overridepublic List<CategoryEntity> listWithTree() {// 1.查询所有商品类目List<CategoryEntity> all=categoryDao.selectList(null);// 2.1、查询一级类目List<CategoryEntity> categoryEntities= all.stream().filter(menu1->{return menu1.getParentCid().equals(0L);}// 刷选出一级分类).map((menu1)->{menu1.setChildren(getChilren(menu1,all));return menu1;}).sorted((item1,item2)->{// 排序return (item1.getSort()==null?0:item1.getSort())-(item2.getSort()==null?0:item2.getSort());}).collect(Collectors.toList());return categoryEntities;}/*** 查询子节点* @param menu1* @param all* @return*/private List<CategoryEntity> getChilren(CategoryEntity menu1, List<CategoryEntity> all) {List<CategoryEntity> chilrenList= all.stream().filter(chilrenMenu->chilrenMenu.getParentCid().equals(menu1.getCatId())// 查询子节点).map((chilrenMenu)->{chilrenMenu.setChildren(getChilren(chilrenMenu,all));return chilrenMenu;}).sorted((item1,item2)->{return (item1.getSort()==null?0:item1.getSort())-(item2.getSort()==null?0:item2.getSort());}).collect(Collectors.toList());return chilrenList;}

后台管理系统的菜单创建

①创建一个商品系统(一级菜单)目录

②在商品菜单目录下创建一个分类维护菜单

菜单路由讲解

当我们点击角色管理时,就会发送一个sys-role的请求,角色管理的菜单路由是sys/role,说明会将sys/role转化成sys-role

实际上访问sys-role就是请求sys文件夹下的role.vue

③分类维护的菜单路由为product/category,所以在views中的modules下面创建一个product文件,在product文件夹中创建category.vue

④编写category.vue请求后台数据

参考role.vue的请求数据方法,对category.vue进行编写

访问的是 http://localhost:8080/renren-fast/product/category/list/tree

而我们想要访问的路径是http://localhost:10000/product/category/list/tree

我们应该将请求统一发送给网关,由网关根据我们的请求路径进行相应路由

配置网关和路径重写

①renren-fast服务注册到网关中

出现问题

java: You aren't using a compiler supported by lombok, so lombok will not work and has been disabled

解决方案:You aren‘t using a compiler supported by lombok, so lombok will not work and has been disabled._小魔王博客-CSDN博客

出现问题:

The following method did not exist:mon.collect.Sets$SetView.iterator()Lcom/google/common/collect/UnmodifiableIterator;The method's class, mon.collect.Sets$SetView, is available from the following locations:jar:file:/D:/MavenRepository/com/google/guava/guava/18.0/guava-18.0.jar!/com/google/common/collect/Sets$SetView.classIt was loaded from the following location:file:/D:/MavenRepository/com/google/guava/guava/18.0/guava-18.0.jar

出现原因是:guava-18跟别的jar有冲突,要么将guava的版本升级要么降级

renren-fast成功注册到nacos中

index.js中配置访问的路径

将其改成访问网关的路径,并且都带上api

路由重写

网关路由配置:

spring:cloud:nacos:discovery:server-addr: 127.0.0.1:8848gateway:routes:- id: admin_routeuri: lb://renren-fast # lb:负载均衡predicates:- Path=/api/**# 路径中带有api的所有请求的都路由filters:- RewritePath=/api/?(?<segment>.*),/renren-fast/$\{segment}application:name: gulimall-gatewayserver:port: 88

出现CROS错误:

Access to XMLHttpRequest at 'http://localhost:88/api/sys/menu/nav?t=1639023916234' from origin 'http://localhost:8001' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

出现原因:当我们想从'http://localhost:8001'访问'http://localhost:88',这个两个ip地址不是在同一个域下的,所以出现了跨域访问问题。'Access-Control-Allow-Origin' header这个请求头不在访问的资源中,解决方案需:要设置允许跨域的请求头

网关统一配置跨域

解决方案:

gateway中编写配置类:所有请求从网关返回的时候都会带上运行跨域访问的请求头

@Configurationpublic class GulimallCROSConfig {@Beanpublic CorsWebFilter corsWebFilter(){UrlBasedCorsConfigurationSource corsConfigurationSource=new UrlBasedCorsConfigurationSource();CorsConfiguration corsConfiguration=new CorsConfiguration();// 跨域设置corsConfiguration.addAllowedHeader("*"); //配置那些请求头可以跨域访问corsConfiguration.addAllowedMethod("*"); //配置那些方法可以跨域访问corsConfiguration.addAllowedOrigin("*"); //配置那些来源可以跨域访问corsConfiguration.setAllowCredentials(true); //配置跨域请求可以携带cookiecorsConfigurationSource.registerCorsConfiguration("/**",corsConfiguration);return new CorsWebFilter(corsConfigurationSource);}}

出现问题:

Access to XMLHttpRequest at 'http://localhost:88/api/sys/login' from origin 'http://localhost:8001' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header contains multiplevalues'http://localhost:8001,http://localhost:8001', but only one is allowed.

允许跨域的请求头被设置了两个,只允许一个

出现问题的原因:renren-fast中的也设置了允许跨域的配置

解决方案:将renren-fast中的允许跨域配置类注释

三级类目后台管理系统的页面显示

经过网关后,请求路径变成了:http://localhost:88/renrenfast/product/category/list/tree

我们想要让请求路径变成:http://localhost:10000/product/category/list/tree

因此,需要编写路由:

出现问题:访问不到

出现问题的原因是:admin_router中的断言会优先将路径进行重写

解决方案:断言中小范围的路径访问要写在大范围的路径访问之前

spring:cloud:nacos:discovery:server-addr: 127.0.0.1:8848gateway:routes:- id: product_routeuri: lb://gulimall-productpredicates:- Path=/api/product/**filters:- RewritePath=/api/?(?<segment>.*),/$\{segment}- id: admin_routeuri: lb://renren-fast # lb:负载均衡predicates:- Path=/api/**# 路径中带有api的所有请求的都路由filters:- RewritePath=/api/?(?<segment>.*),/renren-fast/$\{segment}application:name: gulimall-gatewayserver:port: 88

将获取到data在控制台中打印,发现data中的data才是真正的存放数据的对象

<template><el-tree :data="menu" :props="defaultProps" ></el-tree></template><script>export default {data() {//这里存放数据return {menu: [],defaultProps: {children: 'children', //封装子节点,prop会自动进行一个遍历label: 'name' //显示数据,prop会自动进行一个遍历}};},methods: {//获取数据getDataList() {this.dataListLoading = true;this.$http({url: this.$http.adornUrl("/product/category/list/tree"),method: "get",}).then(({data}) => { // 1.使用解构即{},将data对象解构出来// 2.将data中的data赋值给menuthis.menu=data.data;// 3.将data中的data对象的属性children和name赋值给defaultProps中的children和label});},},created() {//模板一旦被创建就被加载this.getDataList();},};

三级分类删除页面效果的编写

我们使用scoped slot编写添加和删除按键

补上复选框

补全append和remove方法,并打印看看data和node

出现的问题:当我们点击append或者delete时,会自动进行一个扩展,我们想要的效果是只有当我们点击箭头才进行扩展

解决方案:

出现问题:只有节点没有子节点是才能进行delete,只有一级和二级目录才能append

解决方案:使用v-if进行一个判断,首先使用scoped slot会传进来node和data两个数据,其中node有个level属性,就是节点的层级,node还有个childNodes表示子节点的个数即childNodes数组的长度为0可以删除

出现问题:我们需要为Tree设置node-key,方便标识每个节点

解决方案:catId是每个节点唯一的标识属性

三级分类逻辑删除后台实现

①TODO的使用,相当于备用录,用于提醒还未实现的步骤或功能

②alt+enter:快速创建方法

使用postman进行测试:

这是一个真正的物理删除,在实际开发中并不常用,一般使用逻辑删除

mybatis-plus逻辑删除指南地址:逻辑删除 | MyBatis-Plus

mybatis-plus:global-config:db-config:logic-delete-field: flag # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)logic-delete-value: 1 # 逻辑已删除值(默认为 1)logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)

@TableLogicprivate Integer deleted;

说明一下:我使用的是mybatis-plus 3.2版本的没有这个logic-delete-field配置项并不影响使用

出现问题:showStatus属性1代表显示,0代表不显示与我们的逻辑删除配置刚好相反

解决方案:@TableLogic中有两个属性值,可以重新设置逻辑删除的值

日志打印:gulimall包下的都会打印日志

三级类目删除功能的前后联调

在httpRequest.js中url的拼接规则

当我们点击Delete按键就会去调用remove方法,因此需要去重写remove方法

重写remove方法:

出现问题:页面没有即时更新

解决方案:删除成功之后再次调用获取数据方法,进行一个数据的更新

出现问题:1.没有删除确认提示 2.删除成功或失败应该有消息提示 3.删除成功或失败应该父节点应该扩展而不是整个层级合并

<template><!-- 使用v-bind/':'才能为属性赋值成功 --><div><el-treeshow-checkbox:data="menu":props="defaultProps":expand-on-click-node="false"node-key="catId":default-expanded-keys="expandKey"><span class="custom-tree-node" slot-scope="{ node, data }"><span>{{ node.label }}</span><span><!--箭头函数调用append方法--><!-- 一级目录和二级目录才允许append --><el-buttonv-if="node.level <= 2"type="text"size="mini"@click="() => append(data)">Append</el-button><!-- 没有子节点才允许delete --><el-buttonv-if="node.childNodes.length == 0"type="text"size="mini"@click="() => remove(node, data)">Delete</el-button></span></span></el-tree></div></template><script>export default {data() {//这里存放数据return {menu: [],expandKey: [],defaultProps: {children: "children", //封装子节点,prop会自动进行一个遍历label: "name", //显示数据,prop会自动进行一个遍历},};},methods: {//获取数据getDataList() {this.dataListLoading = true;this.$http({url: this.$http.adornUrl("/product/category/list/tree"),method: "get",}).then(({ data }) => {// 1.使用解构即{},将data对象解构出来// 2.将data中的data赋值给menuthis.menu = data.data;// 3.将data中的data对象的属性children和name赋值给defaultProps中的children和label});},append(data) {console.log("append", data);},remove(node, data) {let catId = [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(catId, false),}).then(({ data }) => {this.$message({type: "success",message: "删除成功!",});// 刷新菜单this.getDataList();// 默认菜单展示this.expandKey = [node.parent.data.catId];});}).catch(() => {this.$message({type: "info",message: "已取消删除",});});console.log("remove", node, data);},},//生命周期 - 创建完成(可以访问当前this实例)created() {//模板一旦被创建就被加载this.getDataList();},};

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。