gulimall-分布式基础篇-分类维护

gulimall-分布式基础篇-分类维护

一、三级分类

1.1 效果展示

在这里插入图片描述

1.2 导入数据

在这里插入图片描述

1.3 后端(tree功能)

1.3.1 CategoryEntity

pms_category表

package com.jyyy.gulimall.product.entity;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;

import java.io.Serializable;
import java.util.Date;
import java.util.List;

import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;

@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显示]
	 */
	private Integer showStatus;
	/**
	 * 排序
	 */
	private Integer sort;
	/**
	 * 图标地址
	 */
	private String icon;
	/**
	 * 计量单位
	 */
	private String productUnit;
	/**
	 * 商品数量
	 */
	private Integer productCount;

	// 当为空时不包含,解决前端分类下子菜单为空
	@JsonInclude(JsonInclude.Include.NON_EMPTY)	
	@TableField(exist = false)	// 数据库不存在
	private List<CategoryEntity> children;

}

1.3.2 CategoryController
    @RequestMapping("list/tree")
    public R list(){
        List<CategoryEntity> entities = categoryService.listWithTree();

        return R.ok().put("data",entities);
    }
1.3.3 CategoryService
    /**
     * 三级分类工具类
     * @return
     */
    List<CategoryEntity> listWithTree();
1.3.4 CategoryServiceImpl

在gulimall-product模块,service里创建listWithTree(),impl里实现;

第一层分类要自己在数据库创建

/**
     * 三级分类工具类
     * @return
     */
    public List<CategoryEntity> listWithTree() {

        // 1.查出所有分类
        List<CategoryEntity> entities = baseMapper.selectList(null);

        // 2.组装成父子的树形结构
        return entities.stream()
                // 过滤出一级分类
                .filter(categoryEntity -> categoryEntity.getParentCid() == 0)
                // peek改变元素内部结构,对每个 object 执行 方法(a, b)
                .peek(menu -> menu.setChildren(getChildless(menu,entities)))
                // 按sort排序(过滤完后将所有排序)从上到下展示
                // menu.getSort()如果为0则赋值,不为0则用本身的值
                .sorted(Comparator.comparingInt(menu -> (menu.getSort() == null ? 0 : menu.getSort())))
                .collect(Collectors.toList());
    }

    /**
     * 递归查找所有菜单的子菜单
     * @return
     */
    private List<CategoryEntity> getChildless(CategoryEntity root,List<CategoryEntity> all){
        return all.stream()
                // 过滤父节点相等的
                .filter(categoryEntity -> categoryEntity.getParentCid().equals(root.getCatId()))
                // 处理
                .peek(categoryEntity -> {
                    // 继续
                    categoryEntity.setChildren(getChildless(categoryEntity,all));
                })
                // 排序,Comparator比较器接口,用category的sort排序
                .sorted(Comparator.comparingInt(menu -> (menu.getSort() == null ? 0: menu.getSort())))
                .collect(Collectors.toList());
    }
1.3.5 测试
localhost:10000/product/category/list/tree

在这里插入图片描述

1.4 后端(删除功能)

删除时判断有没有子菜单

1.4.1 配置逻辑删除
配置全局的逻辑删除
spring:
  datasource:
    username: root
    password: root
    url: jdbc:mysql://192.168.33.10:3306/gulimall_pms?useUnicode=true&characterEncoding=UTF-8&userSSL=false&serverTimezone=Asia/Shanghai
    driver-class-name: com.mysql.cj.jdbc.Driver
  application:
    name: gulimall-product
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.33.10:8848


# MapperScan
# sql映射文件位置
mybatis-plus:
  mapper-locations: classpath:/mapper/**/*.xml
  global-config:
    db-config:
      id-type: auto
#这里是全局,如果某一个表不同,则单独配置
      logic-delete-value: 1     #1表示删除
      logic-not-delete-value: 0   #0表示未删除


server:
  port: 10000

不使用全局逻辑删除,使用实体类注解
	@TableLogic(value = "1",delval = "0")
	private Integer showStatus;

1.5 后端(批量修改功能)

CategoryController

拖拽树产生的批量数据

    /**
     * 批量修改
     *  {
     *     "catId": 0,       //菜单id
     *     "catLevel": 0,   //菜单层级
     *     "parentCid": 0,  //父菜单id
     *     "sort": 0        //排序
     *   }
     */
    @RequestMapping("/update/sort")
//    @RequiresPermissions("product:category:update")
    public R update(@RequestBody CategoryEntity[] categorys){
//        categoryService.updateById(category);
        // 这里收集集合对象Collection<T> entityList
        categoryService.updateBatchById(Arrays.asList(categorys));

        return R.ok();
    }

1.6、前端

1.6.1 前端脚手架路由规范
当点击侧边栏目录新增的分类维护时,会跳转到 /product-category,对应新增菜单设置的路由 product/category

页面:对应前端项目 src->views->modules->product->category.vue 页面组件
1.6.2 创建目录/菜单

在这里插入图片描述在这里插入图片描述

1.6.3 创建页面框架

在这里插入图片描述

1.6.4 使用el-tree

在这里插入图片描述

1.6.5 参照系统页面获取数据(拉取数据)

在这里插入图片描述在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

1.6.6 分类维护新增/删除功能

在这里插入图片描述

1.6.7 只有一,二级分类才有新增,没有子节点才有删除

在这里插入图片描述

1.6.8 删除需要选择框,点击时获取到catId

在这里插入图片描述

1.6.9 编写删除方功能

在这里插入图片描述

