feat: 足额免配送费

This commit is contained in:
Kroytz committed 2026-07-16 00:22:26 +08:00
1 parent be9601ff91
commit 2aa950e5f4
14 files changed
+72 -9

No files matched your search

@@ -234,6 +234,9 @@ public class AppStoreOrderServiceImpl extends ServiceImpl<StoreOrderMapper,Store
&& sumPrice.compareTo(storeShopDO.getMinPrice()) < 0) {
throw exception(STORE_ORDER_MIN_PRICE_NOT_MET);
}
if (OrderLogEnum.ORDER_TAKE_OUT.getValue().equals(param.getOrderType())) {
postagePrice = DeliveryCalculator.applyFreeDelivery(storeShopDO, sumPrice, postagePrice);
}
//计算优惠券价格
if(StrUtil.isNotBlank(param.getCouponId())){
@@ -67,6 +67,10 @@ public class StoreShopBaseVO {
@Schema(description = "配送规则(按距离区间阶梯计费)", example = "[{\"minKm\":1,\"maxKm\":3,\"price\":8}]")
private List<DeliveryRule> deliveryRules;
@Schema(description = "满额免配送费门槛,0或空表示不启用", example = "50")
@DecimalMin(value = "0", message = "免配送费门槛不能小于0")
private BigDecimal freeDeliveryAmount;
@Schema(description = "公告", required = true)
@NotNull(message = "公告不能为空")
private String notice;
@@ -24,6 +24,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.math.BigDecimal;
import java.util.List;
import static co.yixiang.yshop.framework.common.pojo.CommonResult.success;
@@ -80,8 +81,9 @@ public class AppStoreController {
@Operation(summary = "预估配送费")
public CommonResult<DeliveryFeeRespVO> getDeliveryFee(@RequestParam("shopId") Long shopId,
@RequestParam("lng") double lng,
@RequestParam("lat") double lat) {
return success(appStoreShopService.getDeliveryFee(shopId, lng, lat));
@RequestParam("lat") double lat,
@RequestParam(value = "amount", required = false) BigDecimal amount) {
return success(appStoreShopService.getDeliveryFee(shopId, lng, lat, amount));
}
@@ -57,6 +57,9 @@ public class AppStoreShopVO {
@Schema(description = "配送规则JSON文本", example = "[{\"minKm\":1,\"maxKm\":3,\"price\":8}]")
private String deliveryRules;
@Schema(description = "满额免配送费门槛,0或空表示不启用", example = "50")
private BigDecimal freeDeliveryAmount;
@Schema(description = "公告", required = true)
private String notice;
@@ -84,6 +84,10 @@ public class StoreShopDO extends BaseDO {
*/
@TableField(typeHandler = DeliveryRuleListTypeHandler.class)
private List<DeliveryRule> deliveryRules;
/**
* 满额免配送费门槛,0或空表示不启用
*/
private BigDecimal freeDeliveryAmount;
/**
* 公告
*/
@@ -5,6 +5,7 @@ import co.yixiang.yshop.module.store.controller.app.storeshop.vo.DeliveryFeeResp
import co.yixiang.yshop.module.store.dal.dataobject.storeshop.StoreShopDO;
import com.baomidou.mybatisplus.extension.service.IService;
import java.math.BigDecimal;
import java.util.List;
/**
@@ -30,6 +31,6 @@ public interface AppStoreShopService extends IService<StoreShopDO> {
* @param lat 收货地址纬度
* @return 配送费及是否超出配送范围
*/
DeliveryFeeRespVO getDeliveryFee(Long shopId, double lng, double lat);
DeliveryFeeRespVO getDeliveryFee(Long shopId, double lng, double lat, BigDecimal amount);
}
@@ -38,7 +38,7 @@ public class AppStoreShopServiceImpl extends ServiceImpl<StoreShopMapper, StoreS
}
@Override
public DeliveryFeeRespVO getDeliveryFee(Long shopId, double lng, double lat) {
public DeliveryFeeRespVO getDeliveryFee(Long shopId, double lng, double lat, BigDecimal amount) {
StoreShopDO shop = getById(shopId);
DeliveryFeeRespVO vo = new DeliveryFeeRespVO();
vo.setOutOfRange(true);
@@ -49,7 +49,8 @@ public class AppStoreShopServiceImpl extends ServiceImpl<StoreShopMapper, StoreS
vo.setMaxDistanceKm(shop.getDistance());
double distanceKm = DeliveryCalculator.calcDistanceKm(
shop.getLng(), shop.getLat(), String.valueOf(lng), String.valueOf(lat));
BigDecimal price = DeliveryCalculator.calcDeliveryPrice(shop, distanceKm);
BigDecimal price = DeliveryCalculator.applyFreeDelivery(shop, amount,
DeliveryCalculator.calcDeliveryPrice(shop, distanceKm));
vo.setDistanceKm(distanceKm);
if (price != null) {
vo.setOutOfRange(false);
@@ -83,4 +83,12 @@ public class DeliveryCalculator {
return shop.getDeliveryPrice();
}
public static BigDecimal applyFreeDelivery(StoreShopDO shop, BigDecimal orderAmount,
BigDecimal deliveryPrice) {
BigDecimal threshold = shop.getFreeDeliveryAmount();
return deliveryPrice != null && orderAmount != null && threshold != null
&& threshold.signum() > 0 && orderAmount.compareTo(threshold) >= 0
? BigDecimal.ZERO : deliveryPrice;
}
}
@@ -0,0 +1,25 @@
package co.yixiang.yshop.module.store.service.storeshop;
import co.yixiang.yshop.module.store.dal.dataobject.storeshop.StoreShopDO;
import org.junit.jupiter.api.Test;
import java.math.BigDecimal;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
class DeliveryCalculatorTest {
@Test
void applyFreeDeliveryUsesConfiguredThreshold() {
StoreShopDO shop = StoreShopDO.builder()
.freeDeliveryAmount(new BigDecimal("30"))
.build();
BigDecimal fee = new BigDecimal("8");
assertEquals(fee, DeliveryCalculator.applyFreeDelivery(shop, new BigDecimal("29.99"), fee));
assertEquals(BigDecimal.ZERO,
DeliveryCalculator.applyFreeDelivery(shop, new BigDecimal("30"), fee));
assertNull(DeliveryCalculator.applyFreeDelivery(shop, new BigDecimal("30"), null));
}
}