• 【第十五篇】商城系统-商品详情页功能实现


    在这里插入图片描述

    商品详情页

    一、服务搭建

    image.png

    1.配置host文件

      我们的商品详情服务是一个独立的服务,我们需要在客户端的host中来配置映射

    image.png

    2.在Nginx中配置

      我们需要在Nginx中配置商品详情服务的反向代理和静态资源的管理,首先看反向代理的配置

    image.png

      然后就是静态资源的管理,我们在es和商城首页的资源的同级目录下创建一个item目录,其中保存的就是商品详情页中的资源

    image.png

    3.网关服务路由

      当Nginx方向代理到了网关服务后,网关服务得跟进host路由到商品服务,我们得修改对应的配置信息

    image.png

    4.商品服务处理

      到请求到了商品服务中我们需要接收请求,并且跳转到商品详情页中。

    /**
     * 商品详情的控制器
     */
    @Controller
    public class ItemController {
    
        @GetMapping("/{skuId}.html")
        public String item(@PathVariable Long skuId){
            System.out.println(skuId);
            return "item";
        }
    }
    

    image.png

    item.html页面中的内容在给大家的资源中有,拷贝进去即可,注意要修改相关的资源的路径

    image.png

    5.检索服务跳转

      商品详情服务搭建好了之后,我们需要通过商品的检索服务调整过来,那么我们需要修改跳转的地址信息

                                <p class="da">
                                    <a th:href="${'http://msb.item.com/'+product.skuId+'.html'}" >
                                        <img th:src="${product.getSkuImg()}" class="dim">
                                    a>
                                p>
    

    最终的商品详情页的展示效果

    image.png

    二、商品详情数据

    1.响应VO封装

      根据SKUID查询对应的商品详情信息,我们需要把对应的信息封装到对应的VO中,我们需要自己来封装该对象。

    /**
     * 商品详情页的数据对象
     */
    @Data
    public class SpuItemVO {
        // 1.sku的基本信息 pms_sku_info
        SkuInfoEntity info;
        // 2.sku的图片信息pms_sku_images
        List<SkuImagesEntity> images;
        // 3.获取spu中的销售属性的组合
        List<SkuItemSaleAttrVo> saleAttrs;
        // 4.获取SPU的介绍
        SpuInfoDescEntity desc;
    
        // 5.获取SPU的规格参数
        List<SpuItemGroupAttrVo> baseAttrs;
    
    }
    

    销售属性的VO

    @ToString
    @Data
    public class SkuItemSaleAttrVo {
        private Long attrId;
        private String attrName;
        private String attrValue;
    }
    

    属性组相关的VO

    @ToString
    @Data
    public class SpuItemGroupAttrVo {
        private String groupName;
        private List<Attr> baseAttrs;
    }
    

    其中的Attr是之前就创建的VO对象

    2.商品详细的数据查询

    2.1 sku的基本信息

    我们可以直接查询获取

    // 1.sku的基本信息 pms_sku_info
      SkuInfoEntity skuInfoEntity = getById(skuId);
    

    2.2 sku的图片信息

    图片信息也是直接获取

    List<SkuImagesEntity> images = skuImagesService.getImagesBySkuId(skuId);
    

    2.3 销售属性

      销售属性的信息是根据SPU找到所有的SKU下的对应的属性信息,首先写出对应的SQL

    ## 根据SPU编号找到所有的SKU编号 然后进而找到所有的销售属性信息
    SELECT
      # psi.sku_id,
      pssav.attr_id,
      pssav.attr_name,
      GROUP_CONCAT( DISTINCT pssav.attr_value)
    FROM `pms_sku_info` psi
    LEFT JOIN `pms_sku_sale_attr_value` pssav 
    	ON psi.sku_id = pssav.sku_id
    WHERE psi.spu_id = 6
    GROUP BY pssav.attr_id,pssav.attr_name
    

    SQL对应的查询结果

    image.png

    对应的Mapper映射

        <select id="getSkuSaleAttrValueBySpuId" resultType="com.msb.mall.product.vo.SkuItemSaleAttrVo">
            SELECT
                pssav.attr_id attr_id,
                pssav.attr_name attr_name,
                GROUP_CONCAT( DISTINCT pssav.attr_value) attr_value
            FROM `pms_sku_info` psi
                     LEFT JOIN `pms_sku_sale_attr_value` pssav
                               ON psi.sku_id = pssav.sku_id
            WHERE psi.spu_id = #{spuId}
            GROUP BY pssav.attr_id,pssav.attr_name
        select>
    

    然后对应的Dao接口

    @Mapper
    public interface SkuSaleAttrValueDao extends BaseMapper<SkuSaleAttrValueEntity> {
    
        List<SkuItemSaleAttrVo> getSkuSaleAttrValueBySpuId(@Param("spuId") Long spuId);
    }
    

    销售属性中的Service接口及实现

    public interface SkuSaleAttrValueService extends IService<SkuSaleAttrValueEntity> {
    
        PageUtils queryPage(Map<String, Object> params);
    
        List<SkuItemSaleAttrVo> getSkuSaleAttrValueBySpuId(Long spuId);
    }
    
        @Override
        public List<SkuItemSaleAttrVo> getSkuSaleAttrValueBySpuId(Long spuId) {
            List<SkuItemSaleAttrVo>  attrsVo = skuSaleAttrValueDao.getSkuSaleAttrValueBySpuId(spuId);
            return attrsVo;
        }
    

    然后就是对应的SkuService中的串联

            // 3.获取spu中的销售属性的组合
            List<SkuItemSaleAttrVo> saleAttrs = skuSaleAttrValueService.getSkuSaleAttrValueBySpuId(spuId);
    

    2.4 spu的详情

    也是直接获取的

            // 4.获取SPU的介绍
            SpuInfoDescEntity spuInfoDescEntity = spuInfoDescService.getById(spuId);
    

    2.5 Spu的规格参数

      Spu的规格参数,我们需要根据sku对应的商品分类和spu编号来查询,完整的SQL语句

    # `pms_attr_group`
    # 根据 SPU编号和CatalogId类别编号 要查询出所有的属性组及其属性信息
    
    SELECT t1.attr_group_id
    	,t1.attr_group_name
    	,t2.attr_id 
    	,t3.attr_name
    	,t4.attr_value
    FROM `pms_attr_group` t1 
    LEFT JOIN `pms_attr_attrgroup_relation` t2 ON t1.attr_group_id = t2.attr_group_id
    LEFT JOIN `pms_attr` t3 ON t2.attr_id = t3.attr_id
    LEFT JOIN `pms_product_attr_value` t4 ON t4.attr_id = t2.attr_id
    WHERE t1.catelog_id = '225' AND t4.spu_id = 6
    

    然后对应的查询效果

    image.png

    具体的实现,Dao层接口和映射文件

    @Mapper
    public interface AttrGroupDao extends BaseMapper<AttrGroupEntity> {
    
        List<SpuItemGroupAttrVo> getAttrgroupWithSpuId(@Param("spuId") Long spuId, @Param("catalogId") Long catalogId);
    }
    
        <resultMap id="SpuItemGroupAttrVo" type="com.msb.mall.product.vo.SpuItemGroupAttrVo">
            <result column="attr_group_name" property="groupName"/>
            <collection property="baseAttrs" ofType="com.msb.mall.product.vo.Attr">
                <id column="attr_id" property="attrId" />
                <result column="attr_name" property="attrName"/>
                <result column="attr_value" property="attrValue" />
            collection>
        resultMap>
    
        <select id="getAttrgroupWithSpuId" resultMap="SpuItemGroupAttrVo">
            SELECT t1.attr_group_id
                 ,t1.attr_group_name
                 ,t2.attr_id
                 ,t3.attr_name
                 ,t4.attr_value
            FROM `pms_attr_group` t1
                     LEFT JOIN `pms_attr_attrgroup_relation` t2 ON t1.attr_group_id = t2.attr_group_id
                     LEFT JOIN `pms_attr` t3 ON t2.attr_id = t3.attr_id
                     LEFT JOIN `pms_product_attr_value` t4 ON t4.attr_id = t2.attr_id
            WHERE t1.catelog_id = #{catalogId} AND t4.spu_id = #{spuId}
    
        select>
    

    对应的AttrGroupService中的定义和实现

        List<SpuItemGroupAttrVo> getAttrgroupWithSpuId(Long spuId
                , Long catalogId);
    
        /**
         * 跟进SpuId和CatalogId查询出对应的 属性组及其属性信息
         * @param spuId
         * @param catalogId
         * @return
         */
        @Override
        public List<SpuItemGroupAttrVo> getAttrgroupWithSpuId(Long spuId, Long catalogId) {
            //
            List<SpuItemGroupAttrVo> groupAttrVo = attrGroupDao.getAttrgroupWithSpuId(spuId,catalogId);
            return groupAttrVo;
        }
    

    然后就是对应的SkuInfoServiceImpl中的处理

            // 5.获取SPU的规格参数
            List<SpuItemGroupAttrVo> groupAttrVo = attrGroupService.getAttrgroupWithSpuId(spuId,catalogId);
    

    2.6 完成的处理

      在SkuInfoServiceImpl中的完整的处理

        @Override
        public SpuItemVO item(Long skuId) {
            SpuItemVO vo = new SpuItemVO();
            // 1.sku的基本信息 pms_sku_info
            SkuInfoEntity skuInfoEntity = getById(skuId);
            vo.setInfo(skuInfoEntity);
            // 获取对应的SPUID
            Long spuId = skuInfoEntity.getSpuId();
            // 获取对应的CatalogId 类别编号
            Long catalogId = skuInfoEntity.getCatalogId();
            // 2.sku的图片信息pms_sku_images
            List<SkuImagesEntity> images = skuImagesService.getImagesBySkuId(skuId);
            vo.setImages(images);
            // 3.获取spu中的销售属性的组合
            List<SkuItemSaleAttrVo> saleAttrs = skuSaleAttrValueService.getSkuSaleAttrValueBySpuId(spuId);
            vo.setSaleAttrs(saleAttrs);
            // 4.获取SPU的介绍
            SpuInfoDescEntity spuInfoDescEntity = spuInfoDescService.getById(spuId);
            vo.setDesc(spuInfoDescEntity);
    
            // 5.获取SPU的规格参数
            List<SpuItemGroupAttrVo> groupAttrVo = attrGroupService.getAttrgroupWithSpuId(spuId,catalogId);
            vo.setBaseAttrs(groupAttrVo);
            return vo;
        }
    

    然后Controller中完成商品详情的数据查询,绑定数据后调整到商品详情页。之后做页面的渲染操作

        /**
         * 根据前端传递的SkuId我们需要查询出对有的商品信息
         * @param skuId
         * @return
         */
        @GetMapping("/{skuId}.html")
        public String item(@PathVariable Long skuId, Model model){
            SpuItemVO itemVO = skuInfoService.item(skuId);
            model.addAttribute("item",itemVO);
            return "item";
        }
    

    3.商品详情页渲染

    3.1 SKU标题

    image.png

    image.png

    3.2 图片展示

    image.png

    image.png

    3.3 价格和有货

    image.png

    image.png

    image.png

    3.4 销售属性

      销售属性是当前SKU对应的SPU下所有的销售属性的组合。

    image.png

    3.5 SPU详情

    image.png

    3.6 规格参数

    image.png

    image.png

    4.异步处理

      然后我们就可以在商品详细信息查询的位置实现CompletableFuture的异步编排处理。

    image.png

    先定义线程池

    @Configuration
    public class MyThreadPoolConfig {
    
        @Bean
        public ThreadPoolExecutor threadPoolExecutor()
        {
            return new ThreadPoolExecutor(20
                    ,200
                    ,10
                    , TimeUnit.SECONDS
                    ,new LinkedBlockingQueue(10000)
                    , Executors.defaultThreadFactory()
                    ,new ThreadPoolExecutor.AbortPolicy()
            );
        }
    }
    

    具体的编排处理

    
    
  • 相关阅读:
    Redis高可用系列——List类型
    MyBatisPlus 分页查询
    springboot和vue:十、vue2和vue3的差异+组件间的传值
    C#程序采用AOT发布,真的可以避免被反编译?
    Redis--1.CentOS8安装redis服务器
    Sklearn基础教程
    眼底相机系统设计
    学习太极创客 — MQTT 第二章(二)ESP8266 QoS 应用
    MapBox实现要素点击高亮的几种思路(点击颜色变化)
    Mac电脑搭建前端项目环境,并适配老项目
  • 原文地址:https://blog.csdn.net/qq_38526573/article/details/127102513