商品详情

详情数据的实体类

最外层

  1. @Data
  2. public class SkuItemVO {
  3. /**
  4. * 1、sku基本信息【标题、副标题、价格】pms_sku_info
  5. * 2、sku图片信息【每个sku_id对应了多个图片】pms_sku_images
  6. * 3、spu下所有sku销售属性组合【不只是当前sku_id所指定的商品】
  7. * 4、spu商品介绍【】
  8. * 5、spu规格与包装【参数信息】
  9. */
  10. //1、sku基本信息(pms_sku_info)【默认图片、标题、副标题、价格】
  11. private SkuInfoEntity info;
  12. private boolean hasStock = true;// 是否有货
  13. //2、sku图片信息(pms_sku_images)
  14. private List<SkuImagesEntity> images;
  15. //3、当前sku所属spu下的所有销售属性组合(pms_sku_sale_attr_value)
  16. private List<SkuItemSaleAttrVO> saleAttr;
  17. //4、spu商品介绍(pms_spu_info_desc)【描述图片】
  18. private SpuInfoDescEntity desc;
  19. //5、spu规格参数信息(pms_attr)【以组为单位】
  20. private List<SpuItemAttrGroupVO> groupAttrs;
  21. }

销售属性组合

  1. @Data
  2. @ToString
  3. public class SkuItemSaleAttrVO {
  4. /**
  5. * 1.销售属性对应1个attrName
  6. * 2.销售属性对应n个attrValue
  7. * 3.n个sku包含当前销售属性(所以前端根据skuId交集区分销售属性的组合【笛卡尔积】)
  8. */
  9. private Long attrId;
  10. private String attrName;
  11. private List<AttrValueWithSkuIdVO> attrValues;
  12. }
  13. @Data
  14. public class AttrValueWithSkuIdVO {
  15. private String attrValue;
  16. private String skuIds;
  17. }

规格参数

  1. @Data
  2. @ToString
  3. public class SpuItemAttrGroupVO {
  4. private String groupName;
  5. private List<Attr> attrs;
  6. }
  7. @Data
  8. public class Attr {
  9. private Long attrId;
  10. private String attrName;
  11. private String attrValue;
  12. private Integer searchType;
  13. private Integer valueType;
  14. private String icon;
  15. private String valueSelect;
  16. private Integer attrType;
  17. private Long enable;
  18. private Long catelogId;
  19. private Integer showDesc;
  20. }

Controller

  1. @Controller
  2. public class ItemController {
  3. @Autowired
  4. private SkuItemService skuItemService;
  5. @GetMapping("/{skuId}.html")
  6. public String item(@PathVariable("skuId") String skuId, Model model) throws ExecutionException, InterruptedException {
  7. SkuItemVo skuItemVo = skuItemService.item(skuId);
  8. model.addAttribute("item", skuItemVo);
  9. return "item";
  10. }
  11. }

service查询VO返回(异步编排)

注意
此处用到的重要技术就是异步编排的使用,开多个线程来查询不同数据的信息。并在主线程获取其返回结果。

  1. @Service
  2. public class SkuItemServiceImpl implements SkuItemService {
  3. @Autowired
  4. private SkuInfoService skuInfoService;
  5. @Autowired
  6. private SkuImagesService skuImagesService;
  7. @Autowired
  8. private SpuInfoDescService spuInfoDescService;
  9. @Autowired
  10. private AttrGroupService attrGroupService;
  11. @Autowired
  12. private SkuSaleAttrValueService skuSaleAttrValueService;
  13. @Autowired
  14. private ThreadPoolExecutor executor;
  15. @Override
  16. public SkuItemVo item(String skuId) throws ExecutionException, InterruptedException {
  17. SkuItemVo skuItemVo = new SkuItemVo();
  18. CompletableFuture<SkuInfoEntity> skuInfoFuture = CompletableFuture.supplyAsync(() -> {
  19. // 1.获取sku基本信息(pms_sku_info)【默认图片、标题、副标题、价格】
  20. SkuInfoEntity skuInfoEntity = skuInfoService.getById(skuId);
  21. skuItemVo.setInfo(skuInfoEntity);
  22. return skuInfoEntity;
  23. }, executor);
  24. // 2.获取sku图片信息(pms_sku_images)
  25. List<SkuImagesEntity> imagesEntityList = skuImagesService.getImgBySkuId(skuId);
  26. skuItemVo.setImages(imagesEntityList);
  27. CompletableFuture<Void> AttrFuture = skuInfoFuture.thenAcceptAsync(res -> {
  28. // 3.获取当前sku所属spu下的所有销售属性组合(pms_sku_info、pms_sku_sale_attr_value)
  29. List<SkuItemSaleAttrVo> skuItemSaleAttrVoList = skuSaleAttrValueService.getSaleAttrsBySpuId(res.getSpuId());
  30. skuItemVo.setSaleAttr(skuItemSaleAttrVoList);
  31. }, executor);
  32. CompletableFuture<Void> spuDescFuture = skuInfoFuture.thenAcceptAsync(res -> {
  33. // 4.获取spu商品介绍(pms_spu_info_desc)【描述图片】
  34. SpuInfoDescEntity spuInfoDescEntity = spuInfoDescService.getById(res.getSpuId());
  35. skuItemVo.setDesc(spuInfoDescEntity);
  36. }, executor);
  37. CompletableFuture<Void> groupFuture = skuInfoFuture.thenAcceptAsync((res -> {
  38. // 5.获取spu规格参数信息(pms_product_attr_value、pms_attr_attrgroup_relation、pms_attr_group)
  39. List<SpuItemAttrGroupVo> groupAttrList = attrGroupService.getGroupAttrGroupWithAttrsBySpuId(res.getSpuId(), res.getCatalogId());
  40. skuItemVo.setGroupAttrs(groupAttrList);
  41. }), executor);
  42. CompletableFuture.allOf(skuInfoFuture, AttrFuture, spuDescFuture, groupFuture).get(); // 阻塞等待所有执行完成
  43. return skuItemVo;
  44. }
  45. }

