商城业务:商品详情

该文章展示了在SpringBoot应用中如何使用CompletableFuture进行异步处理,以提高商品详情页面加载效率。通过SkuInfoService的商品详情接口,分别获取sku的基本信息、图片、销售属性、介绍和规格参数,并利用数据库查询获取spu的相关数据。
摘要由CSDN通过智能技术生成

商品详情SkuItemVo 

@Data
public class SkuItemVo {

    /*** 1 sku基本信息的获取:如标题*/
    SkuInfoEntity info;

    boolean hasStock = true;

    /*** 2 sku的图片信息*/
    List<SkuImagesEntity> images;

    /*** 3 获取spu的销售属性组合。每个attrName对应一个value-list*/
    List<SkuItemSaleAttrVo> saleAttr;

    /*** 4 获取spu的介绍*/
    SpuInfoDescEntity desc;

    /*** 5 获取spu的规格参数信息,每个分组的包含list*/
    List<SpuItemAttrGroupVo> groupAttrs;
    

}

SkuItemSaleAttrVo

@Data
public    class  SkuItemSaleAttrVo{
    private  Long attrId;
    private  String attrName;
    private List<AttrValueWithSkuIdVo> attrValues;
}

SpuItemAttrGroupVo

@Data
public  class  SpuItemAttrGroupVo{
    private  String groupName;
    private List<SpuBaseAttrVo> attrs;
}

SpuBaseAttrVo

@Data
public   class  SpuBaseAttrVo{
    private  String attrName;
    private  String attrValue;
}

 控制层Controller

@Controller
public class itemController {


    @Autowired
    SkuInfoService skuInfoService;

    /**
     * 展示当前sku的详情
     * @param skuId
     * @return
     */
    @GetMapping("/{skuId}.html")
    public String skuItem(@PathVariable("skuId") Long skuId, Model model){

        System.out.println("准备查询"+skuId+"详情");
         SkuItemVo vo= skuInfoService.item(skuId);
         model.addAttribute("item",vo);
        return "item";
    }
}

配置类 

ThreadPoolConfigProperties

@ConfigurationProperties(prefix = "gulimall.thread")
@Component
@Data
public class ThreadPoolConfigProperties {
    private  Integer coreSize;
    private Integer maxSize;
    private  Integer keepAliveTime;
}

MyThreadConfig

@Configuration
public class MyThreadConfig {

