zoukankan      html  css  js  c++  java
  • gulimall分布式商城(三)

      前面经历了漫长的准备阶段,包括各种环境搭建,前端语言学习,项目框架搭建等等。大家可回头参照 gulimall分布式商城(一)gulimall分布式商城(二)结合视频进行学习。好了,不说骚话了,上干货:业务开发之商品服务。

      说明:本文旨在分享学习经历,有错误的地方欢迎大家指出,本人会虚心接受。原创不易,不喜勿喷。

     6、业务开发之商品服务

       前面我们学习了很多基础知识,包括分布式组件的运用及调试,前端框架的基本知识。在这个模块中,你可以尽情的运用上述知识,让你有真人对战的感觉,而不是一直在单机。虽然此处应用还是青铜级的,和实际工作中的高端局有差异,但你可以忽略这些,暗示自己,这就是你刚开始工作要做的事,你把这些知识吃透了,找个工作糊口完全没问题。

       因为内容实在太多,笔者也不可能每段代码都给大家复刻下来,尽量赶重点说吧,最后还是得自己动手敲。还是那句话,我的就是我的,你的也许还在幼儿园。哈哈哈,开个玩笑。

      6.1、三级分类

        6.1.1、查询-递归树形结构获取

          1)、将代码中sql下的pms_catelog.sql内容复制粘贴到sqlyog,运行完成。

             2)、在CategoryController中修改查询所有数据方法

     /**
     *  查出所有分类以及子分类,以树形结构组装起来
     */
    @RequestMapping("/list/tree")
    public R listWithTree(){
        List<CategoryEntity> entities = categoryService.listWithTree();
        /*
         *   1)箭头函数categoryEntity -> categoryEntity.getParentCid() == 0,
         *   表示每个传入的categoryEntity,如果其父分类的id=0,则其为一个一级分类 ;
         *   2)collect(Collectors.toList())表示将所有一级分类收集成一个集合List         *
         */
        entities.stream().filter((categoryEntity) -> {
            return categoryEntity.getParentCid() == 0;
        }).collect(Collectors.toList());
        return R.ok().put("data", entities);
    }

            3)、在CategoryService中生成listWithTree()方法

    List<CategoryEntity> listWithTree();

            4)、在CategoryServiceImpl中实现该方法

    @Override
    public List<CategoryEntity> listWithTree() {
        //1.显示所有分类,没有参数传入
        List<CategoryEntity> entities = baseMapper.selectList(null);
        //2.组装成树形结构
        //1)找到所有的一级分类
        /*
        *   1)箭头函数categoryEntity -> categoryEntity.getParentCid() == 0,
        *   表示每个传入的categoryEntity,如果其父分类的id=0,则其为一个一级分类 ;
        *   2)map将当前菜单的子分类传入,返回所有的分类
        *   3)stream():通过将集合转换为这么一种叫做 “流” 的元素序列,
        *   通过声明性方式,能够对集合中的每个元素进行一系列并行或串行的流水线操作
        *   4)Java8及以上版本中,使用stream().filter(箭头函数)来过滤一个List对象,查找符合条件的对象集合
        */
        List<CategoryEntity> level1Menus = entities.stream().filter((categoryEntity) ->{
              return categoryEntity.getParentCid() == 0;
        }).map((menu) -> {
            //getChildrens(menu,entities):查出当前菜单menu的所有子菜单
            //将当前菜单的子分类保存进入菜单
            menu.setChildren(getChildrens(menu,entities));
            //返回当前菜单
            return menu;
        }).sorted((menu1, menu2) -> {
            //return menu1.getSort() - menu2.getSort()因sort字段没有设置非空,可能会造成空指针异常,需做判定
            //三目运算符menu1.getSort()==null?0:menu1.getSort()即如果为空,则默认给其赋值为0,不为空则等于其自身
            return (menu1.getSort()==null?0:menu1.getSort()) - (menu2.getSort()==null?0:menu2.getSort());
        }).collect(Collectors.toList());
        //返回一级菜单
        return level1Menus;
    }
    
    /**
     * @param root:表示当前菜单
     * @param all:表示所有菜单
     * @return
     */
    //递归查找某一个菜单的子菜单
    private List<CategoryEntity> getChildrens (CategoryEntity root, List < CategoryEntity > all){
        //filter():过滤当前菜单
        List<CategoryEntity> children = all.stream().filter((categoryEntity) -> {
            return categoryEntity.getParentCid() == root.getCatId();
        }).map(categoryEntity -> {
            //将当前菜单的子分类保存进入菜单
            categoryEntity.setChildren(getChildrens(categoryEntity,all));
            return categoryEntity;
            //2.菜单的排序,传入当前菜单menu1和后一个菜单menu2
        }).sorted((menu1,menu2)->{
            //用第一个菜单的排序menu1.getSort()-后一个菜单的排序menu2.getSort()
            return (menu1.getSort()==null?0:menu1.getSort()) - (menu2.getSort()==null?0:menu2.getSort());
        }).collect(Collectors.toList());//Collectors.toList()用来结束Stream流。
        return children;
    }

            5)、访问localhost:10000/product/category/list/tree,得到数据即可。

        6.1.2、网关配置路由与路径重写

          1)、启动renren-fast-vue、renren-fast项目,登录
          2)、在系统管理-菜单管理中新建商品管理
          3)、在菜单管理中新建分类维护
          4)、vscode中view/modules中新建文件夹product,在product下新建Category.vue,使用模板生成组件(在逆向生成代码时有生成前端页面,可以直接拿来使用,这里前端代码就不一一敲了)
          5)、修改static/config/index.js中api请求地址

    // api接口请求地址
    window.SITE_CONFIG['baseUrl'] = 'http://localhost:88/api';

             6)、登录renrne-fast-vue项目报错,验证码不能显示

          7)、在renren-fast项目application.yml中配 

          8)、在gulimall-gateway中配置网关路由

    #将所有带/api/** 的请求都转到renren-fast/**
    - id: admin_route
      uri: lb://renren-fast
      predicates:
        - Path=/api/**
      filters:
         - RewritePath=/api/(?<segment>.*), /renren-fast/${segment}

          9)、再次访问,验证码能正常显示。登录继续报错。到了这一步不要慌,这是因为网关没有配置跨域导致的,下一节我们进行设置,确保登录成功。

        6.1.3、网关统一配置跨域

          1)、关于什么跨域大家自己去看文档或者百度
          2)、在gulimall-gateway中新建config包,创建GulimallCrosConfiguration

    @Configuration
    public class GulimallCrosConfiguration {
        @Bean
        public CorsWebFilter corsWebFilter(){
            UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
            CorsConfiguration corsConfiguration = new CorsConfiguration();
            corsConfiguration.addAllowedHeader("*");
            corsConfiguration.addAllowedMethod("*");
            corsConfiguration.addAllowedOrigin("*");
            corsConfiguration.setAllowCredentials(true);
            source.registerCorsConfiguration("/**",corsConfiguration);
    //      source.registerCorsConfiguration("/**",corsConfiguration);
            return new CorsWebFilter(source);
        }
    }

          3)、设置好跨域后,重启访问,再次报错,如下:

           4)、该错误是因为renren-fast项目自身也设置了跨域,我们将其注释即可。

           5)、再次重启访问,这次OK

        

      

  • 相关阅读:
    随笔一篇
    WPF SDK研究 Intro(2) QuickStart2
    WPF SDK研究 Intro(1) QuickStart1
    两道MS的面试题 及答案
    关于父子类方法的继承
    WCF笔记 1.WCF基础
    Vista下建立WCF遇到的问题及解决方案
    WPF SDK研究 目录
    WPF SDK研究 Printing (1) PrintDialog
    WPF SDK研究 Printing (2) EnumerateSubsetOfPrintQueues
  • 原文地址:https://www.cnblogs.com/gaoyangsixue/p/13280335.html
Copyright © 2011-2022 走看看