获取spu销售属性组合(笛卡尔积)

查询所有属性的skuId交集,组成sku笛卡尔积

GROUP_CONCAT操作是将所有分组的sku_id连接起来,注意去重

商品详情 - 图1

  1. 获取当前sku所属spu下的所有销售属性组合(pms_sku_infopms_sku_sale_attr_value
  2. // 1.通过spuId查询所有sku(pms_sku_info)
  3. // 2.查询sku涉及到的所有销售属性(pms_sku_sale_attr_value)
  4. /**
  5. * 1.销售属性对应1个attrName
  6. * 2.销售属性对应n个attrValue
  7. * 3.n个sku包含当前销售属性(所以前端根据skuId交集区分销售属性的组合【笛卡尔积】)
  8. * sku_ids用,切割成List<String> skuIds
  9. */
  10. <resultMap id="skuItemSaleAttrVo" type="com.atguigu.gulimall.product.vo.SkuItemSaleAttrVo">
  11. <result column="attr_id" property="attrId"></result>
  12. <result column="attr_name" property="attrName"></result>
  13. <collection property="attrValues" ofType="com.atguigu.gulimall.product.vo.AttrValueWithSkuIdVo">
  14. <result column="attr_value" property="attrValue"></result>
  15. <result column="sku_ids" property="skuIds"></result>
  16. </collection>
  17. </resultMap>
  18. <select id="getSaleAttrsBySpuId" resultMap="skuItemSaleAttrVo">
  19. SELECT pss.attr_id, pss.attr_name, pss.attr_value, GROUP_CONCAT(DISTINCT pss.sku_id) sku_ids
  20. FROM pms_sku_info ps
  21. LEFT JOIN pms_sku_sale_attr_value pss ON pss.sku_id = ps.sku_id
  22. WHERE ps.spu_id = #{spuId}
  23. GROUP BY pss.attr_id, pss.attr_name, pss.attr_value;
  24. </select>

获取spu规格参数信息

  1. <resultMap id="spuItemAttrGroupVo" type="com.atguigu.gulimall.product.vo.SpuItemAttrGroupVo">
  2. <result property="groupName" column="attr_group_name"></result>
  3. <collection property="attrs" ofType="com.atguigu.gulimall.product.vo.Attr">
  4. <result property="attrId" column="attr_id"></result>
  5. <result property="attrName" column="attr_name"></result>
  6. <result property="attrValue" column="attr_value"></result>
  7. </collection>
  8. </resultMap>
  9. <!-- 自定义返回结果集 -->
  10. <select id="getGroupAttrGroupWithAttrsBySpuId" resultMap="spuItemAttrGroupVo">
  11. SELECT pav.spu_id, ag.attr_group_name, ag.attr_group_id, pa.attr_id, pa.attr_name, pav.attr_value
  12. FROM pms_attr_group ag
  13. LEFT JOIN pms_attr_attrgroup_relation paa ON paa.attr_group_id = ag.attr_group_id
  14. LEFT JOIN pms_attr pa ON pa.attr_id = paa.attr_id
  15. LEFT JOIN pms_product_attr_value pav ON pav.attr_id = pa.attr_id
  16. WHERE ag.catelog_id = #{catalogId}
  17. AND pav.spu_id = #{spuId};
  18. </select>