1.6.10 删除或新增后刷新还是打开原来打开的分组

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

1.6.11 编写新增功能

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

1.6.12编写修改功能

在这里插入图片描述在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

1.6.13 关闭点击框外关闭

在这里插入图片描述

1.6.14 修改后获取的数据在新增时要清除

修改时都是直接获取的所以不需要清空
在这里插入图片描述

1.6.15 el-tree开启拖拽功能

在这里插入图片描述

1.6.16 验证节点是否能被拖动到指定位置

在这里插入图片描述
在这里插入图片描述
找到拖拽节点最深度

在这里插入图片描述拖拽方法

在这里插入图片描述

1.6.17 拖拽数据搜集

拖拽功能影响的是,父节点,层级,排序

在这里插入图片描述

在这里插入图片描述

1.6.18 解决根分类拖动后没有父id

在这里插入图片描述

1.6.19 修改当前节点层级,包含子节点的层级

在这里插入图片描述
在这里插入图片描述

1.6.20 发送数据到后台

在这里插入图片描述

1.6.21 拖拽成功后要把层级,更新节点数组重新赋值

在这里插入图片描述

1.6.22 开关开启拖动功能

在这里插入图片描述
在这里插入图片描述

1.6.23 开启批量拖拽后再发送数据

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

1.6.24 改变深度求法,批量拖拽应用前端level求

在这里插入图片描述

在这里插入图片描述

1.6.25 每修改一个菜单,要展开的父节点应放数组

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

1.6.26 批量删除

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

二、配置网关

作用:这一节会解决一个前端向多个后端服务请求的问题(API网关),此外还有网关服务与前端前后分离的跨域问题。

流程:前端客户端请求88/api→后端gateway模块→再由gateway模块分去各个模块

2.1 前端工程配置API网关作为唯一接口

打开 static->config->index.js 配置统一请求地址(设置接口请求地址(唯一))

每一个服务都要注册到nacos中

// api网关作为接口请求地址,由网关分发到不同服务
window.SITE_CONFIG['baseUrl'] = 'http://localhost:88/api';

2.2 将renren-fast接入网关服务配置

2.2.1 将renren-fast注册到nacos服务

先创建独有的命名空间

renren-fast引入common依赖
<dependency>
  <groupId>com.jyyy.gulimall</groupId>
  <artifactId>gulimall-common</artifactId>
</dependency>
配置nacos地址
spring:  
  application:
    name: renren-fast
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.10.33:8848
主启动类
@EnableDiscoveryClient
@SpringBootApplication
public class RenrenApplication {
	public static void main(String[] args) {
		SpringApplication.run(RenrenApplication.class, args);
	}
}

2.3 将gulimall-product注册到nacos服务

在这里插入图片描述

2.3.1 配置到注册中心
 application:
    name: gulimall-product
 cloud:
    nacos:
      discovery:
        server-addr: 192.168.33.10:8848
2.3.2 配置到配置中心
spring:
  application:
    name: gulimall-product
  cloud:
    nacos:
      config:
        server-addr: 192.168.33.10:8848
        file-extension: yaml
        namespace: d23e7bc6-dce1-4333-8119-c429c23a609a
2.3.3 主启动类
package com.jyyy.gulimall.product;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@MapperScan("com.jyyy.gulimall.product.dao")
@SpringBootApplication
@EnableDiscoveryClient
public class GulimallProductApplication {

    public static void main(String[] args) {
        SpringApplication.run(GulimallProductApplication.class, args);
    }

}

2.4 网关增加路由断言转发不同服务

spring:
  application:
    name: gulimall-gateway
    cloud:
    nacos:
      discovery:
        server-addr: 192.168.10.33:8848
    gateway:
      routes:
      <!--高优先级路由放前面,模糊路由放面-->
      	- id: product_route
      	 <!--负载均衡到gulimall-product-->
          uri: lb://gulimall-product
          predicates:
            - Path=/api/product/**
          filters:
          <!--路径重写-->
            - RewritePath=/api/(?<segment>.*),/$\{segment}
      
        - id: admin_route
        	<!--负载均衡到renren-fast-->
          uri: lb://renren-fast
         <!-- 断言-->
          predicates:
          <!--所有api的地址都会拦截-->
            - Path=/api/**
          filters:
          <!--路径重写-->
            - RewritePath=/api/(?<segment>.*),/renren-fast/$\{segment}
           

三、跨域

当前网站不允许运行其它网站的脚本,报错,所以要解决

3.1 简介

在这里插入图片描述Method:OPTIONS预请求
在这里插入图片描述

3.2 方法

方法一

在这里插入图片描述

方法二

在这里插入图片描述

3.3 配置跨域

在网关跨域就行,因为前端是请求网关

package com.jyyy.gulimall.gateway.config;

@Configuration
public class MallCorsConfiguration {
    @Bean
    public CorsWebFilter corsWebFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();

        CorsConfiguration corsConfiguration = new CorsConfiguration();

        // 配置跨域
        corsConfiguration.addAllowedHeader("*");
        corsConfiguration.addAllowedMethod("*");
        corsConfiguration.addAllowedOrigin("*");
        // 运行携带cookie不然丢失信息
        corsConfiguration.setAllowCredentials(true);

				// 注册
        source.registerCorsConfiguration("/**", corsConfiguration);
        return new CorsWebFilter(source);
    }
}

3.4 删除renren-fast的跨域

有两个会报错

删除 src/main/java/io/renren/config/CorsConfig.java 中的配置内容
这里会导致请求头添加重复,导致跨域失败

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值