当前位置: 首页 > news >正文

【第九篇】商城系统-商城首页功能

在这里插入图片描述

一、商品上架功能

ElasticSearch实现商城系统中全文检索的流程。

image.png

1.商品ES模型

商品的映射关系

PUT product 
{
	"mappings": {
		"properties": {
			"skuId": {
				"type": "long"
			},
			"spuId": {
				"type": "keyword"
			},
			"skuTitle": {
				"type": "text",
				"analyzer": "ik_smart"
			},
			"skuPrice": {
				"type": "keyword"
			},
			"skuImg": {
				"type": "keyword",
				"index": "false",
				"doc_values": "false"
			},
			"saleCount": {
				"type": "long"
			},
			"hasStock": {
				"type": "boolean"
			},
			"hotScore": {
				"type": "long"
			},
			"brandId": {
				"type": "long"
			},
			"catalogId": {
				"type": "long"
			},
			"brandName": {
				"type": "keyword",
				"index": "false",
				"doc_values": "false"
			},
			"brandImg": {
				"type": "keyword",
				"index": "false",
				"doc_values": "false"
			},
			"catalogName": {
				"type": "keyword",
				"index": "false",
				"doc_values": "false"
			},
			"attrs": {
				"type": "nested",
				"properties": {
					"attrId": {
						"type": "long"
					},
					"attrName": {
						"type": "keyword",
						"index": "false",
						"doc_values": "false"
					},
					"attrValue": {
						"type": "keyword"
					}
				}
			}
		}
	}
}

2.netsted数据类型

参考官网地址:https://www.elastic.co/guide/en/elasticsearch/reference/7.4/nested.html

3.实现上架功能

3.1 创建ESModel

点击上架功能传递spuId到后台,我们需要根据SpuID查询对应的信息,然后封装到自定义的Model对象中,然后将该对象传递给mall-search服务,所以我们需要先定义这样一个Model对象

@Data
public class SkuESModel {
    private Long skuId;
    private Long spuId;
    private String subTitle;
    private BigDecimal skuPrice;
    private String skuImg;
    private Long saleCount;
    private Boolean hasStock;
    private Long hotScore;
    private Long brandId;
    private Long catalogId;
    private String brandName;
    private String brandImg;
    private String catalogName;
    private List<Attrs> attrs;
  
    @Data
    public static class Attrs{
       private Long attrId;
       private String attrName;
       private String attrValue;
    }

}

3.2 上架逻辑实现

/**
     * 实现商品上架--》商品相关数据存储到ElasticSearch中
     * 1.根据SpuID查询出相关的信息
     *   封装到对应的对象中
     * 2.将封装的数据存储到ElasticSearch中--》调用mall-search的远程接口
     * 3.更新SpuID对应的状态--》上架
     *
     * @param spuId
     */
    @Override
    public void up(Long spuId) {
        // 1.根据spuId查询相关的信息 封装到SkuESModel对象中
        List<SkuESModel> skuEs = new ArrayList<>();
        // 根据spuID找到对应的SKU信息
        List<SkuInfoEntity> skus = skuInfoService.getSkusBySpuId(spuId);

        // 对应的规格参数  根据spuId来查询规格参数信息
        List<SkuESModel.Attrs> attrsModel = getAttrsModel(spuId);
        // 需要根据所有的skuId获取对应的库存信息---》远程调用
        List<Long> skuIds = skus.stream().map(sku -> {
            return sku.getSkuId();
        }).collect(Collectors.toList());
        Map<Long, Boolean> skusHasStockMap = getSkusHasStock(skuIds);
        // 2.远程调用mall-search的服务,将SukESModel中的数据存储到ES中
        List<SkuESModel> skuESModels = skus.stream().map(item -> {
            SkuESModel model = new SkuESModel();
            // 先实现属性的复制
            BeanUtils.copyProperties(item,model);
            model.setSubTitle(item.getSkuTitle());
            model.setSkuPrice(item.getPrice());

            // hasStock 是否有库存 --》 库存系统查询  一次远程调用获取所有的skuId对应的库存信息
            if(skusHasStockMap == null){
                model.setHasStock(true);
            }else{
                model.setHasStock(skusHasStockMap.get(item.getSkuId()));
            }
            // hotScore 热度分 --> 默认给0即可
            model.setHotScore(0l);
            // 品牌和类型的名称
            BrandEntity brand = brandService.getById(item.getBrandId());
            CategoryEntity category = categoryService.getById(item.getCatalogId());
            model.setBrandName(brand.getName());
            model.setBrandImg(brand.getLogo());
            model.setCatalogName(category.getName());
            // 需要存储的规格数据
            model.setAttrs(attrsModel);

            return model;
        }).collect(Collectors.toList());
        // 将SkuESModel中的数据存储到ES中
        R r = searchFeginService.productStatusUp(skuESModels);
        // 3.更新SPUID对应的状态
        // 根据对应的状态更新商品的状态
        log.info("----->ES操作完成:{}" ,r.getCode());
        System.out.println("-------------->"+r.getCode());
        if(r.getCode() == 0){
            // 远程调用成功  更新商品的状态为 上架
            baseMapper.updateSpuStatusUp(spuId, ProductConstant.StatusEnum.SPU_UP.getCode());
        }else{
            // 远程调用失败
        }
    }

