diff --git a/mall-common/src/main/java/com/suisung/mall/common/pojo/dto/OrderCheckoutDTO.java b/mall-common/src/main/java/com/suisung/mall/common/pojo/dto/OrderCheckoutDTO.java index 8f77fee2..9a29c966 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/pojo/dto/OrderCheckoutDTO.java +++ b/mall-common/src/main/java/com/suisung/mall/common/pojo/dto/OrderCheckoutDTO.java @@ -9,30 +9,22 @@ import lombok.EqualsAndHashCode; @EqualsAndHashCode(callSuper = false) @ApiModel(value = "CheckoutDTO", description = "CheckoutDTO") public class OrderCheckoutDTO { - @ApiModelProperty(value = "用户编号") - private Integer user_id; - - @ApiModelProperty(value = "是否购物车下单") - private Integer ifcart; - - @ApiModelProperty(value = "收货地址编号") - private Integer ud_id = 0; - @ApiModelProperty(value = "下单商品数据:商品编号|数量,商品编号|数量...") String cart_id = ""; - - @ApiModelProperty(value = "门店编号") - private Integer chain_id = 0; - - @ApiModelProperty(value = "活动编号") - private Integer activity_id = 0; - - @ApiModelProperty(value = "团购编号") - private Integer pfgb_id = 0; - @ApiModelProperty(value = "购物车附件") String cart_file = ""; - + @ApiModelProperty(value = "用户编号") + private Integer user_id; + @ApiModelProperty(value = "是否购物车下单") + private Integer ifcart; + @ApiModelProperty(value = "收货地址编号") + private Integer ud_id = 0; + @ApiModelProperty(value = "门店编号") + private Integer chain_id = 0; + @ApiModelProperty(value = "活动编号") + private Integer activity_id = 0; + @ApiModelProperty(value = "团购编号") + private Integer pfgb_id = 0; @ApiModelProperty(value = "购物车附件标记") private boolean check_flag = false; diff --git a/mall-common/src/main/java/com/suisung/mall/common/pojo/dto/SameCityDeliveryFeeRespDTO.java b/mall-common/src/main/java/com/suisung/mall/common/pojo/dto/SameCityDeliveryFeeRespDTO.java new file mode 100644 index 00000000..f26e3b49 --- /dev/null +++ b/mall-common/src/main/java/com/suisung/mall/common/pojo/dto/SameCityDeliveryFeeRespDTO.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2024. Lorem ipsum dolor sit amet, consectetur adipiscing elit. + * Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan. + * Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna. + * Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus. + * Vestibulum commodo. Ut rhoncus gravida arcu. + */ + +package com.suisung.mall.common.pojo.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.math.BigDecimal; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@ApiModel(value = "同城配送配送费计算返回实体DTO", description = "同城配送配送费计算返回实体DTO") +public class SameCityDeliveryFeeRespDTO implements Serializable { + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "能否配送(在不在配送范围内)") + private Boolean canDelivery; + @ApiModelProperty(value = "是否免运费") + private Boolean isFree; + @ApiModelProperty(value = "原本基础运费") + private BigDecimal baseDeliveryFee; + @ApiModelProperty(value = "减免的运费") + private BigDecimal reduceDeliveryFee; + @ApiModelProperty(value = "最终的运费") + private BigDecimal deliveryFee; + @ApiModelProperty(value = "返回信息") + private String respMsg; +} diff --git a/mall-common/src/main/java/com/suisung/mall/common/pojo/dto/ShopStoreSameCityTransportBaseDTO.java b/mall-common/src/main/java/com/suisung/mall/common/pojo/dto/ShopStoreSameCityTransportBaseDTO.java index 6a7abd54..d73cc613 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/pojo/dto/ShopStoreSameCityTransportBaseDTO.java +++ b/mall-common/src/main/java/com/suisung/mall/common/pojo/dto/ShopStoreSameCityTransportBaseDTO.java @@ -25,12 +25,10 @@ import java.util.List; @ApiModel(value = "同城配送基础设置DTO", description = "同城配送基础设置DTO") public class ShopStoreSameCityTransportBaseDTO implements Serializable { private static final long serialVersionUID = 1L; - - @ApiModelProperty(value = "店铺同城快递基础运费设置") - ShopStoreSameCityTransportBase transportBase; - @ApiModelProperty(value = "店铺同城快递运费设置(起送条件+优惠条件)") public List transportList; + @ApiModelProperty(value = "店铺同城快递基础运费设置") + ShopStoreSameCityTransportBase transportBase; public void rebuildTransportList() { if (this.transportBase == null || this.transportList.isEmpty()) { diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/controller/admin/ShopStorePrinterController.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/controller/admin/ShopStorePrinterController.java index 2ace9f21..8143913f 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/store/controller/admin/ShopStorePrinterController.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/controller/admin/ShopStorePrinterController.java @@ -33,7 +33,7 @@ public class ShopStorePrinterController { @ApiOperation(value = "内部测试案例", notes = "内部测试案例") @RequestMapping(value = "/testcase", method = {RequestMethod.GET}) public CommonResult TestCase() { - Object data = shopStoreSameCityTransportBaseService.computeSameCityTransportFee(2L, BigDecimal.valueOf(110.085), BigDecimal.valueOf(23.37), 20000, BigDecimal.valueOf(102), BigDecimal.valueOf(96), BigDecimal.valueOf(94)); + Object data = shopStoreSameCityTransportBaseService.computeSameCityTransportFee(2L, BigDecimal.valueOf(120.085), BigDecimal.valueOf(23.37), 20000, BigDecimal.valueOf(102), BigDecimal.valueOf(96), BigDecimal.valueOf(94),true); return CommonResult.success(data); } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStoreSameCityTransportBaseService.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStoreSameCityTransportBaseService.java index 5419dcd0..bdc1ca08 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStoreSameCityTransportBaseService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStoreSameCityTransportBaseService.java @@ -10,6 +10,7 @@ package com.suisung.mall.shop.store.service; import com.suisung.mall.common.api.CommonResult; import com.suisung.mall.common.modules.store.ShopStoreSameCityTransportBase; +import com.suisung.mall.common.pojo.dto.SameCityDeliveryFeeRespDTO; import com.suisung.mall.common.pojo.dto.ShopStoreSameCityTransportBaseDTO; import org.springframework.data.util.Pair; @@ -67,8 +68,9 @@ public interface ShopStoreSameCityTransportBaseService { * @param orderProductAmount 订单商品原价金额 * @param orderDiscountAmount 订单商品折扣金额(订单原价减去每个商品折扣费) * @param orderPayAmount 订单实际支付金额(折扣金额-优惠券-积分扣-人工干预扣费),不包含运费 - * @return 是否能配送,最终同城配送费 + * @param canThrow 能否抛出异常? + * @return */ - Pair computeSameCityTransportFee(Long storeId, BigDecimal orderLongitude, BigDecimal orderLatitude, Integer weightGram, BigDecimal orderProductAmount, BigDecimal orderDiscountAmount, BigDecimal orderPayAmount); + SameCityDeliveryFeeRespDTO computeSameCityTransportFee(Long storeId, BigDecimal orderLongitude, BigDecimal orderLatitude, Integer weightGram, BigDecimal orderProductAmount, BigDecimal orderDiscountAmount, BigDecimal orderPayAmount, Boolean canThrow); } \ No newline at end of file diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreSameCityTransportBaseServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreSameCityTransportBaseServiceImpl.java index e10fe190..6a10e9f3 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreSameCityTransportBaseServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStoreSameCityTransportBaseServiceImpl.java @@ -15,11 +15,14 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.suisung.mall.common.api.CommonResult; import com.suisung.mall.common.constant.CommonConstant; import com.suisung.mall.common.domain.UserDto; +import com.suisung.mall.common.exception.ApiException; import com.suisung.mall.common.modules.store.ShopStoreBase; import com.suisung.mall.common.modules.store.ShopStoreSameCityTransport; import com.suisung.mall.common.modules.store.ShopStoreSameCityTransportBase; +import com.suisung.mall.common.pojo.dto.SameCityDeliveryFeeRespDTO; import com.suisung.mall.common.pojo.dto.ShopStoreSameCityTransportBaseDTO; import com.suisung.mall.common.utils.CommonUtil; +import com.suisung.mall.common.utils.I18nUtil; import com.suisung.mall.common.utils.PositionUtil; import com.suisung.mall.core.web.service.impl.BaseServiceImpl; import com.suisung.mall.shop.chain.controller.admin.ShopChainUserController; @@ -234,11 +237,7 @@ public class ShopStoreSameCityTransportBaseServiceImpl extends BaseServiceImpl computeSameCityTransportFee(Long storeId, BigDecimal orderLongitude, BigDecimal orderLatitude, Integer weightGram, BigDecimal orderProductAmount, BigDecimal orderDiscountAmount, BigDecimal orderPayAmount) { + public SameCityDeliveryFeeRespDTO computeSameCityTransportFee(Long storeId, BigDecimal orderLongitude, BigDecimal orderLatitude, Integer weightGram, BigDecimal orderProductAmount, BigDecimal orderDiscountAmount, BigDecimal orderPayAmount, Boolean canThrow) { + // 计算订单同城配送费, + // 1.先获取订单的经纬度,计算配送距离,获取配送范围,确定是否能配送,如果能计算基础运费? + // 2.如果能配送,再订单总重量,订单原价金额,订单折后金额,订单实付金额 + // 3.根据两点经纬度,计算配送距离,结合订单总重量,计算基础运费。 + // 4.查看是否有运费优惠设置,如果有,就直接从基础运费中扣除优惠运费,得出最终的订单配送费。 + // 该订单能否配送? Boolean canDelivery = false; if (CommonUtil.hasAnyBlank(storeId, orderLongitude, orderLatitude) || storeId <= 0) { - logger.error("同城配送费计算:缺少必要的参数"); - return Pair.of(canDelivery, BigDecimal.ZERO); + logger.error("同城配送费计算时,缺少必要的参数。"); + if (canThrow) { + throw new ApiException(I18nUtil._("同城配送费计算时,缺少必要的参数。")); + } + return new SameCityDeliveryFeeRespDTO(canDelivery, false, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, "同城配送费计算时,缺少必要的参数。"); } // 获取基础运费设置记录 ShopStoreSameCityTransportBase transportBase = getShopStoreSameCityTransportBaseById(storeId); if (CommonUtil.hasAnyBlank(transportBase, transportBase.getStore_longitude(), transportBase.getStore_latitude(), transportBase.getDistance_base(), transportBase.getDelivery_base_fee())) { logger.error("同城配送费计算:无法获取基础运费设置记录,或店铺经纬度为空"); - return Pair.of(canDelivery, BigDecimal.ZERO); + if (canThrow) { + throw new ApiException(I18nUtil._("商家未作同城配送设置。")); + } + return new SameCityDeliveryFeeRespDTO(canDelivery, false, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, "商家未作同城配送设置。"); } // 通过高德或百度地图api,计算两点的距离,如果服务不可用或无法计算,使用内部算法计算距离(单位米) @@ -277,7 +289,7 @@ public class ShopStoreSameCityTransportBaseServiceImpl extends BaseServiceImpl transportBase.getDistance_base() * 1000) { + if (CommonUtil.isAllNotBlank(transportBase.getDistance_increase_km(), transportBase.getDistance_increase_fee(), transportBase.getDistance_base()) && distance > transportBase.getDistance_base() * 1000) { // if (transportBase.getDistance_increase_km() != null && transportBase.getDistance_increase_fee() != null && transportBase.getDistance_base() != null && distance > transportBase.getDistance_base() * 1000) { // 实际配送距离超出基础距离,单位km BigDecimal diffDistanceM = CommonUtil.DecimalRoundHalfUp(BigDecimal.valueOf(distance - transportBase.getDistance_base() * 1000).divide(BigDecimal.valueOf(1000))); @@ -296,7 +308,7 @@ public class ShopStoreSameCityTransportBaseServiceImpl extends BaseServiceImpl transportBase.getWeight_base() * 1000) { + if (CommonUtil.isAllNotBlank(transportBase.getWeight_increase_kg(), transportBase.getWeight_increase_fee(), transportBase.getWeight_base()) && weightGram > transportBase.getWeight_base() * 1000) { // if (transportBase.getWeight_increase_kg() != null && transportBase.getWeight_increase_fee() != null && transportBase.getWeight_base() != null && weightGram > transportBase.getWeight_base() * 1000) { // 实际配送重量超出基础重量,单位kg BigDecimal diffWeightKg = CommonUtil.DecimalRoundHalfUp(BigDecimal.valueOf(weightGram - transportBase.getWeight_base() * 1000).divide(BigDecimal.valueOf(1000))); @@ -315,8 +327,8 @@ public class ShopStoreSameCityTransportBaseServiceImpl extends BaseServiceImpl 0) || (CommonConstant.Delivery_Amount_Comput_Type_Discounted.equals(transport.getMin_delivery_amount_type()) && transport.getMin_delivery_amount().compareTo(orderDiscountAmount) > 0) || (CommonConstant.Delivery_Amount_Comput_Type_Payment.equals(transport.getMin_delivery_amount_type()) && transport.getMin_delivery_amount().compareTo(orderPayAmount) > 0)) { - // 订单原价金额小于起送金额,返回订单不能送达了 canDelivery = false; continue; @@ -353,20 +363,25 @@ public class ShopStoreSameCityTransportBaseServiceImpl extends BaseServiceImpl= 0 ? deliveryBaseFee : BigDecimal.ZERO); + BigDecimal deliveryFee = deliveryBaseFee.subtract(reduceDeliveryFee); + boolean isFee = deliveryFee.compareTo(BigDecimal.ZERO) <= 0; + + return new SameCityDeliveryFeeRespDTO(canDelivery, isFee, deliveryBaseFee, reduceDeliveryFee, isFee ? BigDecimal.ZERO : deliveryFee, ""); } - - } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/user/service/impl/ShopUserCartServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/user/service/impl/ShopUserCartServiceImpl.java index 9055be5e..97100a5c 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/user/service/impl/ShopUserCartServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/user/service/impl/ShopUserCartServiceImpl.java @@ -32,6 +32,7 @@ import com.suisung.mall.common.modules.user.ShopUserCart; import com.suisung.mall.common.modules.user.ShopUserDeliveryAddress; import com.suisung.mall.common.modules.user.ShopUserVoucher; import com.suisung.mall.common.pojo.dto.OrderCheckoutDTO; +import com.suisung.mall.common.pojo.dto.SameCityDeliveryFeeRespDTO; import com.suisung.mall.common.service.MessageService; import com.suisung.mall.common.utils.CheckUtil; import com.suisung.mall.common.utils.I18nUtil; @@ -2474,6 +2475,7 @@ public class ShopUserCartServiceImpl extends BaseServiceImpl items = (List) cart_data.get("items"); @@ -2506,29 +2503,40 @@ public class ShopUserCartServiceImpl extends BaseServiceImpl pair = shopStoreSameCityTransportBaseService.computeSameCityTransportFee(storeId,storeLng,storeLat,0,productMoneyOriginGoods,orderSelDiscountAmount,orderPaymentAmount); + // 同城配送运费检查和计算(只返回数据,不能配送不抛异常) + SameCityDeliveryFeeRespDTO sameCityDeliveryFeeResp = shopStoreSameCityTransportBaseService.computeSameCityTransportFee(storeId,storeLng,storeLat,0,productMoneyOriginGoods,orderSelDiscountAmount,orderPaymentAmount,true); - Boolean postFree = pair.getFirst(); - store_row.put("postFree", postFree); // 是否免运费 - store_row.put("freight", pair.getSecond()); // 运费金额 - store_row.put("postFreeBalance", 0); // 还需postFreeBalance元即可免邮费 + // 是否能配送(在配送范围内) + Boolean canDelivery = sameCityDeliveryFeeResp.getCanDelivery(); - // 关键订单金额数据 - orderSelFreightAmount = orderSelFreightAmount.add(Convert.toBigDecimal(pair.getSecond())); // 重要:订单运费金额 - if(postFree) { + // 还差 postFreeBalance 元即可免运费 + BigDecimal postFreeBalance = BigDecimal.ZERO; + if(!sameCityDeliveryFeeResp.getIsFree()){ + postFreeBalance = sameCityDeliveryFeeResp.getBaseDeliveryFee().subtract(sameCityDeliveryFeeResp.getReduceDeliveryFee()); + } + + store_row.put("postFree", sameCityDeliveryFeeResp.getIsFree()); // 是否免运费 + store_row.put("freight", sameCityDeliveryFeeResp.getDeliveryFee()); // 运费金额 + store_row.put("postFreeBalance", postFreeBalance); // 还需postFreeBalance元即可免邮费 + + // 订单的总运费 + 本次订单的运费 + orderSelFreightAmount = orderSelFreightAmount.add(Convert.toBigDecimal(sameCityDeliveryFeeResp.getDeliveryFee())); // 重要:订单运费金额 + + if(canDelivery) { + // 如果能配送,最终支付金额+本次订单的运费。 orderSelMoneyAmount = orderSelMoneyAmount.add(Convert.toBigDecimal(store_row.get("order_money_select_items")));// 重要:订单折后金额(订单金额-折扣金额) } } + // 订单总计运费 cart_data.put("orderSelFreightAmount", orderSelFreightAmount); + // 订单总计支付金额 cart_data.put("orderSelMoneyAmount", orderSelMoneyAmount); + // 这些订单是否能配送(全局) + cart_data.put("can_delivery", can_delivery); - - } else { - // 普通快递运费计算和门店自取分支 - + } else { // 普通快递运费计算和门店自取分支 // 配送不到这个区域商品id List transport_type_none_ids = new ArrayList(); // 配送不到这个区域商品记录