findProductAndImtemId(ShopNumberSeq shopNumberSeq);
+ void myUpdateSeq(ShopNumberSeq shopNumberSeq);
}
diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/number/service/ShopNumberSeqService.java b/mall-shop/src/main/java/com/suisung/mall/shop/number/service/ShopNumberSeqService.java
index eaa5e852..8d3ca7f6 100644
--- a/mall-shop/src/main/java/com/suisung/mall/shop/number/service/ShopNumberSeqService.java
+++ b/mall-shop/src/main/java/com/suisung/mall/shop/number/service/ShopNumberSeqService.java
@@ -3,6 +3,8 @@ package com.suisung.mall.shop.number.service;
import com.suisung.mall.common.modules.number.ShopNumberSeq;
import com.suisung.mall.core.web.service.IBaseService;
+import java.util.List;
+
/**
*
* Id管理表 服务类
@@ -17,4 +19,9 @@ public interface ShopNumberSeqService extends IBaseService {
Long createNextNo(String prefix);
+ List batchCreateNextNo(String seqName, int batchSize);
+
+ void clearRelateGoodsId();
+ void clearKey();
+
}
diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/number/service/impl/ShopNumberSeqServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/number/service/impl/ShopNumberSeqServiceImpl.java
index 1a1df401..7384c498 100644
--- a/mall-shop/src/main/java/com/suisung/mall/shop/number/service/impl/ShopNumberSeqServiceImpl.java
+++ b/mall-shop/src/main/java/com/suisung/mall/shop/number/service/impl/ShopNumberSeqServiceImpl.java
@@ -1,15 +1,25 @@
package com.suisung.mall.shop.number.service.impl;
import cn.hutool.core.date.DateUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.suisung.mall.common.modules.number.ShopNumberSeq;
+import com.suisung.mall.core.web.service.RedisService;
import com.suisung.mall.core.web.service.impl.BaseServiceImpl;
import com.suisung.mall.shop.number.mapper.ShopNumberSeqMapper;
import com.suisung.mall.shop.number.service.ShopNumberSeqService;
+import org.apache.ibatis.session.ExecutorType;
+import org.apache.ibatis.session.SqlSession;
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
+import java.util.Collections;
import java.util.Date;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.LongStream;
/**
@@ -21,8 +31,15 @@ import java.util.Date;
* @since 2021-09-18
*/
@Service
+@lombok.extern.slf4j.Slf4j
public class ShopNumberSeqServiceImpl extends BaseServiceImpl implements ShopNumberSeqService {
+ @Autowired
+ private ShopNumberSeqMapper shopNumberSeqMapper;
+ @Autowired
+ private RedisService redisService;
+ private String CACHE_PREFIX = "shop_number_seq:%S";
+
/**
* 得到下一个Id
* 方法走到这里会产生串行化,集群部署这里不能使用单机锁
@@ -65,6 +82,10 @@ public class ShopNumberSeqServiceImpl extends BaseServiceImpl1;
+ while (!flag){
+ try {
+ Thread.sleep(3600);
+ } catch (InterruptedException e) {
+ log.error("checkPrimaryKey枷锁失败--"+e.getMessage());
+ break;
+ }
+ flag=shopNumberSeqMapper.findNumberFromShopBaseAndItem(new ShopNumberSeq()).size()>1;
+ }
+
+ }
+
+
+ /**
+ * 批量获取id
+ * @param seqName
+ * @param batchSize
+ * @return
+ */
+ @Transactional(propagation = Propagation.NOT_SUPPORTED)
+ public synchronized List batchCreateNextNo(String seqName, int batchSize) {
+ if (batchSize <= 0) {
+ return Collections.emptyList();
+ }
+ long number= 0;
+ if (null==redisService.get(String.format(CACHE_PREFIX, seqName))) {
+ // 1. 获取当前序列值
+ QueryWrapper wrapper = new QueryWrapper<>();
+ wrapper.eq("prefix", seqName);
+ ShopNumberSeq seq = getById(seqName);
+
+ if (seq == null) {
+ seq = new ShopNumberSeq();
+ seq.setPrefix(seqName);
+ seq.setNumber((long) batchSize);
+ save(seq);
+ return LongStream.range(1, batchSize + 1).boxed().collect(Collectors.toList());
+ }
+ number = seq.getNumber();
+ }else {
+ int numberCache=(Integer) redisService.get(String.format(CACHE_PREFIX, seqName))+1;
+ number= numberCache;
+
+ }
+
+ // 2. 计算新值范围
+ long start = number;
+ long end = start + batchSize - 1;
+
+ // 3. 更新序列值到缓存,在并发时使用
+ redisService.set(String.format(CACHE_PREFIX, seqName), end);
+ // 4. 返回生成的ID范围
+ return LongStream.rangeClosed(start, end).boxed().collect(Collectors.toList());
+ }
+
+ public void batchUpdateSeq(List shopNumberSeqList){
+ int count=0;
+ for (int i = 0; i < shopNumberSeqList.size(); i++) {
+ shopNumberSeqMapper.myUpdateSeq(shopNumberSeqList.get(i));
+ count++;
+ }
+ log.info("更新成功{}条数据",count);
+ }
+ public void clearKey(){
+ redisService.del(String.format(CACHE_PREFIX,"item_id"));
+ redisService.del(String.format(CACHE_PREFIX,"product_id"));
+ }
+
+ /**
+ * 清除缓存,专门给并发使用,防止redis的缓存没有加载
+ */
+ @Override
+ public void clearRelateGoodsId(){
+ boolean flag = shopNumberSeqMapper.findNumberFromShopBaseAndItem(new ShopNumberSeq()).size()>1;
+ if(flag){
+ return;
+ }
+ List shopNumberSeqList=shopNumberSeqMapper.findProductAndImtemId(new ShopNumberSeq());
+ for (ShopNumberSeq shopNumberSeq:shopNumberSeqList) {
+ if(shopNumberSeq.getPrefix().equals("product_id")){
+ clearCache("product_id",shopNumberSeq.getNumber());
+ }
+ if(shopNumberSeq.getPrefix().equals("item_id")){
+ clearCache("item_id",shopNumberSeq.getNumber());
+ }
+ }
+ }
+ /**
+ * 刷新缓存
+ */
+ private void clearCache(String seqName,long number){
+ QueryWrapper wrapper = new QueryWrapper<>();
+ wrapper.eq("prefix", seqName);
+ ShopNumberSeq seq = getById(seqName);
+ if (seq != null) {
+ seq = new ShopNumberSeq();
+ seq.setNumber(number-1);
+ seq.setPrefix(seqName);
+ }
+ edit(seq);
+ }
}
diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/page/service/OssService.java b/mall-shop/src/main/java/com/suisung/mall/shop/page/service/OssService.java
index 92324c09..4e5c53b8 100644
--- a/mall-shop/src/main/java/com/suisung/mall/shop/page/service/OssService.java
+++ b/mall-shop/src/main/java/com/suisung/mall/shop/page/service/OssService.java
@@ -1,12 +1,14 @@
package com.suisung.mall.shop.page.service;
+import com.qcloud.cos.model.COSObjectSummary;
import com.suisung.mall.common.pojo.dto.OssCallbackResultDTO;
import com.suisung.mall.common.pojo.dto.OssPolicyResultDTO;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.InputStream;
+import java.util.List;
/**
* oss上传管理Service
@@ -42,4 +44,26 @@ public interface OssService {
*/
String uploadObject4OSS(String fileUrl, String concat);
+ /**
+ * 根据目录查询目录下的目录列表
+ * @param folder
+ * @return
+ */
+ List listFolders(String folder);
+
+ /**
+ * 根据目录查询目录下的文件
+ * @param folder
+ * @return
+ */
+ List listDocuments(String folder);
+
+ /**
+ * 下载文件返回路径
+ * @param ossFolder
+ * @param localFolder
+ * @return
+ */
+ String download(String ossFolder, String localFolder);
+
}
diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/page/service/impl/OssServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/page/service/impl/OssServiceImpl.java
index 3199fbde..342b5142 100644
--- a/mall-shop/src/main/java/com/suisung/mall/shop/page/service/impl/OssServiceImpl.java
+++ b/mall-shop/src/main/java/com/suisung/mall/shop/page/service/impl/OssServiceImpl.java
@@ -14,9 +14,7 @@ import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
-import com.qcloud.cos.model.CannedAccessControlList;
-import com.qcloud.cos.model.PutObjectRequest;
-import com.qcloud.cos.model.PutObjectResult;
+import com.qcloud.cos.model.*;
import com.qcloud.cos.region.Region;
import com.suisung.mall.common.api.CommonResult;
import com.suisung.mall.common.constant.ConfigConstant;
@@ -49,7 +47,9 @@ import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
+import java.util.stream.Collectors;
/**
* oss上传管理Service实现类
@@ -569,4 +569,49 @@ public class OssServiceImpl implements OssService {
}
}
}
+
+ @Override
+ public List listFolders(String folder) {
+ COSClient ossCli = initCOSClient();
+ ListObjectsRequest listObjectsRequest = new ListObjectsRequest();
+ listObjectsRequest.setBucketName(TENGXUN_BUCKET_NAME);
+ listObjectsRequest.setPrefix(folder);
+ listObjectsRequest.setDelimiter("/");
+ ObjectListing objectListing = ossCli.listObjects(listObjectsRequest);
+ List commonPrefixes = objectListing.getCommonPrefixes();
+ logger.info(JSONUtil.toJsonStr(commonPrefixes));
+ return commonPrefixes;
+ }
+
+ @Override
+ public List listDocuments(String folder) {
+ COSClient ossCli = initCOSClient();
+ ListObjectsRequest listObjectsRequest = new ListObjectsRequest();
+ listObjectsRequest.setBucketName(TENGXUN_BUCKET_NAME);
+ listObjectsRequest.setPrefix(folder);
+ listObjectsRequest.setDelimiter("");
+ ObjectListing objectListing = ossCli.listObjects(listObjectsRequest);
+ List files = objectListing.getObjectSummaries()
+ .stream()
+ // 过滤掉目录(目录通常以 '/' 结尾或大小为0)
+ .filter(obj -> !obj.getKey().endsWith("/") || obj.getSize() > 0)
+ .collect(Collectors.toList());
+ // 获取目录下的文件
+ return files;
+ }
+
+ /**
+ *
+ * @param ossFolder 如folder/example.txt
+ * @param localFolder 如/path/to/local/example.txt
+ * @return
+ */
+ @Override
+ public String download(String ossFolder, String localFolder) {
+ COSClient ossCli = initCOSClient();
+ ossCli.getObject(new GetObjectRequest(TENGXUN_BUCKET_NAME, ossFolder),
+ new File(localFolder));
+ return localFolder;
+ }
+
}
\ No newline at end of file
diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/product/service/ShopProductAssistIndexService.java b/mall-shop/src/main/java/com/suisung/mall/shop/product/service/ShopProductAssistIndexService.java
index 2a81ed24..9cd955f9 100644
--- a/mall-shop/src/main/java/com/suisung/mall/shop/product/service/ShopProductAssistIndexService.java
+++ b/mall-shop/src/main/java/com/suisung/mall/shop/product/service/ShopProductAssistIndexService.java
@@ -3,6 +3,8 @@ package com.suisung.mall.shop.product.service;
import com.suisung.mall.common.modules.product.ShopProductAssistIndex;
import com.suisung.mall.core.web.service.IBaseService;
+import java.util.List;
+
/**
*
* 商品与属性对应表 服务类
@@ -12,5 +14,7 @@ import com.suisung.mall.core.web.service.IBaseService;
* @since 2021-05-19
*/
public interface ShopProductAssistIndexService extends IBaseService {
+ List getShopProductAssistIndexStoreId(Integer storeId);
+ void clearCacheShopProductAssistIndexByStoreId(Integer storeId);
}
diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/product/service/ShopProductBaseService.java b/mall-shop/src/main/java/com/suisung/mall/shop/product/service/ShopProductBaseService.java
index 7f12ca15..43ba5b21 100644
--- a/mall-shop/src/main/java/com/suisung/mall/shop/product/service/ShopProductBaseService.java
+++ b/mall-shop/src/main/java/com/suisung/mall/shop/product/service/ShopProductBaseService.java
@@ -283,4 +283,10 @@ public interface ShopProductBaseService extends IBaseService {
Pair saveProduct(ShopProductBase shopProductBase, ShopProductIndex shopProductIndex, ShopProductData shopProductData, ShopProductDetail shopProductDetail, ShopProductInfo shopProductInfo, List shopProductItemList, List shopProductImageList, ShopProductValidPeriod shopProductValidPeriod, List shopProductAssistIndexList);
+ Pair saveProductBatch(List shopProductBaseList, List shopProductIndexList,
+ List shopProductDataList, List shopProductDetailList,
+ List shopProductInfoList, List> shopProductItemList,
+ List> shopProductImageList,
+ List shopProductValidPeriodList,
+ List shopProductAssistIndexList);
}
diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/product/service/ShopProductImageService.java b/mall-shop/src/main/java/com/suisung/mall/shop/product/service/ShopProductImageService.java
index 03dfccef..04f15e22 100644
--- a/mall-shop/src/main/java/com/suisung/mall/shop/product/service/ShopProductImageService.java
+++ b/mall-shop/src/main/java/com/suisung/mall/shop/product/service/ShopProductImageService.java
@@ -3,6 +3,8 @@ package com.suisung.mall.shop.product.service;
import com.suisung.mall.common.modules.product.ShopProductImage;
import com.suisung.mall.core.web.service.IBaseService;
+import java.util.List;
+
/**
*
* 产品图片表,按照颜色规格 服务类
@@ -13,4 +15,7 @@ import com.suisung.mall.core.web.service.IBaseService;
*/
public interface ShopProductImageService extends IBaseService {
+ List getShopProductImageByStoreId(Integer storeId);
+
+ void clearCacheShopProductImageByStoreId(Integer storeId);
}
diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/product/service/impl/ShopProductAssistIndexServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/product/service/impl/ShopProductAssistIndexServiceImpl.java
index 28a03fbe..3a108074 100644
--- a/mall-shop/src/main/java/com/suisung/mall/shop/product/service/impl/ShopProductAssistIndexServiceImpl.java
+++ b/mall-shop/src/main/java/com/suisung/mall/shop/product/service/impl/ShopProductAssistIndexServiceImpl.java
@@ -1,11 +1,17 @@
package com.suisung.mall.shop.product.service.impl;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.suisung.mall.common.modules.product.ShopProductAssistIndex;
+import com.suisung.mall.core.web.service.RedisService;
import com.suisung.mall.core.web.service.impl.BaseServiceImpl;
import com.suisung.mall.shop.product.mapper.ShopProductAssistIndexMapper;
import com.suisung.mall.shop.product.service.ShopProductAssistIndexService;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
+import java.util.Collections;
+import java.util.List;
+
/**
*
@@ -17,4 +23,24 @@ import org.springframework.stereotype.Service;
*/
@Service
public class ShopProductAssistIndexServiceImpl extends BaseServiceImpl implements ShopProductAssistIndexService {
+
+ @Autowired
+ private RedisService redisService;
+
+ @Override
+ public List getShopProductAssistIndexStoreId(Integer storeId) {
+ List shopProductAssistIndexList= (List) redisService.get("ShopProductAssistIndexStoreId:"+storeId);
+ if(shopProductAssistIndexList==null){
+ QueryWrapper queryWrapper= new QueryWrapper();
+ queryWrapper.eq("store_id",storeId);
+ shopProductAssistIndexList=this.list(queryWrapper);
+ redisService.set("ShopProductAssistIndexStoreId:"+storeId,shopProductAssistIndexList);
+ }
+ return shopProductAssistIndexList;
+ }
+
+ @Override
+ public void clearCacheShopProductAssistIndexByStoreId(Integer storeId) {
+ redisService.del("ShopProductAssistIndexStoreId:"+storeId);
+ }
}
diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/product/service/impl/ShopProductBaseServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/product/service/impl/ShopProductBaseServiceImpl.java
index dcd17f5c..3829658c 100644
--- a/mall-shop/src/main/java/com/suisung/mall/shop/product/service/impl/ShopProductBaseServiceImpl.java
+++ b/mall-shop/src/main/java/com/suisung/mall/shop/product/service/impl/ShopProductBaseServiceImpl.java
@@ -6,6 +6,7 @@ import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.date.StopWatch;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
@@ -15,6 +16,8 @@ import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.mapper.Mapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.suisung.mall.common.api.CommonResult;
@@ -62,14 +65,22 @@ import com.suisung.mall.shop.product.pojo.vo.ProductVo;
import com.suisung.mall.shop.product.service.*;
import com.suisung.mall.shop.sixun.service.SxSyncGoodsService;
import com.suisung.mall.shop.store.service.*;
+import com.suisung.mall.shop.sync.Utils.BatchInsertUtils;
import com.suisung.mall.shop.user.service.*;
import org.apache.commons.lang3.StringUtils;
+import org.apache.ibatis.session.SqlSession;
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac;
+import org.mybatis.spring.SqlSessionFactoryBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.util.Pair;
import org.springframework.stereotype.Service;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.annotation.Transactional;
+import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
@@ -81,7 +92,9 @@ import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadPoolExecutor;
+import java.util.function.Function;
import java.util.stream.Collectors;
import static com.suisung.mall.common.utils.ContextUtil.getCurrentUser;
@@ -195,6 +208,11 @@ public class ShopProductBaseServiceImpl extends BaseServiceImpl saveProduct(ShopProductBase shopProductBase, ShopProductIndex shopProductIndex, ShopProductData shopProductData, ShopProductDetail shopProductDetail, ShopProductInfo shopProductInfo, List shopProductItemList, List shopProductImageList, ShopProductValidPeriod shopProductValidPeriod, List shopProductAssistIndexList) {
+ public synchronized Pair saveProduct(ShopProductBase shopProductBase, ShopProductIndex shopProductIndex, ShopProductData shopProductData, ShopProductDetail shopProductDetail, ShopProductInfo shopProductInfo, List shopProductItemList, List shopProductImageList, ShopProductValidPeriod shopProductValidPeriod, List shopProductAssistIndexList) {
Integer store_id = shopProductBase.getStore_id();
if (store_id == null) {
return Pair.of(false, I18nUtil._("缺少店铺ID!"));
@@ -718,7 +736,7 @@ public class ShopProductBaseServiceImpl extends BaseServiceImpl wrapper, Integer pageNum, Integer pageSize) {
Map map = new HashMap();
- Integer store_id = Convert.toInt(getCurrentUser().getStore_id());
+ Integer store_id = Convert.toInt(getCurrentUser().getStore_id(),1);
Integer nodeid = Convert.toInt(getParameter("nodeid"), 0);
if (CheckUtil.isNotEmpty(nodeid)) {
@@ -5243,4 +5261,835 @@ public class ShopProductBaseServiceImpl extends BaseServiceImpl saveProductBatch(List shopProductBaseList, List shopProductIndexList,
+ List shopProductDataList, List shopProductDetailList,
+ List shopProductInfoList, List> shopProductItemList,
+ List> shopProductImageList, List shopProductValidPeriodList,
+ List shopProductAssistIndexList) {
+
+ // 1. 参数校验
+ if (shopProductBaseList == null || shopProductBaseList.isEmpty()) {
+ return Pair.of(false, "商品列表不能为空");
+ }
+
+ // 2. 检查并设置已存在商品的ID
+ Map existingProducts = checkExistingProducts(shopProductBaseList);
+
+ // 3. 分离新增和更新的商品
+ List newProducts = new ArrayList<>();
+ List updateProducts = new ArrayList<>();
+
+ List newShopProductIndexList = new ArrayList<>();
+ List updateShopProductIndexList = new ArrayList<>();
+
+ List newProductDataList=new ArrayList<>();
+ List updateProductDataList=new ArrayList<>();
+
+ List newShopProductDetailList=new ArrayList<>();
+ List updateShopProductDetailList=new ArrayList<>();
+
+ List newShopProductInfoList=new ArrayList<>();
+ List updateShopProductInfoList=new ArrayList<>();
+
+ List> newShopProductItemList=new ArrayList<>();
+ List> updateShopProductItemList=new ArrayList<>();
+
+ List> newShopProductImageList=new ArrayList<>();
+ List> updateShopProductImageList=new ArrayList<>();
+
+ List newShopProductValidPeriodList=new ArrayList<>();
+ List updateShopProductValidPeriodList=new ArrayList<>();
+
+ List newShopProductAssistIndexList=new ArrayList<>();
+ List updateShopProductAssistIndexList=new ArrayList<>();
+ try {
+ for (int i = 0; i < shopProductBaseList.size(); i++) {
+ ShopProductBase base = shopProductBaseList.get(i);
+ String key = base.getStore_id() + "_" + base.getProduct_number();
+ if (existingProducts.containsKey(key)) {
+
+ // 已存在商品,设置ID并加入更新列表
+ Long existId = existingProducts.get(key);
+ base.setProduct_id(existId);
+
+ shopProductBaseList.get(i).setProduct_id(existId);
+ //shopProductIndexList.get(i).setProduct_id(existId);
+ // shopProductIndexList.get(i).setProduct_unit_points(BigDecimal.ZERO);
+ shopProductIndexList.get(i).setProduct_unit_price_max(base.getProduct_market_price());
+ shopProductIndexList.get(i).setProduct_unit_sp(Convert.toBigDecimal(base.getProduct_unit_sp()));
+ shopProductIndexList.get(i).setProduct_sale_time(base.getProduct_sale_time().getTime());
+ shopProductIndexList.get(i).setProduct_verify_id(base.getProduct_verify_id());
+ shopProductIndexList.get(i).setProduct_state_id(base.getProduct_state_id());
+ // 判断店铺是否开启
+// shopProductIndexList.get(i).setStore_is_open(1);
+// shopProductIndexList.get(i).setStore_is_selfsupport(1);
+// shopProductIndexList.get(i).setStore_type(1);
+// shopProductIndexList.get(i).setSubsite_id(0);
+// shopProductIndexList.get(i).setProduct_number(base.getProduct_number());
+
+// shopProductDataList.get(i).setProduct_id(existId);
+// shopProductDetailList.get(i).setProduct_id(existId);
+// shopProductInfoList.get(i).setProduct_id(existId);
+ if(CollUtil.isNotEmpty(shopProductIndexList)){
+ updateShopProductIndexList.add(shopProductIndexList.get(i));
+ }
+ if(CollUtil.isNotEmpty(shopProductDataList)){
+ updateProductDataList.add(shopProductDataList.get(i));
+ }
+ if(CollUtil.isNotEmpty(shopProductDetailList)){
+ updateShopProductDetailList.add(shopProductDetailList.get(i));
+ }
+ if(CollUtil.isNotEmpty(shopProductInfoList)){
+ updateShopProductInfoList.add(shopProductInfoList.get(i));
+ }
+ if(CollUtil.isNotEmpty(shopProductItemList)){
+ updateShopProductItemList.add(shopProductItemList.get(i));
+ }
+
+ if(CollUtil.isNotEmpty(shopProductImageList)){
+ updateShopProductImageList.add(shopProductImageList.get(i));
+ }
+ if(CollUtil.isNotEmpty(shopProductValidPeriodList)){
+ updateShopProductValidPeriodList.add(shopProductValidPeriodList.get(i));
+ }
+ if(CollUtil.isNotEmpty(shopProductAssistIndexList)){
+ updateShopProductAssistIndexList.add(shopProductAssistIndexList.get(i));
+ }
+
+ updateProducts.add(base);
+
+ } else {
+ base.setProduct_verify_id(StateCode.PRODUCT_VERIFY_PASSED);//审核通过
+ base.setProduct_state_id(StateCode.PRODUCT_STATE_OFF_THE_SHELF);//下架状态
+
+ shopProductIndexList.get(i).setProduct_unit_points(BigDecimal.ZERO);
+ shopProductIndexList.get(i).setProduct_unit_price_max(base.getProduct_market_price());
+ shopProductIndexList.get(i).setProduct_unit_sp(Convert.toBigDecimal(base.getProduct_unit_sp()));
+ shopProductIndexList.get(i).setProduct_sale_time(base.getProduct_sale_time().getTime());
+ shopProductIndexList.get(i).setProduct_verify_id(base.getProduct_verify_id());
+ shopProductIndexList.get(i).setProduct_state_id(base.getProduct_state_id());
+ // 判断店铺是否开启
+ shopProductIndexList.get(i).setStore_is_open(1);
+ shopProductIndexList.get(i).setStore_is_selfsupport(1);
+ shopProductIndexList.get(i).setStore_type(1);
+ shopProductIndexList.get(i).setSubsite_id(0);
+ shopProductIndexList.get(i).setProduct_number(base.getProduct_number());
+
+ if(CollUtil.isNotEmpty(shopProductIndexList)){
+ newShopProductIndexList.add(shopProductIndexList.get(i));
+ }
+ if(CollUtil.isNotEmpty(shopProductDataList)){
+ newProductDataList.add(shopProductDataList.get(i));
+ }
+ if(CollUtil.isNotEmpty(shopProductDetailList)){
+ newShopProductDetailList.add(shopProductDetailList.get(i));
+ }
+ if(CollUtil.isNotEmpty(shopProductInfoList)){
+ newShopProductInfoList.add(shopProductInfoList.get(i));
+ }
+ if(CollUtil.isNotEmpty(shopProductItemList)){
+ newShopProductItemList.add(shopProductItemList.get(i));
+ }
+ if(CollUtil.isNotEmpty(shopProductImageList)){
+ newShopProductImageList.add(shopProductImageList.get(i));
+ }
+ if(CollUtil.isNotEmpty(shopProductValidPeriodList)){
+ newShopProductValidPeriodList.add(shopProductValidPeriodList.get(i));
+ }
+ if(CollUtil.isNotEmpty(shopProductAssistIndexList)){
+ newShopProductAssistIndexList.add(shopProductAssistIndexList.get(i));
+ }
+ // 新商品,加入新增列表
+ newProducts.add(base);
+ }
+
+ }
+ }catch (RuntimeException e){
+ logger.info("异常报错:{}",e.getMessage());
+ }
+
+ return executeBatchOperations(newProducts,updateProducts,newShopProductIndexList,updateShopProductIndexList,
+ newProductDataList,updateProductDataList,newShopProductDetailList,updateShopProductDetailList,
+ newShopProductInfoList,updateShopProductInfoList,newShopProductItemList,updateShopProductItemList,
+ newShopProductImageList,updateShopProductImageList,newShopProductValidPeriodList,updateShopProductValidPeriodList,
+ newShopProductAssistIndexList,updateShopProductAssistIndexList);
+ }
+
+ /**
+ * 执行批量操作(新增和更新分开处理)
+ */
+ private Pair executeBatchOperations(List newProducts, List updateProducts,
+ List newShopProductIndexList,List updateShopProductIndexList,
+ List newShopProductDataList, List updateShopProductDataList,
+ List newShopProductDetailList, List updateShopProductDetailList,
+ List newShopProductInfoList, List updateShopProductInfoList,
+ List> newShopProductItemList,List> udpateShopProductItemList,
+ List> newShopProductImageList, List> udpteShopProductImageList,
+ List newShopProductValidPeriodList, List updateShopProductValidPeriodList,
+ List newShopProductAssistIndexList, List udpateShopProductAssistIndexList
+ ) {
+ TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
+ transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
+ transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
+ transactionTemplate.setTimeout(60); // 60秒超时
+ return transactionTemplate.execute(status -> {
+ try {
+ // Map> productToItemsMap = new HashMap<>();
+ List addAnalyticsList = new ArrayList<>();
+ List udpateAnalyticsList = new ArrayList<>();
+
+ List addItemSeqs = new ArrayList<>();
+ List updateItemSeqs = new ArrayList<>();
+
+ List addItemIds = new ArrayList<>();
+ List udpateItemIds = new ArrayList<>();
+ List addShopProductItems=new ArrayList<>();
+ List updateShopProductItems=new ArrayList<>();
+ int taskCount = 2;
+ CountDownLatch latch = new CountDownLatch(taskCount);
+ // 1. 批量新增
+ if (CollUtil.isNotEmpty(newProducts)) {
+ // 4. 批量生成新商品的ID
+ List newIds = shopNumberSeqService.batchCreateNextNo("product_id", newProducts.size());
+ if (newIds == null || newIds.size() != newProducts.size()) {
+ return Pair.of(false, "生成商品编号异常");
+ }
+ for (int i = 0; i < newIds.size(); i++) {
+ Long productId = newIds.get(i);
+ ShopProductBase base = newProducts.get(i);
+ base.setProduct_id(productId);
+ // 设置关联ID
+ newProducts.get(i).setProduct_id(productId);
+ newShopProductIndexList.get(i).setProduct_id(productId);
+ newShopProductDataList.get(i).setProduct_id(productId);
+ newShopProductDetailList.get(i).setProduct_id(productId);
+ newShopProductInfoList.get(i).setProduct_id(productId);
+
+ // 处理商品项
+ List items = newShopProductItemList.get(i);
+ processProductItems(items, productId, addItemSeqs);
+ addShopProductItems.addAll(items);
+
+ // 处理图片
+ if(CollUtil.isNotEmpty(newShopProductImageList)){
+ processProductImages(newShopProductImageList.get(i), productId,base.getStore_id());
+ }
+
+ // 处理辅助属性
+ if(CollUtil.isNotEmpty(newShopProductAssistIndexList)){
+ processAssistIndices(newShopProductAssistIndexList, base.getStore_id(),false);
+ }
+
+ // 准备分析数据
+ ShopProductAnalytics shopProductAnalytics= new ShopProductAnalytics();
+ shopProductAnalytics.setProduct_id(productId);
+ shopProductAnalytics.setProduct_click(0);
+ addAnalyticsList.add(shopProductAnalytics);
+ }
+ List itemIds = processProductItemsId(addShopProductItems, addItemSeqs);
+ addItemIds.addAll(itemIds);
+ // 2. 批量更新
+ if (CollUtil.isNotEmpty(newProducts)) {
+ // new Thread(() -> {
+ logger.info("保存任务开始执行");
+ try {
+ long startTime=System.nanoTime();
+ saveBatch(newProducts,newProducts.size());
+ long endTime = System.nanoTime();
+ long duration = (endTime - startTime);
+ logger.info("新增newProducts--{}条数据耗时:{}",newProducts.size(),duration/1000000000);
+ latch.countDown();
+ } catch (Exception e) {
+ latch.countDown();
+ logger.error("系统异常"+e.getMessage());
+ }
+ // }).start();
+ }else{
+ // latch.countDown();
+ }
+ }else {
+ //latch.countDown();
+ }
+ if (CollUtil.isNotEmpty(updateProducts)) {
+ for(int i=0;i items = udpateShopProductItemList.get(i);
+ processProductItems(items, productId, updateItemSeqs);//
+ updateShopProductItems.addAll(items);
+ //allItemIds.addAll(itemIds);
+ // productToItemsMap.put(productId, itemIds);
+
+ // 处理图片
+ if(CollUtil.isNotEmpty(udpteShopProductImageList)){
+ processProductImages(udpteShopProductImageList.get(i), productId,base.getStore_id());
+ }
+
+ // 处理辅助属性
+ if(CollUtil.isNotEmpty(udpateShopProductAssistIndexList)){
+ processAssistIndices(udpateShopProductAssistIndexList, base.getStore_id(),true);
+ }
+
+ // 准备分析数据
+ ShopProductAnalytics shopProductAnalytics= new ShopProductAnalytics();
+ shopProductAnalytics.setProduct_id(productId);
+ shopProductAnalytics.setProduct_click(0);
+ udpateAnalyticsList.add(shopProductAnalytics);
+ }
+ List itemIds = processProductItemsId(updateShopProductItems, updateItemSeqs);
+ udpateItemIds.addAll(itemIds);
+ // 2. 批量更新
+ if (CollUtil.isNotEmpty(updateProducts)) {
+ // new Thread(() -> {
+ logger.info("更新任务开始执行");
+ try {
+ long startTime=System.nanoTime();
+ updateBatchById(updateProducts);
+ long endTime = System.nanoTime();
+ long duration = (endTime - startTime);
+ logger.info("更新updateProducts-{}条数据耗时:{}",updateProducts.size(),duration/1000000000);
+ latch.countDown();
+ } catch (Exception e) {
+ latch.countDown();
+ logger.error("系统异常"+e.getMessage());
+ }
+ // }).start();
+ }else {
+ //latch.countDown();
+ }
+ }else {
+ // latch.countDown();
+ }
+ // latch.await();
+ // 3. 处理其他表的批量操作(同样需要区分新增和更新)
+ batchProcessOtherTables(newShopProductIndexList,updateShopProductIndexList,newShopProductDataList,updateShopProductDataList,
+ newShopProductDetailList,updateShopProductDetailList,newShopProductInfoList,updateShopProductInfoList,
+ newShopProductValidPeriodList,updateShopProductValidPeriodList,addShopProductItems,updateShopProductItems,
+ addAnalyticsList,udpateAnalyticsList,addItemSeqs,updateItemSeqs);
+ logger.info("处理成功,新增{}条,更新{}条", newProducts.size(), updateProducts.size());
+ return Pair.of(true, String.format("处理成功,新增%d条,更新%d条",
+ newProducts.size(), updateProducts.size()));
+ } catch (RuntimeException e) {
+ status.setRollbackOnly();
+ logger.error("批量操作异常", e);
+ return Pair.of(false, "批量操作异常: " + e.getMessage());
+ }
+// catch (InterruptedException e) {
+// status.setRollbackOnly();
+// logger.error("批量操作异常", e);
+// return Pair.of(false, "批量操作异常: " + e.getMessage());
+// }
+ });
+
+
+ }
+
+ // 批量保存操作
+ private void batchProcessOtherTables(List newShopProductIndex, List updateShopProductIndex,
+ List newShopProductDataList, List updateShopProductDataList,
+ List newshopProductDetailList, List updateShopProductDetailList,
+ List newShopProductInfoList,List updateShopProductInfoList,
+ List newShopProductValidPeriodList,List updateShopProductValidPeriodList,
+ List newshopProductItemList,List updateshopProductItemList,
+ List newShopProductAnalyticList,List updateShopProductAnalyticList,
+ List newShopProductItemSeqList,List updateShopProductItemSeqList) {
+ TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
+ transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
+ transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
+ transactionTemplate.setTimeout(60); // 60秒超时
+ transactionTemplate.execute(status -> {
+ // 并行执行批量保存
+//CompletableFuture future1 = CompletableFuture.runAsync(() -> {
+ try {
+ if (CollUtil.isNotEmpty(newShopProductIndex)) {
+ // synchronized (this){
+ long startTime=System.nanoTime();
+ shopProductIndexService.saveBatch(newShopProductIndex,newShopProductIndex.size());
+ long endTime = System.nanoTime();
+ long duration = (endTime - startTime);
+ logger.info("新增newShopProductIndex-{}条数据耗时:{}",newShopProductIndex.size(),duration/1000000000);
+
+ //}
+
+ }
+ if (CollUtil.isNotEmpty(updateShopProductIndex)) {
+ // synchronized (this) {
+ long startTime=System.nanoTime();
+ shopProductIndexService.updateBatchById(updateShopProductIndex);
+ long endTime = System.nanoTime();
+ long duration = (endTime - startTime);
+ logger.info("更新updateShopProductIndex-{}条数据耗时:{}",updateShopProductIndex.size(),duration/1000000000);
+ // }
+ }
+
+ if (CollUtil.isNotEmpty(newShopProductDataList)) {
+ //synchronized (this) {
+ long startTime=System.nanoTime();
+ shopProductDataService.saveBatch(newShopProductDataList, newShopProductDataList.size());
+ long endTime = System.nanoTime();
+ long duration = (endTime - startTime);
+ logger.info("新增newShopProductDataList-{}条数据耗时:{}",newShopProductDataList.size(),duration/1000000000);
+ //}
+ }
+ if (CollUtil.isNotEmpty(updateShopProductDataList)) {
+ // synchronized (this) {
+ long startTime=System.nanoTime();
+ shopProductDataService.updateBatchById(updateShopProductDataList);
+ long endTime = System.nanoTime();
+ long duration = (endTime - startTime);
+ logger.info("更新updateShopProductDataList-{}条数据耗时:{}",updateShopProductDataList.size(),duration/1000000000);
+ // }
+ }
+ }catch (RuntimeException e){
+ logger.info("批量报错附表失败{}",e.getMessage());
+ }
+
+ // });
+
+ // CompletableFuture future2 = CompletableFuture.runAsync(() -> {
+ try {
+ if (CollUtil.isNotEmpty(newshopProductDetailList)) {
+ // synchronized (this) {
+ long startTime=System.nanoTime();
+ shopProductDetailService.saveBatch(newshopProductDetailList, newshopProductDetailList.size());
+ long endTime = System.nanoTime();
+ long duration = (endTime - startTime);
+ logger.info("新增newshopProductDetailList-{}条数据耗时:{}",newshopProductDetailList.size(),duration/1000000000);
+
+ // }
+ }
+ if (CollUtil.isNotEmpty(updateShopProductDetailList)) {
+ // synchronized (this) {
+ long startTime=System.nanoTime();
+ shopProductDetailService.updateBatchById(updateShopProductDetailList);
+ long endTime = System.nanoTime();
+ long duration = (endTime - startTime);
+ logger.info("更新updateShopProductDetailList-{}条数据耗时:{}",updateShopProductDetailList.size(),duration/1000000000);
+ // }
+ }
+ if (CollUtil.isNotEmpty(newShopProductInfoList)) {
+ // synchronized (this) {
+ long startTime=System.nanoTime();
+ shopProductInfoService.saveBatch(newShopProductInfoList, newShopProductInfoList.size());
+ long endTime = System.nanoTime();
+ long duration = (endTime - startTime);
+ logger.info("新增updateShopProductDetailList-{}条数据耗时:{}",newShopProductInfoList.size(),duration/1000000000);
+ // }
+ }
+ if (CollUtil.isNotEmpty(updateShopProductInfoList)) {
+ // synchronized (this) {
+ long startTime=System.nanoTime();
+ shopProductInfoService.updateBatchById(updateShopProductInfoList);
+ long endTime = System.nanoTime();
+ long duration = (endTime - startTime);
+ logger.info("更新updateShopProductInfoList-{}条数据耗时:{}",updateShopProductInfoList.size(),duration/1000000000);
+ // }
+ }
+ }catch (RuntimeException e){
+ logger.info("批量报错附表失败{}",e.getMessage());
+ }
+ //});
+
+ //CompletableFuture future3 = CompletableFuture.runAsync(() -> {
+ try {
+ if (CollUtil.isNotEmpty(newShopProductValidPeriodList)) {
+ // synchronized (this) {
+ long startTime=System.nanoTime();
+ validPeriodService.saveBatch(newShopProductValidPeriodList, newShopProductValidPeriodList.size());
+ long endTime = System.nanoTime();
+ long duration = (endTime - startTime);
+ logger.info("新增newShopProductValidPeriodList-{}条数据耗时:{}",newShopProductValidPeriodList.size(),duration/1000000000);
+ // }
+ }
+ if (CollUtil.isNotEmpty(updateShopProductValidPeriodList)) {
+ //synchronized (this) {
+ long startTime=System.nanoTime();
+ validPeriodService.updateBatchById(updateShopProductValidPeriodList);
+ long endTime = System.nanoTime();
+ long duration = (endTime - startTime);
+ logger.info("更新updateShopProductValidPeriodList-{}条数据耗时:{}",updateShopProductValidPeriodList.size(),duration/1000000000);
+ // }
+ }
+ if (CollUtil.isNotEmpty(newShopProductAnalyticList)) {
+ // synchronized (this) {
+ long startTime=System.nanoTime();
+ shopProductAnalyticsService.saveBatch(newShopProductAnalyticList, newShopProductAnalyticList.size());
+ long endTime = System.nanoTime();
+ long duration = (endTime - startTime);
+ logger.info("新增newShopProductAnalyticList-{}条数据耗时:{}",newShopProductAnalyticList.size(),duration/1000000000);
+ // }
+ }
+ if (CollUtil.isNotEmpty(updateShopProductAnalyticList)) {
+ // synchronized (this) {
+ long startTime=System.nanoTime();
+ shopProductAnalyticsService.updateBatchById(updateShopProductAnalyticList);
+ long endTime = System.nanoTime();
+ long duration = (endTime - startTime);
+ logger.info("更新updateShopProductAnalyticList-{}条数据耗时:{}",updateShopProductAnalyticList.size(),duration/1000000000);
+ // }
+ }
+ }catch (RuntimeException e){
+ logger.info("批量报错附表失败{}",e.getMessage());
+ }
+
+ //});
+
+ //CompletableFuture future4 = CompletableFuture.runAsync(() -> {
+ try {
+ if (CollUtil.isNotEmpty(newshopProductItemList)) {
+ // synchronized (this) {
+ long startTime=System.nanoTime();
+ shopProductItemService.saveBatch(newshopProductItemList, newshopProductItemList.size());
+ long endTime = System.nanoTime();
+ long duration = (endTime - startTime);
+ logger.info("新增newshopProductItemList-{}条数据耗时:{}",newshopProductItemList.size(),duration/1000000000);
+ //}
+ }
+ if (CollUtil.isNotEmpty(updateshopProductItemList)) {
+ // synchronized (this) {
+ long startTime = System.nanoTime();
+ shopProductItemService.updateBatchById(updateshopProductItemList);
+ long endTime = System.nanoTime();
+ long duration = (endTime - startTime);
+ logger.info("更新updateshopProductItemList-{}条数据耗时:{}",updateshopProductItemList.size(),duration/1000000000);
+ //}
+ }
+ if (CollUtil.isNotEmpty(newShopProductItemSeqList)) {
+ // synchronized (this) {
+ long startTime = System.nanoTime();
+ shopProductItemSeqService.saveBatch(newShopProductItemSeqList, newShopProductItemSeqList.size());
+ long endTime = System.nanoTime();
+ long duration = (endTime - startTime);
+ logger.info("新曾newShopProductItemSeqList-{}条数据耗时:{}",newShopProductItemSeqList.size(),duration/1000000000);
+ // }
+ }
+ if (CollUtil.isNotEmpty(updateShopProductItemSeqList)) {
+ // synchronized (this) {
+ long startTime = System.nanoTime();
+ shopProductItemSeqService.updateBatchById(updateShopProductItemSeqList);
+ long endTime = System.nanoTime();
+ long duration = (endTime - startTime);
+ logger.info("更新updateShopProductItemSeqList-{}条数据耗时:{}",updateShopProductItemSeqList.size(),duration/1000000000);
+ // }
+ }
+ }catch (RuntimeException e){
+ logger.info("批量报错附表失败{}",e.getMessage());
+ }
+ //});
+ // 等待所有操作完成
+ // CompletableFuture.allOf(future1, future2, future3, future4).join();
+ return null;
+ });
+
+ }
+
+ /**
+ * 批量生产itemid
+ * @param items
+ * @param itemSeqs
+ * @return
+ */
+ private List processProductItemsId(List items,List itemSeqs){
+ List itemIds = new ArrayList<>();
+ if (CollUtil.isEmpty(items)) return itemIds;
+ List generatedIds = shopNumberSeqService.batchCreateNextNo("item_id", items.size());
+ for (int i = 0; i < items.size(); i++) {
+ Long itemId = generatedIds.get(i);
+ ShopProductItem item = items.get(i);
+ item.setItem_id(itemId);
+ itemIds.add(itemId);
+ ShopProductItemSeq field_row= itemSeqs.get(i);
+ field_row.setItem_id(itemId);
+
+ }
+
+ return itemIds;
+ }
+
+ // 处理商品项
+ private void processProductItems(List items, Long productId,
+ List itemSeqs) {
+
+ for (int i = 0; i < items.size(); i++) {
+ ShopProductItem item = items.get(i);
+ item.setProduct_id(productId);
+ // itemIds.add(itemId);
+
+ // ITEM_ID/SKU唯一编号表。
+ // product_id + sort(spec_item_id) = 构造唯一ITEM ID
+ String item_spec = item.getItem_spec();
+ cn.hutool.json.JSONArray array_item_spec = cn.hutool.json.JSONUtil.parseArray(item_spec);
+ List spec_item_ids = new ArrayList<>();
+ List item_names = new ArrayList<>();
+ for (Object josn_item_spec : array_item_spec) {
+ cn.hutool.json.JSONObject itemJ = (cn.hutool.json.JSONObject) ((cn.hutool.json.JSONObject) josn_item_spec).get("item");
+ Integer id = Convert.toInt(itemJ.get("id"));
+ String name = Convert.toStr(itemJ.get("name"));
+ if (ObjectUtil.isNotNull(id)) spec_item_ids.add(id);
+ item_names.add(name);
+ }
+
+ if (CollUtil.isNotEmpty(spec_item_ids)) Collections.sort(spec_item_ids);
+
+ //用来判断是否使用
+ item.setSpec_item_ids(CollUtil.join(spec_item_ids, ","));
+
+ // 创建itemSeq记录
+ String skuUniqid = generateSkuUniqid(item); // 生成SKU唯一标识
+ String seqVal = productId + ":" + skuUniqid;
+ ShopProductItemSeq field_row = new ShopProductItemSeq();
+ field_row.setProduct_id(productId);
+ field_row.setProduct_item_seq_val(seqVal);
+ field_row.setProduct_item_seq_id(SecureUtil.md5(seqVal));
+ //field_row.setItem_id(itemId);
+
+ // 修正默认价格, 防止出现不合理价格
+ BigDecimal item_platform_price = NumberUtil.max(item.getItem_cost_price(), item.getItem_platform_price());
+ BigDecimal _item_unit_price = NumberUtil.max(item.getItem_unit_price(), item.getItem_platform_price());
+ item.setItem_platform_price(item_platform_price);
+ item.setItem_unit_price(_item_unit_price);
+ item.setItem_name(CollUtil.join(item_names, ","));
+ item.setItem_title("");
+ item.setItem_freetime(0);
+
+ itemSeqs.add(field_row);
+ }
+ }
+
+ /**
+ * 生成SKU唯一标识符
+ * @param item 商品项
+ * @return SKU唯一标识字符串
+ */
+ private String generateSkuUniqid(ShopProductItem item) {
+ // 1. 获取商品规格信息
+ String itemSpec = item.getItem_spec();
+ if (StrUtil.isBlank(itemSpec)) {
+ return "default"; // 无规格商品的默认标识
+ }
+
+ // 2. 解析规格JSON
+ cn.hutool.json.JSONArray specArray;
+ try {
+ specArray = JSONUtil.parseArray(itemSpec);
+ } catch (Exception e) {
+ logger.warn("商品规格解析失败,使用默认标识", e);
+ return "default";
+ }
+
+ // 3. 提取所有规格项ID并排序
+ List specItemIds = new ArrayList<>();
+ for (Object specObj : specArray) {
+ JSONObject spec = (JSONObject) specObj;
+ JSONObject specItem = spec.getJSONObject("item");
+ if (specItem != null) {
+ Integer id = specItem.getInteger("id");
+ if (id != null) {
+ specItemIds.add(id);
+ }
+ }
+ }
+
+ // 4. 排序确保顺序一致性
+ Collections.sort(specItemIds);
+
+ // 5. 生成唯一标识字符串
+ return CollUtil.join(specItemIds, "-");
+ }
+
+
+
+ /**
+ * 检查哪些商品已存在
+ */
+ private Map checkExistingProducts(List productBases) {
+ // 1. 按店铺和货号分组
+ Map> storeProductMap = productBases.stream()
+ .collect(Collectors.groupingBy(
+ p -> p.getStore_id() + "_" + p.getProduct_number()
+ ));
+
+ // 2. 批量查询已存在的商品
+ List> storeProductPairs = productBases.stream()
+ .map(p -> Pair.of(p.getStore_id(), p.getProduct_number()))
+ .distinct()
+ .collect(Collectors.toList());
+
+ // 3. 批量查询(优化为一次查询)
+ List existing = batchGetByStoreAndProductNumber(storeProductPairs,productBases.get(0).getStore_id());
+
+ // 4. 构建存在商品的映射表
+ return existing.stream()
+ .collect(Collectors.toMap(
+ p -> p.getStore_id() + "_" + p.getProduct_number(),
+ ShopProductBase::getProduct_id
+ ));
+ }
+
+
+ /**
+ * 批量根据店铺和货号查询商品
+ */
+ private List batchGetByStoreAndProductNumber(List> storeProductPairs,Integer storeId) {
+ if (CollUtil.isEmpty(storeProductPairs)) {
+ return Collections.emptyList();
+ }
+
+ // 使用IN查询优化(根据数据库特性可能需要分批)
+ QueryWrapper query = new QueryWrapper<>();
+ query.select("product_id", "store_id", "product_number");
+
+ // 构建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_number", pair.getSecond()));
+ });
+
+ return list(query);
+ }
+
+
+ /**
+ * 处理商品图片批量操作
+ * @param productImages 商品图片列表
+ * @param productId 商品ID
+ */
+ private void processProductImages(List productImages, Long productId, Integer storeId) {
+ if (CollUtil.isEmpty(productImages)) {
+ return;
+ }
+
+ // 1. 查询现有图片
+ List existingImages = shopProductImageService.getShopProductImageByStoreId(storeId);
+ Map existingImageMap = existingImages.stream()
+ .collect(Collectors.toMap(ShopProductImage::getProduct_image_id, Function.identity()));
+
+ // 2. 分离需要新增、更新和删除的图片
+ List toAdd = new ArrayList<>();
+ List