From 8fe046facef85567f44b0d1aaf5164afbda30fe1 Mon Sep 17 00:00:00 2001
From: zhanghua <314079846@qq.com>
Date: 星期三, 10 九月 2025 11:08:04 +0800
Subject: [PATCH] 添加优惠券限制单个商品使用逻辑
---
framework/src/main/java/cn/lili/modules/promotion/entity/dos/MemberCoupon.java | 3
framework/src/main/resources/mapper/lmk/VideoMapper.xml | 4
framework/src/main/java/cn/lili/modules/order/cart/render/impl/CouponRender.java | 47 +++++++++--
framework/src/main/java/cn/lili/modules/order/cart/render/impl/FullDiscountRender.java | 2
framework/src/main/java/cn/lili/modules/order/cart/render/util/PromotionPriceUtil.java | 154 +++++++++++++++++++++++--------------
framework/src/main/java/cn/lili/modules/promotion/entity/dos/Coupon.java | 3
framework/src/main/java/cn/lili/modules/order/cart/entity/dto/SkuMapDTO.java | 12 +++
7 files changed, 154 insertions(+), 71 deletions(-)
diff --git a/framework/src/main/java/cn/lili/modules/order/cart/entity/dto/SkuMapDTO.java b/framework/src/main/java/cn/lili/modules/order/cart/entity/dto/SkuMapDTO.java
new file mode 100644
index 0000000..ff4d8a7
--- /dev/null
+++ b/framework/src/main/java/cn/lili/modules/order/cart/entity/dto/SkuMapDTO.java
@@ -0,0 +1,12 @@
+package cn.lili.modules.order.cart.entity.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+@Data
+@AllArgsConstructor
+
+public class SkuMapDTO {
+ private String skuId;
+ private Double price;
+}
diff --git a/framework/src/main/java/cn/lili/modules/order/cart/render/impl/CouponRender.java b/framework/src/main/java/cn/lili/modules/order/cart/render/impl/CouponRender.java
index 36d0423..24c6404 100644
--- a/framework/src/main/java/cn/lili/modules/order/cart/render/impl/CouponRender.java
+++ b/framework/src/main/java/cn/lili/modules/order/cart/render/impl/CouponRender.java
@@ -5,6 +5,7 @@
import cn.lili.common.utils.CurrencyUtil;
import cn.lili.common.utils.StringUtils;
import cn.lili.modules.order.cart.entity.dto.MemberCouponDTO;
+import cn.lili.modules.order.cart.entity.dto.SkuMapDTO;
import cn.lili.modules.order.cart.entity.dto.TradeDTO;
import cn.lili.modules.order.cart.entity.enums.RenderStepEnums;
import cn.lili.modules.order.cart.entity.vo.CartSkuVO;
@@ -240,8 +241,13 @@
//鎺ユ敹鍏蜂綋浼樻儬鍒镐俊鎭�
MemberCoupon coupon = memberCouponDTO.getMemberCoupon();
+
+ Integer goodsNum = tradeDTO.getSkuList().stream().map(CartSkuVO::getNum).reduce(Integer::sum).get();
+
//澶勭悊涓�涓瀬绔儏鍐碉紝濡傛灉浼樻儬鍒告弧鍑忛噾棰濆ぇ浜庤鍗曢噾棰�
- if (coupon.getCouponType().equals(CouponTypeEnum.PRICE.name()) && coupon.getPrice() > countPrice) {
+ if (coupon.getCouponType().equals(CouponTypeEnum.PRICE.name())
+ && coupon.getPrice() > countPrice
+ && coupon.getGoodsUseLimitNum() >= goodsNum) {
//灏嗙鍚堜紭鎯犲埜鐨勯噾棰濆啓鍏ワ紝鍗虫渶澶ф墸鍑忛噾棰�
coupon.setPrice(countPrice);
}
@@ -264,21 +270,42 @@
* @param memberCouponDTO 鐢ㄤ簬璁$畻浼樻儬鍒哥粨绠楄鎯�
*/
private void renderCouponPrice(Map<String, Double> couponMap, TradeDTO tradeDTO, MemberCoupon coupon, MemberCouponDTO memberCouponDTO) {
+ List<SkuMapDTO> skuMapDTOList = new ArrayList<>();
+ for (String skuId : couponMap.keySet()) {
+ skuMapDTOList.add(new SkuMapDTO(skuId, couponMap.get(skuId)));
+ }
+ skuMapDTOList.sort((o1, o2) -> o2.getPrice().compareTo(o1.getPrice()));
//鍒嗗彂浼樻儬鍒�
- PromotionPriceUtil.recountPrice(tradeDTO, memberCouponDTO.getSkuDetail(), memberCouponDTO.getMemberCoupon().getPrice(),
- Boolean.TRUE.equals(coupon.getPlatformFlag()) ?
- PromotionTypeEnum.PLATFORM_COUPON : PromotionTypeEnum.COUPON, memberCouponDTO.getMemberCoupon().getCouponId());
+ PromotionPriceUtil.recountPrice(tradeDTO, memberCouponDTO.getSkuDetail(),
+ memberCouponDTO.getMemberCoupon().getPrice(),
+ Boolean.TRUE.equals(coupon.getPlatformFlag()) ? PromotionTypeEnum.PLATFORM_COUPON : PromotionTypeEnum.COUPON,
+ memberCouponDTO.getMemberCoupon().getCouponId(),
+ memberCouponDTO.getMemberCoupon().getGoodsUseLimitNum());
//濡傛灉鏄钩鍙板埜 鍒欓渶瑕佽绠楀晢瀹舵壙鎷呮瘮渚�
if (Boolean.TRUE.equals(coupon.getPlatformFlag()) && coupon.getStoreCommission() > 0) {
+ Integer i = coupon.getGoodsUseLimitNum();
//寰幆鎵�鏈変紭鎯犲埜
- for (String skuId : couponMap.keySet()) {
+ for (SkuMapDTO skuMapDTO : skuMapDTOList) {
for (CartSkuVO cartSkuVO : tradeDTO.getSkuList()) {
//鍐欏叆骞冲彴浼樻儬鍒告壙鎷呮瘮渚�
- if (cartSkuVO.getGoodsSku().getId().equals(skuId)) {
- //鍐欏叆搴楅摵鎵挎媴姣斾緥
- cartSkuVO.getPriceDetailDTO().setSiteCouponPoint(coupon.getStoreCommission());
+ if (cartSkuVO.getGoodsSku().getId().equals(skuMapDTO.getSkuId())) {
+ if (i == null) {
+ cartSkuVO.getPriceDetailDTO().setSiteCouponPoint(coupon.getStoreCommission());
+ } else {
+ if (i > 0) {
+ //鍐欏叆搴楅摵鎵挎媴姣斾緥
+ if (i >= cartSkuVO.getNum()) {
+ cartSkuVO.getPriceDetailDTO().setSiteCouponPoint(coupon.getStoreCommission());
+ } else {
+ cartSkuVO.getPriceDetailDTO().setSiteCouponPoint(coupon.getStoreCommission() * i / cartSkuVO.getNum());
+ }
+ i = i - cartSkuVO.getNum();
+ } else {
+ return;
+ }
+ }
}
}
}
@@ -294,6 +321,7 @@
* @param coupon 浼樻儬鍒镐俊鎭�
*/
private void renderCouponDiscount(Map<String, Double> couponMap, TradeDTO tradeDTO, MemberCoupon coupon) {
+
//寰幆鎵�鏈変紭鎯犲埜
for (String skuId : couponMap.keySet()) {
@@ -315,9 +343,10 @@
}
priceDetailDTO.setCouponPrice(CurrencyUtil.add(priceDetailDTO.getCouponPrice(), discountCouponPrice));
+ } else {
+ return;
}
}
}
}
-
}
diff --git a/framework/src/main/java/cn/lili/modules/order/cart/render/impl/FullDiscountRender.java b/framework/src/main/java/cn/lili/modules/order/cart/render/impl/FullDiscountRender.java
index 270caba..0015269 100644
--- a/framework/src/main/java/cn/lili/modules/order/cart/render/impl/FullDiscountRender.java
+++ b/framework/src/main/java/cn/lili/modules/order/cart/render/impl/FullDiscountRender.java
@@ -86,7 +86,7 @@
if (isFull(countPrice, cart)) {
//濡傛灉鍑忕幇閲�
if (Boolean.TRUE.equals(fullDiscount.getFullMinusFlag())) {
- PromotionPriceUtil.recountPrice(tradeDTO, skuPriceDetail, fullDiscount.getFullMinus(), PromotionTypeEnum.FULL_DISCOUNT, fullDiscountVO.getId());
+ PromotionPriceUtil.recountPrice(tradeDTO, skuPriceDetail, fullDiscount.getFullMinus(), PromotionTypeEnum.FULL_DISCOUNT, fullDiscountVO.getId(), 0);
}
//鎵撴姌
else if (Boolean.TRUE.equals(fullDiscount.getFullRateFlag())) {
diff --git a/framework/src/main/java/cn/lili/modules/order/cart/render/util/PromotionPriceUtil.java b/framework/src/main/java/cn/lili/modules/order/cart/render/util/PromotionPriceUtil.java
index f3dedc3..ad9333d 100644
--- a/framework/src/main/java/cn/lili/modules/order/cart/render/util/PromotionPriceUtil.java
+++ b/framework/src/main/java/cn/lili/modules/order/cart/render/util/PromotionPriceUtil.java
@@ -3,11 +3,13 @@
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.SkuMapDTO;
import cn.lili.modules.order.cart.entity.dto.TradeDTO;
import cn.lili.modules.order.cart.entity.vo.CartSkuVO;
import cn.lili.modules.order.order.entity.dto.DiscountPriceItem;
import lombok.extern.slf4j.Slf4j;
+import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
@@ -32,79 +34,111 @@
* @param promotionTypeEnum 淇冮攢绫诲瀷
*/
public static void recountPrice(TradeDTO tradeDTO, Map<String, Double> skuPromotionDetail, Double discountPrice,
- PromotionTypeEnum promotionTypeEnum, String activityId) {
+ PromotionTypeEnum promotionTypeEnum, String activityId, Integer goodsUseLimitNum) {
// sku 淇冮攢淇℃伅闈炵┖鍒ゅ畾
if (skuPromotionDetail == null || skuPromotionDetail.isEmpty()) {
return;
}
-
//璁$畻鎬婚噾棰�
Double totalPrice = 0D;
- for (Double value : skuPromotionDetail.values()) {
- totalPrice = CurrencyUtil.add(totalPrice, value);
- }
-
- //鏋佺鎯呭喌锛屽鏋滄墸鍑忛噾棰濆皬浜庨渶瑕佹敮浠樼殑閲戦锛屽垯鎵e噺閲戦=鏀粯閲戦锛屼笉鑳芥垚涓鸿礋鏁�
- if (discountPrice > totalPrice) {
- discountPrice = totalPrice;
-
- for (String skuId : skuPromotionDetail.keySet()) {
-
- //鑾峰彇瀵瑰簲鍟嗗搧杩涜璁$畻
- for (CartSkuVO cartSkuVO : tradeDTO.getSkuList()) {
-
- if (cartSkuVO.getGoodsSku().getId().equals(skuId)) {
- //浼樻儬鍒搁噾棰濓紝鍒欒鍏ヤ紭鎯犲埜 锛屽叾浠栧垯璁″叆鎬荤殑discount price
- if (promotionTypeEnum == PromotionTypeEnum.COUPON) {
- cartSkuVO.getPriceDetailDTO().setCouponPrice(cartSkuVO.getPriceDetailDTO().getGoodsPrice());
- } else {
- cartSkuVO.getPriceDetailDTO().setDiscountPrice(cartSkuVO.getPriceDetailDTO().getGoodsPrice());
- }
- }
- }
- }
- }
-
//鑾峰彇璐墿杞︿俊鎭�
List<CartSkuVO> skuVOList = tradeDTO.getSkuList();
-
- // 鑾峰彇map鍒嗛厤sku鐨勬�绘暟锛屽鏋滄槸鏈�鍚庝竴涓晢鍝佸垎閰嶉噾棰濓紝鍒欏皢閲戦浠庣櫨鍒嗘瘮鏀逛负鎬婚噾棰濇墸鍑忥紝閬垮厤鍑虹幇灏忔暟闄や笉灏�
- AtomicInteger count = new AtomicInteger(skuPromotionDetail.size());
//宸蹭紭鎯犻噾棰�
AtomicReference<Double> deducted = new AtomicReference<>(0D);
- for (String skuId : skuPromotionDetail.keySet()) {
+ if (goodsUseLimitNum > 0) {
+ // 澶勭悊闄愬埗鍟嗗搧鏁伴噺閫昏緫,鍙鐞嗕竴涓晢鍝�
+ List<SkuMapDTO> skuMapDTOList = new ArrayList<>();
+ for (String skuId : skuPromotionDetail.keySet()) {
+ skuMapDTOList.add(new SkuMapDTO(skuId, skuPromotionDetail.get(skuId)));
+ }
+ skuMapDTOList.sort((o1, o2) -> o2.getPrice().compareTo(o1.getPrice()));
- //鑾峰彇瀵瑰簲鍟嗗搧杩涜璁$畻
+ final int[] i = {0};
+ for (SkuMapDTO skuMap : skuMapDTOList) {
- Double finalDiscountPrice = discountPrice;
- Double finalTotalPrice = totalPrice;
- skuVOList.stream().filter(l -> l.getGoodsSku().getId().equals(skuId)).findFirst().ifPresent(cartSkuVO -> {
- //sku 浼樻儬閲戦
- Double skuDiscountPrice;
- count.getAndDecrement();
+ //鑾峰彇瀵瑰簲鍟嗗搧杩涜璁$畻
+ Double finalDiscountPrice = discountPrice;
+ skuVOList.stream().filter(l -> l.getGoodsSku().getId().equals(skuMap.getSkuId())).findFirst().ifPresent(cartSkuVO -> {
+ //sku 浼樻儬閲戦
+ Double skuDiscountPrice = 0D;
+ if (i[0] < 1) {
- //闈炴渶鍚庝竴涓晢鍝侊紝鍒欐寜鐓ф瘮渚嬭绠�
- 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));
+ if (cartSkuVO.getUtilPrice() > finalDiscountPrice) {
+ skuDiscountPrice = cartSkuVO.getUtilPrice() - finalDiscountPrice;
+ } else {
+ skuDiscountPrice = cartSkuVO.getUtilPrice();
+ }
+ //绱姞宸蹭紭鎯犻噾棰�
+ deducted.set(CurrencyUtil.add(deducted.get(), skuDiscountPrice));
+ i[0] = i[0] + 1;
+ }
+ calculateCartSkuPromotionsPrice(cartSkuVO, skuDiscountPrice, promotionTypeEnum, activityId);
+ });
+ discountPrice = deducted.get();
+ }
+ } else {
+ for (Double value : skuPromotionDetail.values()) {
+ totalPrice = CurrencyUtil.add(totalPrice, value);
+ }
+
+ //鏋佺鎯呭喌锛屽鏋滄墸鍑忛噾棰濆皬浜庨渶瑕佹敮浠樼殑閲戦锛屽垯鎵e噺閲戦=鏀粯閲戦锛屼笉鑳芥垚涓鸿礋鏁�
+ if (discountPrice > totalPrice) {
+ discountPrice = totalPrice;
+
+ for (String skuId : skuPromotionDetail.keySet()) {
+
+ //鑾峰彇瀵瑰簲鍟嗗搧杩涜璁$畻
+ for (CartSkuVO cartSkuVO : tradeDTO.getSkuList()) {
+
+ if (cartSkuVO.getGoodsSku().getId().equals(skuId)) {
+ //浼樻儬鍒搁噾棰濓紝鍒欒鍏ヤ紭鎯犲埜 锛屽叾浠栧垯璁″叆鎬荤殑discount price
+ if (promotionTypeEnum == PromotionTypeEnum.COUPON) {
+ cartSkuVO.getPriceDetailDTO().setCouponPrice(cartSkuVO.getPriceDetailDTO().getGoodsPrice());
+ } else {
+ cartSkuVO.getPriceDetailDTO().setDiscountPrice(cartSkuVO.getPriceDetailDTO().getGoodsPrice());
+ }
+ }
+ }
}
- // 濡傛灉鏄渶鍚庝竴涓晢鍝� 鍒欏噺鍘讳箣鍓嶄紭鎯犵殑閲戦鏉ヨ繘琛岃绠�
- else {
- skuDiscountPrice = CurrencyUtil.sub(finalDiscountPrice, deducted.get());
- }
+ }
- calculateCartSkuPromotionsPrice(cartSkuVO, skuDiscountPrice, promotionTypeEnum, activityId);
- });
+ // 鑾峰彇map鍒嗛厤sku鐨勬�绘暟锛屽鏋滄槸鏈�鍚庝竴涓晢鍝佸垎閰嶉噾棰濓紝鍒欏皢閲戦浠庣櫨鍒嗘瘮鏀逛负鎬婚噾棰濇墸鍑忥紝閬垮厤鍑虹幇灏忔暟闄や笉灏�
+ AtomicInteger count = new AtomicInteger(skuPromotionDetail.size());
+
+ for (String skuId : skuPromotionDetail.keySet()) {
+
+ //鑾峰彇瀵瑰簲鍟嗗搧杩涜璁$畻
+
+ Double finalDiscountPrice = discountPrice;
+ Double finalTotalPrice = totalPrice;
+ skuVOList.stream().filter(l -> l.getGoodsSku().getId().equals(skuId)).findFirst().ifPresent(cartSkuVO -> {
+ //sku 浼樻儬閲戦
+ Double skuDiscountPrice;
+ count.getAndDecrement();
+
+ //闈炴渶鍚庝竴涓晢鍝侊紝鍒欐寜鐓ф瘮渚嬭绠�
+ 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);
}
@@ -218,9 +252,11 @@
// 濡傛灉杩樻湁鍓╀綑閲戦锛屽垯缁х画鍒嗘憡
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);
+ if (skuPromotionDetail.containsKey(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;
}
@@ -235,9 +271,9 @@
private static void filterEnoughSku(List<CartSkuVO> skuVOList, Map<String, Double> skuPromotionDetail,
- Double discountPrice, Double totalPrice,
- AtomicReference<Double> balance, StringBuilder lastSkuId,
- PromotionTypeEnum promotionTypeEnum, String activityId) {
+ 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()) {
diff --git a/framework/src/main/java/cn/lili/modules/promotion/entity/dos/Coupon.java b/framework/src/main/java/cn/lili/modules/promotion/entity/dos/Coupon.java
index 0a8f172..2f801d8 100644
--- a/framework/src/main/java/cn/lili/modules/promotion/entity/dos/Coupon.java
+++ b/framework/src/main/java/cn/lili/modules/promotion/entity/dos/Coupon.java
@@ -82,6 +82,9 @@
@ApiModelProperty(value = "鏈夋晥鏈�")
private Integer effectiveDays;
+ @ApiModelProperty(value = "鍟嗗搧浣跨敤闄愬埗")
+ private Integer goodsUseLimitNum;
+
public Coupon(CouponVO couponVO) {
BeanUtils.copyProperties(couponVO, this);
}
diff --git a/framework/src/main/java/cn/lili/modules/promotion/entity/dos/MemberCoupon.java b/framework/src/main/java/cn/lili/modules/promotion/entity/dos/MemberCoupon.java
index 11c30b9..94d7111 100644
--- a/framework/src/main/java/cn/lili/modules/promotion/entity/dos/MemberCoupon.java
+++ b/framework/src/main/java/cn/lili/modules/promotion/entity/dos/MemberCoupon.java
@@ -107,6 +107,8 @@
@ApiModelProperty(value = "浼氬憳浼樻儬鍒哥姸鎬�")
private String memberCouponStatus;
+ @ApiModelProperty(value = "鍟嗗搧浣跨敤闄愬埗")
+ private Integer goodsUseLimitNum;
public MemberCoupon() {
}
@@ -120,6 +122,7 @@
setScopeType(coupon.getScopeType());
setScopeId(coupon.getScopeId());
setCouponType(coupon.getCouponType());
+ setGoodsUseLimitNum(coupon.getGoodsUseLimitNum());
setStartTime(coupon.getStartTime() == null ? new Date() : coupon.getStartTime());
setGetType(coupon.getGetType());
diff --git a/framework/src/main/resources/mapper/lmk/VideoMapper.xml b/framework/src/main/resources/mapper/lmk/VideoMapper.xml
index 58a6600..b6dc81b 100644
--- a/framework/src/main/resources/mapper/lmk/VideoMapper.xml
+++ b/framework/src/main/resources/mapper/lmk/VideoMapper.xml
@@ -300,7 +300,7 @@
LV.delete_flag = 0
AND LV.STATUS = '1'
AND LV.video_type = #{query.videoType}
- AND lm.id IS NOT NULL
+ AND LM.id IS NOT NULL
UNION ALL
SELECT
LV.author_id,
@@ -334,7 +334,7 @@
LV.delete_flag = 0
AND LV.STATUS = '1'
AND LV.video_type = #{query.videoType}
- AND lm.id IS NOT NULL
+ AND LM.id IS NOT NULL
ORDER BY
create_time DESC
</select>
--
Gitblit v1.8.0