目录

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

后台管理系统的菜单创建

配置网关和路径重写

网关统一配置跨域

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

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

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

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


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

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:com.google.common.collect.Sets$SetView.iterator()Lcom/google/common/collect/UnmodifiableIterator;The method's class, com.google.common.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-gateway
server: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中编写配置类:所有请求从网关返回的时候都会带上运行跨域访问的请求头

@Configuration
public 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-gateway
server: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)

@TableLogic
private 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();},
};

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

  1. 谷粒商城六商品服务三级分类

    递归-树形结构数据获取 sql文件 sql文件太大了,这个博主写的非常厉害,看他的就ok了 CategoryController package com.atguigu.gulistore.produ ...

  2. 谷粒商城基础篇------商品服务 - 三级分类(gulimall-product:pms_category表)

    文章目录 4.1 递归树形结构获取商品分类(pms_category)数据 4.2 配置网关路由与路径重写 1. 前端修改 2.后端-配置网关路由 3.跨域问题的解决 4.再次树形展示商品数据 4.3 ...

  3. 谷粒商城九商品服务之商品属性及仓储服务todo

    之前的文章我都是把整篇的代码直接复制到文章中,这样容易抓不住重点, 但是一段代码都贴出来,又显得繁琐, 从这篇开始,我会把重点步骤写出来,代码还是贴完整的 从这篇开始的mybatis-plus分页插件 ...

  4. 谷粒商城之商品服务-平台属性-属性组管理

    目录 什么是SPU? 什么是SKU? 规格参数 ​ 销售属性 三级分类-属性组-属性的关联关系 SPU-属性&SKU-属性的关联关系 预期效果: 属性分组之前端组件抽取&父子组件交互 ...

  5. 谷粒商城七商品服务品牌管理之oss文件存储

    使用renren-generator生成crud页面 todo谷粒商城二本地虚拟机环境搭建及项目初始化在逆向工程的时候,resources下有一个view文件夹,下面都是可以直接使用的vue文件,我们 ...

  6. 尚硅谷2020微服务分布式电商项目《谷粒商城》-商品搜索

    关注公众号:java星星 获取全套课件资料 1. 导入商品数据 1.1. 搭建搜索工程 pom.xml内容如下: <?xml version="1.0" encoding=& ...

  7. 谷粒商城(新增商品、商品管理、仓库管理)思路详解

    谷粒商城基础分布式总结 1.新增商品 1.调试member服务 2.查询分类下的所有品牌 2.获取分类下面带属性的属性分组. 3.保存设定好的spu和sku信息 2.商品管理 1.spu展示查询(sp ...

  8. 谷粒商城 Day05 商品详情页接口准备

    Day05 商品详情页接口准备 一.Thymeleaf 1.thymeleaf 简介 ① HelloController com.atguigu.thymeleaf.controller.HelloC ...

  9. 【谷粒商城之订单服务-支付】

    本笔记内容为尚硅谷谷粒商城订单服务支付部分 目录 一.支付宝沙箱 沙箱环境 二.公钥.私钥.加密.加签.验签 1.公钥私钥 2.加密和数字签名 3.对称加密和非对称加密 三.内网穿透 四.整合支付 1 ...

最新文章

  1. python程序实例教程基础-python基础教程第三版源代码
  2. 【编译原理】让我们来构建一个简单的解释器(Let’s Build A Simple Interpreter. Part 1.)(python/c/c++版)(笔记)
  3. java执行shell命令
  4. Android动画模式
  5. html中刷新按钮的代码,常见的按钮类型 点击button刷新的几种常用代码
  6. 机器人J中WPR_北方工业大学服务机器人研究项目介绍
  7. 单独像对相对定向的部分基本概念
  8. 将JavaScript函数作为参数传递
  9. Clojure 学习入门(13)- binding
  10. [转载]shell 十三问?
  11. Docker与容器化-03-使用Dockerfile创建镜像
  12. android自定义sufaceview,Android自定义SurfaceView实现画板功能
  13. 2022开源的群管理机器人源码+实测可用
  14. 如何写出优雅的React代码Clean Code vs. Dirty Code
  15. Kotlin-协程Coroutines-组合suspending暂停函数
  16. pancakeswap 开盘抢跑机器人 (附代码)
  17. 【冰糖R语言】Pearson、Spearman相关性及其显著性 cor() rcorr()
  18. 各种语言的特点和介绍
  19. sap成本流怎么看_[原创]SAP方丈-写给新手的SAP成本核算流程
  20. 传宏碁CEO因平板电脑战略失策辞职

热门文章

  1. 仿 iPhone Assistivetouch 自定义view
  2. VISP学习:二、Visp的手动安装
  3. 【前端职业规划思考】
  4. 【无需格式化硬盘即可C盘扩容以及新建磁盘】
  5. 牛客网 NC20859 兔子的名字
  6. Scala基础(一)——常用数据类型
  7. 『科技』2019全球最有前景AI公司TOP100|湾区人工智能
  8. buildroot技巧
  9. buildroot 升级软件包
  10. php对接腾讯云人脸识别