Merge branch 'master' of gitee.com:beijing_hongye_huicheng/lilishop

This commit is contained in:
Chopper711 2024-09-14 11:17:44 +08:00
commit 2e8c40bcf3
4 changed files with 134 additions and 63 deletions

View File

@ -296,4 +296,13 @@ public interface GoodsSkuService extends IService<GoodsSku> {
* @return 库存数量
*/
Integer getGoodsStock(String goodsId);
/**
* 更新sku运费模版
*
* @param goodsId 商品id
* @param templateId 运费模版id
* @return 操作结果
*/
Boolean freight(List<String> goodsId, String templateId);
}

View File

@ -437,6 +437,7 @@ public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements
lambdaUpdateWrapper.in(Goods::getId, goodsIds);
List<String> goodsCache = goodsIds.stream().map(item -> CachePrefix.GOODS.getPrefix() + item).collect(Collectors.toList());
cache.multiDel(goodsCache);
goodsSkuService.freight(goodsIds, templateId);
return this.update(lambdaUpdateWrapper);
}

View File

@ -888,6 +888,17 @@ public class GoodsSkuServiceImpl extends ServiceImpl<GoodsSkuMapper, GoodsSku> i
}
@Override
public Boolean freight(List<String> goodsId, String templateId) {
LambdaUpdateWrapper<GoodsSku> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.in(GoodsSku::getGoodsId, goodsId);
updateWrapper.set(GoodsSku::getFreightTemplateId, templateId);
updateWrapper.set(GoodsSku::getUpdateTime, new Date());
List<String> skuIds = this.list(updateWrapper).stream().map(GoodsSku::getId).collect(Collectors.toList());
skuIds.forEach(this::clearCache);
return this.update(updateWrapper);
}
/**
* 渲染商品sku
*

View File

@ -1,5 +1,6 @@
package cn.lili.modules.order.cart.render.util;
import cn.hutool.core.map.MapUtil;
import cn.lili.common.enums.PromotionTypeEnum;
import cn.lili.common.utils.CurrencyUtil;
import cn.lili.modules.order.cart.entity.dto.TradeDTO;
@ -10,7 +11,8 @@ import lombok.extern.slf4j.Slf4j;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
/**
* 促销价格计算业务层实现
@ -33,7 +35,7 @@ public class PromotionPriceUtil {
PromotionTypeEnum promotionTypeEnum, String activityId) {
// sku 促销信息非空判定
if (skuPromotionDetail == null || skuPromotionDetail.size() == 0) {
if (skuPromotionDetail == null || skuPromotionDetail.isEmpty()) {
return;
}
@ -68,40 +70,39 @@ public class PromotionPriceUtil {
List<CartSkuVO> skuVOList = tradeDTO.getSkuList();
// 获取map分配sku的总数如果是最后一个商品分配金额则将金额从百分比改为总金额扣减避免出现小数除不尽
int count = skuPromotionDetail.size();
AtomicInteger count = new AtomicInteger(skuPromotionDetail.size());
//已优惠金额
Double deducted = 0D;
AtomicReference<Double> deducted = new AtomicReference<>(0D);
for (String skuId : skuPromotionDetail.keySet()) {
//获取对应商品进行计算
for (CartSkuVO cartSkuVO : skuVOList) {
if (cartSkuVO.getGoodsSku().getId().equals(skuId)) {
Double finalDiscountPrice = discountPrice;
Double finalTotalPrice = totalPrice;
skuVOList.stream().filter(l -> l.getGoodsSku().getId().equals(skuId)).findFirst().ifPresent(cartSkuVO -> {
//sku 优惠金额
Double skuDiscountPrice;
count.getAndDecrement();
count--;
//sku 优惠金额
Double skuDiscountPrice;
//非最后一个商品则按照比例计算
if (count > 0) {
//商品金额占比
double point = CurrencyUtil.div(cartSkuVO.getPriceDetailDTO().getGoodsPrice(), totalPrice, 4);
//商品优惠金额
skuDiscountPrice = CurrencyUtil.mul(discountPrice, point);
//累加已优惠金额
deducted = CurrencyUtil.add(deducted, skuDiscountPrice);
}
// 如果是最后一个商品 则减去之前优惠的金额来进行计算
else {
skuDiscountPrice = CurrencyUtil.sub(discountPrice, deducted);
}
calculateCartSkuPromotionsPrice(cartSkuVO, skuDiscountPrice, promotionTypeEnum, activityId);
//非最后一个商品则按照比例计算
if (count.get() > 0) {
//商品金额占比
double point = CurrencyUtil.div(cartSkuVO.getPriceDetailDTO().getGoodsPrice(), finalTotalPrice, 4);
//商品优惠金额
skuDiscountPrice = CurrencyUtil.mul(finalDiscountPrice, point);
//累加已优惠金额
deducted.set(CurrencyUtil.add(deducted.get(), skuDiscountPrice));
}
}
// 如果是最后一个商品 则减去之前优惠的金额来进行计算
else {
skuDiscountPrice = CurrencyUtil.sub(finalDiscountPrice, deducted.get());
}
calculateCartSkuPromotionsPrice(cartSkuVO, skuDiscountPrice, promotionTypeEnum, activityId);
});
}
calculateNotEnoughPromotionsPrice(skuVOList, skuPromotionDetail, discountPrice, totalPrice, promotionTypeEnum, activityId);
@ -186,51 +187,100 @@ public class PromotionPriceUtil {
// 特殊情况处理如参与多个促销活动部分商品在其他促销计算后的金额不足以满足与当前参与的促销活动的优惠金额
// 但当前购物车内存在当前当前促销活动的其他商品且剩余金额也满足分摊不足商品的不足金额则分摊到其他商品上
// 满足当前促销的总优惠金额
if (skuPromotionDetail == null || skuPromotionDetail.isEmpty()) {
if (skuPromotionDetail == null || skuPromotionDetail.size() < 2) {
return;
}
// clone skuPromotionDetail
Map<String, Double> skuPromotionDetailClone = MapUtil.sortByValue(skuPromotionDetail, false);
// 未满足优惠金额的商品
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();
skuVOList.stream().filter(l -> l.getPriceDetailDTO().getFlowPrice() == 0 && skuPromotionDetailClone.containsKey(l.getGoodsSku().getId())).count();
// 参与当前促销活动的商品
long matchPromotionsCount = skuVOList.stream().filter(l -> skuPromotionDetailClone.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 k.getPriceDetailDTO().getCouponPrice() > 0 && skuDiscountPrice > k.getPriceDetailDTO().getCouponPrice();
// 分配到其他商品的优惠金额
AtomicReference<Double> balance = new AtomicReference<>(0D);
StringBuilder lastSkuId = new StringBuilder();
// 计数器
int count = 0;
// 检查是否有不满足优惠金额的商品
filterEnoughSku(skuVOList, skuPromotionDetailClone, discountPrice, totalPrice, balance, lastSkuId, promotionTypeEnum, activityId);
// 循环 优惠金额分摊直到所有商品都满足优惠金额
while (true) {
// 如果还有剩余金额则继续分摊
if (balance.get() > 0) {
skuPromotionDetailClone.remove(lastSkuId.toString());
double lastDiscountPrice = CurrencyUtil.sub(discountPrice, skuPromotionDetail.get(lastSkuId.toString()));
double lastTotalPrice = CurrencyUtil.sub(totalPrice, skuPromotionDetail.get(lastSkuId.toString()));
filterEnoughSku(skuVOList, skuPromotionDetailClone, lastDiscountPrice, lastTotalPrice, balance, lastSkuId, promotionTypeEnum, activityId);
} else {
break;
}
return false;
}).collect(Collectors.toList());
if (!unEnoughSku.isEmpty()) {
if (unEnoughSku.size() == skuVOList.size()) {
return;
count++;
// 防止死循环
if (count > skuPromotionDetail.size()) {
break;
}
for (CartSkuVO cartSkuVO : skuVOList) {
if (unEnoughSku.isEmpty()) {
break;
}
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);
}
private static void filterEnoughSku(List<CartSkuVO> skuVOList, Map<String, Double> skuPromotionDetail,
Double discountPrice, Double totalPrice,
AtomicReference<Double> balance, StringBuilder lastSkuId,
PromotionTypeEnum promotionTypeEnum, String activityId) {
AtomicInteger count = new AtomicInteger(skuPromotionDetail.size());
AtomicReference<Double> countPrice = new AtomicReference<>(0D);
for (String skuId : skuPromotionDetail.keySet()) {
skuVOList.forEach(l -> {
if (l.getGoodsSku().getId().equals(skuId)) {
count.getAndDecrement();
//商品金额占比
double point = CurrencyUtil.div(l.getPriceDetailDTO().getGoodsPrice(), totalPrice, 4);
//商品优惠金额
Double skuDiscountPrice;
if (count.get() > 0) {
//非最后一个商品则按照比例计算
skuDiscountPrice = CurrencyUtil.mul(discountPrice, point);
} else {
// 如果是最后一个商品 则减去之前优惠的金额来进行计算
skuDiscountPrice = CurrencyUtil.sub(discountPrice, countPrice.get());
}
if (balance.get() > 0) {
// 分摊到其他商品 其他商品原优惠金额 + 差额
calculateCartSkuPromotionsPrice(l, balance.get(), promotionTypeEnum, activityId);
}
// 如果商品优惠金额大于商品金额则取商品金额差额分摊到其他商品
if (skuDiscountPrice > l.getPriceDetailDTO().getGoodsPrice()) {
balance.set(CurrencyUtil.sub(skuDiscountPrice, l.getPriceDetailDTO().getGoodsPrice()));
lastSkuId.append(skuId);
skuDiscountPrice = l.getPriceDetailDTO().getGoodsPrice();
} else {
balance.set(0D);
}
countPrice.set(CurrencyUtil.add(countPrice.get(), skuDiscountPrice));
}
});
}
}
/**