    @Bean
    public ThreadPoolExecutor threadPoolExecutor(ThreadPoolConfigProperties pool){
      return    new ThreadPoolExecutor(pool.getCoreSize(),pool.getMaxSize(),pool.getKeepAliveTime(),
                TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(1000),
                Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());
    }
}

 

 skuInfoService.item实现

    @Override
    public SkuItemVo item(Long skuId) {
        SkuItemVo skuItemVo = new SkuItemVo();
        //1.sku基本属性的获取 pms_sku_info
        CompletableFuture<SkuInfoEntity> infoFuture = CompletableFuture.supplyAsync(() -> {
            SkuInfoEntity info = getById(skuId);
            skuItemVo.setInfo(info);
            return info;
        }, executor);
        //2.sku的图片信息 pms_sku_images

        CompletableFuture<Void> imgeFuture = CompletableFuture.runAsync(() -> {
            List<SkuImagesEntity> images = imagesService.getImagesBySKuId(skuId);
            skuItemVo.setImages(images);
        }, executor);

        //3.获取spu的销售属性组合
        CompletableFuture<Void> attrFuture = infoFuture.thenAcceptAsync((res) -> {
            List<SkuItemSaleAttrVo> saleAttrVos = skuSaleAttrValueService.getSaleAttrsBySpuId(res.getSpuId());
            skuItemVo.setSaleAttr(saleAttrVos);
        }, executor);

        //4.获取spu的介绍 pms_spu_info_desc
        CompletableFuture<Void> descFuture = infoFuture.thenAcceptAsync((res) -> {
            SpuInfoDescEntity spuInfo = spuInfoDescService.getById(res.getSpuId());
            skuItemVo.setDesc(spuInfo);
        }, executor);


        //5.获取spu的规格参数信息
        CompletableFuture<Void> spuFuture = infoFuture.thenAcceptAsync((res) -> {
            List<SpuItemAttrGroupVo> attrGroupVos = attrGroupService.getAttrGroupWithAttrsBySpuId(res.getSpuId(), res.getCatalogId());
            skuItemVo.setGroupAttrs(attrGroupVos);
        }, executor);

        try {
            CompletableFuture.allOf(infoFuture,imgeFuture,descFuture,spuFuture,attrFuture).get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        return  skuItemVo;
    }

imagesService.getImagesBySKuId

    @Override
    public List<SkuImagesEntity> getImagesBySKuId(Long skuId) {
        SkuImagesDao imagesDao = this.baseMapper;
        List<SkuImagesEntity> imagesEntities = imagesDao.selectList(new QueryWrapper<SkuImagesEntity>().eq("sku_id", skuId));

        return imagesEntities;
    }

skuSaleAttrValueService.getSaleAttrsBySpuId

    @Override
    public List<SkuItemSaleAttrVo> getSaleAttrsBySpuId(Long spuId) {
        SkuSaleAttrValueDao dao = this.baseMapper;
        List<SkuItemSaleAttrVo> saleAttrVos= dao.getSaleAttrsBySpuId(spuId);
        return saleAttrVos;
    }

dao.getSaleAttrsBySpuId

 

<resultMap id="SkuItemSaleAttrVo" type="com.atguigu.gulimall.product.vo.SkuItemSaleAttrVo">
    <result column="attr_id" property="attrId"></result>
    <result column="attr_name" property="attrName"></result>
    <collection property="attrValues" ofType="com.atguigu.gulimall.product.vo.AttrValueWithSkuIdVo">
        <result column="attr_value" property="attrValue"></result>
        <result column="sku_ids" property="skuIds"></result>
    </collection>
</resultMap>
<select id="getSaleAttrsBySpuId" resultMap="SkuItemSaleAttrVo">
    SELECT ssav.`attr_id`,ssav.`attr_name`,ssav.`attr_value`,
           GROUP_CONCAT(DISTINCT info.`sku_id`) sku_ids
    FROM `pms_sku_info` info LEFT JOIN `pms_sku_sale_attr_value` ssav
                                       ON ssav.`sku_id` = info.`sku_id`
    WHERE info.`spu_id` = #{spuId}
    GROUP BY ssav.`attr_id`,ssav.`attr_name`,ssav.`attr_value`
</select>

 

attrGroupService.getAttrGroupWithAttrsBySpuId

 

    @Override
    public List<SpuItemAttrGroupVo> getAttrGroupWithAttrsBySpuId(Long spuId, Long catalogId) {
        //1.查出当前spu对应的所有属性的分组信息以及当前分组下所有属性对应的值
      
        AttrGroupDao baseMapper = this.getBaseMapper();
        List<SpuItemAttrGroupVo> vos =   baseMapper.getAttrGroupWithAttrsBySpuId(spuId,catalogId);
        return  vos;
    }

baseMapper.getAttrGroupWithAttrsBySpuId(spuId,catalogId)

  • pms_product_attr_value 根据spu_id获得spu相关属性
  • pms_attr_attrgroup_relation根据catelog_id获得属性的分组

 

<resultMap id="SpuItemAttrGroupVo" type="com.atguigu.gulimall.product.vo.SpuItemAttrGroupVo">
    <result column="attr_group_name" property="groupName" javaType="string"></result>
    <collection property="attrs" ofType="com.atguigu.gulimall.product.vo.SpuBaseAttrVo">
        <result column="attr_name" property="attrName" javaType="string"></result>
        <result column="attr_value" property="attrValue" javaType="string"></result>
    </collection>
</resultMap>

 

<select id="getAttrGroupWithAttrsBySpuId"
        resultMap="SpuItemAttrGroupVo">
    SELECT pav.`spu_id`, ag.`attr_group_name`, ag.`attr_group_id`, 
           aar.`attr_id`, attr.`attr_name`,pav.`attr_value`
    FROM `pms_attr_group` ag
             LEFT JOIN `pms_attr_attrgroup_relation` aar 
                 ON aar.`attr_group_id` = ag.`attr_group_id`
             LEFT JOIN `pms_attr` attr 
                 ON attr.`attr_id` = aar.`attr_id`
             LEFT JOIN `pms_product_attr_value` pav 
                 ON pav.`attr_id` = attr.`attr_id`
    WHERE ag.catelog_id = #{catalogId} AND pav.`spu_id` = #{spuId}
</select>

 

前端js代码 

        $(".sku_attr_value").click(function () {
            // 1、点击的元素添加上自定义的属性
            let skus = new Array();
            let curr = $(this).attr("skus").split(",");
             //去掉同一行的所有的check标签
            $(this).parent().parent().find(".sku_attr_value").removeClass("checked");
            $(this).addClass("checked");
            changeCheckedStyle();

            $("a[class='sku_attr_value checked']").each(function () {
                skus.push($(this).attr("skus").split(","));
            });
            //取出交集得到skuId
            let filterEle = skus[0];
            for (let i = 1; i < skus.length; i++) {
                filterEle = $(filterEle).filter(skus[i])[0];
            }

            location.href = "http://item.gulimall.com/" + filterEle + ".html";

            return false;
        });
        $(function () {
            changeCheckedStyle();
        });

        function changeCheckedStyle() {
            $(".sku_attr_value").parent().css({"border": "solid 1px #ccc"});
            $("a[class='sku_attr_value checked']").parent().css({"border": "solid 1px red"});
        };

 

 

 

 

 

 

 

 

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一个风轻云淡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值