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

This commit is contained in:
jason 2023-09-22 19:05:20 +08:00
commit 92f6c8f4d6
3 changed files with 74 additions and 5 deletions

View File

@ -35,6 +35,17 @@ public class TradeConfigDO extends BaseDO {
@TableId
private Long id;
// ========== 配送相关 ==========
// TODO 芋艿未配置
/**
* 是否启用全场包邮
*/
private Boolean deliveryExpressFreeEnabled;
/**
* 全场包邮的最小金额单位
*/
private Integer deliveryExpressFreePrice;
// ========== 分销相关 ==========
/**

View File

@ -5,9 +5,11 @@ import cn.hutool.core.lang.Assert;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.module.member.api.address.AddressApi;
import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO;
import cn.iocoder.yudao.module.trade.dal.dataobject.config.TradeConfigDO;
import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryPickUpStoreDO;
import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryExpressChargeModeEnum;
import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum;
import cn.iocoder.yudao.module.trade.service.config.TradeConfigService;
import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressTemplateService;
import cn.iocoder.yudao.module.trade.service.delivery.DeliveryPickUpStoreService;
import cn.iocoder.yudao.module.trade.service.delivery.bo.DeliveryExpressTemplateRespBO;
@ -44,6 +46,8 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator {
private DeliveryPickUpStoreService deliveryPickUpStoreService;
@Resource
private DeliveryExpressTemplateService deliveryExpressTemplateService;
@Resource
private TradeConfigService tradeConfigService;
@Override
public void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) {
@ -70,19 +74,25 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator {
// ========= 快递发货 ==========
private void calculateExpress(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) {
// 1. 得到收件地址区域
// 0. 得到收件地址区域
if (param.getAddressId() == null) {
throw exception(PRICE_CALCULATE_DELIVERY_PRICE_USER_ADDRESS_IS_EMPTY);
}
AddressRespDTO address = addressApi.getAddress(param.getAddressId(), param.getUserId());
Assert.notNull(address, "收件人({})的地址,不能为空", param.getUserId());
// 2. 过滤出已选中的商品SKU
// 情况一全局包邮
if (isGlobalExpressFree(param, result)) {
return;
}
// 情况二
// 2.1 过滤出已选中的商品SKU
List<OrderItem> selectedItem = filterList(result.getItems(), OrderItem::getSelected);
Set<Long> deliveryTemplateIds = convertSet(selectedItem, OrderItem::getDeliveryTemplateId);
Map<Long, DeliveryExpressTemplateRespBO> expressTemplateMap =
deliveryExpressTemplateService.getExpressTemplateMapByIdsAndArea(deliveryTemplateIds, address.getAreaId());
// 3. 计算配送费用
// 2.2 计算配送费用
if (CollUtil.isEmpty(expressTemplateMap)) {
log.error("[calculate][找不到商品 templateIds {} areaId{} 对应的运费模板]", deliveryTemplateIds, address.getAreaId());
throw exception(PRICE_CALCULATE_DELIVERY_PRICE_TEMPLATE_NOT_FOUND);
@ -90,6 +100,20 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator {
calculateDeliveryPrice(selectedItem, expressTemplateMap, result);
}
/**
* 是否全局包邮
*
* @param param 计算信息
* @param result 计算结果
* @return 是否包邮
*/
private boolean isGlobalExpressFree(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) {
TradeConfigDO config = tradeConfigService.getTradeConfig();
return config != null
&& Boolean.TRUE.equals(config.getDeliveryExpressFreeEnabled()) // 开启包邮
&& result.getPrice().getPayPrice() >= config.getDeliveryExpressFreePrice(); // 满足包邮的价格
}
private void calculateDeliveryPrice(List<OrderItem> selectedSkus,
Map<Long, DeliveryExpressTemplateRespBO> expressTemplateMap,
TradePriceCalculateRespBO result) {

View File

@ -4,8 +4,10 @@ import cn.hutool.core.map.MapUtil;
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
import cn.iocoder.yudao.module.member.api.address.AddressApi;
import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO;
import cn.iocoder.yudao.module.trade.dal.dataobject.config.TradeConfigDO;
import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryExpressChargeModeEnum;
import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum;
import cn.iocoder.yudao.module.trade.service.config.TradeConfigService;
import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressTemplateService;
import cn.iocoder.yudao.module.trade.service.delivery.bo.DeliveryExpressTemplateRespBO;
import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO;
@ -34,10 +36,14 @@ public class TradeDeliveryPriceCalculatorTest extends BaseMockitoUnitTest {
@InjectMocks
private TradeDeliveryPriceCalculator calculator;
@Mock
private AddressApi addressApi;
@Mock
private DeliveryExpressTemplateService deliveryExpressTemplateService;
@Mock
private TradeConfigService tradeConfigService;
private TradePriceCalculateReqBO reqBO;
private TradePriceCalculateRespBO resultBO;
@ -89,9 +95,37 @@ public class TradeDeliveryPriceCalculatorTest extends BaseMockitoUnitTest {
.setCharge(chargeBO).setFree(freeBO));
}
@Test
@DisplayName("全场包邮")
public void testCalculate_expressGlobalFree() {
// mock 方法全场包邮
when(tradeConfigService.getTradeConfig()).thenReturn(new TradeConfigDO().setDeliveryExpressFreeEnabled(true)
.setDeliveryExpressFreePrice(2200));
// 调用
calculator.calculate(reqBO, resultBO);
TradePriceCalculateRespBO.Price price = resultBO.getPrice();
assertThat(price)
.extracting("totalPrice","discountPrice","couponPrice","pointPrice","deliveryPrice","payPrice")
.containsExactly(2200, 0, 0, 0, 0, 2200);
assertThat(resultBO.getItems()).hasSize(3);
// 断言SKU1
assertThat(resultBO.getItems().get(0))
.extracting("price", "count","discountPrice" ,"couponPrice", "pointPrice","deliveryPrice","payPrice")
.containsExactly(100, 2, 0, 0, 0, 0, 200);
// 断言SKU2
assertThat(resultBO.getItems().get(1))
.extracting("price", "count","discountPrice" ,"couponPrice", "pointPrice","deliveryPrice","payPrice")
.containsExactly(200, 10, 0, 0, 0, 0, 2000);
// 断言SKU3 未选中
assertThat(resultBO.getItems().get(2))
.extracting("price", "count","discountPrice" ,"couponPrice", "pointPrice","deliveryPrice","payPrice")
.containsExactly(300, 1, 0, 0, 0, 0, 300);
}
@Test
@DisplayName("按件计算运费不包邮的情况")
public void testCalculateByExpressTemplateCharge() {
public void testCalculate_expressTemplateCharge() {
// SKU 1 : 100 * 2 = 200
// SKU 2 200 * 10 = 2000
// 运费 首件 1000 + 续件 2000 = 3000
@ -123,7 +157,7 @@ public class TradeDeliveryPriceCalculatorTest extends BaseMockitoUnitTest {
@Test
@DisplayName("按件计算运费包邮的情况")
public void testCalculateByExpressTemplateFree() {
public void testCalculate_expressTemplateFree() {
// SKU 1 : 100 * 2 = 200
// SKU 2 200 * 10 = 2000
// 运费 0