day11 商品详情功能

1.环境搭建

  • 上传html页面

    image-20221021201749494

  • 修改网关yml 添加host为item的域名

    image-20221021202135317

  • 修改host文件,通过nginx监听item.dreammall.com域名来转发到gateway网关,再由网关转到product微服务

    image-20221021202311482

  • 上传静态资源到nginx

    image-20221021202940887

  • 修改html页面文件资源的路径

image-20221021203303387

image-20221021203359115

  • 修改index.html查询商品详情的请求地址

    image-20221021210005695

  • 编写controller层

    image-20221021210211216

  • 点击商品详情跳转到详情页面

    image-20221021210235723

2.功能实现

  • 创建VO对象

    @Data
    public class SkuItemVo {
        //1、sku基本信息的获取  pms_sku_info
        private SkuInfo info;
    
        private boolean hasStock = true;
    
        //2、sku的图片信息    pms_sku_images
        private List<SkuImages> images;
    
        //3、获取spu的销售属性组合
        private List<SkuItemSaleAttrVo> saleAttr;
    
        //4、获取spu的介绍
        private SpuInfoDesc desc;
    
        //5、获取spu的规格参数信息
        private List<SpuItemAttrGroupVo> groupAttrs;
    
        @Data
        public static  class  SkuItemSaleAttrVo{
            private Long attrId;
    
            private String attrName;
    
            private List<AttrValueWithSkuIdVo> attrValues;
        }
        @Data
        public static class AttrValueWithSkuIdVo{
    
            private String attrValue;
    
            private String skuIds;
        }
        @Data
        public static  class  SpuItemAttrGroupVo{
    
            private String groupName;
    
            private List<Attr> attrs;
        }
    }
    
  • 编写sql遇到mybatis无法识别内部类怎么办?

    • 将.改成$即可

    image-20221022162349677

  • 业务流程

     		// 获取sku的基本信息
        SkuInfo skuInfo = getById(skuId);
        // 获取sku的图片信息
        List<SkuImages> skuImages = skuImagesService.list(Wrappers.<SkuImages>lambdaQuery().eq(SkuImages::getSkuId, skuId));
        // 获取spu销售属性集合
        List<SkuItemVo.SkuItemSaleAttrVo> saleAttr = skuSaleAttrValueService.getSaleAttrBySpuId(skuInfo.getSpuId());
        // 获取spu的介绍
        SpuInfoDesc spuInfoDesc = spuInfoDescService.getById(skuInfo.getSpuId());
        // 获取spu的规格参数信息
        List<SkuItemVo.SpuItemAttrGroupVo> groupAttrs = attrGroupService.getAttrGroupWithAttrsBySpuId(skuInfo.getSpuId(), skuInfo.getCatalogId());
        // 查询sku是否还有库存
        Map<Long, Boolean> stockMap = null;
        try {
            R skuHasStock = wareFeignService.hasStock(Collections.singletonList(skuInfo.getSkuId()));
            TypeReference<List<SkuHasStockVo>> typeReference = new TypeReference<List<SkuHasStockVo>>() {
            };
            stockMap = skuHasStock.getData(typeReference).stream()
                    .collect(Collectors.toMap(SkuHasStockVo::getSkuId, SkuHasStockVo::getHasStock));
            skuItemVo.setHasStock(stockMap.get(skuInfo.getSkuId()));
        } catch (Exception e) {
            log.error("库存服务查询异常:原因{}", e);
        }
  • 实现获取spu的规格参数信息的sql

        <resultMap id="SpuItemAttrGroupVoMap" type="com.liubo.product.vo.SkuItemVo$SpuItemAttrGroupVo">
            <result property="groupName" column="attr_group_name"/>
            <collection property="attrs" ofType="com.liubo.product.vo.SkuItemVo$AttrVo">
                <result property="attrId" column="attr_id"/>
                <result property="attrName" column="attr_name"/>
                <result property="attrValue" column="attr_value"/>
            </collection>
        </resultMap>
      
      
      <select id="getAttrGroupWithAttrsBySpuId" resultMap="SpuItemAttrGroupVoMap">
            SELECT
                atrgroup.attr_group_name as attr_group_name,
                atrvalue.attr_id as attr_id,
                atrvalue.attr_name as attr_name,
                atrvalue.attr_value as attr_value
            FROM
                pms_product_attr_value AS atrvalue
                    LEFT JOIN pms_attr_attrgroup_relation AS relation ON relation.attr_id = atrvalue.attr_id
                    LEFT JOIN pms_attr_group AS atrgroup ON relation.attr_group_id = atrgroup.attr_group_id
            WHERE
                atrvalue.spu_id = #{spuId} and atrgroup.catelog_id = #{catalogId}
        </select>
    
  • 实现获取销售属性的sql

         <resultMap id="SkuItemSaleAttrVoMap" type="com.liubo.product.vo.SkuItemVo$SkuItemSaleAttrVo">
            <result property="attrId" column="attr_id"/>
            <result property="attrName" column="attr_name"/>
            <collection property="attrValues" ofType="com.liubo.product.vo.SkuItemVo$AttrValueWithSkuIdVo">
                <result column="attr_value" property="attrValue"/>
                <result column="sku_ids" property="skuIds"/>
            </collection>
        </resultMap>   
        
        <select id="getSaleAttrBySpuId" resultMap="SkuItemSaleAttrVoMap">
            SELECT
                b.attr_id as attr_id,
                b.attr_name as attr_name,
                b.attr_value as attr_value,
                GROUP_CONCAT(DISTINCT a.sku_id) as sku_ids
            FROM
                pms_sku_info AS a
                    LEFT JOIN pms_sku_sale_attr_value AS b ON a.sku_id = b.sku_id
            WHERE
                spu_id = #{spuId}
            GROUP BY
                b.attr_id,
                b.attr_name,
                b.attr_value
        </select>
    
  • 页面效果

    image-20221022195513502

  • 页面流程步骤太复杂?尝试用异步编程

    • 自定义线程池

      @Configuration
      @ConfigurationProperties(prefix = "thread.pool")
      public class ThreadPoolConfig {
      
          @Setter
          private int corePoolSize;
          @Setter
          private int maximumPoolSize;
          @Setter
          private int keepAliveTime;
      
          /**
           * 自定义线程池
           * @return
           */
          @Bean
          public ThreadPoolExecutor skuItemThreadPoolExecutor() {
              return new ThreadPoolExecutor(
                      corePoolSize,
                      maximumPoolSize,
                      keepAliveTime,
                      TimeUnit.SECONDS,
                      new LinkedBlockingDeque<>(10000),
                      Executors.defaultThreadFactory()
              );
          }
      }
      
    • 业务代码改造

      public SkuItemVo item(Long skuId) {
              SkuItemVo skuItemVo = new SkuItemVo();
              // 获取sku的基本信息
              CompletableFuture<SkuInfo> skuInfoFuture = CompletableFuture.supplyAsync(() -> {
                  SkuInfo skuInfo = getById(skuId);
                  skuItemVo.setInfo(skuInfo);
                  return skuInfo;
              }, threadPoolExecutor);
              // 获取sku的图片信息
              CompletableFuture<Void> skuImagesFuture = CompletableFuture.runAsync(() -> {
                  List<SkuImages> skuImages = skuImagesService.list(Wrappers.<SkuImages>lambdaQuery().eq(SkuImages::getSkuId, skuId));
                  skuItemVo.setImages(skuImages);
              }, threadPoolExecutor);
              // 获取spu销售属性集合
              CompletableFuture<Void> saleAttrFuture = skuInfoFuture.thenAcceptAsync(result -> {
                  List<SkuItemVo.SkuItemSaleAttrVo> saleAttr = skuSaleAttrValueService.getSaleAttrBySpuId(result.getSpuId());
                  skuItemVo.setSaleAttr(saleAttr);
              }, threadPoolExecutor);
      
              // 获取spu的介绍
              CompletableFuture<Void> spuInfoDescFuture = skuInfoFuture.thenAcceptAsync(result -> {
                  SpuInfoDesc spuInfoDesc = spuInfoDescService.getById(result.getSpuId());
                  skuItemVo.setDesc(spuInfoDesc);
              }, threadPoolExecutor);
      
      
              // 获取spu的规格参数信息
              CompletableFuture<Void> groupAttrsFuture = skuInfoFuture.thenAcceptAsync(result -> {
                  List<SkuItemVo.SpuItemAttrGroupVo> groupAttrs = attrGroupService.getAttrGroupWithAttrsBySpuId(result.getSpuId(), result.getCatalogId());
                  skuItemVo.setGroupAttrs(groupAttrs);
              }, threadPoolExecutor);
      
              // 等待所有任务完成
              CompletableFuture.allOf(skuInfoFuture, skuImagesFuture, saleAttrFuture, spuInfoDescFuture, groupAttrsFuture).join();
      
              // 查询sku是否还有库存
              Map<Long, Boolean> stockMap = null;
              try {
                  R skuHasStock = wareFeignService.hasStock(Collections.singletonList(skuId));
                  TypeReference<List<SkuHasStockVo>> typeReference = new TypeReference<List<SkuHasStockVo>>() {
                  };
                  stockMap = skuHasStock.getData(typeReference).stream()
                          .collect(Collectors.toMap(SkuHasStockVo::getSkuId, SkuHasStockVo::getHasStock));
                  skuItemVo.setHasStock(stockMap.get(skuId));
              } catch (Exception e) {
                  log.error("库存服务查询异常:原因{}", e);
              }
              return skuItemVo;
          }
      
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值