Commit e0d9f7cfbaccf578b9b0351f8eec077404183c7e

Authored by puhui999
1 parent cccad2c6

【功能新增】商城: 满减送活动下单后,赠送积分、优惠劵、包邮

Showing 13 changed files with 135 additions and 41 deletions
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityBaseVO.java
... ... @@ -96,7 +96,7 @@ public class RewardActivityBaseVO {
96 96 @AssertTrue(message = "优惠劵和数量必须一一对应")
97 97 @JsonIgnore
98 98 public boolean isCouponCountsValid() {
99   - return BooleanUtil.isFalse(givePoint) || CollUtil.size(couponIds) == CollUtil.size(couponCounts);
  99 + return BooleanUtil.isFalse(giveCoupon) || CollUtil.size(couponIds) == CollUtil.size(couponCounts);
100 100 }
101 101  
102 102 @AssertTrue(message = "赠送的积分不能小于 1")
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordServiceImpl.java
... ... @@ -340,7 +340,7 @@ public class CombinationRecordServiceImpl implements CombinationRecordService {
340 340 CombinationRecordStatusEnum.FAILED);
341 341 // 2. 订单取消
342 342 headAndRecords.forEach(item -> tradeOrderApi.cancelPaidOrder(item.getUserId(), item.getOrderId(),
343   - TradeOrderCancelTypeEnum.COMBINATION_CLOSE));
  343 + TradeOrderCancelTypeEnum.COMBINATION_CLOSE.getType()));
344 344 }
345 345  
346 346 /**
... ...
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/order/TradeOrderApi.java
1 1 package cn.iocoder.yudao.module.trade.api.order;
2 2  
3 3 import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderRespDTO;
4   -import cn.iocoder.yudao.module.trade.enums.order.TradeOrderCancelTypeEnum;
5 4  
6 5 import java.util.Collection;
7 6 import java.util.List;
... ... @@ -34,8 +33,8 @@ public interface TradeOrderApi {
34 33 *
35 34 * @param userId 用户编号
36 35 * @param orderId 订单编号
37   - * @param cancelTypeEnum 取消类型
  36 + * @param cancelType 取消类型
38 37 */
39   - void cancelPaidOrder(Long userId, Long orderId, TradeOrderCancelTypeEnum cancelTypeEnum);
  38 + void cancelPaidOrder(Long userId, Long orderId, Integer cancelType);
