!284 fix & improve

Merge pull request !284 from OceansDeep/pg
This commit is contained in:
OceansDeep 2023-05-09 06:01:31 +00:00 committed by Gitee
commit 54b40c35f4
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
4 changed files with 151 additions and 60 deletions

View File

@ -90,6 +90,7 @@ public abstract class BaseElasticsearchService {
request.settings(Settings.builder()
.put("index.number_of_shards", elasticsearchProperties.getIndex().getNumberOfShards())
.put("index.number_of_replicas", elasticsearchProperties.getIndex().getNumberOfReplicas())
.put("index.max_result_window", 100000) //最大查询结果数
.put("index.mapping.total_fields.limit", 2000));
//创建索引

View File

@ -10,6 +10,7 @@ import lombok.extern.slf4j.Slf4j;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 促销价格计算业务层实现
@ -66,7 +67,7 @@ public class PromotionPriceUtil {
List<CartSkuVO> skuVOList = tradeDTO.getSkuList();
// 获取map分配sku的总数如果是最后一个商品分配金额则将金额从百分比改为总金额扣减避免出现小数除不尽
Integer count = skuPromotionDetail.size();
int count = skuPromotionDetail.size();
//已优惠金额
Double deducted = 0D;
@ -81,12 +82,12 @@ public class PromotionPriceUtil {
count--;
//sku 优惠金额
Double skuDiscountPrice = 0d;
Double skuDiscountPrice;
//非最后一个商品则按照比例计算
if (count > 0) {
//商品金额占比
Double point = CurrencyUtil.div(cartSkuVO.getPriceDetailDTO().getGoodsPrice(), totalPrice, 4);
double point = CurrencyUtil.div(cartSkuVO.getPriceDetailDTO().getGoodsPrice(), totalPrice, 4);
//商品优惠金额
skuDiscountPrice = CurrencyUtil.mul(discountPrice, point);
//累加已优惠金额
@ -96,64 +97,135 @@ public class PromotionPriceUtil {
else {
skuDiscountPrice = CurrencyUtil.sub(discountPrice, deducted);
}
//优惠券金额则计入优惠券 其他则计入总的discount price
if (promotionTypeEnum == PromotionTypeEnum.COUPON) {
cartSkuVO.getPriceDetailDTO().setCouponPrice(
CurrencyUtil.add(cartSkuVO.getPriceDetailDTO().getCouponPrice(), skuDiscountPrice));
cartSkuVO.getPriceDetailDTO().addDiscountPriceItem(
DiscountPriceItem.builder()
.goodsId(cartSkuVO.getGoodsSku().getGoodsId())
.skuId(cartSkuVO.getGoodsSku().getId())
.discountPrice(skuDiscountPrice)
.promotionTypeEnum(PromotionTypeEnum.COUPON)
.promotionId(activityId)
.build()
);
} else if (promotionTypeEnum == PromotionTypeEnum.PLATFORM_COUPON) {
cartSkuVO.getPriceDetailDTO().setSiteCouponPrice(
CurrencyUtil.add(cartSkuVO.getPriceDetailDTO().getCouponPrice(), skuDiscountPrice));
cartSkuVO.getPriceDetailDTO().setCouponPrice(
CurrencyUtil.add(cartSkuVO.getPriceDetailDTO().getCouponPrice(), cartSkuVO.getPriceDetailDTO().getSiteCouponPrice()));
cartSkuVO.getPriceDetailDTO().addDiscountPriceItem(
DiscountPriceItem.builder()
.goodsId(cartSkuVO.getGoodsSku().getGoodsId())
.skuId(cartSkuVO.getGoodsSku().getId())
.discountPrice(skuDiscountPrice)
.promotionTypeEnum(PromotionTypeEnum.PLATFORM_COUPON)
.promotionId(activityId)
.build()
);
} else {
cartSkuVO.getPriceDetailDTO().setDiscountPrice(
CurrencyUtil.add(cartSkuVO.getPriceDetailDTO().getDiscountPrice(), skuDiscountPrice));
//目前剩余的只有满减金额活动后续如果需要调整这里建议传递活动类型进来
cartSkuVO.getPriceDetailDTO().addDiscountPriceItem(
DiscountPriceItem.builder()
.goodsId(cartSkuVO.getGoodsSku().getGoodsId())
.skuId(cartSkuVO.getGoodsSku().getId())
.discountPrice(skuDiscountPrice)
.promotionTypeEnum(PromotionTypeEnum.FULL_DISCOUNT)
.promotionId(activityId)
.build()
);
}
calculateCartSkuPromotionsPrice(cartSkuVO, skuDiscountPrice, promotionTypeEnum, activityId);
}
}
}
calculateNotEnoughPromotionsPrice(skuVOList, skuPromotionDetail, discountPrice, totalPrice, promotionTypeEnum, activityId);
}
/**
* 计算购物车商品优惠金额
*
* @param cartSkuVO 购物车商品
* @param skuDiscountPrice 商品优惠金额
* @param promotionTypeEnum 优惠类型
* @param activityId 优惠活动id
*/
private static void calculateCartSkuPromotionsPrice(CartSkuVO cartSkuVO, Double skuDiscountPrice, PromotionTypeEnum promotionTypeEnum, String activityId) {
//优惠券金额则计入优惠券 其他则计入总的discount price
if (promotionTypeEnum == PromotionTypeEnum.COUPON) {
cartSkuVO.getPriceDetailDTO().setCouponPrice(
CurrencyUtil.add(cartSkuVO.getPriceDetailDTO().getCouponPrice(), skuDiscountPrice));
cartSkuVO.getPriceDetailDTO().addDiscountPriceItem(
DiscountPriceItem.builder()
.goodsId(cartSkuVO.getGoodsSku().getGoodsId())
.skuId(cartSkuVO.getGoodsSku().getId())
.discountPrice(skuDiscountPrice)
.promotionTypeEnum(PromotionTypeEnum.COUPON)
.promotionId(activityId)
.build()
);
} else if (promotionTypeEnum == PromotionTypeEnum.PLATFORM_COUPON) {
cartSkuVO.getPriceDetailDTO().setSiteCouponPrice(
CurrencyUtil.add(cartSkuVO.getPriceDetailDTO().getCouponPrice(), skuDiscountPrice));
cartSkuVO.getPriceDetailDTO().setCouponPrice(
CurrencyUtil.add(cartSkuVO.getPriceDetailDTO().getCouponPrice(), cartSkuVO.getPriceDetailDTO().getSiteCouponPrice()));
cartSkuVO.getPriceDetailDTO().addDiscountPriceItem(
DiscountPriceItem.builder()
.goodsId(cartSkuVO.getGoodsSku().getGoodsId())
.skuId(cartSkuVO.getGoodsSku().getId())
.discountPrice(skuDiscountPrice)
.promotionTypeEnum(PromotionTypeEnum.PLATFORM_COUPON)
.promotionId(activityId)
.build()
);
} else {
cartSkuVO.getPriceDetailDTO().setDiscountPrice(
CurrencyUtil.add(cartSkuVO.getPriceDetailDTO().getDiscountPrice(), skuDiscountPrice));
//目前剩余的只有满减金额活动后续如果需要调整这里建议传递活动类型进来
cartSkuVO.getPriceDetailDTO().addDiscountPriceItem(
DiscountPriceItem.builder()
.goodsId(cartSkuVO.getGoodsSku().getGoodsId())
.skuId(cartSkuVO.getGoodsSku().getId())
.discountPrice(skuDiscountPrice)
.promotionTypeEnum(PromotionTypeEnum.FULL_DISCOUNT)
.promotionId(activityId)
.build()
);
}
}
/**
* 特殊情况处理如参与多个促销活动部分商品在其他促销计算后的金额不足以满足与当前参与的促销活动的优惠金额
*
* @param skuVOList 获取购物车信息
* @param skuPromotionDetail 参与活动的商品以及商品总金额
* @param discountPrice 需要分发的优惠金额
* @param totalPrice 计算总金额
* @param promotionTypeEnum 优惠类型
* @param activityId 优惠活动id
*/
private static void calculateNotEnoughPromotionsPrice(List<CartSkuVO> skuVOList, Map<String, Double> skuPromotionDetail, Double discountPrice, Double totalPrice, PromotionTypeEnum promotionTypeEnum, String activityId) {
// 特殊情况处理如参与多个促销活动部分商品在其他促销计算后的金额不足以满足与当前参与的促销活动的优惠金额
// 但当前购物车内存在当前当前促销活动的其他商品且剩余金额也满足分摊不足商品的不足金额则分摊到其他商品上
// 满足当前促销的总优惠金额
if (skuPromotionDetail == null || skuPromotionDetail.isEmpty()) {
return;
}
long matchPromotionsZeroCount = skuVOList.stream().filter(l -> l.getPriceDetailDTO().getFlowPrice() == 0 && skuPromotionDetail.containsKey(l.getGoodsSku().getId())).count();
long matchPromotionsCount = skuVOList.stream().filter(l -> skuPromotionDetail.containsKey(l.getGoodsSku().getId())).count();
if (matchPromotionsZeroCount == matchPromotionsCount) {
return;
}
// 获取剩余金额不足优惠金额的商品
List<CartSkuVO> unEnoughSku = skuVOList.stream().filter(k -> {
if (skuPromotionDetail.containsKey(k.getGoodsSku().getId()) && skuPromotionDetail.size() >= 2) {
//商品金额占比
double point = CurrencyUtil.div(k.getPriceDetailDTO().getGoodsPrice(), totalPrice, 4);
//商品优惠金额
Double skuDiscountPrice = CurrencyUtil.mul(discountPrice, point);
return skuDiscountPrice > k.getPriceDetailDTO().getCouponPrice();
}
return false;
}).collect(Collectors.toList());
if (!unEnoughSku.isEmpty()) {
for (CartSkuVO cartSkuVO : skuVOList) {
if (unEnoughSku.isEmpty()) {
return;
}
if (skuPromotionDetail.containsKey(cartSkuVO.getGoodsSku().getId()) && unEnoughSku.stream().noneMatch(k -> k.getGoodsSku().getId().equals(cartSkuVO.getGoodsSku().getId()))) {
// 商品金额占比
double point = CurrencyUtil.div(cartSkuVO.getPriceDetailDTO().getGoodsPrice(), totalPrice, 4);
// 商品优惠金额
Double skuDiscountPrice = CurrencyUtil.mul(discountPrice, point);
// 商品优惠金额 - 不足优惠金额 = 差额
Double sub = CurrencyUtil.sub(skuDiscountPrice, unEnoughSku.get(0).getPriceDetailDTO().getCouponPrice());
// 分摊到其他商品 其他商品原优惠金额 + 差额
calculateCartSkuPromotionsPrice(cartSkuVO, sub, promotionTypeEnum, activityId);
// 从不足商品列表中移除
unEnoughSku.remove(0);
}
}
} else {
return;
}
calculateNotEnoughPromotionsPrice(skuVOList, skuPromotionDetail, discountPrice, totalPrice, promotionTypeEnum, activityId);
}
/**
* 检查活动有效时间
*

View File

@ -66,6 +66,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.SearchPage;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
@ -178,7 +179,7 @@ public class EsGoodsIndexServiceImpl extends BaseElasticsearchService implements
skuCountQueryWrapper.eq("auth_flag", GoodsAuthEnum.PASS.name());
skuCountQueryWrapper.eq("market_enable", GoodsStatusEnum.UPPER.name());
skuCountQueryWrapper.eq("delete_flag", false);
skuCountQueryWrapper.ge("quantity", 0);
skuCountQueryWrapper.gt("quantity", 0);
resultMap = new HashMap<>();
resultMap.put(KEY_SUCCESS, 0L);
resultMap.put(KEY_FAIL, 0L);
@ -675,14 +676,30 @@ public class EsGoodsIndexServiceImpl extends BaseElasticsearchService implements
@Override
public void deleteEsGoodsPromotionByPromotionKey(String promotionsKey) {
ThreadUtil.execAsync(() -> {
BulkRequest bulkRequest = new BulkRequest();
for (EsGoodsIndex goodsIndex : this.goodsIndexRepository.findAll()) {
UpdateRequest updateRequest = this.removePromotionByPromotionKey(goodsIndex, promotionsKey);
if (updateRequest != null) {
bulkRequest.add(updateRequest);
for (int i = 0; ; i++) {
BulkRequest bulkRequest = new BulkRequest();
NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
nativeSearchQueryBuilder.withQuery(QueryBuilders.matchAllQuery());
nativeSearchQueryBuilder.withPageable(PageRequest.of(i, 1000));
try {
SearchHits<EsGoodsIndex> esGoodsIndices = this.restTemplate.search(nativeSearchQueryBuilder.build(), EsGoodsIndex.class);
if (esGoodsIndices.isEmpty() || esGoodsIndices.getSearchHits().isEmpty()) {
break;
}
for (SearchHit<EsGoodsIndex> searchHit : esGoodsIndices.getSearchHits()) {
EsGoodsIndex goodsIndex = searchHit.getContent();
UpdateRequest updateRequest = this.removePromotionByPromotionKey(goodsIndex, promotionsKey);
if (updateRequest != null) {
bulkRequest.add(updateRequest);
}
}
this.executeBulkUpdateRequest(bulkRequest);
} catch (Exception e) {
log.error("删除索引中指定的促销活动id的促销活动失败key: {}", promotionsKey, e);
return;
}
}
this.executeBulkUpdateRequest(bulkRequest);
});
}

View File

@ -84,11 +84,12 @@ public class EsGoodsSearchServiceImpl implements EsGoodsSearchService {
//如果搜索词不为空且明显不是sql注入那么就将搜索词加入热搜词
//PS:线上环境运行很多客户反馈被sql攻击写在了搜索热词里这里控制命中关键字就不做热词统计如果线上比较严格可以调用关键词替换不过不建议这么做
if (CharSequenceUtil.isNotBlank(searchDTO.getKeyword()) && !SqlFilter.hit(searchDTO.getKeyword())) {
if (CharSequenceUtil.isNotBlank(searchDTO.getKeyword()) && Boolean.FALSE.equals(SqlFilter.hit(searchDTO.getKeyword()))) {
cache.incrementScore(CachePrefix.HOT_WORD.getPrefix(), searchDTO.getKeyword());
}
NativeSearchQueryBuilder searchQueryBuilder = createSearchQueryBuilder(searchDTO, pageVo);
NativeSearchQuery searchQuery = searchQueryBuilder.build();
searchQuery.setTrackTotalHits(true);
log.debug("searchGoods DSL:{}", searchQuery.getQuery());
SearchHits<EsGoodsIndex> search = restTemplate.search(searchQuery, EsGoodsIndex.class);
return SearchHitSupport.searchPageFor(search, searchQuery.getPageable());