Commit 86b02b698a99e186366b36b62aa1c07d80802c05

Authored by 痴货
1 parent e44c0e66

【功能】完成下单确认页价格计算功能(只做了满减,还没做满送)

yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java
@@ -46,6 +46,7 @@ public interface ErrorCodeConstants { @@ -46,6 +46,7 @@ public interface ErrorCodeConstants {
46 ErrorCode REWARD_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED = new ErrorCode(1_013_006_003, "满减送活动未关闭,不能删除"); 46 ErrorCode REWARD_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED = new ErrorCode(1_013_006_003, "满减送活动未关闭,不能删除");
47 ErrorCode REWARD_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1_013_006_004, "满减送活动已关闭,不能重复关闭"); 47 ErrorCode REWARD_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1_013_006_004, "满减送活动已关闭,不能重复关闭");
48 ErrorCode REWARD_ACTIVITY_SCOPE_EXISTS = new ErrorCode(1_013_006_005, "与该时间段已存在的满减送活动商品范围冲突"); 48 ErrorCode REWARD_ACTIVITY_SCOPE_EXISTS = new ErrorCode(1_013_006_005, "与该时间段已存在的满减送活动商品范围冲突");
  49 + ErrorCode REWARD_ACTIVITY_TYPE_NOT_EXISTS = new ErrorCode(1_013_006_006, "满减送活动类型不存在");
