• 2022谷粒商城学习笔记(十三)ElasticSearch安装和商品上架功能


    前言

    本系列博客基于B站谷粒商城,只作为本人学习总结使用。这里我会比较注重业务逻辑的编写和相关配置的流程。有问题可以评论或者联系我互相交流。原视频地址谷粒商城雷丰阳版。本人git仓库地址Draknessssw的谷粒商城


    docker安装elasticsearch和kibana

    版本要和SpringBoot的版本对应

    下载镜像文件

    docker pull elasticsearch:7.6.2 
    docker pull kibana:7.6.2 
    
    • 1
    • 2

    创建实例,配置文件和数据文件,以及写入可以被任何远程访问的配置

    mkdir -p /mydata/elasticsearch/config 
    mkdir -p /mydata/elasticsearch/data 
    echo "http.host: 0.0.0.0" >> /mydata/elasticsearch/config/elasticsearch.yml
    
    • 1
    • 2
    • 3

    为elasticsearch文件夹赋予权限

    chmod -R 777 /mydata/elasticsearch/ 
    
    • 1

    启动elasticsearch

    docker run --name elasticsearch -p 9200:9200 -p 9300:9300 \
    -e "discovery.type=single-node" \
    -e ES_JAVA_OPTS="-Xms64m -Xmx512m" \
    -v /mydata/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
    -v /mydata/elasticsearch/data:/usr/share/elasticsearch/data \
    -v /mydata/elasticsearch/plugins:/usr/share/elasticsearch/plugins \ 
    -d elasticsearch:7.6.2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    安装运行kibana

    docker run --name kibana -e ELASTICSEARCH_HOSTS=http://192.168.56.10:9200 -p 5601:5601 \ -d kibana:7.6.2
    
    • 1

    其中,http://192.168.56.10:9200 一定改为自己虚拟机的地址,端口默认9200就好


    商品上架

    在elasticsearch中存储要搜索的数据模型(kibana可视化页面,本地ip地址加dev_tools)

    在这里插入图片描述

    其中,库存信息的标题使用了ik分词器,图片信息,品牌名,品牌id等信息均不可检索。商品的规格参数等信息以nested类型,即嵌入属性存储。相关的细节这里不再赘述。

    PUT product
    {
      "mappings": {
        "properties": {
          "skuId": {
            "type": "long"
          },
          "spuId": {
            "type": "long"
          },
          "skuTitle": {
            "type": "text",
            "analyzer": "ik_smart"
          },
          "skuPrice": {
            "type": "keyword"
          },
          "skuImg": {
            "type": "keyword",
            "index": false,
            "doc_values": false
          },
          "saleCount": {
            "type": "long"
          },
          "hosStock": {
            "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"
              }
            }
          }
        }
      }
    }
    
    • 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

    仿照数据模型,在common公共部分新建to,用于search服务和product服务传输数据

    package com.xxxx.common.to.es;
    
    import lombok.Data;
    
    import java.math.BigDecimal;
    import java.util.List;
    
    
    
    @Data
    public class SkuEsModel {
    
        private Long skuId;
    
        private Long spuId;
    
        private String skuTitle;
    
        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;
    
        }
    
    
    }
    
    
    • 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

    业务
    在这里插入图片描述

    //商品上架
        ///product/spuinfo/{spuId}/up
        @PostMapping(value = "/{spuId}/up")
        public R spuUp(@PathVariable("spuId") Long spuId) {
    
            spuInfoService.up(spuId);
    
            return R.ok();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    实现类
    首先,查询出可以被检索的库存商品的属性信息和这些库存。
    根据商品集合id查询商品库存信息

    //1、查出当前spuId对应的所有sku信息,品牌的名字
            List<SkuInfoEntity> skuInfoEntities = skuInfoService.getSkusBySpuId(spuId);
    
    • 1
    • 2

    对应实现方法

    @Override
        public List<SkuInfoEntity> getSkusBySpuId(Long spuId) {
            List<SkuInfoEntity> skuInfoEntities = this.list(new QueryWrapper<SkuInfoEntity>().eq("spu_id", spuId));
    
            return skuInfoEntities;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    根据商品集合id查出对应的所有商品集合属性信息,查出来后封装属性id

    List<ProductAttrValueEntity> baseAttrs = productAttrValueService.baseAttrListforspu(spuId);
    
    List<Long> attrIds = baseAttrs.stream().map(attr -> {
                return attr.getAttrId();
            }).collect(Collectors.toList());
    
    • 1
    • 2
    • 3
    • 4
    • 5

    对应实现方法

    	@Override
        public List<ProductAttrValueEntity> baseAttrListforspu(Long spuId) {
    
            List<ProductAttrValueEntity> attrValueEntityList = this.baseMapper.selectList(
                    new QueryWrapper<ProductAttrValueEntity>().eq("spu_id", spuId));
    
            return attrValueEntityList;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    根据当前属性id验证这些属性id是否存在并且这个属性是否可以被搜索。将可以被搜索的属性的id封装成set。

    		List<Long> searchAttrIds = attrService.selectSearchAttrs(attrIds);
            //转换为Set集合
            Set<Long> idSet = searchAttrIds.stream().collect(Collectors.toSet());
    
    • 1
    • 2
    • 3

    对应实现方法

    	@Override
        public List<Long> selectSearchAttrs(List<Long> attrIds) {
    
            List<Long> searchAttrIds = this.baseMapper.selectSearchAttrIds(attrIds);
    
            return searchAttrIds;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    搜索语句

    	<select id="selectSearchAttrIds" resultType="java.lang.Long">
    
            SELECT attr_id FROM pms_attr WHERE attr_id IN
            <foreach collection="attrIds" item="id" separator="," open="(" close=")">
                #{id}
            </foreach>
            AND search_type = 1
    
        </select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在To里面验证当前商品集合的属性确实是可以被检索的,然后设置To的属性信息。

    		List<SkuEsModel.Attrs> attrsList = baseAttrs.stream().filter(item -> {
                return idSet.contains(item.getAttrId());
            }).map(item -> {
                SkuEsModel.Attrs attrs = new SkuEsModel.Attrs();
                BeanUtils.copyProperties(item, attrs);
                return attrs;
            }).collect(Collectors.toList());
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    封装这个商品集合的库存信息的id,远程调用查询库存。最后封装对应的库存信息Vo。

    		Map<Long, Boolean> stockMap = null;
            try {
                R skuHasStock = wareFeignService.getSkuHasStock(skuIdList);
                //
                TypeReference<List<SkuHasStockVo>> typeReference = new TypeReference<List<SkuHasStockVo>>() {};
                stockMap = skuHasStock.getData(typeReference).stream()
                        .collect(Collectors.toMap(SkuHasStockVo::getSkuId, item -> item.getHasStock()));
            } catch (Exception e) {
                log.error("库存服务查询异常:原因{}",e);
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    对应远程调用接口

    在这里插入图片描述

    package com.xxxx.gulimall.product.feign;
    
    import com.xxxx.common.utils.R;
    import org.springframework.cloud.openfeign.FeignClient;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestBody;
    
    import java.util.List;
    
    
    
    @FeignClient("gulimall-ware")
    public interface WareFeignService {
    
        @PostMapping(value = "/ware/waresku/hasStock")
        R getSkuHasStock(@RequestBody List<Long> skuIds);
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    查看是否有库存的方法

    	/**
         * 查询sku是否有库存
         * @return
         */
        @PostMapping(value = "/hasStock")
        public R getSkuHasStock(@RequestBody List<Long> skuIds) {
    
            //skuId stock
            List<SkuHasStockVo> vos = wareSkuService.getSkuHasStock(skuIds);
    
            return R.ok().setData(vos);
    
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    实现类
    若是有库存,设置库存Vo为true,否则为false

    	@Override
        public List<SkuHasStockVo> getSkuHasStock(List<Long> skuIds) {
    
            List<SkuHasStockVo> skuHasStockVos = skuIds.stream().map(item -> {
                Long count = this.baseMapper.getSkuStock(item);
                SkuHasStockVo skuHasStockVo = new SkuHasStockVo();
                skuHasStockVo.setSkuId(item);
                skuHasStockVo.setHasStock(count == null?false:count > 0);
                return skuHasStockVo;
            }).collect(Collectors.toList());
            return skuHasStockVos;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    sql

    	<select id="getSkuStock" resultType="java.lang.Long">
            SELECT
                   SUM(stock - stock_locked)
            FROM
                 wms_ware_sku
            WHERE
                  sku_id = #{skuId}
        </select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    对应Vo

    package com.xxxx.common.to;
    
    import lombok.Data;
    
    
    
    @Data
    public class SkuHasStockVo {
    
        private Long skuId;
    
        private Boolean hasStock;
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    第二步,封装库存信息

    但是在设置库存的时候,没有库存也得给它设置为true(不然会出异常),否则就按查到的库存数量来。

    		Map<Long, Boolean> finalStockMap = stockMap;
            List<SkuEsModel> collect = skuInfoEntities.stream().map(sku -> {
                //组装需要的数据
                SkuEsModel esModel = new SkuEsModel();
                esModel.setSkuPrice(sku.getPrice());
                esModel.setSkuImg(sku.getSkuDefaultImg());
    
                //设置库存信息
                if (finalStockMap == null) {
                    esModel.setHasStock(true);
                } else {
                    esModel.setHasStock(finalStockMap.get(sku.getSkuId()));
                }
    
                //TODO 2、热度评分。0
                esModel.setHotScore(0L);
    
                //TODO 3、查询品牌和分类的名字信息
                BrandEntity brandEntity = brandService.getById(sku.getBrandId());
                esModel.setBrandName(brandEntity.getName());
                esModel.setBrandId(brandEntity.getBrandId());
                esModel.setBrandImg(brandEntity.getLogo());
    
                CategoryEntity categoryEntity = categoryService.getById(sku.getCatalogId());
                esModel.setCatalogId(categoryEntity.getCatId());
                esModel.setCatalogName(categoryEntity.getName());
    
                //设置检索属性
                esModel.setAttrs(attrsList);
    
                BeanUtils.copyProperties(sku,esModel);
    
                return esModel;
            }).collect(Collectors.toList());
    
    • 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

    第三步就是发送这些库存信息给search服务,要是成功上架,修改商品库存信息状态为“上架”

    		R r = searchFeignService.productStatusUp(collect);
    
            if (r.getCode() == 0) {
                //远程调用成功
                //TODO 6、修改当前spu的状态
                this.baseMapper.updaSpuStatus(spuId, ProductConstant.ProductStatusEnum.SPU_UP.getCode());
            } else {
                //远程调用失败
                //TODO 7、重复调用?接口幂等性:重试机制
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    远程接口

    package com.xxxx.gulimall.product.feign;
    
    
    import com.xxxx.common.to.es.SkuEsModel;
    import com.xxxx.common.utils.R;
    import org.springframework.cloud.openfeign.FeignClient;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestBody;
    
    import java.util.List;
    
    
    
    @FeignClient("gulimall-search")
    public interface SearchFeignService {
    
        @PostMapping(value = "/search/save/product")
        public R productStatusUp(@RequestBody List<SkuEsModel> skuEsModels);
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    库存服务的对应Controller

    	/**
         * 上架商品
         * @param skuEsModels
         * @return
         */
        @PostMapping(value = "/product")
        public R productStatusUp(@RequestBody List<SkuEsModel> skuEsModels) {
    
            boolean status=false;
            try {
                status = productSaveService.productStatusUp(skuEsModels);
            } catch (IOException e) {
                //log.error("商品上架错误{}",e);
    
                return R.error(BizCodeEnum.PRODUCT_UP_EXCEPTION.getCode(),BizCodeEnum.PRODUCT_UP_EXCEPTION.getMessage());
            }
    
            if(status){
                return R.error(BizCodeEnum.PRODUCT_UP_EXCEPTION.getCode(),BizCodeEnum.PRODUCT_UP_EXCEPTION.getMessage());
            }else {
                return R.ok();
            }
    
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    在保存信息之前,得在es中保存索引

    在这里插入图片描述

    package com.xxxx.gulimall.search.constant;
    
    
    public class EsConstant {
    
        //在es中的索引
        public static final String PRODUCT_INDEX = "gulimall_product";
    
        public static final Integer PRODUCT_PAGESIZE = 16;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    以及elasticsearch的客户端连接配置

    package com.xxxx.gulimall.search.config;
    
    import org.apache.http.HttpHost;
    import org.elasticsearch.client.RequestOptions;
    import org.elasticsearch.client.RestClient;
    import org.elasticsearch.client.RestHighLevelClient;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class GulimallElasticSearchConfig {
    
        public static final RequestOptions COMMON_OPTIONS;
    
        /**
         * 通用设置项
         */
        static {
            RequestOptions.Builder builder = RequestOptions.DEFAULT.toBuilder();
    //        builder.addHeader("Authorization", "Bearer " + TOKEN);
    //        builder.setHttpAsyncResponseConsumerFactory(
    //                new HttpAsyncResponseConsumerFactory
    //                        .HeapBufferedResponseConsumerFactory(30 * 1024 * 1024 * 1024));
            COMMON_OPTIONS = builder.build();
        }
    
        @Bean
        public RestHighLevelClient esRestClient() {
            RestHighLevelClient client = new RestHighLevelClient(
                    RestClient.builder(
                            new HttpHost("192.168.75.129", 9200, "http")));// 如果此处是集群,传入多个主机就可以了
            return client;
        }
    }
    
    
    • 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

    对应实现类

    package com.xxxx.gulimall.search.service.impl;
    
    import com.alibaba.fastjson.JSON;
    import com.xxxx.common.to.es.SkuEsModel;
    import com.xxxx.gulimall.search.config.GulimallElasticSearchConfig;
    import com.xxxx.gulimall.search.constant.EsConstant;
    import com.xxxx.gulimall.search.service.ProductSaveService;
    import lombok.extern.slf4j.Slf4j;
    import org.elasticsearch.action.bulk.BulkRequest;
    import org.elasticsearch.action.bulk.BulkResponse;
    import org.elasticsearch.action.index.IndexRequest;
    import org.elasticsearch.client.RestHighLevelClient;
    import org.elasticsearch.common.xcontent.XContentType;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import java.io.IOException;
    import java.util.Arrays;
    import java.util.List;
    import java.util.stream.Collectors;
    
    
    
    @Slf4j
    @Service("productSaveService")
    public class ProductSaveServiceImpl implements ProductSaveService {
    
        @Autowired
        private RestHighLevelClient esRestClient;
    
        @Override
        public boolean productStatusUp(List<SkuEsModel> skuEsModels) throws IOException {
    
    //1.在es中建立索引,建立号映射关系(doc/json/product-mapping.json)
    
            //2. 在ES中保存这些数据
            BulkRequest bulkRequest = new BulkRequest();
            for (SkuEsModel skuEsModel : skuEsModels) {
                //构造保存请求
                IndexRequest indexRequest = new IndexRequest(EsConstant.PRODUCT_INDEX);
                indexRequest.id(skuEsModel.getSkuId().toString());
                String jsonString = JSON.toJSONString(skuEsModel);
                indexRequest.source(jsonString, XContentType.JSON);
                bulkRequest.add(indexRequest);
            }
    
    
            BulkResponse bulk = esRestClient.bulk(bulkRequest, GulimallElasticSearchConfig.COMMON_OPTIONS);
    
            //TODO 如果批量错误
            boolean hasFailures = bulk.hasFailures();
    
            List<String> collect = Arrays.asList(bulk.getItems()).stream().map(item -> {
                return item.getId();
            }).collect(Collectors.toList());
    
            log.info("商品上架完成:{}",collect);
    
            return hasFailures;
        }
    }
    
    
    • 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

    最终效果如下

    	@Autowired
        private AttrService attrService;
    
        @Autowired
        private ProductAttrValueService productAttrValueService;
    
        @Autowired
        private SkuInfoService skuInfoService;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    @Transactional
        @Override
        public void up(Long spuId) {
    
            //1、查出当前spuId对应的所有sku信息,品牌的名字
            List<SkuInfoEntity> skuInfoEntities = skuInfoService.getSkusBySpuId(spuId);
    
            //TODO 4、查出当前sku的所有可以被用来检索的规格属性
            List<ProductAttrValueEntity> baseAttrs = productAttrValueService.baseAttrListforspu(spuId);
    
            List<Long> attrIds = baseAttrs.stream().map(attr -> {
                return attr.getAttrId();
            }).collect(Collectors.toList());
    
            List<Long> searchAttrIds = attrService.selectSearchAttrs(attrIds);
            //转换为Set集合
            Set<Long> idSet = searchAttrIds.stream().collect(Collectors.toSet());
    
            List<SkuEsModel.Attrs> attrsList = baseAttrs.stream().filter(item -> {
                return idSet.contains(item.getAttrId());
            }).map(item -> {
                SkuEsModel.Attrs attrs = new SkuEsModel.Attrs();
                BeanUtils.copyProperties(item, attrs);
                return attrs;
            }).collect(Collectors.toList());
    
            List<Long> skuIdList = skuInfoEntities.stream()
                    .map(SkuInfoEntity::getSkuId)
                    .collect(Collectors.toList());
            //TODO 1、发送远程调用,库存系统查询是否有库存
            Map<Long, Boolean> stockMap = null;
            try {
                R skuHasStock = wareFeignService.getSkuHasStock(skuIdList);
                //
                TypeReference<List<SkuHasStockVo>> typeReference = new TypeReference<List<SkuHasStockVo>>() {};
                stockMap = skuHasStock.getData(typeReference).stream()
                        .collect(Collectors.toMap(SkuHasStockVo::getSkuId, item -> item.getHasStock()));
            } catch (Exception e) {
                log.error("库存服务查询异常:原因{}",e);
            }
    
            //2、封装每个sku的信息
            Map<Long, Boolean> finalStockMap = stockMap;
            List<SkuEsModel> collect = skuInfoEntities.stream().map(sku -> {
                //组装需要的数据
                SkuEsModel esModel = new SkuEsModel();
                esModel.setSkuPrice(sku.getPrice());
                esModel.setSkuImg(sku.getSkuDefaultImg());
    
                //设置库存信息
                if (finalStockMap == null) {
                    esModel.setHasStock(true);
                } else {
                    esModel.setHasStock(finalStockMap.get(sku.getSkuId()));
                }
    
                //TODO 2、热度评分。0
                esModel.setHotScore(0L);
    
                //TODO 3、查询品牌和分类的名字信息
                BrandEntity brandEntity = brandService.getById(sku.getBrandId());
                esModel.setBrandName(brandEntity.getName());
                esModel.setBrandId(brandEntity.getBrandId());
                esModel.setBrandImg(brandEntity.getLogo());
    
                CategoryEntity categoryEntity = categoryService.getById(sku.getCatalogId());
                esModel.setCatalogId(categoryEntity.getCatId());
                esModel.setCatalogName(categoryEntity.getName());
    
                //设置检索属性
                esModel.setAttrs(attrsList);
    
                BeanUtils.copyProperties(sku,esModel);
    
                return esModel;
            }).collect(Collectors.toList());
    
            //TODO 5、将数据发给es进行保存:gulimall-search
            R r = searchFeignService.productStatusUp(collect);
    
            if (r.getCode() == 0) {
                //远程调用成功
                //TODO 6、修改当前spu的状态
                this.baseMapper.updaSpuStatus(spuId, ProductConstant.ProductStatusEnum.SPU_UP.getCode());
            } else {
                //远程调用失败
                //TODO 7、重复调用?接口幂等性:重试机制
            }
        }
    
    • 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
  • 相关阅读:
    简易实现QT中的virtualkeyboard及问题总结
    JS深浅拷贝
    喜报 | 人大金仓荣获2023“金鼎奖”,金融系统解决方案再获认可
    Oracle-数据的基本操作
    node(三)express框架
    TCP中发送数据的情况
    Redis详细教程
    记研二首次组会汇报暨进组后第三次组会汇报
    大数据技术大全
    数字化转型道阻且长,如何迈好关键的第一步
  • 原文地址:https://blog.csdn.net/qq_44737138/article/details/126474709