• 商城项目08_三级分类前端展示、新增、修改、删除


    ①. 树形前端展示

    • ①. 这个时候去访问在页面访问:http://localhost:88/api/product/category/list/tree可以显示数据
      (在product的配置文件中配置注册中心和配置中心的配置文件)
    #  如下的配置在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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

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

    在这里插入图片描述

    • ②. 使用java8新特性查找三级联洞并封装成树形结构
    @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);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
       @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;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    @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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    在这里插入图片描述

    • ③. 设置前端代码,在页面展示树状结构查询
    
    <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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57

    在这里插入图片描述

    ②. 三级分类删除逻辑

    在这里插入图片描述

        /**
         * 删除
         * @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();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • ③. 使用postman发送删除的逻辑
      在这里插入图片描述

    • ④. 前端代码如下所示

    1. show-checkbox:显示复选框
    2. node-key:每个树节点用来作为唯一标识的属性,整棵树应该是唯一的
    3. expand-on-click-node:是否在点击节点的时候展开或者收缩节点,默认值为true,如果为false,则只有点箭头图标的时候才会展开或者收缩节点
    4. default-expanded-keys:默认展开的节点的key的数组
    <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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115

    在这里插入图片描述


    修改和删除等后续有时间再补充

  • 相关阅读:
    字符串——重复的子字符串
    Spring之BeanFactoryPostProcessor(bean工厂后置处理器)
    记一次dubbo整合nacos no Provider排查
    CPU眼里的C/C++:1.2 查看变量和函数在内存中的存储位置
    zookeeper节点数据类型介绍及集群搭建
    算法整理(二)
    nodejs 启动第三方exe
    APK反编译工具汇总
    如何利用Git中的tag管理项目版本号
    如何用产品思维做好互联网运营?
  • 原文地址:https://blog.csdn.net/TZ845195485/article/details/126796717