49 50
50 // ========== TODO 空着 1-013-007-000 ============ 51 // ========== TODO 空着 1-013-007-000 ============
51 52
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/discount/DiscountProductMapper.java
1 package cn.iocoder.yudao.module.promotion.dal.mysql.discount; 1 package cn.iocoder.yudao.module.promotion.dal.mysql.discount;
2 2
3 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 3 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  4 +import cn.iocoder.yudao.module.promotion.api.discount.dto.DiscountProductRespDTO;
4 import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO; 5 import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO;
5 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 6 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
6 import org.apache.ibatis.annotations.Mapper; 7 import org.apache.ibatis.annotations.Mapper;
@@ -31,7 +32,7 @@ public interface DiscountProductMapper extends BaseMapperX<DiscountProductDO> { @@ -31,7 +32,7 @@ public interface DiscountProductMapper extends BaseMapperX<DiscountProductDO> {
31 } 32 }
32 33
33 // TODO @zhangshuai:逻辑里,尽量避免写 join 语句哈,你可以看看这个查询,有什么办法优化?目前的一个思路,是分 2 次查询,性能也是 ok 的 34 // TODO @zhangshuai:逻辑里,尽量避免写 join 语句哈,你可以看看这个查询,有什么办法优化?目前的一个思路,是分 2 次查询,性能也是 ok 的
34 - List<DiscountProductDO> getMatchDiscountProductList(@Param("skuIds") Collection<Long> skuIds); 35 + List<DiscountProductRespDTO> getMatchDiscountProductList(@Param("skuIds") Collection<Long> skuIds);
35 36
36 /** 37 /**
37 * 查询出指定 spuId 的 spu 参加的活动最接近现在的一条记录。多个的话,一个 spuId 对应一个最近的活动编号 38 * 查询出指定 spuId 的 spu 参加的活动最接近现在的一条记录。多个的话,一个 spuId 对应一个最近的活动编号
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityService.java
1 package cn.iocoder.yudao.module.promotion.service.discount; 1 package cn.iocoder.yudao.module.promotion.service.discount;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.promotion.api.discount.dto.DiscountProductRespDTO;
4 import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityCreateReqVO; 5 import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityCreateReqVO;
5 import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityPageReqVO; 6 import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityPageReqVO;
6 import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityUpdateReqVO; 7 import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityUpdateReqVO;
@@ -27,7 +28,7 @@ public interface DiscountActivityService { @@ -27,7 +28,7 @@ public interface DiscountActivityService {
27 * @param skuIds SKU 编号数组 28 * @param skuIds SKU 编号数组
28 * @return 匹配的限时折扣商品 29 * @return 匹配的限时折扣商品
29 */ 30 */
30 - List<DiscountProductDO> getMatchDiscountProductList(Collection<Long> skuIds); 31 + List<DiscountProductRespDTO> getMatchDiscountProductList(Collection<Long> skuIds);
31 32
32 /** 33 /**
33 * 创建限时折扣活动 34 * 创建限时折扣活动
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityServiceImpl.java
@@ -6,6 +6,7 @@ import cn.hutool.core.map.MapUtil; @@ -6,6 +6,7 @@ import cn.hutool.core.map.MapUtil;
6 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; 6 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
7 import cn.iocoder.yudao.framework.common.pojo.PageResult; 7 import cn.iocoder.yudao.framework.common.pojo.PageResult;
8 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 8 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  9 +import cn.iocoder.yudao.module.promotion.api.discount.dto.DiscountProductRespDTO;
9 import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityBaseVO; 10 import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityBaseVO;
10 import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityCreateReqVO; 11 import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityCreateReqVO;
11 import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityPageReqVO; 12 import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityPageReqVO;
@@ -49,7 +50,7 @@ public class DiscountActivityServiceImpl implements DiscountActivityService { @@ -49,7 +50,7 @@ public class DiscountActivityServiceImpl implements DiscountActivityService {
49 private DiscountProductMapper discountProductMapper; 50 private DiscountProductMapper discountProductMapper;
50 51
51 @Override 52 @Override
52 - public List<DiscountProductDO> getMatchDiscountProductList(Collection<Long> skuIds) { 53 + public List<DiscountProductRespDTO> getMatchDiscountProductList(Collection<Long> skuIds) {
53 return discountProductMapper.getMatchDiscountProductList(skuIds); 54 return discountProductMapper.getMatchDiscountProductList(skuIds);
54 } 55 }
55 56
@@ -130,7 +131,7 @@ public class DiscountActivityServiceImpl implements DiscountActivityService { @@ -130,7 +131,7 @@ public class DiscountActivityServiceImpl implements DiscountActivityService {
130 List<DiscountProductDO> list = discountProductMapper.selectListByActivityId(id); 131 List<DiscountProductDO> list = discountProductMapper.selectListByActivityId(id);
131 // TODO @zhangshuai:一般简单的 stream 方法,建议是使用 CollectionUtils,例如说这里是 convertList 对把。 132 // TODO @zhangshuai:一般简单的 stream 方法,建议是使用 CollectionUtils,例如说这里是 convertList 对把。
132 List<Long> skuIds = list.stream().map(item -> item.getSkuId()).collect(Collectors.toList()); 133 List<Long> skuIds = list.stream().map(item -> item.getSkuId()).collect(Collectors.toList());
133 - List<DiscountProductDO> matchDiscountProductList = getMatchDiscountProductList(skuIds); 134 + List<DiscountProductRespDTO> matchDiscountProductList = getMatchDiscountProductList(skuIds);
134 if (id != null) { // 排除自己这个活动 135 if (id != null) { // 排除自己这个活动
135 matchDiscountProductList.removeIf(product -> id.equals(product.getActivityId())); 136 matchDiscountProductList.removeIf(product -> id.equals(product.getActivityId()));
136 } 137 }
yudao-module-mall/yudao-module-promotion-biz/src/main/resources/mapper/discount/DiscountProductMapper.xml
@@ -3,8 +3,8 @@ @@ -3,8 +3,8 @@
3 <mapper namespace="cn.iocoder.yudao.module.promotion.dal.mysql.discount.DiscountProductMapper"> 3 <mapper namespace="cn.iocoder.yudao.module.promotion.dal.mysql.discount.DiscountProductMapper">
4 4
5 5
6 - <select id="getMatchDiscountProductList" resultType="cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO">  
7 - SELECT pdp.* 6 + <select id="getMatchDiscountProductList" resultType="cn.iocoder.yudao.module.promotion.api.discount.dto.DiscountProductRespDTO">
  7 + SELECT pdp.*,pda.name as activity_name
8 FROM promotion_discount_product pdp 8 FROM promotion_discount_product pdp
9 LEFT JOIN promotion_discount_activity pda 9 LEFT JOIN promotion_discount_activity pda
10 ON pdp.activity_id = pda.id 10 ON pdp.activity_id = pda.id
@@ -17,8 +17,10 @@ @@ -17,8 +17,10 @@
17 </if> 17 </if>
18 AND pda.start_time &lt;= CURRENT_TIME AND pda.end_time &gt;= CURRENT_TIME 18 AND pda.start_time &lt;= CURRENT_TIME AND pda.end_time &gt;= CURRENT_TIME
19 AND pda.`status` = 0 19 AND pda.`status` = 0
20 - AND pda.deleted != 1 20 + AND pda.deleted =0
  21 + AND pdp.deleted = 0
21 </where> 22 </where>
  23 + ORDER BY pdp.id DESC
22 </select> 24 </select>
23 25
24 </mapper> 26 </mapper>
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementRespVO.java
1 package cn.iocoder.yudao.module.trade.controller.app.order.vo; 1 package cn.iocoder.yudao.module.trade.controller.app.order.vo;
2 2
3 import cn.iocoder.yudao.module.trade.controller.app.base.property.AppProductPropertyValueDetailRespVO; 3 import cn.iocoder.yudao.module.trade.controller.app.base.property.AppProductPropertyValueDetailRespVO;
  4 +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO;
4 import io.swagger.v3.oas.annotations.media.Schema; 5 import io.swagger.v3.oas.annotations.media.Schema;
5 import jakarta.validation.constraints.NotNull; 6 import jakarta.validation.constraints.NotNull;
6 import lombok.AllArgsConstructor; 7 import lombok.AllArgsConstructor;
@@ -31,6 +32,13 @@ public class AppTradeOrderSettlementRespVO { @@ -31,6 +32,13 @@ public class AppTradeOrderSettlementRespVO {
31 @Schema(description = "总积分", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") 32 @Schema(description = "总积分", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
32 private Integer totalPoint; 33 private Integer totalPoint;
33 34
  35 + /**
  36 + * 营销活动数组
  37 + *
  38 + * 只对应 {@link TradePriceCalculateRespBO.Price#items} 商品匹配的活动
  39 + */
  40 + private List<TradePriceCalculateRespBO.Promotion> promotions;
  41 +
