后端接收
//商品上架
///gulimallproduct/spuinfo/{spuId}/up
@PostMapping(value = "/{spuId}/up")
public R spuUp(@PathVariable("spuId") Long spuId) {
spuInfoService.up(spuId);
return R.ok();
}
up方法
//点击上架,调用这个方法完成上架
//1.查出当前spuId对应的所有sku信息,品牌的名字 去skuservice查询
//2.查出当前sku的所有可以被用来检索的规格属性
//2.1 传入spuid 查询当前spu的产品属性
//2.2 遍历基础属性,查询到所有的属性id,装到list
//2.3 传入id集合,查出所有可以被检索的属性,属性表中有个字段search_type 是0就是不可被检索
//2.4 转换为Set集合 set集合的contains方法比list快
//2.5 遍历属性集合,过滤掉集合id不包含在set集合中的数据,然后将剩下的放到SkuEsModel.Attrs中,然后返回这 个包含合格数据的list集合
//3.发送远程调用,库存系统查询是否有库存
//3.1 查出所有的skuid,一开始查出了所有的sku信息,遍历这个集合拿到id即可
//3.2 据skuid集合查出这些spu是否有库存,返回的类型为R 数据在R.data中 R本身为一个map
//需要远程调用库存服务,将返回的R类型的data字段的数据封装到map,key为skuid,value为是否有库存
//4.封装每条sku数据到SkuEsModel中
//5.调用远程search服务,将数据保存到elasticsearch中
//6.成功后,更新spu的publish_status字段为1,表示上架
public void up(Long spuId) {
//1、查出当前spuId对应的所有sku信息,品牌的名字 去skuservice查询
List<SkuInfoEntity> skuInfoEntities = skuInfoService.getSkusBySpuId(spuId);
//TODO 4、查出当前sku的所有可以被用来检索的规格属性
//传入spuid 查询当前spu的产品属性
List<ProductAttrValueEntity> baseAttrs = productAttrValueService.baseAttrlistforspu(spuId);
//遍历基础属性
List<Long> attrIds = baseAttrs.stream().map(attr -> {
//返回所有的属性id
return attr.getAttrId();
}).collect(Collectors.toList());
//查出所有可以被检索的属性,属性表中有个字段search_type 是0就是不可被检索
List<Long> searchAttrIds = attrService.selectSearchAttrs(attrIds);
//转换为Set集合 set集合的contains方法比list快
Set<Long> idSet = searchAttrIds.stream().collect(Collectors.toSet());
//遍历基础属性
List<SkuEsModel.Attrs> attrsList = baseAttrs.stream().filter(item -> {
//如果可搜索的id集合中包含遍历的条目获取的id值就返回这个条目,也就是这条属性
return idSet.contains(item.getAttrId());
}).map(item -> {
//es专用的实体类
SkuEsModel.Attrs attrs = new SkuEsModel.Attrs();
//将符合要求的可搜索的属性copy到实体类中
BeanUtils.copyProperties(item, attrs);
//将这个属性返回
return attrs;
}).collect(Collectors.toList());
//TODO 1、发送远程调用,库存系统查询是否有库存
//查出所有的skuid
List<Long> skuIdList = skuInfoEntities.stream()
.map(SkuInfoEntity::getSkuId)
.collect(Collectors.toList());
Map<Long, Boolean> stockMap = null;
try {
//根据skuid集合查出这些spu是否有库存,返回的类型为R 数据在data中 R本身为一个map
//try是因为可能查询失败,避免卡在这里
//skuHasStock的“data”属性中 存的是List<SkuHasStockVo> skuHasStockVos
R skuHasStock = wareFeignService.getSkuHasStock(skuIdList);
//将每条sku是否有库存存为一个map,key:skuId value:是否有库存
TypeReference<List<SkuHasStockVo>> typeReference = new TypeReference<List<SkuHasStockVo>>() {};
stockMap = skuHasStock.getData(typeReference).stream()
.collect(Collectors.toMap(SkuHasStockVo::getSkuId, item -> item.getHasStock()));
} catch (Exception e) {
log.error("库存服务查询异常:原因{}",e);
}
//2、封装每个sku的信息
Map<Long, Boolean> finalStockMap = stockMap;
List<SkuEsModel> uoproducts = skuInfoEntities.stream().map(sku -> {
//组装需要的数据
SkuEsModel esModel = new SkuEsModel();
esModel.setSkuPrice(sku.getPrice());
esModel.setSkuImg(sku.getSkuDefaultImg());
//远程调用设置库存信息
//为空说明远程调用有异常,将属性设为true
if (finalStockMap == null) {
esModel.setHasStock(true);
} else {
//远程调用没异常,就正常保存
esModel.setHasStock(finalStockMap.get(sku.getSkuId()));
}
//TODO 2、热度评分。0
esModel.setHotScore(0L);
//TODO 3、查询品牌和分类的名字信息
BrandEntity brandEntity = brandService.getById(sku.getBrandId());
esModel.setBrandName(brandEntity.getName());
esModel.setBrandId(brandEntity.getBrandId());
esModel.setBrandImg(brandEntity.getLogo());
CategoryEntity categoryEntity = categoryService.getById(sku.getCatalogId());
esModel.setCatalogId(categoryEntity.getCatId());
esModel.setCatalogName(categoryEntity.getName());
//设置检索属性
esModel.setAttrs(attrsList);
BeanUtils.copyProperties(sku,esModel);
return esModel;
}).collect(Collectors.toList());
//TODO 5、将数据发给es进行保存:gulimall-search
R r = searchFeignService.productStatusUp(uoproducts);
if (r.getCode() == 0) {
//远程调用成功
//TODO 6、修改当前spu的状态
this.baseMapper.updaSpuStatus(spuId, ProductConstant.ProductStatusEnum.SPU_UP.getCode());
} else {
//远程调用失败
//TODO 7、重复调用?接口幂等性:重试机制
}
}