当前位置: 首页 > news >正文

商品中心—3.商品可采可补可售的技术文档上

大纲

1.可采可补可售业务的数据库建模设计

2.定时同步可采商品

3.定时同步可补商品

4.定时同步可售商品

5.商品中心架构梳理

1.可采可补可售业务的数据库建模设计

(1)可采可补可售

(2)可采业务表

(3)可补业务表

(4)可售业务表

(5)基础配置表

(1)可采可补可售

可售:配置了卖家组(售卖区)的商品,在该卖家组下的区域是可售状态
可补:可售商品,微仓是否可补,指⼤仓向微仓补货
可采:可售商品,⼤仓是否可采,指⼤仓采购

(2)可采业务表

一.商品与卖家组关系表

二.组套商品与SKU关系表

三.商品ITEM表

四.商品SKU表

五.商品⽆需采购配置表

一.商品与卖家组关系表

CREATE TABLE `sku_seller_relation` (`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主健',`item_id` varchar(40) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT 'itemId',`sku_id` varchar(40) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT 'skuId',`seller_group_id` varchar(50) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '卖家组ID',`seller_type` int(10) DEFAULT '0' COMMENT '卖家类型(1-⾃营,2-POP)',`relation_type` tinyint(3) DEFAULT '0' COMMENT '关系类型(1-可售,2-屏蔽)',`del_flag` tinyint(1) DEFAULT '1' COMMENT '删除标记(1-有效,0-删除)',`create_user` int(10) DEFAULT '0' COMMENT '创建⼈',`create_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',`update_user` int(10) DEFAULT '0' COMMENT '更新⼈',`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='商品与卖家组关系表';

二.组套商品与SKU关系表

CREATE TABLE `stack_sku_relation` (`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',`sku_id` varchar(40) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '售卖sku(组套商品)',`stack_sku_id` varchar(40) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '普通商品skuId或原料商品skuId',`stack_num` int(10) NOT NULL DEFAULT '0' COMMENT '数量',`channel` tinyint(3) NOT NULL DEFAULT '0' COMMENT '渠道(1-每日⽣鲜、2-美团、3-饿了么、4-淘鲜达、5-招商银⾏)',`seller_type` int(10) NOT NULL DEFAULT '0' COMMENT '卖家类型(1-⾃营,2-POP)',`features` varchar(500) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '扩展字段',`version_id` int(10) NOT NULL DEFAULT '0' COMMENT '版本号',`del_flag` tinyint(1) NOT NULL DEFAULT '0' COMMENT '删除标记(1-有效,0-删除)',`create_user` int(10) NOT NULL DEFAULT '0' COMMENT '创建⼈',`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',`update_user` int(10) NOT NULL DEFAULT '0' COMMENT '更新⼈',`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更改时间',PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='组套商品与SKU关系表';

三.商品ITEM表

CREATE TABLE `item_info` (`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',`item_id` varchar(40) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '商品ID',`item_name` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '商品名称',`recommend` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '推荐语',`item_type` int(10) NOT NULL DEFAULT '0' COMMENT '商品类型',`channel` tinyint(3) NOT NULL DEFAULT '0' COMMENT '渠道(1-每日⽣鲜、2-美团、3-饿了么、4-淘鲜达、5-招商银⾏)',`seller_type` int(10) NOT NULL DEFAULT '0' COMMENT '卖家类型(1-⾃营,2-POP)',`producing_area_id` int(10) NOT NULL DEFAULT '0' COMMENT '产地ID',`item_status` int(10) NOT NULL DEFAULT '0' COMMENT '商品状态',`brand_id` int(10) NOT NULL DEFAULT '0' COMMENT '品牌ID',`shelf_life` int(10) NOT NULL DEFAULT '0' COMMENT '保质期(⼩时)',`store_condition_type` int(10) NOT NULL DEFAULT '0' COMMENT '存储条件',`category_id` int(10) NOT NULL DEFAULT '0' COMMENT '末级品类ID',`first_category_id` int(10) NOT NULL DEFAULT '0' COMMENT '⼀级品类ID',`second_category_id` int(10) NOT NULL DEFAULT '0' COMMENT '⼆级品类ID',`third_category_id` int(10) NOT NULL DEFAULT '0' COMMENT '三级品类ID',`item_specs_value` varchar(2048) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '规格值([{"颜⾊":"⾦⾊", "内存":"128g"},{"颜⾊":"银⾊", "内存":"256g"}])',`features` varchar(500) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '扩展字段',`version_id` int(10) NOT NULL DEFAULT '0' COMMENT '版本号',`del_flag` tinyint(1) NOT NULL DEFAULT '0' COMMENT '删除标记(1-有效,0-删除)',`create_user` int(10) NOT NULL DEFAULT '0' COMMENT '创建⼈',`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',`update_user` int(10) NOT NULL DEFAULT '0' COMMENT '更新⼈',`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',PRIMARY KEY (`id`) 
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8 COMMENT='商品ITEM表';

四.商品SKU表

CREATE TABLE `sku_info` (`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',`sku_id` varchar(40) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT 'skuId',`item_id` varchar(40) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT 'itemId',`sku_name` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT 'sku名称',`sku_type` int(10) NOT NULL DEFAULT '0' COMMENT 'sku类型(与item保持⼀致)',`base_price` int(10) NOT NULL DEFAULT '0' COMMENT '商城价格(单位:分)',`vip_price` int(10) NOT NULL DEFAULT '0' COMMENT '会员价格(单位:分)',`sku_grade` int(10) NOT NULL DEFAULT '0' COMMENT '商品分级(ABC标签,运营归类处理)',`channel` tinyint(3) NOT NULL DEFAULT '0' COMMENT '渠道(1-每日⽣鲜、2-美团、3-饿了么、4-淘鲜达、5-招商银⾏)',`seller_type` int(10) NOT NULL DEFAULT '0' COMMENT '卖家类型(1-⾃营,2-POP)',`sku_specs_value` varchar(2048) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '规格值({"颜⾊":"⾦⾊", "内存":"128g"})',`features` varchar(500) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '扩展字段',`version_id` int(10) NOT NULL DEFAULT '0' COMMENT '版本号',`del_flag` tinyint(1) NOT NULL DEFAULT '0' COMMENT '删除标记(1-有效,0-删除)',`create_user` int(10) NOT NULL DEFAULT '0' COMMENT '创建⼈',`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',`update_user` int(10) NOT NULL DEFAULT '0' COMMENT '更新⼈',`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更改时间',PRIMARY KEY (`id`) 
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8 COMMENT='商品SKU表';

五.商品⽆需采购配置表

CREATE TABLE `item_procurement_config` (`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',`category_id` int(10) NOT NULL DEFAULT '0' COMMENT '品类ID',`procurement_type` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否需要采购(1-需要,0-⽆需)',`version_id` int(10) NOT NULL DEFAULT '0' COMMENT '版本号',`del_flag` tinyint(1) NOT NULL DEFAULT '0' COMMENT '删除标记(1-有效,0-删除)',`create_user` int(10) NOT NULL DEFAULT '0' COMMENT '创建⼈',`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',`update_user` int(10) NOT NULL DEFAULT '0' COMMENT '更新⼈',`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更改时间',PRIMARY KEY (`id`) 
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8 COMMENT='商品⽆需采购配置表';

(3)可补业务表

一.商品ITEM表

二.组套商品与SKU关系表

三.商品与卖家组关系表

四.商品属性扩展表

一.商品ITEM表

CREATE TABLE `item_info` (`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',`item_id` varchar(40) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '商品ID',`item_name` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '商品名称',`recommend` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '推荐语',`item_type` int(10) NOT NULL DEFAULT '0' COMMENT '商品类型',`channel` tinyint(3) NOT NULL DEFAULT '0' COMMENT '渠道(1-每日⽣鲜、2-美团、3-饿了么、4-淘鲜达、5-招商银⾏)',`seller_type` int(10) NOT NULL DEFAULT '0' COMMENT '卖家类型(1-⾃营,2-POP)',`producing_area_id` int(10) NOT NULL DEFAULT '0' COMMENT '产地ID',`item_status` int(10) NOT NULL DEFAULT '0' COMMENT '商品状态',`brand_id` int(10) NOT NULL DEFAULT '0' COMMENT '品牌ID',`shelf_life` int(10) NOT NULL DEFAULT '0' COMMENT '保质期(⼩时)',`store_condition_type` int(10) NOT NULL DEFAULT '0' COMMENT '存储条件',`category_id` int(10) NOT NULL DEFAULT '0' COMMENT '末级品类ID',`first_category_id` int(10) NOT NULL DEFAULT '0' COMMENT '⼀级品类ID',`second_category_id` int(10) NOT NULL DEFAULT '0' COMMENT '⼆级品类ID',`third_category_id` int(10) NOT NULL DEFAULT '0' COMMENT '三级品类ID',`item_specs_value` varchar(2048) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '规格值([{"颜⾊":"⾦⾊", "内存":"128g"},{"颜⾊":"银⾊", "内存":"256g"}])',`features` varchar(500) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '扩展字段',`version_id` int(10) NOT NULL DEFAULT '0' COMMENT '版本号',`del_flag` tinyint(1) NOT NULL DEFAULT '0' COMMENT '删除标记(1-有效,0-删除)',`create_user` int(10) NOT NULL DEFAULT '0' COMMENT '创建⼈',`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',`update_user` int(10) NOT NULL DEFAULT '0' COMMENT '更新⼈',`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8 COMMENT='商品ITEM表';

二.组套商品与SKU关系表

CREATE TABLE `stack_sku_relation` (`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',`sku_id` varchar(40) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '售卖sku(组套商品)',`stack_sku_id` varchar(40) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '普通商品skuId或原料商品skuId',`stack_num` int(10) NOT NULL DEFAULT '0' COMMENT '数量',`channel` tinyint(3) NOT NULL DEFAULT '0' COMMENT '渠道(1-每日⽣鲜、2-美团、3-饿了么、4-淘鲜达、5-招商银⾏)',`seller_type` int(10) NOT NULL DEFAULT '0' COMMENT '卖家类型(1-⾃营,2-POP)',`features` varchar(500) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '扩展字段',`version_id` int(10) NOT NULL DEFAULT '0' COMMENT '版本号',`del_flag` tinyint(1) NOT NULL DEFAULT '0' COMMENT '删除标记(1-有效,0-删除)',`create_user` int(10) NOT NULL DEFAULT '0' COMMENT '创建⼈',`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',`update_user` int(10) NOT NULL DEFAULT '0' COMMENT '更新⼈',`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更改时间',PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='组套商品与SKU关系表';

三.商品与卖家组关系表

CREATE TABLE `sku_seller_relation` (`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主健',`item_id` varchar(40) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT 'itemId',`sku_id` varchar(40) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT 'skuId',`seller_group_id` varchar(50) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '卖家组ID',`seller_type` int(10) DEFAULT '0' COMMENT '卖家类型(1-⾃营,2-POP)',`relation_type` tinyint(3) DEFAULT '0' COMMENT '关系类型(1-可售,2-屏蔽)',`del_flag` tinyint(1) DEFAULT '1' COMMENT '删除标记(1-有效,0-删除)',`create_user` int(10) DEFAULT '0' COMMENT '创建⼈',`create_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',`update_user` int(10) DEFAULT '0' COMMENT '更新⼈',`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='商品与卖家组关系表';

四.商品属性扩展表

CREATE TABLE `attribute_extend` (`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',`participate_id` varchar(40) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '参与ID(ITEM_ID或SKU_ID)',`participate_type` int(10) NOT NULL DEFAULT '0' COMMENT '参与类型(1-ITEM,2-SKU)',`attribute_content` varchar(2048) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '属性内容',`feature` varchar(500) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '扩展字段',`version_id` int(10) NOT NULL DEFAULT '0' COMMENT '版本号',`del_flag` tinyint(1) NOT NULL DEFAULT '0' COMMENT '删除标记(1-有效,0-删除)',`create_user` int(10) NOT NULL DEFAULT '0' COMMENT '创建⼈',`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',`update_user` int(10) NOT NULL DEFAULT '0' COMMENT '更新⼈',`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',PRIMARY KEY (`ID`) 
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 COMMENT='商品属性扩展表';

(4)可售业务表

一.商品与卖家组关系表

二.商品卖家库存关系表

一.商品与卖家组关系表

CREATE TABLE `sku_seller_relation` (`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主健',`item_id` varchar(40) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT 'itemId',`sku_id` varchar(40) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT 'skuId',`seller_group_id` varchar(50) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '卖家组ID',`seller_type` int(10) DEFAULT '0' COMMENT '卖家类型(1-⾃营,2-POP)',`relation_type` tinyint(3) DEFAULT '0' COMMENT '关系类型(1-可售,2-屏蔽)',`del_flag` tinyint(1) DEFAULT '1' COMMENT '删除标记(1-有效,0-删除)',`create_user` int(10) DEFAULT '0' COMMENT '创建⼈',`create_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',`update_user` int(10) DEFAULT '0' COMMENT '更新⼈',`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='商品与卖家组关系表';

二.商品卖家库存关系表

CREATE TABLE `sku_stock_seller_relation` (`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,`sku_id` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '商品ID',`seller_type` tinyint(3) NULL DEFAULT NULL COMMENT '卖家类型(1-⾃营,2-POP)',`seller_id` bigint(20) NULL DEFAULT NULL COMMENT '卖家ID',`stock_num` bigint(20) NULL DEFAULT NULL COMMENT '库存数量',`stock_unit` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '库存单位',`del_flag` tinyint(1) NULL DEFAULT NULL COMMENT '删除标记(1-有效,0-删除)',`create_user` int(11) NULL DEFAULT NULL COMMENT '创建⼈',`create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',`update_user` int(11) NULL DEFAULT NULL COMMENT '更新⼈',`update_time` datetime NULL DEFAULT NULL COMMENT '更新时间',PRIMARY KEY (`id`) USING BTREE 
) ENGINE = InnoDB AUTO INCREMENT = 1 DEFAULT CHARSET=utf8 COMMENT='商品卖家库存关系表';

(5)基础配置表

leaf⾃增序列表leaf_alloc

CREATE TABLE `leaf_alloc` (`biz_tag` varchar(128) NOT NULL DEFAULT '' COMMENT '业务key',`max_id` bigint(20) NOT NULL DEFAULT '1' COMMENT '当前已经分配了的最⼤id',`step` int(11) NOT NULL COMMENT '初始步⻓,也是动态调整的最⼩步⻓',`description` varchar(256) DEFAULT NULL COMMENT '业务key的描述',`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '数据库维护的更新时间',PRIMARY KEY (`biz_tag`) 
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='leaf⾃增序列表';

2.定时同步可采商品

(1)定时调度任务定时同步可采商品

(2)定时同步可采商品时的卖家组数据分页查询

(3)过滤无效的卖家组与查询卖家组支持的可售商品

(4)卖家组支持的可售商品十万级数据量查询实现

(5)根据卖家组支持的可售商品查询商品信息

(6)对可售商品进行无需采购以及生命周期过滤

(7)对卖家组支持的可售商品进行过滤组套商品

(8)将过滤后的商品数据与卖家组进行关联

(9)读取缓存与刷入缓存的逻辑

(10)卖家组支持的可采商品与缓存的diff逻辑

(11)基于DB的分段发号器组件

(1)定时调度任务定时同步可采商品

使用场景:定时任务调度,可以按不同的卖家类型分任务进⾏执⾏同步结果。

@Component
public class RecoverableJobHandler {@DubboReference(version = "1.0.0")private RecoverableApi recoverableApi;@XxlJob("syncRecoverableProduct")public void syncAvailableProduct(RecoverableRequest request) {XxlJobHelper.log("sync available product job starting...");JsonResult result = recoverableApi.syncRecoverableProduct(request);XxlJobHelper.log("sync available product job end, result:{}", result);}
}@DubboService(version = "1.0.0", interfaceClass = RecoverableApi.class, retries = 0)
public class RecoverableApiImpl implements RecoverableApi {@Autowiredprivate RecoverableService recoverableService;//同步可采商品@Overridepublic JsonResult syncRecoverableProduct(RecoverableRequest request) {try {return recoverableService.syncRecoverableProduct(request);} 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 RecoverableServiceImpl implements RecoverableService {...//同步可采的数据入缓存@Overridepublic JsonResult syncRecoverableProduct(RecoverableRequest 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.进行item级别的商品过滤(无需采购和生命周期)List<ProductDetailDO> itemFilterList = itemFilter(productDetailDOList);//5.进行组套商品的商品过滤(无需采购和生命周期)List<ProductDetailDO> suitFilterList = suitFilter(itemFilterList);//6.将详情的商品sku信息绑定到卖家上List<ProductSellerRelationBO> productSellerRelationBOList = buildBinding(sellerRelationDOList, suitFilterList);//7.读取历史的缓存信息,对已经存在的缓存进行diff处理并刷入缓存diffRecoverableCache(productSellerRelationBOList, sellerGroupResponses);pageNo++;sellerGroupResponses = querySellerGroupList(pageNo, request.getSellerGroupType());}return JsonResult.buildSuccess();}...
}

具体实现:

一.调⽤查询卖家信息接⼝,传⼊卖家类型,返回对应的卖家组信息列表
二.过滤掉返回的卖家组列表中⾮有效状态的卖家组
三.根据卖家组ID列表获取这些卖家组所⽀持售卖的商品
四.根据商品sku表sku_info查询得到⾃营类型的商品
五.根据商品⽆需采购配置表获取得到不需要采购的品类信息
六.根据sku列表批量查询⽣命周期的可采结果,并过滤不可采的商品信息七.进⾏组套商品验证,先通过sku批量查询组套商品与sku关系表
获取得到每个sku下的原料以及普通商品信息
对每个商品进⾏⽆需采购以及⽣命周期的验证
当组合商品下的sku都满⾜条件则可补,否则过滤
组套商品与SKU关系表是stack_sku_relation八.对已经存在的缓存数据和当前这次同步处理后的数据进⾏差集处理,发⽣变化的数据才需要刷⼊缓存(新增的或者⽆效的数据)
九.构建缓存模型,对可补的商品数据进⾏缓存,缓存的模型对象为:key为'前缀标识+卖家组ID',value为'可采sku+品类'

时序图:

流程图:

(2)定时同步可采商品时的卖家组数据分页查询

@Service
public class RecoverableServiceImpl implements RecoverableService {@Autowiredprivate SellerRemote sellerRemote;...//分页查询卖家组(售卖区)信息public List<SellerGroupResponse> querySellerGroupList(Integer pageNo, Integer sellerGroupType) {PageResult<SellerGroupResponse> sellerGroupPage = sellerRemote.getSellerGroupList(pageNo, CompensationConstants.SELLER_PAGE_SIZE, sellerGroupType);return sellerGroupPage.getContent();}//同步可采的数据入缓存@Overridepublic JsonResult syncRecoverableProduct(RecoverableRequest 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.进行item级别的商品过滤(无需采购和生命周期)List<ProductDetailDO> itemFilterList = itemFilter(productDetailDOList);//5.进行组套商品的商品过滤(无需采购和生命周期)List<ProductDetailDO> suitFilterList = suitFilter(itemFilterList);//6.将详情的商品sku信息绑定到卖家上List<ProductSellerRelationBO> productSellerRelationBOList = buildBinding(sellerRelationDOList, suitFilterList);//7.读取历史的缓存信息,对已经存在的缓存进行diff处理并刷入缓存diffRecoverableCache(productSellerRelationBOList, sellerGroupResponses);pageNo++;sellerGroupResponses = querySellerGroupList(pageNo, request.getSellerGroupType());}return JsonResult.buildSuccess();}...
}

(3)过滤无效的卖家组与查询卖家组支持的可售商品

@Service
public class RecoverableServiceImpl implements RecoverableService {...//对卖家组状态非有效的进行过滤private List<SellerGroupResponse> sellerGroupFilter(List<SellerGroupResponse> sellerGroupResponses) {//过滤无效的卖家组信息return sellerGroupResponses.stream().filter(sellerGroupResponse -> SellerGroupStatusEnum.EFFECTIVE_STATUS.getCode().equals(sellerGroupResponse.getSellerGroupStatus())).collect(Collectors.toList());}//返回卖家组支持的可售商品列表private List<SkuSellerRelationDO> queryAvailableProduct(List<SellerGroupResponse> sellerGroupResponses) {if (!CollectionUtils.isEmpty(sellerGroupResponses)) {//转换为所有的卖家组IDList<Long> sellerGroupIds = sellerGroupResponses.stream().map(SellerGroupResponse::getSellerGroupId).collect(Collectors.toList());//分页批量查询卖家组支持的可售商品列表return productRelationRepository.pageQueryAvailableProduct(sellerGroupIds);}return new ArrayList<>();}...
}

(4)卖家组支持的可售商品十万级数据量查询实现

一个SkuSellerRelationDO对象大概就50Byte,10万个SkuSellerRelationDO对象大概就是500万Byte=4MB。

@Repository
public class ProductRelationRepository {...//分页查询 卖家组ID 可售商品信息public List<SkuSellerRelationDO> pageQueryAvailableProduct(List<Long> sellerGroupIds) {//默认集合初始大小为50000,避免扩容次数频繁,一般商品的数量最多也就是几万-几十万List<SkuSellerRelationDO> sellerRelationAllList = new ArrayList<>(RecoverableConstants.SKU_INIT_NUM);//一次最大查询10 卖家组ID,多个分页查询,这里做数据切割List<List<Long>> splitList = DataCuttingUtil.dataCuttingString(sellerGroupIds, RecoverableConstants.SELLER_ID_LIMIT_NUM);for (List<Long> sellerGroupIdList : splitList) {List<SkuSellerRelationDO> productDetailDOList = queryAvailableProduct(sellerGroupIdList);if (!CollectionUtils.isEmpty(productDetailDOList)) {sellerRelationAllList.addAll(productDetailDOList);}}return sellerRelationAllList;}//根据卖家组ID 批量查询 可售商品信息public List<SkuSellerRelationDO> queryAvailableProduct(List<Long> sellerGroupIds) {//获取卖家组对应的可售商品LambdaQueryWrapper<SkuSellerRelationDO> queryWrapper = Wrappers.lambdaQuery();queryWrapper.in(SkuSellerRelationDO::getSellerGroupId, sellerGroupIds).eq(SkuSellerRelationDO::getRelationType, SkuSellerRelationTypeEnum.RELATION_TYPE_YES.getCode()).eq(SkuSellerRelationDO::getDelFlag, DelFlagEnum.EFFECTIVE.getCode());return skuSellerRelationMapper.selectList(queryWrapper);}...
}public class DataCuttingUtil {//对集合数据进行切割,切割的数量按传入切割大小计算public static <T> List<List<T>> dataCuttingString(List<T> splitList, Integer splitSize) {Integer size = splitList.size();//计算出可以切分出多少个集合对象int limit = (size + splitSize - 1) / splitSize;return Stream.iterate(0, n -> n + 1).limit(limit).parallel().map(a -> splitList.stream().skip((long) a * splitSize).limit(splitSize).parallel().collect(Collectors.toList())).collect(Collectors.toList());}...
}

(5)根据卖家组支持的可售商品查询商品信息

@Service
public class RecoverableServiceImpl implements RecoverableService {@Autowiredprivate ProductRepository productRepository;...//根据卖家组支持的可售商品,查询商品信息并过滤非自营的商品private List<ProductDetailDO> queryProductDetailList(List<SkuSellerRelationDO> sellerRelationDOList) {if (!CollectionUtils.isEmpty(sellerRelationDOList)) {//先获取到对应的skuID列表Set<String> skuIdList = sellerRelationDOList.stream().map(SkuSellerRelationDO::getSkuId).collect(Collectors.toSet());//一次最大查询1000skuId,多个分页查询,这里做数据切割List<ProductDetailDO> productDetailDOList = productRepository.pageQueryProductInfoList(skuIdList);if (!CollectionUtils.isEmpty(productDetailDOList)) {List<ProductDetailDO> productDetailDOS = productDetailDOList.stream().filter(productDetailDO -> productDetailDO.getSellerType().equals(SellerTypeEnum.SELF.getCode())).collect(Collectors.toList());return productDetailDOS;}}return new ArrayList<>();}...
}@Repository
public class ProductRepository {...//分页查询sku信息public List<ProductDetailDO> pageQueryProductInfoList(Set<String> skuIdList) {//默认集合初始大小为50000,避免扩容次数频繁,一般商品的数量最多也就是几万-几十万List<ProductDetailDO> productDetailAllList = new ArrayList<>(RecoverableConstants.SKU_INIT_NUM);//一次最大查询1000skuId,多个分页查询,这里做数据切割List<Set<String>> splitList = DataCuttingUtil.dataCuttingString(skuIdList, RecoverableConstants.SKU_LIMIT_NUM);for (Set<String> skuIds : splitList) {List<ProductDetailDO> productDetailDOList = queryProductInfoList(skuIds);if (!CollectionUtils.isEmpty(productDetailDOList)) {productDetailAllList.addAll(productDetailDOList);}}return productDetailAllList;}//批量查询商品的详情信息public List<ProductDetailDO> queryProductInfoList(Set<String> skuId) {return skuInfoMapper.queryProductInfoList(skuId);}...
}public class DataCuttingUtil {//对集合数据进行切割,切割的数量按传入切割大小计算public static <T> List<List<T>> dataCuttingString(List<T> splitList, Integer splitSize) {Integer size = splitList.size();//计算出可以切分出多少个集合对象int limit = (size + splitSize - 1) / splitSize;return Stream.iterate(0, n -> n + 1).limit(limit).parallel().map(a -> splitList.stream().skip((long) a * splitSize).limit(splitSize).parallel().collect(Collectors.toList())).collect(Collectors.toList());}...
}

(6)对可售商品进行无需采购以及生命周期过滤

@Service
public class RecoverableServiceImpl implements RecoverableService {...//进行item级别的商品过滤(无需采购和生命周期)private List<ProductDetailDO> itemFilter(List<ProductDetailDO> productDetailDOList) {if (!CollectionUtils.isEmpty(productDetailDOList)) {//过滤掉无需采购的商品列表List<ProductDetailDO> productDetailList = filterPurchaseProduct(productDetailDOList);//商品进行生命周期的查询检查,过滤不符合条件的商品return filterLifeCycle(productDetailList);}return productDetailDOList;}//过滤无需采购的item列表信息private List<ProductDetailDO> filterPurchaseProduct(List<ProductDetailDO> suitItemDOList) {//获取配置的无需采购的列表List<ItemProcurementConfigDO> itemProcurementConfigList = productConfigRepository.queryProcurementConfigList();//空集合判断if (CollectionUtils.isEmpty(suitItemDOList)) {return new ArrayList();}if (CollectionUtils.isEmpty(itemProcurementConfigList)) {return suitItemDOList;}//集合转map,方便验证是否命中Map<Integer, ItemProcurementConfigDO> procurementConfigMap = itemProcurementConfigList.stream().collect(Collectors.toMap(ItemProcurementConfigDO::getCategoryId, Function.identity()));//开始过滤无需采购的商品信息List<ProductDetailDO> productDetailDOList = suitItemDOList.stream().filter(productDetail -> !procurementConfigMap.containsKey(productDetail.getCategoryId())).collect(Collectors.toList());//返回过滤后的商品信息return productDetailDOList;}//进行商品生命周期的过滤private List<ProductDetailDO> filterLifeCycle(List<ProductDetailDO> productDetailList) {if (!CollectionUtils.isEmpty(productDetailList)) {//构建调用生命周期的接口入参模型Set<String> itemIdList = productDetailList.stream().map(ProductDetailDO::getItemId).collect(Collectors.toSet());List<ItemExpriResultDTO> skuExpriResultDTOS = itemPeriodStageRemote.queryByItemIds(itemIdList);//集合转map,方便验证是否命中Map<String, ItemExpriResultDTO> itemExpriResultMap = skuExpriResultDTOS.stream().collect(Collectors.toMap(ItemExpriResultDTO::getItemId, Function.identity()));//过滤不符合条件的商品List<ProductDetailDO> productDetailDOList = productDetailList.stream().filter(productDetail -> {//没有命中不保留if (!itemExpriResultMap.containsKey(productDetail.getItemId())) {return false;}ItemExpriResultDTO itemExpriResultDTO = itemExpriResultMap.get(productDetail.getItemId());//可采的状态返回truereturn itemExpriResultDTO.getPurchaseStatus().equals(ItemExpriEnum.RECOVERABLE_STATUS_YES.getCode());}).collect(Collectors.toList());//返回过滤后的商品信息return productDetailDOList;}return productDetailList;}...
}

(7)对卖家组支持的可售商品进行过滤组套商品

@Service
public class RecoverableServiceImpl implements RecoverableService {...//进行组套商品的商品过滤(无需采购和生命周期)private List<ProductDetailDO> suitFilter(List<ProductDetailDO> productDetailList) {if (!CollectionUtils.isEmpty(productDetailList)) {//1.查询哪些是组套商品,并且反向寻找到组套商品归属的item信息List<ProductDetailDO> suitItemDOList = querySuitList(productDetailList);//2.过滤掉无需采购的商品列表List<ProductDetailDO> productDetailDOList = filterSuitPurchaseProduct(suitItemDOList);//3.商品进行生命周期的查询检查,过滤不符合条件的商品return filterSuitLifeCycle(productDetailDOList);}return productDetailList;}//通过商品明细,查询出哪些是组套商品,并输出对应的归属item数据结构private List<ProductDetailDO> querySuitList(List<ProductDetailDO> productDetailDOList) {//根据skuId批量查询是否组套商品List<StackSkuRelationDO> stackSkuRelationAllList = queryStackSkuListByIds(productDetailDOList);//没有组套商品的直接返回if (CollectionUtils.isEmpty(stackSkuRelationAllList)) {return productDetailDOList;}//返回组套商品的详情集合信息(包含item信息)List<ProductDetailDO> itemProductList = queryProductInfoList(stackSkuRelationAllList);//将组套商品绑定到上级对应商品下return buildSuitBinding(itemProductList, productDetailDOList, stackSkuRelationAllList);}//根据skuId批量查询是否组套商品private List<StackSkuRelationDO> queryStackSkuListByIds(List<ProductDetailDO> productDetailDOList) {//先获取到对应的skuID列表Set<String> skuIdList = productDetailDOList.stream().map(ProductDetailDO::getSkuId).collect(Collectors.toSet());return productRelationRepository.pageQueryStackSkuListByIds(skuIdList);}//获取组套商品的详情集合信息private List<ProductDetailDO> queryProductInfoList(List<StackSkuRelationDO> stackSkuRelationAllList) {//获取组套商品的sku列表,通过sku列表联合查询得到对应的item信息Set<String> stackSkuIdList = stackSkuRelationAllList.stream().map(StackSkuRelationDO::getStackSkuId).collect(Collectors.toSet());//查询组套商品详情集合信息return productRepository.pageQueryProductInfoList(stackSkuIdList);}//将组套商品绑定上private List<ProductDetailDO> buildSuitBinding(List<ProductDetailDO> itemProductList, List<ProductDetailDO> productDetailDOList, List<StackSkuRelationDO> stackSkuRelationAllList) {List<ProductDetailDO> productSellerRelationBOList = recoverableConverter.converterProductList(productDetailDOList);//sku对应的组套商品详情(对应组套商品的stackSkuId)Map<String, ProductDetailDO> productDetailMap = itemProductList.stream().collect(Collectors.toMap(ProductDetailDO::getSkuId, Function.identity()));//组套的商品集合(一个商品下多个物料sku组装而成)Map<String, List<StackSkuRelationDO>> stackSkuRelationMap = stackSkuRelationAllList.stream().collect(Collectors.groupingBy(StackSkuRelationDO::getSkuId));for (ProductDetailDO productDetailDO : productSellerRelationBOList) {//命中到了对应的组套商品if (stackSkuRelationMap.containsKey(productDetailDO.getSkuId())) {List<ProductDetailDO> productDetailDOS = new ArrayList<>();//标记为组套商品productDetailDO.setProductType(2);//同时存储对应的组套商品详情信息List<StackSkuRelationDO> stackSkuRelationList = stackSkuRelationMap.get(productDetailDO.getSkuId());for (StackSkuRelationDO stackSkuRelationDO : stackSkuRelationList) {if (productDetailMap.containsKey(stackSkuRelationDO.getStackSkuId())) {ProductDetailDO productDetail = productDetailMap.get(stackSkuRelationDO.getStackSkuId());productDetailDOS.add(productDetail);}}productDetailDO.setProductDetailList(productDetailDOS);}}return productSellerRelationBOList;}//过滤无需采购的组套商品private List<ProductDetailDO> filterSuitPurchaseProduct(List<ProductDetailDO> suitItemDOList) {//获取配置的无需采购的列表List<ItemProcurementConfigDO> itemProcurementConfigList = productConfigRepository.queryProcurementConfigList();//空集合判断if (CollectionUtils.isEmpty(suitItemDOList)) {return new ArrayList();}if (CollectionUtils.isEmpty(itemProcurementConfigList)) {return suitItemDOList;}//集合转map,方便验证是否命中Map<Integer, ItemProcurementConfigDO> procurementConfigMap = itemProcurementConfigList.stream().collect(Collectors.toMap(ItemProcurementConfigDO::getCategoryId, Function.identity()));List<ProductDetailDO> productDetailDOList = new ArrayList<>(suitItemDOList.size());for (ProductDetailDO productDetailDO : suitItemDOList) {if (productDetailDO.getProductType().equals(2)) {List<ProductDetailDO> productDetailList = productDetailDO.getProductDetailList();//组套商品有商品不满足条件if (checkSuitPurchaseProduct(productDetailList, procurementConfigMap)) {continue;}}productDetailDOList.add(productDetailDO);}return productDetailDOList;}//进行组套商品生命周期的过滤private List<ProductDetailDO> filterSuitLifeCycle(List<ProductDetailDO> productDetailList) {List<ProductDetailDO> productDetailDOAllList = new ArrayList<>(productDetailList.size());if (!CollectionUtils.isEmpty(productDetailList)) {//查询返回生命周期的数据模型Map<String, ItemExpriResultDTO> itemExpriResultMap = queryItemExpriMap(productDetailList);for (ProductDetailDO productDetailDO : productDetailList) {if (productDetailDO.getProductType().equals(2)) {List<ProductDetailDO> productDetailDOList = productDetailDO.getProductDetailList();if (checkSuitLifeCycle(productDetailDOList, itemExpriResultMap)) {continue;}}productDetailDOAllList.add(productDetailDO);}}return productDetailDOAllList;}...
}

(8)将过滤后的商品数据与卖家组进行关联

@Service
public class RecoverableServiceImpl implements RecoverableService {...//同步可采的数据入缓存@Overridepublic JsonResult syncRecoverableProduct(RecoverableRequest 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.进行item级别的商品过滤(无需采购和生命周期)List<ProductDetailDO> itemFilterList = itemFilter(productDetailDOList);//5.进行组套商品的商品过滤(无需采购和生命周期)List<ProductDetailDO> suitFilterList = suitFilter(itemFilterList);//6.将详情的商品sku信息绑定到卖家上List<ProductSellerRelationBO> productSellerRelationBOList = buildBinding(sellerRelationDOList, suitFilterList);//7.读取历史的缓存信息,对已经存在的缓存进行diff处理并刷入缓存diffRecoverableCache(productSellerRelationBOList, sellerGroupResponses);pageNo++;sellerGroupResponses = querySellerGroupList(pageNo, request.getSellerGroupType());}return JsonResult.buildSuccess();}//将过滤后的商品明细绑定到卖家组上private List<ProductSellerRelationBO> buildBinding(List<SkuSellerRelationDO> sellerRelationDOList, List<ProductDetailDO> productDetailDOList) {//先转换集合为map,key为商品的skuId标识Map<String, ProductDetailDO> skuInfoDOMap = productDetailDOList.stream().collect(Collectors.toMap(ProductDetailDO::getSkuId, Function.identity()));//按卖家组ID进行分组,把下属的商品合并到一个上Map<Long, List<SkuSellerRelationDO>> skuSellerRelationMap = sellerRelationDOList.stream().collect(Collectors.groupingBy(SkuSellerRelationDO::getSellerGroupId));//返回的绑定卖家组和商品明细的集合对象List<ProductSellerRelationBO> sellerRelationBOList = new ArrayList<>(sellerRelationDOList.size());//遍历卖家和商品关系集合,开始填充商品sku信息绑定到卖家组上for (Map.Entry<Long, List<SkuSellerRelationDO>> entry : skuSellerRelationMap.entrySet()) {List<SkuSellerRelationDO> skuSellerRelationDOS = entry.getValue();Long sellerGroupId = entry.getKey();//循环绑定卖家组下的商品关系ProductSellerRelationBO productSellerRelationBO = new ProductSellerRelationBO();productSellerRelationBO.setSellerId(sellerGroupId);List<ProductDetailDO> productDetailList = new ArrayList<>();//遍历卖家组下的可售商品列表for (SkuSellerRelationDO sellerRelationDO : skuSellerRelationDOS) {//查询的数据集合中 存在这个商品数据if (skuInfoDOMap.containsKey(sellerRelationDO.getSkuId())) {ProductDetailDO productDetailDO = skuInfoDOMap.get(sellerRelationDO.getSkuId());//绑定数据到卖家组上productDetailList.add(productDetailDO);}}productSellerRelationBO.setProductDetailList(productDetailList);sellerRelationBOList.add(productSellerRelationBO);}return sellerRelationBOList;}...
}

相关文章:

  • 与AI联手,ModbusTCP 转Ethercat控制系统升级解决刚需新思路
  • MyBatis-Plus 混合使用 XML 和注解
  • 一个教学项目pom.xml杂记
  • DevOps软件开发流程规范
  • 【笔记】NVIDIA AI Workbench 中安装 PyTorch
  • 山东大学软件学院项目实训-基于大模型的模拟面试系统-面试对话标题自动总结
  • 【计算机存储架构】层次化存储架构
  • JAVA-springboot Filter过滤器
  • Amazon Linux 2023 系统上 Radius 部署文档
  • 1Panel 部署 OpenResty + Redis 实现 IP 动态封禁教程
  • gbase8s数据库获取jdbc/odbc协议的几种方式
  • 合同管理登记台账是什么?合同管理登记台账有哪些功能?
  • 基于GA遗传优化的PID控制器最优控制参数整定matlab仿真
  • Matlab解决无法读取路径中的空格
  • 前端实战:用 HTML+JS 打造可拖动图像对比滑块,提升视觉交互体
  • 硬件行业职业规划四篇
  • (功能测试Charles)如何抓取手机http的报文
  • 软件测试之基于博客系统项目的功能测试
  • 解锁Flink CDC:实时数据同步秘籍
  • 速盾:高防CDN可以加速数据库吗?
  • 自适应网站建设方案/广州做网站的公司哪家好
  • 网站内链 工具/企业管理培训机构
  • 招聘网站比对表怎么做/上海发布微信公众号
  • 网站备案被删除/济南公司网站推广优化最大的
  • 温州手机网站制作联系电话/百度投诉中心24小时电话
  • 惠州企业建站系统/宁波网站优化公司价格