二、三级分类数据

1.一级分类的数据

加载商城首页的时候就需要获取一级分类的数据

    @GetMapping({"/","/index.html","/home","/home.html"})
    public String index(Model model){
        // 查询出所有的一级分类的信息
        List<CategoryEntity> list = categoryService.getLeve1Category();
        model.addAttribute("categorys",list);
        // classPath:/templates/
        // .html
        return "index";
    }

在Service中的实现

    /**
     * 查询出所有的商品大类(一级分类)
     * @return
     */
    @Override
    public List<CategoryEntity> getLeve1Category() {
        List<CategoryEntity> list = baseMapper.queryLeve1Category();
        return list;
    }

然后在index.html中处理

image.png

然后访问页面的效果

image.png

2.二三级分类数据

在默认的情况下其实加载的是写死的JSON文件

image.png

结合这个文件我们创建了对应的VO对象来封装对应的数据

package com.msb.mall.product.vo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

/**
 * 二级分类需要展示的数据VO
 */
@NoArgsConstructor
@AllArgsConstructor
@Data
public class Catalog2VO {

    private String  catalog1Id; // 二级分类对应的一级父类的编号
    private List<Catalog3VO> catalog3List; // 二级分类对应的三级分类的数据
    private String id; // 二级分类的编号
    private String name ; // 二级分类对应的类别名称


    /**
     * 三级分类
     */
    @NoArgsConstructor
    @AllArgsConstructor
    @Data
    public static class Catalog3VO{

        private String catalog2Id ; // 三级分类对应的二级分类的编号
        private String id; // 三级分类编号
        private String name; // 三级分类名称

    }
}

然后我们在服务端查询对应的数据

    @ResponseBody
    @RequestMapping("/index/catalog.json")
    public Map<String, List<Catalog2VO>> getCatalog2JSON(){
        Map<String, List<Catalog2VO>> map = categoryService.getCatelog2JSON();
        return map;
    }

然后在service中完成对应的逻辑

    /**
     * 查询出所有的二级和三级分类的数据
     * 并封装为Map<String, Catalog2VO>对象
     * @return
     */
    @Override
    public Map<String, List<Catalog2VO>> getCatelog2JSON() {
        // 获取所有的一级分类的数据
        List<CategoryEntity> leve1Category = this.getLeve1Category();
        // 把一级分类的数据转换为Map容器 key就是一级分类的编号, value就是一级分类对应的二级分类的数据
        Map<String, List<Catalog2VO>> map = leve1Category.stream().collect(Collectors.toMap(
                key -> key.getCatId().toString()
                , value -> {
                    // 根据一级分类的编号,查询出对应的二级分类的数据
                    List<CategoryEntity> l2Catalogs = baseMapper
                            .selectList(new QueryWrapper<CategoryEntity>().eq("parent_cid", value.getCatId()));
                    List<Catalog2VO> Catalog2VOs =null;
                    if(l2Catalogs != null){
                        Catalog2VOs = l2Catalogs.stream().map(l2 -> {
                            // 需要把查询出来的二级分类的数据填充到对应的Catelog2VO中
                            Catalog2VO catalog2VO = new Catalog2VO(l2.getParentCid().toString(), null, l2.getCatId().toString(), l2.getName());
                            // 根据二级分类的数据找到对应的三级分类的信息
                            List<CategoryEntity> l3Catelogs = baseMapper.selectList(new QueryWrapper<CategoryEntity>().eq("parent_cid", catalog2VO.getId()));
                            if(l3Catelogs != null){
                                // 获取到的二级分类对应的三级分类的数据
                                List<Catalog2VO.Catalog3VO> catalog3VOS = l3Catelogs.stream().map(l3 -> {
                                    Catalog2VO.Catalog3VO catalog3VO = new Catalog2VO.Catalog3VO(l3.getParentCid().toString(), l3.getCatId().toString(), l3.getName());
                                    return catalog3VO;
                                }).collect(Collectors.toList());
                                // 三级分类关联二级分类
                                catalog2VO.setCatalog3List(catalog3VOS);
                            }
                            return catalog2VO;
                        }).collect(Collectors.toList());
                    }

                    return Catalog2VOs;
                }
        ));
        return map;
    }

