...
|
...
|
@@ -10,6 +10,7 @@ import java.util.Map; |
|
|
import java.util.Set;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
import com.yoho.search.consumer.service.bo.ProductHeatValueBO;
|
|
|
import org.apache.commons.collections.CollectionUtils;
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
...
|
...
|
@@ -29,147 +30,155 @@ import com.yoho.search.dal.model.Storage; |
|
|
@Component
|
|
|
public class ProductSizesLogicService {
|
|
|
|
|
|
private static final Integer VALID_STATUS = Integer.valueOf(1);
|
|
|
|
|
|
@Autowired
|
|
|
private GoodsMapper goodsMapper;
|
|
|
@Autowired
|
|
|
private StorageMapper storageMapper;
|
|
|
@Autowired
|
|
|
private SizeMapper sizeMapper;
|
|
|
@Autowired
|
|
|
private ProductHeatValueLogicService productHeatValueLogicService;
|
|
|
|
|
|
/**
|
|
|
* 全量增量都有调用
|
|
|
*/
|
|
|
public List<ProductSizesBO> getProductSizeBOList(List<Integer> productIds) {
|
|
|
// 获取ProductId对应的上架的goodsId列表
|
|
|
List<Goods> validGoodsList = goodsMapper.selectValidListByProductIds(productIds);
|
|
|
if (CollectionUtils.isEmpty(validGoodsList)) {
|
|
|
return new ArrayList<>();
|
|
|
}
|
|
|
|
|
|
// 获取goodsId对应得Storage列表
|
|
|
List<Integer> validGoodsIdList = validGoodsList.stream().map(Goods::getId).collect(Collectors.toList());
|
|
|
List<Storage> storageList = storageMapper.selectByGoodsIds(validGoodsIdList);
|
|
|
if (CollectionUtils.isEmpty(storageList)) {
|
|
|
return new ArrayList<>();
|
|
|
}
|
|
|
|
|
|
// 按productId分组
|
|
|
Map<Integer, List<Storage>> productStorageMap = new HashMap<Integer, List<Storage>>();
|
|
|
for (Storage storage : storageList) {
|
|
|
Integer productId = storage.getProductId();
|
|
|
List<Storage> productStorageList = productStorageMap.get(productId);
|
|
|
if (productStorageList == null) {
|
|
|
productStorageList = new ArrayList<Storage>();
|
|
|
productStorageMap.put(productId, productStorageList);
|
|
|
}
|
|
|
productStorageList.add(storage);
|
|
|
}
|
|
|
|
|
|
// 批量获取尺码信息
|
|
|
Set<Integer> sizeIdSet = new HashSet<>();
|
|
|
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);
|
|
|
|
|
|
// 构造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());
|
|
|
|
|
|
// 获取信息
|
|
|
Set<Integer> sizeIds = new HashSet<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(StringUtils.join((this.getSizeNames(sizeIds, sizeNameMap)), ","));
|
|
|
|
|
|
// 填充人气值[断码率>50,则人气值减半]
|
|
|
BigDecimal heatValue = heatValueMap.get(productSizesBO.getProductId());
|
|
|
if (heatValue == null) {
|
|
|
heatValue = new BigDecimal(0);
|
|
|
}
|
|
|
if (productSizesBO.getBreakSizePercent() > 50) {
|
|
|
heatValue = heatValue.multiply(new BigDecimal("0.5"));
|
|
|
}
|
|
|
productSizesBO.setHeatValue(heatValue);
|
|
|
results.add(productSizesBO);
|
|
|
}
|
|
|
return results;
|
|
|
|
|
|
}
|
|
|
|
|
|
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());
|
|
|
}
|
|
|
return this.getBreakSizePercent(productValidStatusSizes.size(), productHasStorageSizes.size());
|
|
|
}
|
|
|
|
|
|
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.add(sizeName);
|
|
|
}
|
|
|
return results;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 保留两位小数
|
|
|
*/
|
|
|
private double getBreakSizePercent(Integer validStatusSizeCount, Integer hasStorageSizeCount) {
|
|
|
if (validStatusSizeCount == null || validStatusSizeCount <= 0) {
|
|
|
return 100d;
|
|
|
}
|
|
|
if (hasStorageSizeCount == null || hasStorageSizeCount <= 0) {
|
|
|
return 100d;
|
|
|
}
|
|
|
double breakSizePercent = 100d * (validStatusSizeCount - hasStorageSizeCount) / validStatusSizeCount;
|
|
|
BigDecimal bg = new BigDecimal(breakSizePercent);
|
|
|
double result = bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
|
|
|
return result;
|
|
|
}
|
|
|
private static final Integer VALID_STATUS = Integer.valueOf(1);
|
|
|
|
|
|
@Autowired
|
|
|
private GoodsMapper goodsMapper;
|
|
|
@Autowired
|
|
|
private StorageMapper storageMapper;
|
|
|
@Autowired
|
|
|
private SizeMapper sizeMapper;
|
|
|
@Autowired
|
|
|
private ProductHeatValueLogicService productHeatValueLogicService;
|
|
|
|
|
|
/**
|
|
|
* 全量增量都有调用
|
|
|
*/
|
|
|
public List<ProductSizesBO> getProductSizeBOList(List<Integer> productIds) {
|
|
|
// 获取ProductId对应的上架的goodsId列表
|
|
|
List<Goods> validGoodsList = goodsMapper.selectValidListByProductIds(productIds);
|
|
|
if (CollectionUtils.isEmpty(validGoodsList)) {
|
|
|
return new ArrayList<>();
|
|
|
}
|
|
|
|
|
|
// 获取goodsId对应得Storage列表
|
|
|
List<Integer> validGoodsIdList = validGoodsList.stream().map(Goods::getId).collect(Collectors.toList());
|
|
|
List<Storage> storageList = storageMapper.selectByGoodsIds(validGoodsIdList);
|
|
|
if (CollectionUtils.isEmpty(storageList)) {
|
|
|
return new ArrayList<>();
|
|
|
}
|
|
|
|
|
|
// 按productId分组
|
|
|
Map<Integer, List<Storage>> productStorageMap = new HashMap<Integer, List<Storage>>();
|
|
|
for (Storage storage : storageList) {
|
|
|
Integer productId = storage.getProductId();
|
|
|
List<Storage> productStorageList = productStorageMap.get(productId);
|
|
|
if (productStorageList == null) {
|
|
|
productStorageList = new ArrayList<>();
|
|
|
productStorageMap.put(productId, productStorageList);
|
|
|
}
|
|
|
productStorageList.add(storage);
|
|
|
}
|
|
|
|
|
|
// 批量获取尺码信息
|
|
|
Set<Integer> sizeIdSet = new HashSet<>();
|
|
|
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, ProductHeatValueBO> heatValueMap = productHeatValueLogicService.queryProductIdHeatValue(productIds);
|
|
|
|
|
|
// 构造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());
|
|
|
|
|
|
// 获取信息
|
|
|
Set<Integer> sizeIds = new HashSet<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(StringUtils.join((this.getSizeNames(sizeIds, sizeNameMap)), ","));
|
|
|
|
|
|
// 填充人气值[断码率>50,则人气值减半]
|
|
|
ProductHeatValueBO productHeatValueBO = heatValueMap.get(productSizesBO.getProductId());
|
|
|
BigDecimal heatValue = null;
|
|
|
BigDecimal ctrValue = null;
|
|
|
if (productHeatValueBO == null) {
|
|
|
heatValue = new BigDecimal(0);
|
|
|
ctrValue = new BigDecimal(0);
|
|
|
} else {
|
|
|
heatValue = productHeatValueBO.getHeatValue();
|
|
|
ctrValue = productHeatValueBO.getCtrValue();
|
|
|
}
|
|
|
if (productSizesBO.getBreakSizePercent() > 50) {
|
|
|
heatValue = heatValue.multiply(new BigDecimal("0.5"));
|
|
|
ctrValue = ctrValue.multiply(new BigDecimal("0.5"));
|
|
|
}
|
|
|
productSizesBO.setHeatValue(heatValue);
|
|
|
productSizesBO.setCtrValue(ctrValue);
|
|
|
results.add(productSizesBO);
|
|
|
}
|
|
|
return results;
|
|
|
|
|
|
}
|
|
|
|
|
|
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());
|
|
|
}
|
|
|
return this.getBreakSizePercent(productValidStatusSizes.size(), productHasStorageSizes.size());
|
|
|
}
|
|
|
|
|
|
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.add(sizeName);
|
|
|
}
|
|
|
return results;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 保留两位小数
|
|
|
*/
|
|
|
private double getBreakSizePercent(Integer validStatusSizeCount, Integer hasStorageSizeCount) {
|
|
|
if (validStatusSizeCount == null || validStatusSizeCount <= 0) {
|
|
|
return 100d;
|
|
|
}
|
|
|
if (hasStorageSizeCount == null || hasStorageSizeCount <= 0) {
|
|
|
return 100d;
|
|
|
}
|
|
|
double breakSizePercent = 100d * (validStatusSizeCount - hasStorageSizeCount) / validStatusSizeCount;
|
|
|
BigDecimal bg = new BigDecimal(breakSizePercent);
|
|
|
double result = bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
|
|
|
return result;
|
|
|
}
|
|
|
} |
...
|
...
|
|