3.定时同步可补商品
(1)时序图
(2)流程图
一.分⻚查询卖家组信息。每次处理完⼀批数据后,剩余数据会继续通过下⼀⻚来查询获取。
二.根据卖家组和商品的关系表查询出卖家组所⽀持的商品。查询商品与卖家组关系表 sku_seller_relation,过滤掉⾮⾃营的商品。
三.根据查询返回的 item 列表批量查询得到商品的 item 信息。查询过程需要商品表 item_info 关联查询商品扩展属性表 attribute_extend,然后填充屏蔽微仓的扩展 JSON 信息,并对该屏蔽的卖家 ID 进⾏过滤商品。
四.遍历商品检查商品状态是否为试销。商品状态:1 准备上架、2 试销上架、3 上架、4 预下架、5 下架、6 停售。如果是试销商品,则查询当前商品归属的仓是否有试销标识。如果不是试销商品或试销商品所属的仓没有试销标识,则进⾏过滤。
五.根据商品的存储条件对归属仓的存储条件进⾏匹配。只有商品的存储条件和归属仓的存储条件匹配了才允许补货,存储条件即 sellerLableList 卖家标签:1 常温、2 冷藏、3 冷冻、4⽔产。
六.进⾏组套商品验证。先通过 sku 批量查询组套商品与 SKU 关系表 stack_sku_relation,获取到每个 sku 下的原料以及普通商品信息,然后对每个商品进⾏试销判断以及存储条件处理,两者都满⾜才允许补货。
七.对已存在的缓存数据和当前这次同步处理后的数据进⾏差集 diff 处理。发⽣变化的数据才需要刷⼊缓存,比如新增的或者⽆效的数据。
八.构建缓存模型,对可补的商品信息进⾏缓存。key 为'前缀标识+卖家 ID',value 为'可补的 sku 列表'。
(3)代码实现
@Component
public class CompensationJobHandler {
@DubboReference(version = "1.0.0")
private CompensationApi compensationApi;
@XxlJob("syncCompensationProduct")
public void syncCompensationProduct(CompensationRequest request) {
XxlJobHelper.log("sync available product job starting...");
JsonResult result = compensationApi.syncCompensationProduct(request);
XxlJobHelper.log("sync available product job end, result:{}", result);
}
}
@DubboService(version = "1.0.0", interfaceClass = CompensationApi.class, retries = 0)
public class CompensationApiImpl implements CompensationApi {
@Resource
private CompensationService compensationService;
//同步可补商品
@Override
public JsonResult syncCompensationProduct(CompensationRequest request) {
try {
return compensationService.syncCompensationProduct(request);
} catch (ProductBizException e) {
log.error("biz error: ", e);
return JsonResult.buildError(e.getErrorCode(), e.getErrorMsg());
} catch (Exception e) {
log.error("system error: ", e);
return JsonResult.buildError(e.getMessage());
}
}
}
@Service
public class CompensationServiceImpl implements CompensationService {
...
//同步可补的数据入缓存
@Override
public JsonResult syncCompensationProduct(CompensationRequest request) {
//分页查询商品信息,处理商品可补的数据
Integer pageNo = 1;
List<SellerGroupResponse> sellerGroupResponses = querySellerGroupList(pageNo, request.getSellerGroupType());
while (!CollectionUtils.isEmpty(sellerGroupResponses)) {
//1.过滤卖家组的非有效状态信息数据
List<SellerGroupResponse> sellerGroupResponseList = sellerGroupFilter(sellerGroupResponses);
//2.根据卖家组获取卖家支持的可售商品列表
List<SkuSellerRelationDO> sellerRelationDOList = queryAvailableProduct(sellerGroupResponseList);
//3.查询商品信息,并过滤非自营的商品,填充关于商品的扩展信息
List<ProductDetailDO> productDetailDOList = queryProductDetailList(sellerRelationDOList);
//4.解析屏蔽微仓的扩展json,对屏蔽的卖家ID进行过滤,并将详情的商品sku信息绑定到卖家上
List<ProductSellerRelationBO> sellerFilterList = sellerFilter(productDetailDOList, sellerRelationDOList, sellerGroupResponses);
//5.普通商品过滤(试销品过滤,存储条件过滤)
List<ProductSellerRelationBO> itemFilterList = itemFilter(sellerFilterList);
//6.组套商品过滤(试销品过滤,存储条件过滤)
List<ProductSellerRelationBO> suitFilterList = suitFilter(itemFilterList);
//7.读取历史的缓存信息,对已经存在的缓存进行diff处理,处理新增或者修改的数据更新缓存
diffRecoverableCache(suitFilterList, sellerGroupResponses);
pageNo++;
sellerGroupResponses = querySellerGroupList(pageNo, request.getSellerGroupType());
}
return JsonResult.buildSuccess();
}
...
}
复制代码
4.定时同步可售商品
(1)时序图
(2)流程图
一.分页查询卖家组信息,调⽤查询卖家组信息接⼝,返回卖家组信息列表。
二.对返回的卖家组列表进行过滤,过滤无效状态的卖家组。
三.根据卖家组列表获取⽀撑这些卖家组所⽀持售卖的商品,通过商品与卖家组关系表 sku_seller_relation 查询出卖家组⽀持售卖的商品。查询时匹配字段 relation_type 关系类型,只获取可售商品。relation_type 关系类型有:1 可售、2 屏蔽。
四.根据商品卖家库存关系表查询得到卖家组⽀持售卖的库存充⾜的商品。商品卖家库存关系表是 sku_stock_seller_relation,查询时匹配库存数量 stock_num > 0,且 seller_type 卖家类型是⾃营的商品。seller_type 卖家类型有:1⾃营、2POP。
五.通过商品与卖家组关系表和商品卖家库存关系表构建卖家可售商品信息。商品与卖家组关系表是 sku_seller_relation,商品卖家库存关系表是 sku_stock_seller_relation。
六.根据商品属性扩展表查询到商品的属性内容进行过滤,也就是对商品中屏蔽卖家的扩展信息进⾏筛选。商品属性扩展表是 attribute_extend,商品的属性内容表是 attribute_content。
七.读取历史的缓存信息,对已经存在的缓存进⾏diff 处理,需要处理新增或者修改的数据更新缓存。
八.构建缓存模型,对可售的商品数据进⾏缓存。卖家的缓存的模型对象为:key 为'前缀标识+卖家 ID',value 为'可售 skuId'。卖家类型的缓存模型对象为:key 为'前缀标识+卖家类型',value 为'可售 skuId'。
(3)代码实现
@Component
public class AvailableJobHandler {
@DubboReference(version = "1.0.0")
private AvailableApi availableApi;
@XxlJob("syncAvailableProduct")
public void syncAvailableProduct() {
XxlJobHelper.log("sync available product job starting...");
JsonResult result = availableApi.syncAvailableProduct(null);
XxlJobHelper.log("sync available product job end, result:{}", result);
}
}
@DubboService(version = "1.0.0", interfaceClass = AvailableApi.class, retries = 0)
public class AvailableApiImpl implements AvailableApi {
@Resource
private AvailableService availableService;
//同步可售商品
@Override
public JsonResult syncAvailableProduct(AvailableRequest request) {
try {
Boolean success = availableService.syncAvailableProduct(request);
return JsonResult.buildSuccess(success);
} catch (ProductBizException e) {
log.error("biz error: request={}", JSON.toJSONString(request), e);
return JsonResult.buildError(e.getErrorCode(), e.getErrorMsg());
} catch (Exception e) {
log.error("system error: request={}", JSON.toJSONString(request), e);
return JsonResult.buildError(e.getMessage());
}
}
}
@Service
public class AvailableServiceImpl implements AvailableService {
...
//同步可售商品
@Override
public Boolean syncAvailableProduct(AvailableRequest request) {
//分页查询商品信息,处理商品可售的数据
Integer pageNo = 1;
//1.获取卖家组信息列表
List<SellerGroupResponse> sellerGroupList = querySellerGroupList(pageNo, request.getSellerGroupType());
//自营还是POP可售的skuId集合
Map<Integer, List<String>> sellerTypeSkuIdMap = new HashMap<>(2);
while (!CollectionUtils.isEmpty(sellerGroupList)) {
//2.对卖家组状态非有效的进行过滤
List<SellerGroupResponse> effectiveSellerGroupList = sellerGroupFilter(sellerGroupList);
//3.根据卖家组列表获取卖家组所支持售卖的商品
List<SkuSellerRelationDTO> saleProductList = querySaleProductList(effectiveSellerGroupList);
//4.获取自营可售商品的且库存充足的信息
Map<Long, String> sellerInStockMap = querySellerInStockProductMap(saleProductList);
//5.构建卖家可售商品信息
Map<Long, List<String>> sellerSaleProductMap = buildSellerAvailableProduct(sellerInStockMap, effectiveSellerGroupList, saleProductList);
//6.对商品中屏蔽卖家的扩展信息进行筛选
sellerSaleProductMap = sellerFilter(sellerSaleProductMap, saleProductList);
//7.合并卖家类型的可售商品
mergeSellerTypeSkuIdMap(sellerTypeSkuIdMap, saleProductList, sellerSaleProductMap);
//8.读取历史的缓存信息,对已经存在的缓存进行diff处理,需要处理新增或者修改的数据更新缓存
//构建数据模型,将卖家可售商品缓存起来 缓存结构 key:"前缀标识+卖家id",value:"可售商品"
Map<String, RedisSortedSetCache> sortedSetSourceMap = diffAvailableCache(sellerSaleProductMap, sellerGroupList);
//9.刷新缓存信息
redisReadWriteManager.flushIncrSortedSetMap(sortedSetSourceMap);
pageNo++;
sellerGroupList = querySellerGroupList(pageNo, request.getSellerGroupType());
}
//10.将卖家类型可售商品缓存起来 缓存结构 key:"前缀标识+卖家类型",value:"可售商品",逻辑与卖家可售商品缓存一致
//这里需要将分页查询的卖家组的可售商品合并起来,最后做已经存在的缓存diff处理
Map<String, RedisSortedSetCache> sortedSetSourceMap = diffSellerTypeAvailableCache(sellerTypeSkuIdMap);
//11.刷新缓存信息
redisReadWriteManager.flushIncrSortedSetMap(sortedSetSourceMap);
return Boolean.TRUE;
}
...
}
复制代码
5.商品中心架构梳理
商品M端系统:eshop-construction-service
商品C端系统:eshop-diplomacy-service
商品生命周期系统:eshop-lifecycle-service
商品调度系统:eshop-scheduling-service(定时调度可采可补可售任务)
商品补货系统:eshop-replenished-service(处理商品可采可补可售)
商品卖家系统:eshop-seller-service
复制代码
文章转载自:东阳马生架构
原文链接:https://www.cnblogs.com/mjunz/p/18924638
体验地址:http://www.jnpfsoft.com/?from=001YH
评论