前言
本系列博客基于B站谷粒商城,只作为本人学习总结使用。这里我会比较注重业务逻辑的编写和相关配置的流程。有问题可以评论或者联系我互相交流。原视频地址谷粒商城雷丰阳版。本人git仓库地址Draknessssw的谷粒商城
配置
加域名
nginx配置
网关配置
网页的静态资源全部上传到nginx服务器的指定访问目录
业务
Controller
package com.xxxx.gulimall.product.web;
import com.xxxx.gulimall.product.service.SkuInfoService;
import com.xxxx.gulimall.product.vo.SkuItemVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import java.util.concurrent.ExecutionException;
/**
* @author LinLinD
* @Create 2022-07-24-16:55
*/
@Controller
public class ItemController {
@Autowired
private SkuInfoService skuInfoService;
/**
* 展示当前sku的详情
* @param skuId
* @return
*/
@GetMapping("/{skuId}.html")
public String skuItem(@PathVariable("skuId") Long skuId, Model model) throws ExecutionException, InterruptedException {
System.out.println("准备查询" + skuId + "详情");
SkuItemVo vos = skuInfoService.item(skuId);
model.addAttribute("item",vos);
return "item";
}
}
商品详情Vo
package com.xxxx.gulimall.product.vo;
import com.xxxx.gulimall.product.entity.SkuImagesEntity;
import com.xxxx.gulimall.product.entity.SkuInfoEntity;
import com.xxxx.gulimall.product.entity.SpuInfoDescEntity;
import lombok.Data;
import lombok.ToString;
import java.util.List;
@ToString
@Data
public class SkuItemVo {
//1、sku基本信息的获取 pms_sku_info
SkuInfoEntity info;
boolean hasStock = true;
//2、sku的图片信息 pms_sku_images
List<SkuImagesEntity> images;
//3、获取spu的销售属性组合
List<SkuItemSaleAttrVo> saleAttr;
//4、获取spu的介绍
SpuInfoDescEntity desc;
//5、获取spu的规格参数信息
List<SpuItemAttrGroupVo> groupAttrs;
// //6、秒杀商品的优惠信息
// private SeckillSkuVo seckillSkuVo;
}
销售属性Vo
package com.xxxx.gulimall.product.vo;
import lombok.Data;
import lombok.ToString;
import java.util.List;
@Data
@ToString
public class SkuItemSaleAttrVo {
private Long attrId;
private String attrName;
private List<AttrValueWithSkuIdVo> attrValues;
}
销售属性和规格的关联Vo
规格参数Vo
package com.xxxx.gulimall.product.vo;
import lombok.Data;
import lombok.ToString;
import java.util.List;
@Data
@ToString
public class SpuItemAttrGroupVo {
private String groupName;
private List<Attr> attrs;
}
实现类
其中,商品图片信息可以直接获取。而其他的信息需要在获取商品信息以后异步获取。
@Autowired
SpuInfoDescService spuInfoDescService;
@Autowired
private ThreadPoolExecutor executor;
@Autowired
SkuImagesService skuImagesService;
@Autowired
AttrGroupService attrGroupService;
@Autowired
SkuSaleAttrValueService skuSaleAttrValueService;
@Override
public SkuItemVo item(Long skuId) throws ExecutionException, InterruptedException {
SkuItemVo skuItemVo = new SkuItemVo();
CompletableFuture<SkuInfoEntity> infoFuture = CompletableFuture.supplyAsync(() -> {
//1、sku基本信息的获取 pms_sku_info
SkuInfoEntity info = this.getById(skuId);
skuItemVo.setInfo(info);
return info;
}, executor);
CompletableFuture<Void> saleAttrFuture = infoFuture.thenAcceptAsync((res) -> {
//3、获取spu的销售属性组合
List<SkuItemSaleAttrVo> saleAttrVos = skuSaleAttrValueService.getSaleAttrBySpuId(res.getSpuId());
skuItemVo.setSaleAttr(saleAttrVos);
}, executor);
CompletableFuture<Void> descFuture = infoFuture.thenAcceptAsync((res) -> {
//4、获取spu的介绍 pms_spu_info_desc
SpuInfoDescEntity spuInfoDescEntity = spuInfoDescService.getById(res.getSpuId());
skuItemVo.setDesc(spuInfoDescEntity);
}, executor);
CompletableFuture<Void> baseAttrFuture = infoFuture.thenAcceptAsync((res) -> {
//5、获取spu的规格参数信息
List<SpuItemAttrGroupVo> attrGroupVos = attrGroupService.getAttrGroupWithAttrsBySpuId(res.getSpuId(), res.getCatalogId());
skuItemVo.setGroupAttrs(attrGroupVos);
}, executor);
// Long spuId = info.getSpuId();
// Long catalogId = info.getCatalogId();
//2、sku的图片信息 pms_sku_images
CompletableFuture<Void> imageFuture = CompletableFuture.runAsync(() -> {
List<SkuImagesEntity> imagesEntities = skuImagesService.getImagesBySkuId(skuId);
skuItemVo.setImages(imagesEntities);
}, executor);
//等到所有任务都完成
CompletableFuture.allOf(saleAttrFuture,descFuture,baseAttrFuture,imageFuture).get();
return skuItemVo;
}
获取销售属性的实现类
@Override
public List<SkuItemSaleAttrVo> getSaleAttrBySpuId(Long spuId) {
SkuSaleAttrValueDao baseMapper = this.getBaseMapper();
List<SkuItemSaleAttrVo> saleAttrVos = baseMapper.getSaleAttrBySpuId(spuId);
return saleAttrVos;
}
sql
<select id="getSaleAttrBySpuId" resultMap="skuItemSaleAttrVo">
SELECT
ssav.attr_id attr_id,
ssav.attr_name 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>
<resultMap id="skuItemSaleAttrVo" type="com.xxxx.gulimall.product.vo.SkuItemSaleAttrVo">
<result column="attr_id" property="attrId"></result>
<result column="attr_name" property="attrName"></result>
<collection property="attrValues" ofType="com.xxxx.gulimall.product.vo.AttrValueWithSkuIdVo">
<result column="attr_value" property="attrValue"></result>
<result column="sku_ids" property="skuIds"></result>
</collection>
</resultMap>
获取规格参数实现类
@Override
public List<SpuItemAttrGroupVo> getAttrGroupWithAttrsBySpuId(Long catalogId, Long spuId) {
//1、查出当前spu对应的所有属性的分组信息以及当前分组下的所有属性对应的值
AttrGroupDao baseMapper = this.getBaseMapper();
List<SpuItemAttrGroupVo> vos = baseMapper.getAttrGroupWithAttrsBySpuId(spuId,catalogId);
return vos;
}
sql
<select id="getAttrGroupWithAttrsBySpuId" resultMap="spuAttrGroup">
SELECT
product.spu_id,
pag.attr_group_id,
pag.attr_group_name,
product.attr_id,
product.attr_name,
product.attr_value
FROM
pms_product_attr_value product
LEFT JOIN pms_attr_attrgroup_relation paar ON product.attr_id = paar.attr_id
LEFT JOIN pms_attr_group pag ON paar.attr_group_id = pag.attr_group_id
WHERE
product.spu_id = #{spuId}
AND pag.catelog_id = #{catalogId}
</select>
<resultMap id="spuAttrGroup" type="com.xxxx.gulimall.product.vo.SpuItemAttrGroupVo">
<result property="groupName" column="attr_group_name"/>
<collection property="attrs" ofType="com.xxxx.gulimall.product.vo.Attr">
<result property="attrId" column="attr_id"></result>
<result property="attrName" column="attr_name"></result>
<result property="attrValue" column="attr_value"></result>
</collection>
</resultMap>
获取商品图片的实现类
@Override
public List<SkuImagesEntity> getImagesBySkuId(Long skuId) {
List<SkuImagesEntity> imagesEntities = this.baseMapper.selectList(new QueryWrapper<SkuImagesEntity>().eq("sku_id", skuId));
return imagesEntities;
}