1.环境搭建
-
上传html页面
-
修改网关yml 添加host为item的域名
-
修改host文件,通过nginx监听item.dreammall.com域名来转发到gateway网关,再由网关转到product微服务
-
上传静态资源到nginx
-
修改html页面文件资源的路径
-
修改index.html查询商品详情的请求地址
-
编写controller层
-
点击商品详情跳转到详情页面
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无法识别内部类怎么办?
- 将.改成$即可
-
业务流程
// 获取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>
-
页面效果
-
页面流程步骤太复杂?尝试用异步编程
-
自定义线程池
@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; }
-