34 @Schema(description = "购物项") 42 @Schema(description = "购物项")
35 @Data 43 @Data
36 public static class Item { 44 public static class Item {
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDiscountActivityPriceCalculator.java
@@ -3,6 +3,10 @@ package cn.iocoder.yudao.module.trade.service.price.calculator; @@ -3,6 +3,10 @@ package cn.iocoder.yudao.module.trade.service.price.calculator;
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 import cn.hutool.core.util.ObjectUtil; 4 import cn.hutool.core.util.ObjectUtil;
5 import cn.hutool.core.util.StrUtil; 5 import cn.hutool.core.util.StrUtil;
  6 +import cn.iocoder.yudao.module.member.api.level.MemberLevelApi;
  7 +import cn.iocoder.yudao.module.member.api.level.dto.MemberLevelRespDTO;
  8 +import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
  9 +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
6 import cn.iocoder.yudao.module.promotion.api.discount.DiscountActivityApi; 10 import cn.iocoder.yudao.module.promotion.api.discount.DiscountActivityApi;
7 import cn.iocoder.yudao.module.promotion.api.discount.dto.DiscountProductRespDTO; 11 import cn.iocoder.yudao.module.promotion.api.discount.dto.DiscountProductRespDTO;
8 import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum; 12 import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum;
@@ -32,6 +36,10 @@ public class TradeDiscountActivityPriceCalculator implements TradePriceCalculato @@ -32,6 +36,10 @@ public class TradeDiscountActivityPriceCalculator implements TradePriceCalculato
32 36
33 @Resource 37 @Resource
34 private DiscountActivityApi discountActivityApi; 38 private DiscountActivityApi discountActivityApi;
  39 + @Resource
  40 + private MemberLevelApi memberLevelApi;
  41 + @Resource
  42 + private MemberUserApi memberUserApi;
35 43
36 @Override 44 @Override
37 public void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) { 45 public void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) {
@@ -39,6 +47,7 @@ public class TradeDiscountActivityPriceCalculator implements TradePriceCalculato @@ -39,6 +47,7 @@ public class TradeDiscountActivityPriceCalculator implements TradePriceCalculato
39 if (ObjectUtil.notEqual(result.getType(), TradeOrderTypeEnum.NORMAL.getType())) { 47 if (ObjectUtil.notEqual(result.getType(), TradeOrderTypeEnum.NORMAL.getType())) {
40 return; 48 return;
41 } 49 }
  50 + //----------------------------------限时折扣计算-----------------------------------------
42 // 获得 SKU 对应的限时折扣活动 51 // 获得 SKU 对应的限时折扣活动
43 List<DiscountProductRespDTO> discountProducts = discountActivityApi.getMatchDiscountProductList( 52 List<DiscountProductRespDTO> discountProducts = discountActivityApi.getMatchDiscountProductList(
44 convertSet(result.getItems(), TradePriceCalculateRespBO.OrderItem::getSkuId)); 53 convertSet(result.getItems(), TradePriceCalculateRespBO.OrderItem::getSkuId));
@@ -47,27 +56,64 @@ public class TradeDiscountActivityPriceCalculator implements TradePriceCalculato @@ -47,27 +56,64 @@ public class TradeDiscountActivityPriceCalculator implements TradePriceCalculato
47 } 56 }
48 Map<Long, DiscountProductRespDTO> discountProductMap = convertMap(discountProducts, DiscountProductRespDTO::getSkuId); 57 Map<Long, DiscountProductRespDTO> discountProductMap = convertMap(discountProducts, DiscountProductRespDTO::getSkuId);
49 58
50 - // 处理每个 SKU 的限时折扣 59 +
  60 +
  61 + //----------------------------------会员计算-----------------------------------------
  62 +
  63 + // 获得用户的会员等级
  64 + MemberUserRespDTO user = memberUserApi.getUser(param.getUserId());
  65 + if (user.getLevelId() == null || user.getLevelId() <= 0) {
  66 + return;
  67 + }
  68 + MemberLevelRespDTO level = memberLevelApi.getMemberLevel(user.getLevelId());
  69 + if (level == null || level.getDiscountPercent() == null) {
  70 + return;
  71 + }
  72 +
  73 + // 2. 计算每个 SKU 的优惠金额