40 39  
41 40 }
... ...
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java
... ... @@ -60,6 +60,7 @@ public interface ErrorCodeConstants {
60 60 ErrorCode PRICE_CALCULATE_DELIVERY_PRICE_TEMPLATE_NOT_FOUND = new ErrorCode(1_011_003_002, "计算快递运费异常,找不到对应的运费模板");
61 61 ErrorCode PRICE_CALCULATE_COUPON_NOT_MATCH_NORMAL_ORDER = new ErrorCode(1_011_003_004, "参与秒杀、拼团、砍价的营销商品,无法使用优惠劵");
62 62 ErrorCode PRICE_CALCULATE_SECKILL_TOTAL_LIMIT_COUNT = new ErrorCode(1_011_003_005, "参与秒杀的商品,超过了秒杀总限购数量");
  63 + ErrorCode PRICE_CALCULATE_DELIVERY_PRICE_TYPE_ILLEGAL = new ErrorCode(1_011_003_006, "计算快递运费异常,配送方式不匹配");
63 64  
64 65 // ========== 物流 Express 模块 1-011-004-000 ==========
65 66 ErrorCode EXPRESS_NOT_EXISTS = new ErrorCode(1_011_004_000, "快递公司不存在");
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/api/order/TradeOrderApiImpl.java
... ... @@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.trade.api.order;
2 2  
3 3 import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderRespDTO;
4 4 import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert;
5   -import cn.iocoder.yudao.module.trade.enums.order.TradeOrderCancelTypeEnum;
6 5 import cn.iocoder.yudao.module.trade.service.order.TradeOrderQueryService;
7 6 import cn.iocoder.yudao.module.trade.service.order.TradeOrderUpdateService;
8 7 import jakarta.annotation.Resource;
... ... @@ -37,8 +36,8 @@ public class TradeOrderApiImpl implements TradeOrderApi {
37 36 }
38 37  
39 38 @Override
40   - public void cancelPaidOrder(Long userId, Long orderId, TradeOrderCancelTypeEnum cancelTypeEnum) {
41   - tradeOrderUpdateService.cancelPaidOrder(userId, orderId, cancelTypeEnum);
  39 + public void cancelPaidOrder(Long userId, Long orderId, Integer cancelType) {
  40 + tradeOrderUpdateService.cancelPaidOrder(userId, orderId, cancelType);
42 41 }
43 42  
44 43 }
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderItemDO.java
... ... @@ -160,6 +160,19 @@ public class TradeOrderItemDO extends BaseDO {
160 160 */
161 161 private Integer vipPrice;
162 162  
  163 + /**
  164 + * 赠送的优惠劵编号的数组
  165 + *
  166 + * 目的:用于后续取消或者售后订单时,需要扣减赠送
  167 + */
  168 + private List<Long> couponIds;
  169 + /**
  170 + * 赠送的优惠券数量的数组
  171 + *
  172 + * 目的:用于后续取消或者售后订单时,需要扣减赠送
  173 + */
  174 + private List<Integer> couponCounts;
  175 +
163 176 // ========== 售后基本信息 ==========
164 177  
165 178 /**
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateService.java
... ... @@ -9,7 +9,6 @@ import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderSettle
9 9 import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderSettlementRespVO;
10 10 import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemCommentCreateReqVO;
11 11 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
12   -import cn.iocoder.yudao.module.trade.enums.order.TradeOrderCancelTypeEnum;
13 12 import jakarta.validation.constraints.NotNull;
14 13  
15 14 /**
... ... @@ -186,14 +185,13 @@ public interface TradeOrderUpdateService {
186 185 */
187 186 void updateOrderCombinationInfo(Long orderId, Long activityId, Long combinationRecordId, Long headId);
188 187  
189   - // TODO @puhui999:不传递枚举哈。因为 rpc 不好支持。
190 188 /**
191 189 * 取消支付订单
192 190 *
193 191 * @param userId 用户编号
194 192 * @param orderId 订单编号
195   - * @param cancelType 取消类型
  193 + * @param cancelType 取消类型
196 194 */
197   - void cancelPaidOrder(Long userId, Long orderId, TradeOrderCancelTypeEnum cancelType);
  195 + void cancelPaidOrder(Long userId, Long orderId, Integer cancelType);
198 196  
199 197 }
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java
... ... @@ -858,8 +858,11 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
858 858  
859 859 @Override
860 860 @Transactional(rollbackFor = Exception.class)
861   - public void cancelPaidOrder(Long userId, Long orderId, TradeOrderCancelTypeEnum cancelType) {
862   - // TODO @puhui999:这里校验下 cancelType 只允许拼团关闭;
  861 + public void cancelPaidOrder(Long userId, Long orderId, Integer cancelType) {
  862 + // 1. 这里校验下 cancelType 只允许拼团关闭;
  863 + if (!TradeOrderCancelTypeEnum.COMBINATION_CLOSE.getType().equals(cancelType)) {
  864 + return;
  865 + }
863 866 // 1.1 检验订单存在
864 867 TradeOrderDO order = tradeOrderMapper.selectOrderByIdAndUserId(orderId, userId);
865 868 if (order == null) {
... ... @@ -876,13 +879,13 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
876 879 }
877 880  
878 881 // 2.1 取消订单
879   - cancelOrder0(order, cancelType);
  882 + cancelOrder0(order, TradeOrderCancelTypeEnum.COMBINATION_CLOSE);
880 883 // 2.2 创建退款单
881 884 payRefundApi.createRefund(new PayRefundCreateReqDTO()
882 885 .setAppKey(tradeOrderProperties.getPayAppKey()).setUserIp(getClientIP()) // 支付应用
883 886 .setMerchantOrderId(String.valueOf(order.getId())) // 支付单号
884 887 .setMerchantRefundId(String.valueOf(order.getId()))
885   - .setReason(cancelType.getName()).setPrice(order.getPayPrice()));// 价格信息
  888 + .setReason(TradeOrderCancelTypeEnum.COMBINATION_CLOSE.getName()).setPrice(order.getPayPrice()));// 价格信息
886 889 }
887 890  
888 891 /**
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeCouponOrderHandler.java
... ... @@ -4,9 +4,9 @@ import cn.iocoder.yudao.module.promotion.api.coupon.CouponApi;
4 4 import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponUseReqDTO;
5 5 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
6 6 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
  7 +import jakarta.annotation.Resource;
7 8 import org.springframework.stereotype.Component;
8 9  
9   -import jakarta.annotation.Resource;
10 10 import java.util.List;
11 11  
12 12 /**
... ... @@ -31,6 +31,11 @@ public class TradeCouponOrderHandler implements TradeOrderHandler {
31 31 }
32 32  
33 33 @Override
  34 + public void afterPayOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems) {
  35 +
  36 + }
  37 +
  38 + @Override
34 39 public void afterCancelOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems) {
35 40 if (order.getCouponId() == null || order.getCouponId() <= 0) {
36 41 return;
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java
... ... @@ -68,6 +68,21 @@ public class TradePriceCalculateRespBO {
68 68 private Long bargainActivityId;
69 69  
70 70 /**
  71 + * 是否包邮
  72 + */
  73 + private Boolean freeDelivery;
  74 +
  75 + // TODO @puhui999: 订单保存时需要保存
  76 + /**
  77 + * 赠送的优惠劵编号的数组
  78 + */
  79 + private List<Long> couponIds;
  80 + /**
  81 + * 赠送的优惠券数量的数组
  82 + */
  83 + private List<Integer> couponCounts;
  84 +
  85 + /**
71 86 * 订单价格
72 87 */
73 88 @Data
... ... @@ -213,8 +228,19 @@ public class TradePriceCalculateRespBO {
213 228 */
214 229 private Long categoryId;
215 230  
  231 + // ========== 物流相关字段 =========
  232 +
216 233 /**
217   - * 运费模板 Id
  234 + * 配送方式数组
  235 + *
  236 + * 对应 DeliveryTypeEnum 枚举
  237 + */
  238 + private List<Integer> deliveryTypes;
  239 +
  240 + /**
  241 + * 物流配置模板编号
  242 + *
  243 + * 对应 TradeDeliveryExpressTemplateDO 的 id 编号
218 244 */
219 245 private Long deliveryTemplateId;
220 246  
... ... @@ -234,7 +260,7 @@ public class TradePriceCalculateRespBO {
234 260 private List<ProductPropertyValueDetailRespDTO> properties;
235 261  
236 262 /**
237   - * 使用的积分
  263 + * 赠送的积分
238 264 */
239 265 private Integer givePoint;
240 266  
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculator.java
... ... @@ -6,8 +6,6 @@ import cn.hutool.core.util.StrUtil;
6 6 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
7 7 import cn.iocoder.yudao.module.member.api.address.MemberAddressApi;
8 8 import cn.iocoder.yudao.module.member.api.address.dto.MemberAddressRespDTO;
9   -import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
10   -import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
11 9 import cn.iocoder.yudao.module.trade.dal.dataobject.config.TradeConfigDO;
12 10 import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryPickUpStoreDO;
13 11 import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryExpressChargeModeEnum;
... ... @@ -30,8 +28,7 @@ import java.util.Set;
30 28  
31 29 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
32 30 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
33   -import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.PICK_UP_STORE_NOT_EXISTS;
34   -import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.PRICE_CALCULATE_DELIVERY_PRICE_TEMPLATE_NOT_FOUND;
  31 +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*;
35 32  
36 33 /**
37 34 * 运费的 {@link TradePriceCalculator} 实现类
... ... @@ -52,19 +49,15 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator {
52 49 private DeliveryExpressTemplateService deliveryExpressTemplateService;
53 50 @Resource
54 51 private TradeConfigService tradeConfigService;
55   - @Resource
56   - private ProductSpuApi productSpuApi;
57 52  
58 53 @Override
59 54 public void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) {
60 55 if (param.getDeliveryType() == null) {
61 56 return;
62 57 }
63   - // TODO @puhui999:1)TradePriceCalculateRespBO 传递进来 delveryType 配送方式,减少读取;2)如果不匹配,抛出业务异常; = = 不然就不扣钱啦。
64 58 // 校验是不是存在商品不能门店自提,或者不能快递发货的情况。就是说,配送方式不匹配哈
65   - List<ProductSpuRespDTO> spuList = productSpuApi.getSpuList(convertSet(result.getItems(), OrderItem::getSpuId));
66   - if (anyMatch(spuList, item -> !item.getDeliveryTypes().contains(param.getDeliveryType()))) {
67   - return;
  59 + if (anyMatch(result.getItems(), item -> !item.getDeliveryTypes().contains(param.getDeliveryType()))) {
  60 + throw exception(PRICE_CALCULATE_DELIVERY_PRICE_TYPE_ILLEGAL);
68 61 }
69 62  
70 63 if (DeliveryTypeEnum.PICK_UP.getType().equals(param.getDeliveryType())) {
... ... @@ -101,7 +94,12 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator {
101 94 return;
102 95 }
103 96  
104   - // 情况二:快递模版
  97 + // 情况二:活动包邮
  98 + if (Boolean.TRUE.equals(result.getFreeDelivery())) {
  99 + return;
  100 + }
  101 +
  102 + // 情况三:快递模版
105 103 // 2.1 过滤出已选中的商品 SKU
106 104 List<OrderItem> selectedItem = filterList(result.getItems(), OrderItem::getSelected);
107 105 Set<Long> deliveryTemplateIds = convertSet(selectedItem, OrderItem::getDeliveryTemplateId);
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java
... ... @@ -31,8 +31,8 @@ public class TradePriceCalculatorHelper {
31 31 List<ProductSpuRespDTO> spuList, List<ProductSkuRespDTO> skuList) {
32 32 // 创建 PriceCalculateRespDTO 对象
33 33 TradePriceCalculateRespBO result = new TradePriceCalculateRespBO();
34   - result.setType(getOrderType(param));
35   - result.setPromotions(new ArrayList<>());
  34 + result.setType(getOrderType(param)).setPromotions(new ArrayList<>())
  35 + .setCouponIds(new ArrayList<>()).setCouponCounts(new ArrayList<>());
36 36  
37 37 // 创建它的 OrderItem 属性
38 38 result.setItems(new ArrayList<>(param.getItems().size()));
... ... @@ -60,7 +60,7 @@ public class TradePriceCalculatorHelper {
60 60 .setWeight(sku.getWeight()).setVolume(sku.getVolume());
61 61 // spu 信息
62 62 orderItem.setSpuName(spu.getName()).setCategoryId(spu.getCategoryId())
63   - .setDeliveryTemplateId(spu.getDeliveryTemplateId())
  63 + .setDeliveryTypes(spu.getDeliveryTypes()).setDeliveryTemplateId(spu.getDeliveryTemplateId())
64 64 .setGivePoint(spu.getGiveIntegral()).setUsePoint(0);
65 65 if (StrUtil.isBlank(orderItem.getPicUrl())) {
66 66 orderItem.setPicUrl(spu.getPicUrl());
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeRewardActivityPriceCalculator.java
... ... @@ -3,9 +3,11 @@ package cn.iocoder.yudao.module.trade.service.price.calculator;
3 3 import cn.hutool.core.collection.CollUtil;
4 4 import cn.hutool.core.util.ObjectUtil;
5 5 import cn.hutool.core.util.StrUtil;
  6 +import cn.iocoder.yudao.framework.common.util.number.MoneyUtils;
6 7 import cn.iocoder.yudao.module.promotion.api.reward.RewardActivityApi;
7 8 import cn.iocoder.yudao.module.promotion.api.reward.dto.RewardActivityMatchRespDTO;
8 9 import cn.iocoder.yudao.module.promotion.enums.common.PromotionConditionTypeEnum;
  10 +import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum;
9 11 import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum;
10 12 import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum;
11 13 import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO;
... ... @@ -14,6 +16,8 @@ import jakarta.annotation.Resource;
14 16 import org.springframework.core.annotation.Order;
15 17 import org.springframework.stereotype.Component;
16 18  
  19 +import java.util.ArrayList;
  20 +import java.util.Comparator;
17 21 import java.util.List;
18 22  
19 23 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
... ... @@ -61,7 +65,7 @@ public class TradeRewardActivityPriceCalculator implements TradePriceCalculator
61 65 if (rule == null) {
62 66 TradePriceCalculatorHelper.addNotMatchPromotion(result, orderItems,
63 67 rewardActivity.getId(), rewardActivity.getName(), PromotionTypeEnum.REWARD_ACTIVITY.getType(),
64   - getRewardActivityNotMeetTip(rewardActivity));
  68 + getRewardActivityNotMeetTip(rewardActivity, orderItems));
65 69 return;
66 70 }
67 71  
... ... @@ -84,6 +88,26 @@ public class TradeRewardActivityPriceCalculator implements TradePriceCalculator
84 88 TradePriceCalculatorHelper.recountPayPrice(orderItem);
85 89 }
86 90 TradePriceCalculatorHelper.recountAllPrice(result);
  91 +
  92 + // 4.1 记录赠送的积分
  93 + if (rule.getGivePoint()) {
  94 + List<Integer> dividePoints = TradePriceCalculatorHelper.dividePrice(orderItems, rule.getPoint());
  95 + for (int i = 0; i < orderItems.size(); i++) {
  96 + TradePriceCalculateRespBO.OrderItem orderItem = orderItems.get(i);
  97 + // 商品可能赠送了积分,所以这里要加上
  98 + orderItem.setGivePoint(orderItem.getGivePoint() + dividePoints.get(i));
  99 + }
  100 + }
  101 + // 4.2 记录订单是否包邮
  102 + if (rule.getFreeDelivery()) {
  103 + // 只要满足一个活动包邮那么这单就包邮
  104 + result.setFreeDelivery(true);
  105 + }
  106 + // 4.3 记录赠送的优惠券
  107 + if (rule.getGiveCoupon()) {
  108 + // TODO @puhui999: 需要考虑赠送的优惠券是否重叠,重叠则对数量进行累加
  109 + result.setCouponIds(rule.getCouponIds()).setCouponCounts(rule.getCouponCounts());
  110 + }
87 111 }
88 112  
89 113 /**
... ... @@ -95,9 +119,21 @@ public class TradeRewardActivityPriceCalculator implements TradePriceCalculator
95 119 */
96 120 private List<TradePriceCalculateRespBO.OrderItem> filterMatchActivityOrderItems(TradePriceCalculateRespBO result,
97 121 RewardActivityMatchRespDTO rewardActivity) {
98   - // TODO @puhui999:是不是得根据类型过滤哈
99   - return filterList(result.getItems(),
100   - orderItem -> CollUtil.contains(rewardActivity.getProductScopeValues(), orderItem.getSpuId()));
  122 + // 情况一:全部商品都可以参与
  123 + if (PromotionProductScopeEnum.isAll(rewardActivity.getProductScope())) {
  124 + return result.getItems();
  125 + }
  126 + // 情况二:指定商品参与
  127 + if (PromotionProductScopeEnum.isSpu(rewardActivity.getProductScope())) {
  128 + return filterList(result.getItems(),
  129 + orderItem -> CollUtil.contains(rewardActivity.getProductScopeValues(), orderItem.getSpuId()));
  130 + }
  131 + // 情况三:指定商品类型参与
  132 + if (PromotionProductScopeEnum.isCategory(rewardActivity.getProductScope())) {
  133 + return filterList(result.getItems(),
  134 + orderItem -> CollUtil.contains(rewardActivity.getProductScopeValues(), orderItem.getCategoryId()));
  135 + }
  136 + return List.of();
101 137 }
102 138  
103 139 /**
... ... @@ -130,14 +166,30 @@ public class TradeRewardActivityPriceCalculator implements TradePriceCalculator
130 166 }
131 167  
132 168 /**
133   - * 获得满减送活动部匹配时的提示
  169 + * 获得满减送活动不匹配时的提示
134 170 *
135 171 * @param rewardActivity 满减送活动
136 172 * @return 提示
137 173 */
138   - private String getRewardActivityNotMeetTip(RewardActivityMatchRespDTO rewardActivity) {
139   - // TODO 芋艿:后面再想想;应该找第一个规则,算下还差多少即可。
140   - return "TODO";
  174 + private String getRewardActivityNotMeetTip(RewardActivityMatchRespDTO rewardActivity,
  175 + List<TradePriceCalculateRespBO.OrderItem> orderItems) {
  176 + // 1. 计算数量和价格
  177 + Integer count = TradePriceCalculatorHelper.calculateTotalCount(orderItems);
  178 + Integer price = TradePriceCalculatorHelper.calculateTotalPayPrice(orderItems);
  179 + assert count != null && price != null;
  180 +
  181 + // 2. 构建不满足时的提示信息-按最低档规则算
  182 + String meetTip = "满减送:购满 {} {},可以减 {} 元";
  183 + List<RewardActivityMatchRespDTO.Rule> rules = new ArrayList<>(rewardActivity.getRules());
  184 + rules.sort(Comparator.comparing(RewardActivityMatchRespDTO.Rule::getLimit)); // 按优惠门槛降序
  185 + RewardActivityMatchRespDTO.Rule rule = rules.get(0);
  186 + if (PromotionConditionTypeEnum.PRICE.getType().equals(rewardActivity.getConditionType())) {
  187 + return StrUtil.format(meetTip, rule.getLimit(), "元", MoneyUtils.fenToYuanStr(rule.getDiscountPrice()));
  188 + }
  189 + if (PromotionConditionTypeEnum.COUNT.getType().equals(rewardActivity.getConditionType())) {
  190 + return StrUtil.format(meetTip, rule.getLimit(), "件", MoneyUtils.fenToYuanStr(rule.getDiscountPrice()));
  191 + }
  192 + return StrUtil.EMPTY;
141 193 }
142 194  
143 195 }
... ...