规格匹配功能优化

This commit is contained in:
liyj 2025-07-29 15:02:57 +08:00
parent 28224ef6db
commit aecce566ef
5 changed files with 80 additions and 29 deletions

View File

@ -5500,10 +5500,9 @@ public class ShopProductBaseServiceImpl extends BaseServiceImpl<ShopProductBaseM
List<ShopProductItem> addShopProductItems = new ArrayList<>();
List<ShopProductItem> updateShopProductItems = new ArrayList<>();
List<ShopProductSpecItem> addShopProductSpecItems = new ArrayList<>();
List<ShopProductSpecItem> updateShopProductSpecItems = new ArrayList<>();
// int taskCount = 2;
// CountDownLatch latch = new CountDownLatch(taskCount);
// 2. 检查并设置已存在商品的ID
// 1. 批量新增
if (CollUtil.isNotEmpty(newProducts)) {
// 4. 批量生成新商品的ID
@ -5528,7 +5527,6 @@ public class ShopProductBaseServiceImpl extends BaseServiceImpl<ShopProductBaseM
List<ShopProductItem> items = newShopProductItemList.get(i);
processProductItems(items, productId, addItemSeqs);
addShopProductItems.addAll(items);
// 处理图片
if (CollUtil.isNotEmpty(newShopProductImageList)) {
processProductImages(newShopProductImageList.get(i), productId, base.getStore_id(), newProducts.get(i).getProduct_number(), newProducts.get(i).getProduct_name());//设置默认属性1
@ -5562,11 +5560,11 @@ public class ShopProductBaseServiceImpl extends BaseServiceImpl<ShopProductBaseM
}
}
if (CollUtil.isNotEmpty(updateProducts)) {
Map<Long, Long> existingProducts = checkExistingProductsItem(updateProducts);
for (int i = 0; i < updateProducts.size(); i++) {
Long productId = updateProducts.get(i).getProduct_id();
ShopProductBase base = updateProducts.get(i);
base.setProduct_id(productId);
// 设置关联ID
updateProducts.get(i).setProduct_id(productId);
updateShopProductIndexList.get(i).setProduct_id(productId);
@ -5574,8 +5572,13 @@ public class ShopProductBaseServiceImpl extends BaseServiceImpl<ShopProductBaseM
updateShopProductDetailList.get(i).setProduct_id(productId);
updateShopProductInfoList.get(i).setProduct_id(productId);
//计算规格
if(existingProducts.get(productId)!=null){
udpateShopProductItemList.get(i).get(0).setItem_id(existingProducts.get(productId));
udpateItemIds.add(existingProducts.get(productId));
}
// 处理商品项
List<ShopProductItem> items = udpateShopProductItemList.get(i);
processProductItems(items, productId, updateItemSeqs);//
updateShopProductItems.addAll(items);
@ -5595,8 +5598,8 @@ public class ShopProductBaseServiceImpl extends BaseServiceImpl<ShopProductBaseM
shopProductAnalytics.setProduct_click(0);
udpateAnalyticsList.add(shopProductAnalytics);
}
List<Serializable> itemIds = processProductItemsId(updateShopProductItems, updateItemSeqs, newShopProductInfoList);
udpateItemIds.addAll(itemIds);
//List<Serializable> itemIds = processProductItemsId(updateShopProductItems, updateItemSeqs, updateShopProductInfoList);
//udpateItemIds.addAll(itemIds);
// 2. 批量更新
if (CollUtil.isNotEmpty(updateProducts)) {
logger.info("更新任务开始执行");
@ -5620,11 +5623,11 @@ public class ShopProductBaseServiceImpl extends BaseServiceImpl<ShopProductBaseM
//计算规格
if (CollUtil.isNotEmpty(newProducts)) {
productMappingService.computeProductMapping(newProducts, newProducts.get(0).getStore_id(),shopProductSpecItemMap,ShopBaseProductSpecMap,productMappingMap, isUpdatePrice);
productMappingService.computeProductMapping(newProducts, newProducts.get(0).getStore_id(),shopProductSpecItemMap,ShopBaseProductSpecMap,productMappingMap, isUpdatePrice,DicEnum.YESORNO_0.getCode());
}
if (CollUtil.isNotEmpty(updateProducts)) {//如果时自动优先则按平台规则切割商品
if (DicEnum.PRIORITY_MODE_2.getCode().equals(priorityMode)) {
productMappingService.computeProductMapping(updateProducts, updateProducts.get(0).getStore_id(),shopProductSpecItemMap,ShopBaseProductSpecMap,productMappingMap, true);
productMappingService.computeProductMapping(updateProducts, updateProducts.get(0).getStore_id(),shopProductSpecItemMap,ShopBaseProductSpecMap,productMappingMap, true,DicEnum.YESORNO_0.getCode());
}
}
return Pair.of(true, String.format("处理成功,新增%d条更新%d条",
@ -6070,6 +6073,35 @@ public class ShopProductBaseServiceImpl extends BaseServiceImpl<ShopProductBaseM
));
}
/**
* 检查哪些商品已存在
*/
private Map<Long, Long> checkExistingProductsItem(List<ShopProductBase> productBases) {
List<Pair<Integer, Long>> storeProductPairs = productBases.stream()
.map(p -> Pair.of(p.getStore_id(), p.getProduct_id()))
.distinct()
.collect(Collectors.toList());
// 使用IN查询优化根据数据库特性可能需要分批
QueryWrapper<ShopProductItem> query = new QueryWrapper<>();
query.select("product_id", "min(item_id) as item_id");
// 构建OR条件 (store_id=X AND product_number=Y) OR (store_id=A AND product_number=B)...
storeProductPairs.forEach(pair -> {
query.or(q -> q.eq("store_id", pair.getFirst())
.eq("product_id", pair.getSecond()));
});
query.groupBy("product_id");
List<ShopProductItem> existing = shopProductItemService.list(query);
// 4. 构建存在商品的映射表
return existing.stream()
.collect(Collectors.toMap(
ShopProductItem::getProduct_id,
ShopProductItem::getItem_id
));
}
/**
* 批量根据店铺和货号查询商品
*/

View File

@ -188,17 +188,17 @@ public class ProductMappingController extends BaseControllerImpl {
*/
@ApiOperation(value = "自动计算并上架商品", notes = "自动计算并上架商品")
@RequestMapping(value = "/syncProductMaping", method = RequestMethod.PUT)
public CommonResult syncProductMaping(@RequestParam(required = false) Integer storeId) {
public CommonResult syncProductMaping(@RequestParam(required = false) Integer storeId,@RequestParam(defaultValue = "0") String isPublish) {
UserDto userDto=ContextUtil.getCurrentUser();
assert userDto != null;
if(userDto.isStore()) {//商店自己同步
return productMappingService.syncAllProductMapping(Integer.valueOf(userDto.getStore_id()));
return productMappingService.syncAllProductMapping(Integer.valueOf(userDto.getStore_id()),isPublish);
}else {
if(ObjectUtil.isEmpty(storeId)){
return CommonResult.failed("请传入店铺id");
}
}
return productMappingService.syncAllProductMapping(storeId);
return productMappingService.syncAllProductMapping(storeId,isPublish);
}
/**

View File

@ -23,11 +23,11 @@ public interface ProductMappingService extends IBaseService<ProductMapping> {
*/
void computeProductMapping(List<ShopProductBase> shopProductBaseList,Integer storeId,
Map shopProductSpecItemMap,Map ShopBaseProductSpecMap, Map productMappingMap,
boolean isUpdate);
boolean isUpdate,String isPubish);
Map getProductMapping(Integer storeId);
CommonResult syncAllProductMapping(Integer storeId);
CommonResult syncAllProductMapping(Integer storeId,String isPublish);
CommonResult getSyncProductUnchecked(Integer storeId);

View File

@ -27,6 +27,8 @@ import com.suisung.mall.common.modules.sync.ProductMapping;
import com.suisung.mall.common.modules.sync.StoreDbConfig;
import com.suisung.mall.common.utils.ContextUtil;
import com.suisung.mall.common.utils.StringUtils;
import com.suisung.mall.core.consts.ConstantRedis;
import com.suisung.mall.core.web.service.RedisService;
import com.suisung.mall.core.web.service.impl.BaseServiceImpl;
import com.suisung.mall.shop.base.service.ShopBaseProductSpecService;
@ -48,6 +50,7 @@ import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -106,6 +109,9 @@ public class ProductMappingServiceImpl extends BaseServiceImpl<ProductMappingMap
private static final String EXPORT_NAME = "商品映射数据.xlsx";
private final Integer SHOPBASEPAGE=500;
@Qualifier("redisService")
@Autowired
private RedisService redisService;
@Override
public CommonResult findPageProductMapping(ProductMapping productMapping,Integer pageNum,Integer pageSize) {
@ -123,13 +129,13 @@ public class ProductMappingServiceImpl extends BaseServiceImpl<ProductMappingMap
}
@Override
public void computeProductMapping(List<ShopProductBase> shopProductBaseList,Integer storeId,Map shopProductSpecItemMap,Map ShopBaseProductSpecMap, Map productMappingMap,boolean isUpdate) {
public void computeProductMapping(List<ShopProductBase> shopProductBaseList,Integer storeId,Map shopProductSpecItemMap,Map ShopBaseProductSpecMap, Map productMappingMap,boolean isUpdate,String isPubish) {
shopProductBaseList= shopProductBaseList.stream().filter(base ->StateCode.PRODUCT_STATE_OFF_THE_SHELF_UNCHECK==(base.getProduct_state_id())).collect(Collectors.toList());
if (CollUtil.isEmpty(shopProductBaseList)) {
log.info("没有规格数据要处理");
return;
}
dealData(shopProductBaseList,shopProductSpecItemMap,ShopBaseProductSpecMap,productMappingMap,isUpdate);
dealData(shopProductBaseList,shopProductSpecItemMap,ShopBaseProductSpecMap,productMappingMap,isUpdate,isPubish);
}
@Override
@ -152,7 +158,7 @@ public class ProductMappingServiceImpl extends BaseServiceImpl<ProductMappingMap
* @param ShopBaseProductSpecMap
* @param productMappingMap
*/
public void dealData(List<ShopProductBase> shopProductBaseList,Map shopProductSpecItemMap,Map ShopBaseProductSpecMap, Map productMappingMap,boolean isUpdate){
public void dealData(List<ShopProductBase> shopProductBaseList,Map shopProductSpecItemMap,Map ShopBaseProductSpecMap, Map productMappingMap,boolean isUpdate,String isPublish){
List<ShopProductItem> shopProductItems=findShopProductItemsList(shopProductBaseList);
List<ShopProductInfo> shopProductInfoList=findShopProductInfoList(shopProductBaseList);
List<ShopProductSpecItem> addShopProductSpecItemList=new ArrayList<>();
@ -162,17 +168,24 @@ public class ProductMappingServiceImpl extends BaseServiceImpl<ProductMappingMap
List<ShopProductIndex> updateShopProductIndexList=new ArrayList<>();
List<ShopProductItem> updateShopProductItemList=new ArrayList<>();
List<ShopProductInfo> updateShopProductInfoList=new ArrayList<>();
//找出需要更新的列表
for (int i = 0; i < shopProductBaseList.size(); i++){
ShopProductSpecItem shopProductSpecItem=processShopProductSpecItem(shopProductBaseList.get(i),shopProductItems.get(i).getCategory_id(),shopProductSpecItemMap,ShopBaseProductSpecMap,productMappingMap,null);
if(shopProductSpecItem!=null){
ShopProductIndex shopProductIndex=new ShopProductIndex();
shopProductIndex.setProduct_id(shopProductBaseList.get(i).getProduct_id());
Integer stateId= shopProductBaseList.get(i).getProduct_state_id();
if(stateId!=StateCode.PRODUCT_STATE_NORMAL){
shopProductBaseList.get(i).setProduct_state_id(StateCode.PRODUCT_STATE_OFF_THE_SHELF);
shopProductIndex.setProduct_state_id(StateCode.PRODUCT_STATE_OFF_THE_SHELF);
shopProductItems.get(i).setItem_enable(StateCode.PRODUCT_STATE_OFF_THE_SHELF);
if(ObjectUtil.equals(DicEnum.YESORNO_1.getCode(),isPublish)){
shopProductBaseList.get(i).setProduct_state_id(StateCode.PRODUCT_STATE_NORMAL);
shopProductIndex.setProduct_state_id(StateCode.PRODUCT_STATE_NORMAL);
shopProductItems.get(i).setItem_enable(StateCode.PRODUCT_STATE_NORMAL);
}else {
Integer stateId= shopProductBaseList.get(i).getProduct_state_id();
if(stateId!=StateCode.PRODUCT_STATE_NORMAL){
shopProductBaseList.get(i).setProduct_state_id(StateCode.PRODUCT_STATE_OFF_THE_SHELF);
shopProductIndex.setProduct_state_id(StateCode.PRODUCT_STATE_OFF_THE_SHELF);
shopProductItems.get(i).setItem_enable(StateCode.PRODUCT_STATE_OFF_THE_SHELF);
}
}
shopProductItems.get(i).setItem_is_default(1);
if(shopProductSpecItem.isUpdate()){
@ -374,7 +387,7 @@ public class ProductMappingServiceImpl extends BaseServiceImpl<ProductMappingMap
}
@Override
public CommonResult syncAllProductMapping(Integer storeId) {
public CommonResult syncAllProductMapping(Integer storeId,String isPublish) {
if(ObjectUtil.isEmpty(storeId)){
storeId= Integer.valueOf(Objects.requireNonNull(ContextUtil.getCurrentUser()).getStore_id());
}
@ -407,7 +420,7 @@ public class ProductMappingServiceImpl extends BaseServiceImpl<ProductMappingMap
Integer finalStoreId = storeId;
List<ShopProductBase> shopProductBaseList=shopProductBaseService.lists(queryWrapper, finalI,SHOPBASEPAGE).getRecords();
futures.add(executor.submit(() -> {
this.computeProductMapping(shopProductBaseList, finalStoreId,shopProductSpecItemMap,ShopBaseProductSpecMap, productMappingMap,isUpDatePrice);
this.computeProductMapping(shopProductBaseList, finalStoreId,shopProductSpecItemMap,ShopBaseProductSpecMap, productMappingMap,isUpDatePrice,isPublish);
return "成功" + finalI;
}));
}
@ -420,9 +433,15 @@ public class ProductMappingServiceImpl extends BaseServiceImpl<ProductMappingMap
}
}
executor.shutdown();
shopNumberSeqService.clearKeyStoreItemSepcId();
shopNumberSeqService.clearKeyStoreItemSepcId();
Set<String> item_keys = redisService.keys(ConstantRedis.Cache_NameSpace +"shop_product_item"+ "*");
redisService.del(item_keys);
Set<String> base_keys = redisService.keys(ConstantRedis.Cache_NameSpace +"shop_product_base"+ "*");
redisService.del(base_keys);
Set<String> index_keys = redisService.keys(ConstantRedis.Cache_NameSpace +"shop_product_index"+ "*");
redisService.del(index_keys);
Set<String> info_keys = redisService.keys(ConstantRedis.Cache_NameSpace +"shop_product_info"+ "*");
redisService.del(info_keys);
return CommonResult.success(true);
}

View File

@ -758,13 +758,13 @@ public abstract class SyncBaseThirdSxAbstract{
}
}
BigDecimal stock= jsonObj.getBigDecimal("stock");//库存
if(ObjectUtil.equals(isNegativeAllowed,DicEnum.YESORNO_1)&&stock.compareTo(BigDecimal.ZERO)<=0){//允许负库存每次都加满就是一直有售卖
if(ObjectUtil.equals(isNegativeAllowed,DicEnum.YESORNO_1.getCode())&&stock.compareTo(BigDecimal.ZERO)<=0){//允许负库存每次都加满就是一直有售卖
stock=new BigDecimal("99");
}
//商品总量
if(ObjectUtil.isNotEmpty(jsonObj.getStr("unit"))&&ObjectUtil.isNotEmpty(jsonObj.getStr("stock"))
&& "KG,kg,公斤".contains(jsonObj.getStr("unit"))&&!(productName.contains("g")||productName.contains("ml")||productName.contains("ML")||productName.contains("kg")||
productName.contains("KG")||productName.contains("L")||productName.contains("l"))){//这样做主要是有些超时有了kg又打包成克来卖
productName.contains("KG")||productName.contains("L")||productName.contains("l")||productName.contains(""))){//这样做主要是有些超时有了kg又打包成克来卖
shopProductBase.setShop_weight(stock);
shopProductBase.setUnit_name(jsonObj.getStr("unit"));
shopProductBase.setProduct_state_id(StateCode.PRODUCT_STATE_OFF_THE_SHELF_UNCHECK);
@ -778,7 +778,7 @@ public abstract class SyncBaseThirdSxAbstract{
shopProductBase.setProduct_state_id(StateCode.PRODUCT_STATE_OFF_THE_SHELF);//默认是下架
shopProductBase.setUnit_price(BigDecimal.valueOf(jsonObj.getDouble("retail_price")));
if(!(productName.contains("g")||productName.contains("ml")||productName.contains("ML")||productName.contains("kg")||
productName.contains("KG")||productName.contains("L")||productName.contains("l"))){
productName.contains("KG")||productName.contains("L")||productName.contains("l")||productName.contains(""))){
String spectItem=StringUtils.isNotEmpty(shopProductBase.getSpecItem())?shopProductBase.getSpecItem():"";
String unit=StringUtils.isNotEmpty(shopProductBase.getSpecUnit())?shopProductBase.getSpecUnit():"";
if(StringUtils.isNotEmpty(spectItem)||StringUtils.isNotEmpty(unit)){