|
|
package com.yoho.search.consumer.service.logic.productIndex;
|
|
|
|
|
|
import java.math.BigDecimal;
|
|
|
import java.util.ArrayList;
|
|
|
import java.util.Collection;
|
|
|
import java.util.HashMap;
|
|
|
import java.util.HashSet;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
import java.util.Set;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
import org.apache.commons.collections.CollectionUtils;
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Component;
|
|
|
|
|
|
import com.yoho.search.consumer.service.bo.ProductSizesBO;
|
|
|
import com.yoho.search.dal.GoodsMapper;
|
|
|
import com.yoho.search.dal.ProductSizesMapper;
|
|
|
import com.yoho.search.dal.SizeMapper;
|
|
|
import com.yoho.search.dal.StorageMapper;
|
|
|
import com.yoho.search.dal.model.Goods;
|
|
|
import com.yoho.search.dal.model.ProductSizes;
|
|
|
import com.yoho.search.dal.model.Size;
|
|
|
import com.yoho.search.dal.model.Storage;
|
|
|
import org.apache.commons.collections.CollectionUtils;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Component;
|
|
|
|
|
|
import java.math.BigDecimal;
|
|
|
import java.util.*;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
/**
|
|
|
* Created by wangnan on 2016/6/30.
|
...
|
...
|
@@ -32,8 +38,6 @@ public class ProductSizesLogicService { |
|
|
@Autowired
|
|
|
private SizeMapper sizeMapper;
|
|
|
@Autowired
|
|
|
private ProductSizesMapper productSizesMapper;
|
|
|
@Autowired
|
|
|
private ProductHeatValueLogicService productHeatValueLogicService;
|
|
|
|
|
|
/**
|
...
|
...
|
@@ -41,85 +45,71 @@ public class ProductSizesLogicService { |
|
|
*/
|
|
|
public List<ProductSizesBO> getProductSizeBOList(List<Integer> productIds) {
|
|
|
// 获取ProductId对应的上架的goodsId列表
|
|
|
List<Goods> goodsList = goodsMapper.selectByIdsAndStatus(productIds);
|
|
|
if (CollectionUtils.isEmpty(goodsList)) {
|
|
|
List<Goods> validGoodsList = goodsMapper.selectValidListByProductIds(productIds);
|
|
|
if (CollectionUtils.isEmpty(validGoodsList)) {
|
|
|
return new ArrayList<>();
|
|
|
}
|
|
|
|
|
|
// 获取goodsId对应得Storage列表
|
|
|
List<Integer> goodsIdList = goodsList.stream().map(Goods::getId).collect(Collectors.toList());
|
|
|
List<Storage> oldStorageList = storageMapper.selectByGoodsIds(goodsIdList);
|
|
|
if (CollectionUtils.isEmpty(oldStorageList)) {
|
|
|
List<Integer> validGoodsIdList = validGoodsList.stream().map(Goods::getId).collect(Collectors.toList());
|
|
|
List<Storage> storageList = storageMapper.selectByGoodsIds(validGoodsIdList);
|
|
|
if (CollectionUtils.isEmpty(storageList)) {
|
|
|
return new ArrayList<>();
|
|
|
}
|
|
|
|
|
|
// 过滤状态是上架的且有库存的Goods和Storage
|
|
|
Map<Integer, Set<Integer>> productValidStatusSizes = new HashMap<Integer, Set<Integer>>();
|
|
|
Map<Integer, Set<Integer>> productHasStorageSizes = new HashMap<Integer, Set<Integer>>();
|
|
|
List<Storage> effectiveStorageList = new ArrayList<Storage>();
|
|
|
for (Storage storage : oldStorageList) {
|
|
|
// 按productId分组
|
|
|
Map<Integer, List<Storage>> productStorageMap = new HashMap<Integer, List<Storage>>();
|
|
|
for (Storage storage : storageList) {
|
|
|
Integer productId = storage.getProductId();
|
|
|
// 处理未下架的sku
|
|
|
if (!VALID_STATUS.equals(storage.getStatus())) {
|
|
|
continue;
|
|
|
}
|
|
|
this.addValueToSet(productId, storage.getGoodsDimensionId(), productValidStatusSizes);
|
|
|
// 处理有库存的sku
|
|
|
if (storage.getStorageNum() == null || storage.getStorageNum().intValue() <= 0) {
|
|
|
continue;
|
|
|
}
|
|
|
this.addValueToSet(productId, storage.getGoodsDimensionId(), productHasStorageSizes);
|
|
|
effectiveStorageList.add(storage);
|
|
|
}
|
|
|
|
|
|
if (CollectionUtils.isEmpty(effectiveStorageList)) {
|
|
|
return new ArrayList<>();
|
|
|
}
|
|
|
|
|
|
// 根据上架的GoodsId筛选Storage数据
|
|
|
Set<Integer> validGoodsIdSet = goodsIdList.stream().collect(Collectors.toSet());
|
|
|
List<Integer> validErpSkuIdList = new ArrayList<>();
|
|
|
for (Storage s : effectiveStorageList) {
|
|
|
if (validGoodsIdSet.contains(s.getGoodsId())) {
|
|
|
validErpSkuIdList.add(s.getErpSkuId());
|
|
|
List<Storage> productStorageList = productStorageMap.get(productId);
|
|
|
if (productStorageList == null) {
|
|
|
productStorageList = new ArrayList<Storage>();
|
|
|
productStorageMap.put(productId, productStorageList);
|
|
|
}
|
|
|
}
|
|
|
// 判断sku列表是否为空
|
|
|
if (validErpSkuIdList == null || validErpSkuIdList.isEmpty()) {
|
|
|
return new ArrayList<>();
|
|
|
}
|
|
|
|
|
|
// 从数据库中获取真实库存
|
|
|
List<ProductSizes> productSizesFromDb = productSizesMapper.selectProductSizes(validErpSkuIdList);
|
|
|
if (CollectionUtils.isEmpty(productSizesFromDb)) {
|
|
|
return new ArrayList<>();
|
|
|
}
|
|
|
|
|
|
// 构造返回结果对象
|
|
|
List<ProductSizesBO> results = new ArrayList<ProductSizesBO>();
|
|
|
for (ProductSizes productSizes : productSizesFromDb) {
|
|
|
results.add(new ProductSizesBO(productSizes));
|
|
|
productStorageList.add(storage);
|
|
|
}
|
|
|
|
|
|
// 获取尺码信息
|
|
|
// 批量获取尺码信息
|
|
|
Set<Integer> sizeIdSet = new HashSet<>();
|
|
|
for (ProductSizesBO productSizesBO : results) {
|
|
|
sizeIdSet.addAll(productSizesBO.getSizeIdSet());
|
|
|
for (Storage s : storageList) {
|
|
|
sizeIdSet.add(s.getGoodsDimensionId());
|
|
|
}
|
|
|
List<Size> sizeList = sizeMapper.selectByIds(sizeIdSet.stream().collect(Collectors.toList()));
|
|
|
Map<Integer, String> sizeNameMap = sizeList.stream().collect(Collectors.toMap(Size::getId, Size::getSizeName));
|
|
|
|
|
|
// 获取人气值信息
|
|
|
// 批量获取人气值信息
|
|
|
Map<Integer, BigDecimal> heatValueMap = productHeatValueLogicService.queryProductIdHeatValue(productIds);
|
|
|
|
|
|
// 填充其他信息
|
|
|
for (ProductSizesBO productSizesBO : results) {
|
|
|
// 构造ProductSizesBO
|
|
|
List<ProductSizesBO> results = new ArrayList<ProductSizesBO>();
|
|
|
for (Map.Entry<Integer, List<Storage>> entry : productStorageMap.entrySet()) {
|
|
|
Integer productId = entry.getKey();
|
|
|
List<Storage> productStorageList = entry.getValue();
|
|
|
ProductSizesBO productSizesBO = new ProductSizesBO();
|
|
|
productSizesBO.setProductId(productId);
|
|
|
productSizesBO.setBreakSizePercent(this.getBreakSizePercent(productStorageList));// 计算断码率
|
|
|
|
|
|
// 过滤出有效的和有库存的库存
|
|
|
List<Storage> validteStorages = productStorageList.stream()
|
|
|
.filter(storage -> VALID_STATUS.equals(storage.getStatus()) && storage.getStorageNum() != null && storage.getStorageNum() > 0)
|
|
|
.collect(Collectors.toList());
|
|
|
|
|
|
// 获取信息
|
|
|
List<Integer> sizeIds = new ArrayList<Integer>();
|
|
|
List<Integer> skuIds = new ArrayList<Integer>();
|
|
|
int storageNum = 0;
|
|
|
for (Storage storage : validteStorages) {
|
|
|
sizeIds.add(storage.getGoodsDimensionId());
|
|
|
skuIds.add(storage.getErpSkuId());
|
|
|
storageNum = storageNum + storage.getStorageNum();
|
|
|
}
|
|
|
productSizesBO.setSkuIds(StringUtils.join(skuIds, ","));
|
|
|
productSizesBO.setSizeIds(StringUtils.join(sizeIds, ","));
|
|
|
productSizesBO.setStorageNum(storageNum);
|
|
|
|
|
|
// 填充尺码名称
|
|
|
productSizesBO.setSizeNames(this.getSizeNames(productSizesBO.getSizeIdSet(), sizeNameMap));
|
|
|
// 填充断码率
|
|
|
Integer validStatusSizeCount = productValidStatusSizes.getOrDefault(productSizesBO.getProductId(), new HashSet<Integer>()).size();
|
|
|
Integer hasStorageSizeCount = productHasStorageSizes.getOrDefault(productSizesBO.getProductId(), new HashSet<Integer>()).size();
|
|
|
productSizesBO.setBreakSizePercent(this.getBreakSizePercent(validStatusSizeCount, hasStorageSizeCount));
|
|
|
productSizesBO.setSizeNames(StringUtils.join((this.getSizeNames(sizeIds, sizeNameMap)), ","));
|
|
|
|
|
|
// 填充人气值[断码率>50,则人气值减半]
|
|
|
BigDecimal heatValue = heatValueMap.get(productSizesBO.getProductId());
|
|
|
if (heatValue == null) {
|
...
|
...
|
@@ -129,29 +119,42 @@ public class ProductSizesLogicService { |
|
|
heatValue = heatValue.multiply(new BigDecimal("0.5"));
|
|
|
}
|
|
|
productSizesBO.setHeatValue(heatValue);
|
|
|
results.add(productSizesBO);
|
|
|
}
|
|
|
return results;
|
|
|
|
|
|
}
|
|
|
|
|
|
private <K, V> void addValueToSet(K key, V value, Map<K, Set<V>> map) {
|
|
|
Set<V> values = map.get(key);
|
|
|
if (values == null) {
|
|
|
values = new HashSet<V>();
|
|
|
map.put(key, values);
|
|
|
private double getBreakSizePercent(List<Storage> storageList) {
|
|
|
Set<Integer> productValidStatusSizes = new HashSet<Integer>();// 上架了的尺码【计算断码率】
|
|
|
Set<Integer> productHasStorageSizes = new HashSet<Integer>();// 有库存的尺码【计算断码率】
|
|
|
for (Storage storage : storageList) {
|
|
|
// 处理未下架的sku
|
|
|
if (!VALID_STATUS.equals(storage.getStatus())) {
|
|
|
continue;
|
|
|
}
|
|
|
// 记录有效的尺码id
|
|
|
productValidStatusSizes.add(storage.getGoodsDimensionId());
|
|
|
// 处理有库存的sku
|
|
|
if (storage.getStorageNum() == null || storage.getStorageNum().intValue() <= 0) {
|
|
|
continue;
|
|
|
}
|
|
|
// 记录有库存的尺码id
|
|
|
productHasStorageSizes.add(storage.getGoodsDimensionId());
|
|
|
}
|
|
|
values.add(value);
|
|
|
return this.getBreakSizePercent(productValidStatusSizes.size(), productHasStorageSizes.size());
|
|
|
}
|
|
|
|
|
|
private String getSizeNames(Set<Integer> sizeIds, Map<Integer, String> sizeNameMap) {
|
|
|
StringBuilder results = new StringBuilder();
|
|
|
private List<String> getSizeNames(Collection<Integer> sizeIds, Map<Integer, String> sizeNameMap) {
|
|
|
List<String> results = new ArrayList<String>();
|
|
|
for (Integer sizeId : sizeIds) {
|
|
|
String sizeName = sizeNameMap.get(sizeId);
|
|
|
if (sizeName == null) {
|
|
|
continue;
|
|
|
}
|
|
|
results.append(',').append(sizeName);
|
|
|
results.add(sizeName);
|
|
|
}
|
|
|
return results.toString().replaceFirst(",", "");
|
|
|
return results;
|
|
|
}
|
|
|
|
|
|
/**
|
...
|
...
|
|