Commit 92f6c8f4d673b8dcf3b8fd9b7330ce14d711ecb0

Authored by jason
2 parents 910ffa7a 24111c15

Merge remote-tracking branch 'origin/feature/mall_product' into feature/mall_product

yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/config/TradeConfigDO.java
... ... @@ -35,6 +35,17 @@ public class TradeConfigDO extends BaseDO {
35 35 @TableId
36 36 private Long id;
37 37  
  38 + // ========== 配送相关 ==========
  39 + // TODO 芋艿:未配置
  40 + /**
  41 + * 是否启用全场包邮
  42 + */
  43 + private Boolean deliveryExpressFreeEnabled;
  44 + /**
  45 + * 全场包邮的最小金额,单位:分
  46 + */
  47 + private Integer deliveryExpressFreePrice;
  48 +
38 49 // ========== 分销相关 ==========
39 50  
40 51 /**
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculator.java
... ... @@ -5,9 +5,11 @@ import cn.hutool.core.lang.Assert;
5 5 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
6 6 import cn.iocoder.yudao.module.member.api.address.AddressApi;
7 7 import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO;
  8 +import cn.iocoder.yudao.module.trade.dal.dataobject.config.TradeConfigDO;
8 9 import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryPickUpStoreDO;
9 10 import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryExpressChargeModeEnum;
10 11 import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum;
  12 +import cn.iocoder.yudao.module.trade.service.config.TradeConfigService;
11 13 import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressTemplateService;
12 14 import cn.iocoder.yudao.module.trade.service.delivery.DeliveryPickUpStoreService;
13 15 import cn.iocoder.yudao.module.trade.service.delivery.bo.DeliveryExpressTemplateRespBO;
... ... @@ -44,6 +46,8 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator {
44 46 private DeliveryPickUpStoreService deliveryPickUpStoreService;
45 47 @Resource
46 48 private DeliveryExpressTemplateService deliveryExpressTemplateService;
  49 + @Resource
  50 + private TradeConfigService tradeConfigService;
47 51  
48 52 @Override
49 53 public void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) {
... ... @@ -70,19 +74,25 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator {
70 74 // ========= 快递发货 ==========
71 75  
72 76 private void calculateExpress(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) {
73   - // 1. 得到收件地址区域
  77 + // 0. 得到收件地址区域
74 78 if (param.getAddressId() == null) {
75 79 throw exception(PRICE_CALCULATE_DELIVERY_PRICE_USER_ADDRESS_IS_EMPTY);
76 80 }
77 81 AddressRespDTO address = addressApi.getAddress(param.getAddressId(), param.getUserId());
78 82 Assert.notNull(address, "收件人({})的地址,不能为空", param.getUserId());
79 83  
80   - // 2. 过滤出已选中的商品SKU
  84 + // 情况一:全局包邮
  85 + if (isGlobalExpressFree(param, result)) {
  86 + return;
  87 + }
  88 +
  89 + // 情况二:
  90 + // 2.1 过滤出已选中的商品SKU
81 91 List<OrderItem> selectedItem = filterList(result.getItems(), OrderItem::getSelected);
82 92 Set<Long> deliveryTemplateIds = convertSet(selectedItem, OrderItem::getDeliveryTemplateId);
83 93 Map<Long, DeliveryExpressTemplateRespBO> expressTemplateMap =
84 94 deliveryExpressTemplateService.getExpressTemplateMapByIdsAndArea(deliveryTemplateIds, address.getAreaId());
85   - // 3. 计算配送费用
  95 + // 2.2 计算配送费用
86 96 if (CollUtil.isEmpty(expressTemplateMap)) {
87 97 log.error("[calculate][找不到商品 templateIds {} areaId{} 对应的运费模板]", deliveryTemplateIds, address.getAreaId());
88 98 throw exception(PRICE_CALCULATE_DELIVERY_PRICE_TEMPLATE_NOT_FOUND);
... ... @@ -90,6 +100,20 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator {
90 100 calculateDeliveryPrice(selectedItem, expressTemplateMap, result);
91 101 }
92 102  
  103 + /**
  104 + * 是否全局包邮
  105 + *
  106 + * @param param 计算信息
  107 + * @param result 计算结果
  108 + * @return 是否包邮
  109 + */
  110 + private boolean isGlobalExpressFree(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) {
  111 + TradeConfigDO config = tradeConfigService.getTradeConfig();
  112 + return config != null
  113 + && Boolean.TRUE.equals(config.getDeliveryExpressFreeEnabled()) // 开启包邮
  114 + && result.getPrice().getPayPrice() >= config.getDeliveryExpressFreePrice(); // 满足包邮的价格
  115 + }
  116 +
93 117 private void calculateDeliveryPrice(List<OrderItem> selectedSkus,
94 118 Map<Long, DeliveryExpressTemplateRespBO> expressTemplateMap,
95 119 TradePriceCalculateRespBO result) {
... ...
yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculatorTest.java
... ... @@ -4,8 +4,10 @@ import cn.hutool.core.map.MapUtil;
4 4 import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
5 5 import cn.iocoder.yudao.module.member.api.address.AddressApi;
6 6 import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO;
  7 +import cn.iocoder.yudao.module.trade.dal.dataobject.config.TradeConfigDO;
7 8 import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryExpressChargeModeEnum;
8 9 import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum;
  10 +import cn.iocoder.yudao.module.trade.service.config.TradeConfigService;
9 11 import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressTemplateService;
10 12 import cn.iocoder.yudao.module.trade.service.delivery.bo.DeliveryExpressTemplateRespBO;
11 13 import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO;
... ... @@ -34,10 +36,14 @@ public class TradeDeliveryPriceCalculatorTest extends BaseMockitoUnitTest {
34 36  
35 37 @InjectMocks
36 38 private TradeDeliveryPriceCalculator calculator;
  39 +
37 40 @Mock
38 41 private AddressApi addressApi;
  42 +
39 43 @Mock
40 44 private DeliveryExpressTemplateService deliveryExpressTemplateService;
  45 + @Mock
  46 + private TradeConfigService tradeConfigService;
41 47  
42 48 private TradePriceCalculateReqBO reqBO;
43 49 private TradePriceCalculateRespBO resultBO;
... ... @@ -90,8 +96,36 @@ public class TradeDeliveryPriceCalculatorTest extends BaseMockitoUnitTest {
90 96 }
91 97  
92 98 @Test
  99 + @DisplayName("全场包邮")
  100 + public void testCalculate_expressGlobalFree() {
  101 + // mock 方法(全场包邮)
  102 + when(tradeConfigService.getTradeConfig()).thenReturn(new TradeConfigDO().setDeliveryExpressFreeEnabled(true)
  103 + .setDeliveryExpressFreePrice(2200));
  104 +
  105 + // 调用
  106 + calculator.calculate(reqBO, resultBO);
  107 + TradePriceCalculateRespBO.Price price = resultBO.getPrice();
  108 + assertThat(price)
  109 + .extracting("totalPrice","discountPrice","couponPrice","pointPrice","deliveryPrice","payPrice")
  110 + .containsExactly(2200, 0, 0, 0, 0, 2200);
  111 + assertThat(resultBO.getItems()).hasSize(3);
  112 + // 断言:SKU1
  113 + assertThat(resultBO.getItems().get(0))
  114 + .extracting("price", "count","discountPrice" ,"couponPrice", "pointPrice","deliveryPrice","payPrice")
  115 + .containsExactly(100, 2, 0, 0, 0, 0, 200);
  116 + // 断言:SKU2
  117 + assertThat(resultBO.getItems().get(1))
  118 + .extracting("price", "count","discountPrice" ,"couponPrice", "pointPrice","deliveryPrice","payPrice")
  119 + .containsExactly(200, 10, 0, 0, 0, 0, 2000);
  120 + // 断言:SKU3 未选中
  121 + assertThat(resultBO.getItems().get(2))
  122 + .extracting("price", "count","discountPrice" ,"couponPrice", "pointPrice","deliveryPrice","payPrice")
  123 + .containsExactly(300, 1, 0, 0, 0, 0, 300);
  124 + }
  125 +
  126 + @Test
93 127 @DisplayName("按件计算运费不包邮的情况")
94   - public void testCalculateByExpressTemplateCharge() {
  128 + public void testCalculate_expressTemplateCharge() {
95 129 // SKU 1 : 100 * 2 = 200
96 130 // SKU 2 :200 * 10 = 2000
97 131 // 运费 首件 1000 + 续件 2000 = 3000
... ... @@ -123,7 +157,7 @@ public class TradeDeliveryPriceCalculatorTest extends BaseMockitoUnitTest {
123 157  
124 158 @Test
125 159 @DisplayName("按件计算运费包邮的情况")
126   - public void testCalculateByExpressTemplateFree() {
  160 + public void testCalculate_expressTemplateFree() {
127 161 // SKU 1 : 100 * 2 = 200
128 162 // SKU 2 :200 * 10 = 2000
129 163 // 运费 0
... ...