双向同步库存计算
This commit is contained in:
parent
3d8999d51e
commit
19d97f6829
@ -5497,7 +5497,10 @@ public class ShopProductBaseServiceImpl extends BaseServiceImpl<ShopProductBaseM
|
|||||||
// 1. 批量新增
|
// 1. 批量新增
|
||||||
if (CollUtil.isNotEmpty(newProducts)) {
|
if (CollUtil.isNotEmpty(newProducts)) {
|
||||||
// 4. 批量生成新商品的ID
|
// 4. 批量生成新商品的ID
|
||||||
List<Long> newIds = shopNumberSeqService.batchCreateNextNo("product_id", newProducts.size());
|
List<Long> newIds=new ArrayList<>();
|
||||||
|
synchronized (this){
|
||||||
|
newIds = shopNumberSeqService.batchCreateNextNo("product_id", newProducts.size());
|
||||||
|
}
|
||||||
if (newIds == null || newIds.size() != newProducts.size()) {
|
if (newIds == null || newIds.size() != newProducts.size()) {
|
||||||
return Pair.of(false, "生成商品编号异常");
|
return Pair.of(false, "生成商品编号异常");
|
||||||
}
|
}
|
||||||
@ -5565,6 +5568,7 @@ public class ShopProductBaseServiceImpl extends BaseServiceImpl<ShopProductBaseM
|
|||||||
//计算规格
|
//计算规格
|
||||||
if (existingProducts.get(productId) != null) {
|
if (existingProducts.get(productId) != null) {
|
||||||
udpateShopProductItemList.get(i).get(0).setItem_id(existingProducts.get(productId));
|
udpateShopProductItemList.get(i).get(0).setItem_id(existingProducts.get(productId));
|
||||||
|
udpateShopProductItemList.get(i).get(0).setItem_src_id(String.valueOf(existingProducts.get(productId)));
|
||||||
udpateItemIds.add(existingProducts.get(productId));
|
udpateItemIds.add(existingProducts.get(productId));
|
||||||
}
|
}
|
||||||
// 处理商品项
|
// 处理商品项
|
||||||
@ -5916,12 +5920,16 @@ public class ShopProductBaseServiceImpl extends BaseServiceImpl<ShopProductBaseM
|
|||||||
List<ShopProductInfo> newShopProductInfoList) {
|
List<ShopProductInfo> newShopProductInfoList) {
|
||||||
List<Serializable> itemIds = new ArrayList<>();
|
List<Serializable> itemIds = new ArrayList<>();
|
||||||
if (CollUtil.isEmpty(items)) return itemIds;
|
if (CollUtil.isEmpty(items)) return itemIds;
|
||||||
List<Long> generatedIds = shopNumberSeqService.batchCreateNextNo("item_id", items.size());
|
List<Long> generatedIds =new ArrayList<>();
|
||||||
|
synchronized (this){
|
||||||
|
generatedIds = shopNumberSeqService.batchCreateNextNo("item_id", items.size());
|
||||||
|
}
|
||||||
// Map<String,String> cacheMap=new HashMap<>();
|
// Map<String,String> cacheMap=new HashMap<>();
|
||||||
for (int i = 0; i < items.size(); i++) {
|
for (int i = 0; i < items.size(); i++) {
|
||||||
Long itemId = generatedIds.get(i);
|
Long itemId = generatedIds.get(i);
|
||||||
ShopProductItem item = items.get(i);
|
ShopProductItem item = items.get(i);
|
||||||
item.setItem_id(itemId);
|
item.setItem_id(itemId);
|
||||||
|
item.setItem_src_id(String.valueOf(itemId));
|
||||||
// if(StringUtils.isNotEmpty(item.getItem_spec())){
|
// if(StringUtils.isNotEmpty(item.getItem_spec())){
|
||||||
// String product_uniqid=ShopJsonUtils.generateJsonWithOrgJson(item.getSpec_item_ids(),new Object[]{itemId,item.getItem_unit_price(),"",1002});
|
// String product_uniqid=ShopJsonUtils.generateJsonWithOrgJson(item.getSpec_item_ids(),new Object[]{itemId,item.getItem_unit_price(),"",1002});
|
||||||
// cacheMap.put(item.getProductName(),product_uniqid);
|
// cacheMap.put(item.getProductName(),product_uniqid);
|
||||||
|
|||||||
@ -122,7 +122,7 @@ public interface SyncThirdDataService {
|
|||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
Map<String, Integer> getProductStockFromRedis();
|
Map<String, Double> getProductStockFromRedis();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 下单或支付后,批量累加减商品库存,使用 Redis Hash 的原子自增操作,保证并发安全
|
* 下单或支付后,批量累加减商品库存,使用 Redis Hash 的原子自增操作,保证并发安全
|
||||||
|
|||||||
@ -35,7 +35,9 @@ import com.suisung.mall.common.feignService.SearchService;
|
|||||||
import com.suisung.mall.common.modules.account.AccountUserBase;
|
import com.suisung.mall.common.modules.account.AccountUserBase;
|
||||||
import com.suisung.mall.common.modules.base.ShopBaseProductBrand;
|
import com.suisung.mall.common.modules.base.ShopBaseProductBrand;
|
||||||
import com.suisung.mall.common.modules.base.ShopBaseProductCategory;
|
import com.suisung.mall.common.modules.base.ShopBaseProductCategory;
|
||||||
|
import com.suisung.mall.common.modules.product.ShopProductBase;
|
||||||
import com.suisung.mall.common.modules.product.ShopProductIndex;
|
import com.suisung.mall.common.modules.product.ShopProductIndex;
|
||||||
|
import com.suisung.mall.common.modules.product.ShopProductItem;
|
||||||
import com.suisung.mall.common.modules.sixun.SxSyncGoods;
|
import com.suisung.mall.common.modules.sixun.SxSyncGoods;
|
||||||
import com.suisung.mall.common.modules.sixun.SxSyncVip;
|
import com.suisung.mall.common.modules.sixun.SxSyncVip;
|
||||||
import com.suisung.mall.common.modules.store.ShopStoreActivityBase;
|
import com.suisung.mall.common.modules.store.ShopStoreActivityBase;
|
||||||
@ -50,13 +52,11 @@ import com.suisung.mall.common.utils.I18nUtil;
|
|||||||
import com.suisung.mall.common.utils.StringUtils;
|
import com.suisung.mall.common.utils.StringUtils;
|
||||||
import com.suisung.mall.shop.base.service.ShopBaseProductBrandService;
|
import com.suisung.mall.shop.base.service.ShopBaseProductBrandService;
|
||||||
import com.suisung.mall.shop.base.service.ShopBaseProductCategoryService;
|
import com.suisung.mall.shop.base.service.ShopBaseProductCategoryService;
|
||||||
import com.suisung.mall.shop.base.service.ShopBaseProductSpecService;
|
|
||||||
import com.suisung.mall.shop.number.service.ShopNumberSeqService;
|
import com.suisung.mall.shop.number.service.ShopNumberSeqService;
|
||||||
import com.suisung.mall.shop.page.service.OssService;
|
import com.suisung.mall.shop.page.service.OssService;
|
||||||
import com.suisung.mall.shop.product.service.ShopProductBaseService;
|
import com.suisung.mall.shop.product.service.ShopProductBaseService;
|
||||||
import com.suisung.mall.shop.product.service.ShopProductIndexService;
|
import com.suisung.mall.shop.product.service.ShopProductIndexService;
|
||||||
import com.suisung.mall.shop.product.service.ShopProductItemService;
|
import com.suisung.mall.shop.product.service.ShopProductItemService;
|
||||||
import com.suisung.mall.shop.product.service.ShopProductSpecItemService;
|
|
||||||
import com.suisung.mall.shop.sixun.dao.SxDataDao;
|
import com.suisung.mall.shop.sixun.dao.SxDataDao;
|
||||||
import com.suisung.mall.shop.sixun.dto.DataBaseInfo;
|
import com.suisung.mall.shop.sixun.dto.DataBaseInfo;
|
||||||
import com.suisung.mall.shop.sixun.dto.SxCategoryModel;
|
import com.suisung.mall.shop.sixun.dto.SxCategoryModel;
|
||||||
@ -788,7 +788,7 @@ public class SyncThirdDataServiceImpl extends SyncBaseThirdSxAbstract implements
|
|||||||
// storeDataResultMap = sme.stream().filter(m -> !(m.getValue().equals((double) 0))).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
// storeDataResultMap = sme.stream().filter(m -> !(m.getValue().equals((double) 0))).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||||
// }
|
// }
|
||||||
|
|
||||||
Map<String, Integer> storeDataResultMap = getProductStockFromRedis();
|
Map<String, Double> storeDataResultMap = getProductStockFromRedis();
|
||||||
|
|
||||||
return new ThirdApiRes().success("success", storeDataResultMap);
|
return new ThirdApiRes().success("success", storeDataResultMap);
|
||||||
}
|
}
|
||||||
@ -812,7 +812,7 @@ public class SyncThirdDataServiceImpl extends SyncBaseThirdSxAbstract implements
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Integer> getProductStockFromRedis() {
|
public Map<String, Double> getProductStockFromRedis() {
|
||||||
try {
|
try {
|
||||||
// 从 Redis 获取 hash 结构的所有键值对
|
// 从 Redis 获取 hash 结构的所有键值对
|
||||||
Map<Object, Object> redisHash = redisTemplate.opsForHash().entries(RedisKey.STOREDATARELEASE);
|
Map<Object, Object> redisHash = redisTemplate.opsForHash().entries(RedisKey.STOREDATARELEASE);
|
||||||
@ -823,7 +823,7 @@ public class SyncThirdDataServiceImpl extends SyncBaseThirdSxAbstract implements
|
|||||||
return redisHash.entrySet().stream()
|
return redisHash.entrySet().stream()
|
||||||
.collect(Collectors.toMap(
|
.collect(Collectors.toMap(
|
||||||
entry -> String.valueOf(entry.getKey()),
|
entry -> String.valueOf(entry.getKey()),
|
||||||
entry -> Convert.toInt(entry.getValue(), 0) // 转换失败时默认为 0
|
entry -> Convert.toDouble(entry.getValue(), 0.00) // 转换失败时默认为 0
|
||||||
));
|
));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error("从 Redis 获取商品库存失败: {}", e.getMessage(), e);
|
logger.error("从 Redis 获取商品库存失败: {}", e.getMessage(), e);
|
||||||
@ -845,14 +845,53 @@ public class SyncThirdDataServiceImpl extends SyncBaseThirdSxAbstract implements
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
QueryWrapper<ShopProductItem> queryWrapper = new QueryWrapper<>();
|
||||||
|
queryWrapper.eq("item_src_id", productKey);
|
||||||
|
List<ShopProductItem> shopProductItems=shopProductItemService.list(queryWrapper);
|
||||||
|
if(shopProductItems==null || shopProductItems.isEmpty()){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ShopProductItem spuItem = shopProductItems.get(0);
|
||||||
|
cn.hutool.json.JSONArray array_item_spec= JSONUtil.parseArray(spuItem.getItem_spec());
|
||||||
|
if(array_item_spec.isEmpty()){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
cn.hutool.json.JSONObject item = (cn.hutool.json.JSONObject) ((cn.hutool.json.JSONObject) array_item_spec.get(0)).get("item");
|
||||||
|
String name = Convert.toStr(item.get("name"));
|
||||||
|
BigDecimal itemQuaryty = getBigDecimal(delta, name);
|
||||||
|
Long productId = spuItem.getProduct_id();
|
||||||
|
ShopProductBase productBase = shopProductBaseService.get(productId);
|
||||||
|
if(productBase==null){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String itemId=productBase.getProduct_number();
|
||||||
// 使用 Redis 的 HINCRBY 保证原子性和高性能
|
// 使用 Redis 的 HINCRBY 保证原子性和高性能
|
||||||
redisTemplate.opsForHash().increment(RedisKey.STOREDATARELEASE, productKey, delta);
|
redisTemplate.opsForHash().increment(RedisKey.STOREDATARELEASE, itemId, itemQuaryty.doubleValue());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error("库存累计失败,productKey={}, delta={}, error={}", productKey, delta, e.getMessage(), e);
|
logger.error("库存累计失败,productKey={}, delta={}, error={}", productKey, delta, e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算最终数量 如果是g转换为kg,如果是数量就是直接值
|
||||||
|
* @param delta
|
||||||
|
* @param name
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private static BigDecimal getBigDecimal(Integer delta, String name) {
|
||||||
|
BigDecimal itemQuaryty = new BigDecimal(delta);
|
||||||
|
if(name.contains("kg")){
|
||||||
|
String weightStr= name.split("kg")[0];
|
||||||
|
itemQuaryty=new BigDecimal(weightStr).multiply(new BigDecimal(delta));
|
||||||
|
}
|
||||||
|
if(name.contains("g")){
|
||||||
|
String weightStr= name.split("g")[0];
|
||||||
|
itemQuaryty=new BigDecimal(weightStr).multiply(new BigDecimal(delta)).divide(new BigDecimal(1000),4,RoundingMode.HALF_UP);
|
||||||
|
}
|
||||||
|
return itemQuaryty;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 压缩商家数据,并上传cos
|
* 压缩商家数据,并上传cos
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user