51 result.getItems().forEach(orderItem -> { 74 result.getItems().forEach(orderItem -> {
52 - // 1. 获取该 SKU 的优惠信息 75 +
  76 + //----------------------------------限时折扣计算-----------------------------------------
  77 +
  78 + // 2.1 计算限时折扣优惠信息
53 DiscountProductRespDTO discountProduct = discountProductMap.get(orderItem.getSkuId()); 79 DiscountProductRespDTO discountProduct = discountProductMap.get(orderItem.getSkuId());
54 if (discountProduct == null) { 80 if (discountProduct == null) {
55 return; 81 return;
56 } 82 }
57 - // 2. 计算优惠金额 83 + // 2.2 计算优惠金额
58 Integer newPayPrice = calculatePayPrice(discountProduct, orderItem); 84 Integer newPayPrice = calculatePayPrice(discountProduct, orderItem);
59 Integer newDiscountPrice = orderItem.getPayPrice() - newPayPrice; 85 Integer newDiscountPrice = orderItem.getPayPrice() - newPayPrice;
60 86
61 - // 3.1 记录优惠明细 87 +
  88 + //----------------------------------会员计算-----------------------------------------
  89 +
  90 + // 2.3 计算会员优惠金额
  91 + Integer vipPrice = calculateVipPrice(orderItem.getPayPrice(), level.getDiscountPercent());
  92 + if (vipPrice <= 0) {
  93 + return;
  94 + }
  95 +
  96 + // 2.4 记录优惠明细
62 if (orderItem.getSelected()) { 97 if (orderItem.getSelected()) {
63 - // 注意,只有在选中的情况下,才会记录到优惠明细。否则仅仅是更新 SKU 优惠金额,用于展示  
64 - TradePriceCalculatorHelper.addPromotion(result, orderItem,  
65 - discountProduct.getActivityId(), discountProduct.getActivityName(), PromotionTypeEnum.DISCOUNT_ACTIVITY.getType(),  
66 - StrUtil.format("限时折扣:省 {} 元", formatPrice(newDiscountPrice)),  
67 - newDiscountPrice); 98 + if(newDiscountPrice > vipPrice){
  99 + // 注意,只有在选中的情况下,才会记录到优惠明细。否则仅仅是更新 SKU 优惠金额,用于展示
  100 + TradePriceCalculatorHelper.addPromotion(result, orderItem,
  101 + discountProduct.getActivityId(), discountProduct.getActivityName(), PromotionTypeEnum.DISCOUNT_ACTIVITY.getType(),
  102 + StrUtil.format("限时折扣:省 {} 元", formatPrice(newDiscountPrice)),
  103 + newDiscountPrice);
  104 + // 2.5 更新 SKU 优惠金额
  105 + orderItem.setDiscountPrice(orderItem.getDiscountPrice() + newDiscountPrice);
  106 + }else{
  107 + // 注意,只有在选中的情况下,才会记录到优惠明细。否则仅仅是更新 SKU 优惠金额,用于展示
  108 + TradePriceCalculatorHelper.addPromotion(result, orderItem,
  109 + level.getId(), level.getName(), PromotionTypeEnum.MEMBER_LEVEL.getType(),
  110 + String.format("会员等级折扣:省 %s 元", formatPrice(vipPrice)),
  111 + vipPrice);
  112 + // 2.5 更新 SKU 的优惠金额
  113 + orderItem.setVipPrice(vipPrice);
  114 + }
68 } 115 }
69 - // 3.2 更新 SKU 优惠金额  
70 - orderItem.setDiscountPrice(orderItem.getDiscountPrice() + newDiscountPrice); 116 +
71 TradePriceCalculatorHelper.recountPayPrice(orderItem); 117 TradePriceCalculatorHelper.recountPayPrice(orderItem);
72 }); 118 });
73 TradePriceCalculatorHelper.recountAllPrice(result); 119 TradePriceCalculatorHelper.recountAllPrice(result);
@@ -77,7 +123,7 @@ public class TradeDiscountActivityPriceCalculator implements TradePriceCalculato @@ -77,7 +123,7 @@ public class TradeDiscountActivityPriceCalculator implements TradePriceCalculato
77 TradePriceCalculateRespBO.OrderItem orderItem) { 123 TradePriceCalculateRespBO.OrderItem orderItem) {
78 Integer price = orderItem.getPayPrice(); 124 Integer price = orderItem.getPayPrice();
79 if (PromotionDiscountTypeEnum.PRICE.getType().equals(discountProduct.getDiscountType())) { // 减价 125 if (PromotionDiscountTypeEnum.PRICE.getType().equals(discountProduct.getDiscountType())) { // 减价
80 - price -= discountProduct.getDiscountPrice() * orderItem.getCount(); 126 + price -= discountProduct.getDiscountPrice() * 100 * orderItem.getCount();
81 } else if (PromotionDiscountTypeEnum.PERCENT.getType().equals(discountProduct.getDiscountType())) { // 打折 127 } else if (PromotionDiscountTypeEnum.PERCENT.getType().equals(discountProduct.getDiscountType())) { // 打折
82 price = price * discountProduct.getDiscountPercent() / 100; 128 price = price * discountProduct.getDiscountPercent() / 100;
83 } else { 129 } else {
@@ -86,4 +132,19 @@ public class TradeDiscountActivityPriceCalculator implements TradePriceCalculato @@ -86,4 +132,19 @@ public class TradeDiscountActivityPriceCalculator implements TradePriceCalculato
86 return price; 132 return price;
87 } 133 }
88 134
  135 + /**
  136 + * 计算会员 VIP 优惠价格
  137 + *
  138 + * @param price 原价
  139 + * @param discountPercent 折扣
  140 + * @return 优惠价格
  141 + */
  142 + public Integer calculateVipPrice(Integer price, Integer discountPercent) {
  143 + if (discountPercent == null) {
  144 + return 0;
  145 + }
  146 + Integer newPrice = price * discountPercent / 100;
  147 + return price - newPrice;
  148 + }
  149 +
