|
|
package com.yoho.search.consumer.service.logic.productIndex.viewBuilder;
|
|
|
|
|
|
import java.math.BigDecimal;
|
|
|
import java.math.RoundingMode;
|
|
|
import java.text.DecimalFormat;
|
|
|
import java.util.Date;
|
|
|
import java.util.HashMap;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Component;
|
|
|
|
|
|
import com.yoho.search.base.utils.DateUtil;
|
|
|
import com.yoho.search.base.utils.MathUtils;
|
|
|
import com.yoho.search.base.utils.ProductIndexEsField;
|
|
|
import com.yoho.search.consumer.service.bo.ProductIndexBO;
|
|
|
import com.yoho.search.consumer.service.bo.ProductPriceBO;
|
|
|
import com.yoho.search.consumer.service.logic.SpecialDealLogicService;
|
|
|
import com.yoho.search.consumer.service.logic.VipPriceLogicService;
|
|
|
import com.yoho.search.dal.ProductPriceMapper;
|
|
|
import com.yoho.search.dal.model.ProductPrice;
|
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Component;
|
|
|
|
|
|
import java.math.BigDecimal;
|
|
|
import java.math.RoundingMode;
|
|
|
import java.text.DecimalFormat;
|
|
|
import java.util.Date;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
/**
|
|
|
* Created by wangnan on 2017/1/6.
|
...
|
...
|
@@ -27,150 +30,184 @@ import java.util.stream.Collectors; |
|
|
@Component
|
|
|
public class ProductPriceBuilder implements ViewBuilder {
|
|
|
|
|
|
private final Logger logger = LoggerFactory.getLogger(ProductPriceBuilder.class);
|
|
|
private final Logger logger = LoggerFactory.getLogger(ProductPriceBuilder.class);
|
|
|
|
|
|
@Autowired
|
|
|
private ProductPriceMapper productPriceMapper;
|
|
|
@Autowired
|
|
|
private VipPriceLogicService vipPriceLogicService;
|
|
|
@Autowired
|
|
|
private SpecialDealLogicService specialSearchFieldLogicService;
|
|
|
@Autowired
|
|
|
private ProductPriceMapper productPriceMapper;
|
|
|
@Autowired
|
|
|
private VipPriceLogicService vipPriceLogicService;
|
|
|
@Autowired
|
|
|
private SpecialDealLogicService specialSearchFieldLogicService;
|
|
|
|
|
|
@Override
|
|
|
public void build(List<ProductIndexBO> productIndexBOs, List<Integer> ids, List<Integer> sknList) {
|
|
|
List<ProductPrice> productPrices = productPriceMapper.selectBySknList(sknList);
|
|
|
Map<Integer, ProductPrice> productPricesMap = productPrices.stream().collect(Collectors.toMap(ProductPrice::getProductSkn, (p) -> p));
|
|
|
for (ProductIndexBO productIndexBO : productIndexBOs) {
|
|
|
try {
|
|
|
// 如果该skn对应价格对象不存在,直接跳过
|
|
|
ProductPrice productPrice = productPricesMap.get(productIndexBO.getProductSkn());
|
|
|
if (productPrice == null) {
|
|
|
continue;
|
|
|
}
|
|
|
// 构造ProductPriceBO
|
|
|
ProductPriceBO productPriceBO = new ProductPriceBO(productPrice);
|
|
|
this.buildProductPriceBO(productPriceBO);
|
|
|
// 构造ProductIndexBO
|
|
|
this.buildProductIndexBO(productIndexBO, productPriceBO);
|
|
|
} catch (Exception e) {
|
|
|
logger.error(e.getMessage(), e);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@Override
|
|
|
public void build(List<ProductIndexBO> productIndexBOs, List<Integer> ids, List<Integer> sknList) {
|
|
|
List<ProductPrice> productPrices = productPriceMapper.selectBySknList(sknList);
|
|
|
Map<Integer, ProductPrice> productPricesMap = productPrices.stream().collect(Collectors.toMap(ProductPrice::getProductSkn, (p) -> p));
|
|
|
for (ProductIndexBO productIndexBO : productIndexBOs) {
|
|
|
try {
|
|
|
// 如果该skn对应价格对象不存在,直接跳过
|
|
|
ProductPrice productPrice = productPricesMap.get(productIndexBO.getProductSkn());
|
|
|
if (productPrice == null) {
|
|
|
continue;
|
|
|
}
|
|
|
// 构造ProductPriceBO
|
|
|
ProductPriceBO productPriceBO = new ProductPriceBO(productPrice);
|
|
|
this.buildProductPriceBO(productPriceBO);
|
|
|
// 构造ProductIndexBO
|
|
|
this.buildProductIndexBO(productIndexBO, productPriceBO);
|
|
|
} catch (Exception e) {
|
|
|
logger.error(e.getMessage(), e);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 增量+全量都调用
|
|
|
*/
|
|
|
public void buildProductPriceBO(ProductPriceBO productPriceBO) {
|
|
|
// 1、计算并重设vip相关价格
|
|
|
vipPriceLogicService.fillProductPriceVipPrice(productPriceBO);
|
|
|
// 2、计算折扣相关
|
|
|
double salesPrice = this.getDoubleFromBigDecimal(productPriceBO.getSalesPrice());
|
|
|
double marketPrice = this.getDoubleFromBigDecimal(productPriceBO.getMarketPrice());
|
|
|
/**
|
|
|
* 增量+全量都调用
|
|
|
*/
|
|
|
public void buildProductPriceBO(ProductPriceBO productPriceBO) {
|
|
|
// 1、计算并重设vip相关价格
|
|
|
vipPriceLogicService.fillProductPriceVipPrice(productPriceBO);
|
|
|
// 2、计算折扣相关
|
|
|
double salesPrice = this.getDoubleFromBigDecimal(productPriceBO.getSalesPrice());
|
|
|
double marketPrice = this.getDoubleFromBigDecimal(productPriceBO.getMarketPrice());
|
|
|
productPriceBO.setIsDiscount(salesPrice < marketPrice ? "Y" : "N");
|
|
|
double specialOffer = this.divide(1, productPriceBO.getSalesPrice(), productPriceBO.getMarketPrice());
|
|
|
if (specialOffer <= 0.5) {
|
|
|
productPriceBO.setSpecialoffer("Y");
|
|
|
} else {
|
|
|
productPriceBO.setSpecialoffer("N");
|
|
|
}
|
|
|
double promotionDiscountInt = this.divide(1, productPriceBO.getSalesPrice().multiply(new BigDecimal(10)), productPriceBO.getMarketPrice());
|
|
|
productPriceBO.setPromotionDiscountInt((long) promotionDiscountInt);
|
|
|
double promotionDiscount = this.divide(3, productPriceBO.getSalesPrice(), productPriceBO.getMarketPrice());
|
|
|
productPriceBO.setPromotionDiscount(this.getBigDecimalFromDouble(promotionDiscount));
|
|
|
// 3、设置学生价相关属性
|
|
|
productPriceBO.setIsStudentPrice(productPriceBO.getStudentPrice() != null ? "Y" : "N");
|
|
|
productPriceBO.setIsstudentrebate(productPriceBO.getStudentCoinRate() == null || productPriceBO.getStudentCoinRate().compareTo(BigDecimal.ZERO) == 0 ? "N" : "Y");
|
|
|
}
|
|
|
double specialOffer = this.divide(1, productPriceBO.getSalesPrice(), productPriceBO.getMarketPrice());
|
|
|
if (specialOffer <= 0.5) {
|
|
|
productPriceBO.setSpecialoffer("Y");
|
|
|
} else {
|
|
|
productPriceBO.setSpecialoffer("N");
|
|
|
}
|
|
|
double promotionDiscountInt = this.divide(1, productPriceBO.getSalesPrice().multiply(new BigDecimal(10)), productPriceBO.getMarketPrice());
|
|
|
productPriceBO.setPromotionDiscountInt((long) promotionDiscountInt);
|
|
|
double promotionDiscount = this.divide(3, productPriceBO.getSalesPrice(), productPriceBO.getMarketPrice());
|
|
|
productPriceBO.setPromotionDiscount(this.getBigDecimalFromDouble(promotionDiscount));
|
|
|
// 3、设置学生价相关属性
|
|
|
BigDecimal studentPrice = productPriceBO.getStudentPrice();
|
|
|
productPriceBO.setIsStudentPrice(studentPrice== null || studentPrice.compareTo(BigDecimal.ZERO)==0 ? "N" : "Y");
|
|
|
productPriceBO.setIsstudentrebate(productPriceBO.getStudentCoinRate() == null || productPriceBO.getStudentCoinRate().compareTo(BigDecimal.ZERO) == 0 ? "N" : "Y");
|
|
|
}
|
|
|
|
|
|
private void buildProductIndexBO(ProductIndexBO productIndexBO, ProductPriceBO productPriceBO) {
|
|
|
productIndexBO.setIsDiscount("N");
|
|
|
productIndexBO.setSpecialoffer("N");
|
|
|
productIndexBO.setPromotionDiscount(new BigDecimal(1));
|
|
|
productIndexBO.setPromotionDiscountInt(10L);
|
|
|
productIndexBO.setIsStudentPrice("N");
|
|
|
productIndexBO.setIsStudentRebate("N");
|
|
|
productIndexBO.setIsnew("N");
|
|
|
productIndexBO.setMarketPrice(productPriceBO.getMarketPrice());
|
|
|
productIndexBO.setVipDiscountType(productPriceBO.getVipDiscountType());
|
|
|
productIndexBO.setSalesPrice(productPriceBO.getSalesPrice());
|
|
|
productIndexBO.setVipPrice(productPriceBO.getVipPrice());
|
|
|
productIndexBO.setVip1Price(productPriceBO.getVip1Price());
|
|
|
productIndexBO.setVip2Price(productPriceBO.getVip2Price());
|
|
|
productIndexBO.setVip3Price(productPriceBO.getVip3Price());
|
|
|
productIndexBO.setStudentPrice(productPriceBO.getStudentPrice());
|
|
|
// 折扣相关
|
|
|
productIndexBO.setIsDiscount(productPriceBO.getIsDiscount());
|
|
|
productIndexBO.setSpecialoffer(productPriceBO.getSpecialoffer());
|
|
|
productIndexBO.setPromotionDiscountInt(productPriceBO.getPromotionDiscountInt());
|
|
|
productIndexBO.setPromotionDiscount(productPriceBO.getPromotionDiscount());
|
|
|
// 学生价相关字段
|
|
|
productIndexBO.setIsStudentPrice(productPriceBO.getIsStudentPrice());
|
|
|
productIndexBO.setIsStudentRebate(productPriceBO.getIsstudentrebate());
|
|
|
// 设置vipLevels
|
|
|
productIndexBO.setVipLevels(productPriceBO.getVipLevels());
|
|
|
// 设置价格更新时间
|
|
|
productIndexBO.setPriceUpdateTime(productPriceBO.getUpdateTime());
|
|
|
// 设置最后一次降价时间
|
|
|
productIndexBO.setLastReducePriceTime(productPriceBO.getLastReducePriceTime());
|
|
|
// 计算isNew(规则:首次上架7天内展示且折扣率大于等于88折)
|
|
|
productIndexBO.setIsnew("N");
|
|
|
if (this.isNew(productIndexBO.getFirstShelveTime(), productIndexBO.getMarketPrice(), productIndexBO.getSalesPrice())) {
|
|
|
productIndexBO.setIsnew("Y");
|
|
|
}
|
|
|
// 计算specialSearchFieldPrice
|
|
|
productIndexBO.setSpecialSearchFieldPrice(specialSearchFieldLogicService.getSpecialSearchFieldPrice(productPriceBO));
|
|
|
}
|
|
|
|
|
|
private void buildProductIndexBO(ProductIndexBO productIndexBO, ProductPriceBO productPriceBO) {
|
|
|
productIndexBO.setIsDiscount("N");
|
|
|
productIndexBO.setSpecialoffer("N");
|
|
|
productIndexBO.setPromotionDiscount(new BigDecimal(1));
|
|
|
productIndexBO.setPromotionDiscountInt(10L);
|
|
|
productIndexBO.setIsStudentPrice("N");
|
|
|
productIndexBO.setIsStudentRebate("N");
|
|
|
productIndexBO.setIsnew("N");
|
|
|
productIndexBO.setMarketPrice(productPriceBO.getMarketPrice());
|
|
|
productIndexBO.setVipDiscountType(productPriceBO.getVipDiscountType());
|
|
|
productIndexBO.setSalesPrice(productPriceBO.getSalesPrice());
|
|
|
productIndexBO.setVipPrice(productPriceBO.getVipPrice());
|
|
|
productIndexBO.setVip1Price(productPriceBO.getVip1Price());
|
|
|
productIndexBO.setVip2Price(productPriceBO.getVip2Price());
|
|
|
productIndexBO.setVip3Price(productPriceBO.getVip3Price());
|
|
|
productIndexBO.setStudentPrice(productPriceBO.getStudentPrice());
|
|
|
// 折扣相关
|
|
|
productIndexBO.setIsDiscount(productPriceBO.getIsDiscount());
|
|
|
productIndexBO.setSpecialoffer(productPriceBO.getSpecialoffer());
|
|
|
productIndexBO.setPromotionDiscountInt(productPriceBO.getPromotionDiscountInt());
|
|
|
productIndexBO.setPromotionDiscount(productPriceBO.getPromotionDiscount());
|
|
|
// 学生价相关字段
|
|
|
productIndexBO.setIsStudentPrice(productPriceBO.getIsStudentPrice());
|
|
|
productIndexBO.setIsStudentRebate(productPriceBO.getIsstudentrebate());
|
|
|
// 设置vipLevels
|
|
|
productIndexBO.setVipLevels(productPriceBO.getVipLevels());
|
|
|
// 设置价格更新时间
|
|
|
productIndexBO.setPriceUpdateTime(productPriceBO.getUpdateTime());
|
|
|
// 设置最后一次降价时间
|
|
|
productIndexBO.setLastReducePriceTime(productPriceBO.getLastReducePriceTime());
|
|
|
// 计算isNew(规则:首次上架7天内展示且折扣率大于等于88折)
|
|
|
productIndexBO.setIsnew("N");
|
|
|
if (this.isNew(productIndexBO.getFirstShelveTime(), productIndexBO.getMarketPrice(), productIndexBO.getSalesPrice())) {
|
|
|
productIndexBO.setIsnew("Y");
|
|
|
}
|
|
|
// 计算specialSearchFieldPrice
|
|
|
productIndexBO.setSpecialSearchFieldPrice(specialSearchFieldLogicService.getSpecialSearchFieldPrice(productPriceBO));
|
|
|
}
|
|
|
public Map<String, Object> getProductPriceModelMap(Integer productId, Integer firstShelveTime, ProductPrice pp) {
|
|
|
Map<String, Object> indexData = new HashMap<String, Object>();
|
|
|
indexData.put("isnew", "N");
|
|
|
if (pp == null) {
|
|
|
return indexData;
|
|
|
}
|
|
|
// 构造ProductPriceBO
|
|
|
ProductPriceBO productPriceBO = new ProductPriceBO(pp);
|
|
|
this.buildProductPriceBO(productPriceBO);
|
|
|
indexData.put("productId", productId);
|
|
|
indexData.put("marketPrice", this.getDoubleFromBigDecimal(productPriceBO.getMarketPrice()));
|
|
|
indexData.put("salesPrice", this.getDoubleFromBigDecimal(productPriceBO.getSalesPrice()));
|
|
|
indexData.put("vipPrice", this.getDoubleFromBigDecimal(productPriceBO.getVipPrice()));
|
|
|
indexData.put("vipDiscountType", productPriceBO.getVipDiscountType());
|
|
|
indexData.put("vip1Price", this.getDoubleFromBigDecimal(productPriceBO.getVip1Price()));
|
|
|
indexData.put("vip2Price", this.getDoubleFromBigDecimal(productPriceBO.getVip2Price()));
|
|
|
indexData.put("vip3Price", this.getDoubleFromBigDecimal(productPriceBO.getVip3Price()));
|
|
|
indexData.put("studentPrice", this.getDoubleFromBigDecimal(productPriceBO.getStudentPrice()));
|
|
|
|
|
|
indexData.put("isDiscount", productPriceBO.getIsDiscount());
|
|
|
indexData.put("specialoffer", productPriceBO.getSpecialoffer());
|
|
|
indexData.put("promotionDiscountInt", productPriceBO.getPromotionDiscountInt());
|
|
|
indexData.put("promotionDiscount", this.getDoubleFromBigDecimal(productPriceBO.getPromotionDiscount()));
|
|
|
indexData.put("isStudentPrice", productPriceBO.getIsStudentPrice());
|
|
|
indexData.put("isstudentrebate", productPriceBO.getIsstudentrebate());
|
|
|
indexData.put("vipLevels", productPriceBO.getVipLevels());
|
|
|
indexData.put("priceUpdateTime", productPriceBO.getUpdateTime());
|
|
|
if (firstShelveTime != null) {
|
|
|
indexData.put("isnew", this.isNew(firstShelveTime, productPriceBO.getMarketPrice(), productPriceBO.getSalesPrice()));
|
|
|
}
|
|
|
indexData.put(ProductIndexEsField.specialSearchFieldPrice, specialSearchFieldLogicService.getSpecialSearchFieldPrice(productPriceBO));
|
|
|
return indexData;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* isNew 标签逻辑
|
|
|
*/
|
|
|
public boolean isNew(Integer firstShelveTime, BigDecimal marketPrice, BigDecimal salesPrice) {
|
|
|
try {
|
|
|
if (firstShelveTime == null || firstShelveTime <= 0 || salesPrice == null || marketPrice == null) {
|
|
|
return false;
|
|
|
}
|
|
|
long dateCount = DateUtil.daysBetween(new Date(firstShelveTime * 1000L), new Date());
|
|
|
if (dateCount > 7) {
|
|
|
return false;
|
|
|
}
|
|
|
// 计算折扣
|
|
|
Double discount = MathUtils.getDevideValue(salesPrice, marketPrice, 2, RoundingMode.DOWN);
|
|
|
if (discount >= 0.88) {
|
|
|
return true;
|
|
|
}
|
|
|
return false;
|
|
|
} catch (Exception e) {
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
/**
|
|
|
* isNew 标签逻辑
|
|
|
*/
|
|
|
public boolean isNew(Integer firstShelveTime, BigDecimal marketPrice, BigDecimal salesPrice) {
|
|
|
try {
|
|
|
if (firstShelveTime == null || firstShelveTime <= 0 || salesPrice == null || marketPrice == null) {
|
|
|
return false;
|
|
|
}
|
|
|
long dateCount = DateUtil.daysBetween(new Date(firstShelveTime * 1000L), new Date());
|
|
|
if (dateCount > 7) {
|
|
|
return false;
|
|
|
}
|
|
|
// 计算折扣
|
|
|
Double discount = MathUtils.getDevideValue(salesPrice, marketPrice, 2, RoundingMode.DOWN);
|
|
|
if (discount >= 0.88) {
|
|
|
return true;
|
|
|
}
|
|
|
return false;
|
|
|
} catch (Exception e) {
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
private double divide(int scale, BigDecimal a, BigDecimal b) {
|
|
|
if (b == null || b.compareTo(BigDecimal.ZERO) == 0) {
|
|
|
return 0;
|
|
|
}
|
|
|
StringBuilder sb = new StringBuilder("0.0");
|
|
|
for (int i = 1; i < scale; i++) {
|
|
|
sb.append('0');
|
|
|
}
|
|
|
BigDecimal divideResult = a.divide(b, scale, RoundingMode.DOWN);
|
|
|
DecimalFormat decimalFormat = new DecimalFormat(sb.toString());
|
|
|
String result = decimalFormat.format(divideResult);
|
|
|
return Double.parseDouble(result);
|
|
|
}
|
|
|
private double divide(int scale, BigDecimal a, BigDecimal b) {
|
|
|
if (b == null || b.compareTo(BigDecimal.ZERO) == 0) {
|
|
|
return 0;
|
|
|
}
|
|
|
StringBuilder sb = new StringBuilder("0.0");
|
|
|
for (int i = 1; i < scale; i++) {
|
|
|
sb.append('0');
|
|
|
}
|
|
|
BigDecimal divideResult = a.divide(b, scale, RoundingMode.DOWN);
|
|
|
DecimalFormat decimalFormat = new DecimalFormat(sb.toString());
|
|
|
String result = decimalFormat.format(divideResult);
|
|
|
return Double.parseDouble(result);
|
|
|
}
|
|
|
|
|
|
private double getDoubleFromBigDecimal(BigDecimal bigDecimal) {
|
|
|
if (bigDecimal == null) {
|
|
|
return 0d;
|
|
|
}
|
|
|
return bigDecimal.doubleValue();
|
|
|
}
|
|
|
private double getDoubleFromBigDecimal(BigDecimal bigDecimal) {
|
|
|
if (bigDecimal == null) {
|
|
|
return 0d;
|
|
|
}
|
|
|
return bigDecimal.doubleValue();
|
|
|
}
|
|
|
|
|
|
private BigDecimal getBigDecimalFromDouble(Double d) {
|
|
|
if (d == null) {
|
|
|
return new BigDecimal(0);
|
|
|
}
|
|
|
return new BigDecimal(d);
|
|
|
}
|
|
|
private BigDecimal getBigDecimalFromDouble(Double d) {
|
|
|
if (d == null) {
|
|
|
return new BigDecimal(0);
|
|
|
}
|
|
|
return new BigDecimal(d);
|
|
|
}
|
|
|
} |
...
|
...
|
|