修改js中的访问路径

image.png

然后访问即可

image.png

三、Nginx域名

1.hosts文件

在c:/window/system32/drivers/etc/hosts文件,我们在这个文件中添加

192.168.56.100 msb.mall.com

注意如果是没有操作权限,那么点击该文件右击属性,去掉只读属性即可

通过这个域名访问到Nginx服务

2.Nginx的方向代理

image.png

image.png

3.Nginx的负载均衡

image.png

image.png

image.png

对应的需要修改网关的配置

image.png

然后即可通过域名来访问商城的首页

image.png

相关文章:

  • 【SpringBoot+MyBatisPlus】系统全局异常处理器的使用以及添加员工功能的实现
  • FreeRTOS大杂烩
  • 都这麽大了还不快了解防病毒网关?
  • HTML 笔记(八):SVG
  • 15.5 - 边界值法
  • 图解MySQL 记录
  • Effective C++学习笔记——确定对象被使用前已先被初始化
  • 一文弄懂 HashMap 中的位运算
  • 【易购管理系统】路由界面基础搭建
  • Linux系统常规异常报错解决汇总:
  • 【编程语言】什么是闭包?你可能经常在用它,但不知道它叫闭包!
  • 【live2D看板娘】为你的网站添加萌萌的二次元板娘,这都拿不下你?
  • 信息学奥赛一本通:1014:与圆相关的计算
  • 【APP 逆向百例】Frida 初体验,root 检测与加密字符串定位
  • 安卓中listview中性能优化的处理
  • 【Under-the-hood-ReactJS-Part0】React源码解读
  • 【跃迁之路】【641天】程序员高效学习方法论探索系列(实验阶段398-2018.11.14)...
  • Docker: 容器互访的三种方式
  • IDEA常用插件整理
  • JavaScript 基本功--面试宝典
  • Java多态
  • js操作时间(持续更新)
  • leetcode98. Validate Binary Search Tree
  • Otto开发初探——微服务依赖管理新利器
  • Python_网络编程
  • 开源地图数据可视化库——mapnik
  • 前端设计模式
  • 说说动画卡顿的解决方案
  • 一起来学SpringBoot | 第十篇:使用Spring Cache集成Redis
  • 原生JS动态加载JS、CSS文件及代码脚本
  • MiKTeX could not find the script engine ‘perl.exe‘ which is required to execute ‘latexmk‘.
  • elasticsearch-head插件安装
  • 京东物流联手山西图灵打造智能供应链,让阅读更有趣 ...
  • 如何用纯 CSS 创作一个菱形 loader 动画
  • ​【C语言】长篇详解,字符系列篇3-----strstr,strtok,strerror字符串函数的使用【图文详解​】
  • # 学号 2017-2018-20172309 《程序设计与数据结构》实验三报告
  • #Spring-boot高级
  • (附源码)spring boot公选课在线选课系统 毕业设计 142011
  • (已解决)vue+element-ui实现个人中心,仿照原神
  • ***php进行支付宝开发中return_url和notify_url的区别分析
  • .net mvc 获取url中controller和action
  • .NET 程序如何获取图片的宽高(框架自带多种方法的不同性能)
  • .NET 服务 ServiceController
  • /ThinkPHP/Library/Think/Storage/Driver/File.class.php  LINE: 48
  • @ 代码随想录算法训练营第8周(C语言)|Day57(动态规划)
  • @ModelAttribute使用详解
  • [ C++ ] STL_list 使用及其模拟实现
  • [ vulhub漏洞复现篇 ] ECShop 2.x / 3.x SQL注入/远程执行代码漏洞 xianzhi-2017-02-82239600
  • [ 网络基础篇 ] MAP 迈普交换机常用命令详解
  • [BZOJ2281][SDOI2011]黑白棋(K-Nim博弈)
  • [CareerCup] 12.3 Test Move Method in a Chess Game 测试象棋游戏中的移动方法
  • [flask] flask的基本介绍、flask快速搭建项目并运行
  • [hdu 4552] 怪盗基德的挑战书
  • [HeMIM]Cl,[AeMIM]Br,[CeEIM]Cl,([HO-PECH-MIM]Cl,[HOOC-PECH-MIM]Cl改性酚醛树脂
  • [IE编程] IE中使网页元素进入编辑模式