89 } 150 }
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeMemberLevelPriceCalculator.java
@@ -30,44 +30,49 @@ public class TradeMemberLevelPriceCalculator implements TradePriceCalculator { @@ -30,44 +30,49 @@ public class TradeMemberLevelPriceCalculator implements TradePriceCalculator {
30 @Resource 30 @Resource
31 private MemberUserApi memberUserApi; 31 private MemberUserApi memberUserApi;
32 32
  33 + /**
  34 + * 会员计算迁移到限时优惠计算里
  35 + * @param param
  36 + * @param result
  37 + */
33 @Override 38 @Override
34 public void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) { 39 public void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) {
35 - // 0. 只有【普通】订单,才计算该优惠  
36 - if (ObjectUtil.notEqual(result.getType(), TradeOrderTypeEnum.NORMAL.getType())) {  
37 - return;  
38 - }  
39 - // 1. 获得用户的会员等级  
40 - MemberUserRespDTO user = memberUserApi.getUser(param.getUserId());  
41 - if (user.getLevelId() == null || user.getLevelId() <= 0) {  
42 - return;  
43 - }  
44 - MemberLevelRespDTO level = memberLevelApi.getMemberLevel(user.getLevelId());  
45 - if (level == null || level.getDiscountPercent() == null) {  
46 - return;  
47 - }  
48 -  
49 - // 2. 计算每个 SKU 的优惠金额  
50 - result.getItems().forEach(orderItem -> {  
51 - // 2.1 计算优惠金额  
52 - Integer vipPrice = calculateVipPrice(orderItem.getPayPrice(), level.getDiscountPercent());  
53 - if (vipPrice <= 0) {  
54 - return;  
55 - }  
56 -  
57 - // 2.2 记录优惠明细  
58 - if (orderItem.getSelected()) {  
59 - // 注意,只有在选中的情况下,才会记录到优惠明细。否则仅仅是更新 SKU 优惠金额,用于展示  
60 - TradePriceCalculatorHelper.addPromotion(result, orderItem,  
61 - level.getId(), level.getName(), PromotionTypeEnum.MEMBER_LEVEL.getType(),  
62 - String.format("会员等级折扣:省 %s 元", formatPrice(vipPrice)),  
63 - vipPrice);  
64 - }  
65 -  
66 - // 2.3 更新 SKU 的优惠金额  
67 - orderItem.setVipPrice(vipPrice);  
68 - TradePriceCalculatorHelper.recountPayPrice(orderItem);  
69 - });  
70 - TradePriceCalculatorHelper.recountAllPrice(result); 40 +// // 0. 只有【普通】订单,才计算该优惠
  41 +// if (ObjectUtil.notEqual(result.getType(), TradeOrderTypeEnum.NORMAL.getType())) {
  42 +// return;
  43 +// }
  44 +// // 1. 获得用户的会员等级
  45 +// MemberUserRespDTO user = memberUserApi.getUser(param.getUserId());
  46 +// if (user.getLevelId() == null || user.getLevelId() <= 0) {
  47 +// return;
  48 +// }
  49 +// MemberLevelRespDTO level = memberLevelApi.getMemberLevel(user.getLevelId());
  50 +// if (level == null || level.getDiscountPercent() == null) {
  51 +// return;
  52 +// }
  53 +//
  54 +// // 2. 计算每个 SKU 的优惠金额
  55 +// result.getItems().forEach(orderItem -> {
  56 +// // 2.1 计算优惠金额
  57 +// Integer vipPrice = calculateVipPrice(orderItem.getPayPrice(), level.getDiscountPercent());
  58 +// if (vipPrice <= 0) {
  59 +// return;
  60 +// }
  61 +//
  62 +// // 2.2 记录优惠明细
  63 +// if (orderItem.getSelected()) {
  64 +// // 注意,只有在选中的情况下,才会记录到优惠明细。否则仅仅是更新 SKU 优惠金额,用于展示
  65 +// TradePriceCalculatorHelper.addPromotion(result, orderItem,
  66 +// level.getId(), level.getName(), PromotionTypeEnum.MEMBER_LEVEL.getType(),
  67 +// String.format("会员等级折扣:省 %s 元", formatPrice(vipPrice)),
  68 +// vipPrice);
  69 +// }
  70 +//
  71 +// // 2.3 更新 SKU 的优惠金额
  72 +// orderItem.setVipPrice(vipPrice);
  73 +// TradePriceCalculatorHelper.recountPayPrice(orderItem);
  74 +// });
  75 +// TradePriceCalculatorHelper.recountAllPrice(result);
71 } 76 }
72 77
73 /** 78 /**
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeRewardActivityPriceCalculator.java
@@ -23,8 +23,10 @@ import java.util.Comparator; @@ -23,8 +23,10 @@ import java.util.Comparator;
23 import java.util.List; 23 import java.util.List;
24 import java.util.Map; 24 import java.util.Map;
25 25
  26 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
26 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; 27 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
27 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList; 28 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList;
  29 +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.REWARD_ACTIVITY_TYPE_NOT_EXISTS;
28 import static cn.iocoder.yudao.module.trade.service.price.calculator.TradePriceCalculatorHelper.formatPrice; 30 import static cn.iocoder.yudao.module.trade.service.price.calculator.TradePriceCalculatorHelper.formatPrice;
29 31
30 // TODO @puhui999:相关的单测,建议改一改 32 // TODO @puhui999:相关的单测,建议改一改
@@ -53,9 +55,10 @@ public class TradeRewardActivityPriceCalculator implements TradePriceCalculator @@ -53,9 +55,10 @@ public class TradeRewardActivityPriceCalculator implements TradePriceCalculator
53 if (CollUtil.isEmpty(rewardActivities)) { 55 if (CollUtil.isEmpty(rewardActivities)) {
54 return; 56 return;
55 } 57 }
56 -  
57 - // 处理每个满减送活动  
58 - rewardActivities.forEach(rewardActivity -> calculate(param, result, rewardActivity)); 58 + // 处理最新的满减送活动
  59 + if(!rewardActivities.isEmpty()){
  60 + calculate(param, result, rewardActivities.get(0));
  61 + }
59 } 62 }
60 63
61 private void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result, 64 private void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result,
@@ -120,27 +123,24 @@ public class TradeRewardActivityPriceCalculator implements TradePriceCalculator @@ -120,27 +123,24 @@ public class TradeRewardActivityPriceCalculator implements TradePriceCalculator
120 /** 123 /**
121 * 获得满减送的订单项(商品)列表 124 * 获得满减送的订单项(商品)列表
122 * 125 *
123 - * @param result 计算结果 126 + * @param result 计算结果
124 * @param rewardActivity 满减送活动 127 * @param rewardActivity 满减送活动
125 * @return 订单项(商品)列表 128 * @return 订单项(商品)列表
126 */ 129 */
127 private List<TradePriceCalculateRespBO.OrderItem> filterMatchActivityOrderItems(TradePriceCalculateRespBO result, 130 private List<TradePriceCalculateRespBO.OrderItem> filterMatchActivityOrderItems(TradePriceCalculateRespBO result,
128 RewardActivityMatchRespDTO rewardActivity) { 131 RewardActivityMatchRespDTO rewardActivity) {
129 - // 情况一:全部商品都可以参与  
130 - if (PromotionProductScopeEnum.isAll(rewardActivity.getProductScope())) { 132 + Integer productScope = rewardActivity.getProductScope();
  133 + if(PromotionProductScopeEnum.isAll(productScope)){
131 return result.getItems(); 134 return result.getItems();
132 - }  
133 - // 情况二:指定商品参与  
134 - if (PromotionProductScopeEnum.isSpu(rewardActivity.getProductScope())) { 135 + }else if (PromotionProductScopeEnum.isSpu(productScope)) {
135 return filterList(result.getItems(), 136 return filterList(result.getItems(),
136 orderItem -> CollUtil.contains(rewardActivity.getProductScopeValues(), orderItem.getSpuId())); 137 orderItem -> CollUtil.contains(rewardActivity.getProductScopeValues(), orderItem.getSpuId()));
137 - }  
138 - // 情况三:指定商品类型参与  
139 - if (PromotionProductScopeEnum.isCategory(rewardActivity.getProductScope())) { 138 + }else if (PromotionProductScopeEnum.isCategory(productScope)) {
140 return filterList(result.getItems(), 139 return filterList(result.getItems(),
141 orderItem -> CollUtil.contains(rewardActivity.getProductScopeValues(), orderItem.getCategoryId())); 140 orderItem -> CollUtil.contains(rewardActivity.getProductScopeValues(), orderItem.getCategoryId()));
  141 + }else{
  142 + throw exception(REWARD_ACTIVITY_TYPE_NOT_EXISTS);
142 } 143 }
143 - return List.of();  
144 } 144 }
145 145
146 /** 146 /**