双向同步库存计算
This commit is contained in:
parent
3d8999d51e
commit
19d97f6829
@ -5497,7 +5497,10 @@ public class ShopProductBaseServiceImpl extends BaseServiceImpl<ShopProductBaseM
|
||||
// 1. 批量新增
|
||||
if (CollUtil.isNotEmpty(newProducts)) {
|
||||
// 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()) {
|
||||
return Pair.of(false, "生成商品编号异常");
|
||||
}
|
||||
@ -5565,6 +5568,7 @@ public class ShopProductBaseServiceImpl extends BaseServiceImpl<ShopProductBaseM
|
||||
//计算规格
|
||||
if (existingProducts.get(productId) != null) {
|
||||
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));
|
||||
}
|
||||
// 处理商品项
|
||||
@ -5916,12 +5920,16 @@ public class ShopProductBaseServiceImpl extends BaseServiceImpl<ShopProductBaseM
|
||||
List<ShopProductInfo> newShopProductInfoList) {
|
||||
List<Serializable> itemIds = new ArrayList<>();
|
||||
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<>();
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
Long itemId = generatedIds.get(i);
|
||||
ShopProductItem item = items.get(i);
|
||||
item.setItem_id(itemId);
|
||||
item.setItem_src_id(String.valueOf(itemId));
|
||||
// if(StringUtils.isNotEmpty(item.getItem_spec())){
|
||||
// String product_uniqid=ShopJsonUtils.generateJsonWithOrgJson(item.getSpec_item_ids(),new Object[]{itemId,item.getItem_unit_price(),"",1002});
|
||||
// cacheMap.put(item.getProductName(),product_uniqid);
|
||||
|
||||
@ -122,7 +122,7 @@ public interface SyncThirdDataService {
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Map<String, Integer> getProductStockFromRedis();
|
||||
Map<String, Double> getProductStockFromRedis();
|
||||
|
||||
/**
|
||||
* 下单或支付后,批量累加减商品库存,使用 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.base.ShopBaseProductBrand;
|
||||
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.ShopProductItem;
|
||||
import com.suisung.mall.common.modules.sixun.SxSyncGoods;
|
||||
import com.suisung.mall.common.modules.sixun.SxSyncVip;
|
||||
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.shop.base.service.ShopBaseProductBrandService;
|
||||
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.page.service.OssService;
|
||||
import com.suisung.mall.shop.product.service.ShopProductBaseService;
|
||||
import com.suisung.mall.shop.product.service.ShopProductIndexService;
|
||||
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.dto.DataBaseInfo;
|
||||
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));
|
||||
// }
|
||||
|
||||
Map<String, Integer> storeDataResultMap = getProductStockFromRedis();
|
||||
Map<String, Double> storeDataResultMap = getProductStockFromRedis();
|
||||
|
||||
return new ThirdApiRes().success("success", storeDataResultMap);
|
||||
}
|
||||
@ -812,7 +812,7 @@ public class SyncThirdDataServiceImpl extends SyncBaseThirdSxAbstract implements
|
||||
|
||||
|
||||
@Override
|
||||
public Map<String, Integer> getProductStockFromRedis() {
|
||||
public Map<String, Double> getProductStockFromRedis() {
|
||||
try {
|
||||
// 从 Redis 获取 hash 结构的所有键值对
|
||||
Map<Object, Object> redisHash = redisTemplate.opsForHash().entries(RedisKey.STOREDATARELEASE);
|
||||
@ -823,7 +823,7 @@ public class SyncThirdDataServiceImpl extends SyncBaseThirdSxAbstract implements
|
||||
return redisHash.entrySet().stream()
|
||||
.collect(Collectors.toMap(
|
||||
entry -> String.valueOf(entry.getKey()),
|
||||
entry -> Convert.toInt(entry.getValue(), 0) // 转换失败时默认为 0
|
||||
entry -> Convert.toDouble(entry.getValue(), 0.00) // 转换失败时默认为 0
|
||||
));
|
||||
} catch (Exception e) {
|
||||
logger.error("从 Redis 获取商品库存失败: {}", e.getMessage(), e);
|
||||
@ -845,14 +845,53 @@ public class SyncThirdDataServiceImpl extends SyncBaseThirdSxAbstract implements
|
||||
continue;
|
||||
}
|
||||
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 保证原子性和高性能
|
||||
redisTemplate.opsForHash().increment(RedisKey.STOREDATARELEASE, productKey, delta);
|
||||
redisTemplate.opsForHash().increment(RedisKey.STOREDATARELEASE, itemId, itemQuaryty.doubleValue());
|
||||
} catch (Exception 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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user