平台内部配送费的逻辑新增。

This commit is contained in:
Jack 2025-12-11 12:06:35 +08:00
parent c1dc9994eb
commit 78dce9f77b
21 changed files with 728 additions and 81 deletions

View File

@ -326,12 +326,12 @@ public interface ShopService {
/**
* 获取店铺的内部运费 shopping_fee_inner 远程调用用途
*
* @param store_id
* @param order_id
* @return
*/
@ApiOperation(value = "获取店铺的内部运费 shopping_fee_inner", notes = "获取店铺的内部运费 shopping_fee_inner (远程调用用途)")
@RequestMapping(value = "/admin/shop/shop-store-info/shopping-fee-inner", method = RequestMethod.POST)
Integer storeShoppingFeeInner(@RequestParam(name = "store_id") Integer store_id);
Integer storeShoppingFeeInner(@RequestParam(name = "order_id") String order_id);
@GetMapping(value = "/admin/shop/shop-store-employee-rights-base/queryByRightsIds")

View File

@ -0,0 +1,47 @@
package com.suisung.mall.common.pojo.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.math.BigDecimal;
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value = "OrderDeliveryInfoDTO", description = "计算订单内部配送费参数实体类")
public class OrderCacDeliveryFeeDTO implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "订单ID")
private String order_id;
@ApiModelProperty(value = "店铺ID")
private Integer store_id;
@ApiModelProperty(value = "配送方式Id")
private Integer delivery_type_id;
@ApiModelProperty(value = "订单商品金额")
private BigDecimal order_product_amount;
@ApiModelProperty(value = "订单支付金额")
private BigDecimal order_payment_amount;
@ApiModelProperty(value = "订单折扣金额")
private BigDecimal order_discount_amount;
@ApiModelProperty(value = "订单重量(克)")
private Integer order_weight_gram;
@ApiModelProperty(value = "配送地址经度")
private String da_longitude;
@ApiModelProperty(value = "配送地址纬度")
private String da_latitude;
}

View File

@ -50,9 +50,9 @@ public interface AccountBaseConfigService extends IBaseService<AccountBaseConfig
/**
* 获取店铺或平台内部最低配送费单位
*
* @param storeId 店铺Id
* @param orderId 店铺Id
* @return 配送费单位分
*/
Integer getInnerMinDeliveryFee(Integer storeId);
Integer getInnerMinDeliveryFee(String orderId);
}

View File

@ -263,27 +263,34 @@ public class AccountBaseConfigServiceImpl extends BaseServiceImpl<AccountBaseCon
/**
* 获取店铺或平台内部最低配送费单位
*
* @param storeId 店铺Id
* @param orderId 订单Id
* @return 配送费单位分
*/
@Override
public Integer getInnerMinDeliveryFee(Integer storeId) {
// 如果storeId无效直接使用平台默认配置
if (storeId == null || storeId <= 0) {
return getDefaultMinDeliveryFee();
public Integer getInnerMinDeliveryFee(String orderId) {
// 参数校验
if (StrUtil.isBlank(orderId)) {
log.warn("[内部配送费] 订单ID为空");
return 0;
}
// 获取店铺内部运费
Integer storeFee = shopService.storeShoppingFeeInner(storeId);
try {
// 获取店铺内部运费
Integer storeFee = shopService.storeShoppingFeeInner(orderId);
// 如果店铺未设置有效运费则使用平台默认配置
if (storeFee == null || storeFee <= 0) {
return getDefaultMinDeliveryFee();
// 如果店铺未设置有效运费则使用平台默认配置
if (storeFee == null || storeFee <= 0) {
return getDefaultMinDeliveryFee();
}
return storeFee;
} catch (Exception e) {
log.error("[内部配送费] 计算异常orderId: {}", orderId, e);
return 0;
}
return storeFee;
}
/**
* 获取平台默认最低配送费
*

View File

@ -250,9 +250,9 @@ public class LakalaPayServiceImpl implements LakalaPayService {
return respBody;
}
// 平台最低配送费单位
Integer innerMinDeliverFee = accountBaseConfigService.getInnerMinDeliveryFee(Convert.toInt(storeId));
reqData.set("shopping_fee_inner", innerMinDeliverFee); // 重要平台内部最低配送费单位
// 重要平台内部最低配送费单位
Integer innerMinDeliverFee = accountBaseConfigService.getInnerMinDeliveryFee(orderId);
reqData.set("shopping_fee_inner", innerMinDeliverFee);
log.info("[拉卡拉预下单] 支付成功,准备保存订单记录, orderId={}", orderId);
// 新增一个拉卡拉订单记录 shop_order_lkl

View File

@ -678,7 +678,7 @@ public class PayUserPayServiceImpl extends BaseServiceImpl<PayUserPayMapper, Pay
}
// 平台最低配送费单位
Integer innerMinDeliverFee = accountBaseConfigService.getInnerMinDeliveryFee(storeId);
Integer innerMinDeliverFee = accountBaseConfigService.getInnerMinDeliveryFee(out_trade_no);
logger.debug("预支付时,查到的订单{},商家配送费:{}元,平台最低配送费要求:{}分", out_trade_no, shippingFee, innerMinDeliverFee);
// 平台最低配送费单位

View File

@ -62,8 +62,24 @@ public interface AccountBaseConfigService extends IBaseService<AccountBaseConfig
/**
* 获取店铺或平台内部最低配送费单位
*
* @param storeId 店铺Id
* @param orderId 店铺Id
* @return 配送费单位分
*/
Integer getInnerMinDeliveryFee(Integer storeId);
Integer getInnerMinDeliveryFee(String orderId);
/**
* (下单前获取店铺或平台内部最低配送费单位
*
* @param deliveryTypeId 配送方式Id
* @param storeId 店铺Id
* @param orderLongitude 订单经度
* @param orderLatitude 订单纬度
* @param orderWeightGram 订单商品重量
* @param orderProductAmount 订单商品金额
* @param orderDiscountAmount 订单优惠金额
* @param orderPayAmount 订单支付金额
* @return
*/
Integer getInnerMinDeliveryFee(Integer deliveryTypeId, Integer storeId, String orderLongitude, String orderLatitude, Integer orderWeightGram, BigDecimal orderProductAmount, BigDecimal orderDiscountAmount, BigDecimal orderPayAmount);
}

View File

@ -14,6 +14,7 @@ import com.suisung.mall.common.exception.ApiException;
import com.suisung.mall.common.feignService.AccountService;
import com.suisung.mall.common.modules.account.AccountBaseConfig;
import com.suisung.mall.common.modules.account.AccountUserInfo;
import com.suisung.mall.common.pojo.dto.OrderCacDeliveryFeeDTO;
import com.suisung.mall.common.utils.CheckUtil;
import com.suisung.mall.common.utils.CommonUtil;
import com.suisung.mall.common.utils.I18nUtil;
@ -22,7 +23,9 @@ import com.suisung.mall.core.web.service.impl.BaseServiceImpl;
import com.suisung.mall.shop.base.mapper.AccountBaseConfigMapper;
import com.suisung.mall.shop.base.service.AccountBaseConfigService;
import com.suisung.mall.shop.config.CookieUtil;
import com.suisung.mall.shop.order.service.ShopOrderInfoService;
import com.suisung.mall.shop.store.service.ShopStoreInfoService;
import com.suisung.mall.shop.store.service.ShopStoreSameCityTransportBaseService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
@ -58,6 +61,14 @@ public class AccountBaseConfigServiceImpl extends BaseServiceImpl<AccountBaseCon
@Autowired
private ShopStoreInfoService shopStoreInfoService;
@Lazy
@Autowired
private ShopOrderInfoService shopOrderInfoService;
@Lazy
@Autowired
private ShopStoreSameCityTransportBaseService shopStoreSameCityTransportBaseService;
@Autowired
private RedisService redisService;
@ -376,29 +387,146 @@ public class AccountBaseConfigServiceImpl extends BaseServiceImpl<AccountBaseCon
}
/**
* 获取店铺或平台内部最低配送费单位
* 下单后获取店铺或平台内部最低配送费单位
*
* @param storeId 店铺Id
* @param orderId 订单Id
* @return 配送费单位分
*/
@Override
public Integer getInnerMinDeliveryFee(Integer storeId) {
// 如果storeId无效直接使用平台默认配置
if (storeId == null || storeId <= 0) {
return getDefaultMinDeliveryFee();
public Integer getInnerMinDeliveryFee(String orderId) {
// 参数校验
if (StrUtil.isBlank(orderId)) {
log.warn("[内部配送费] 订单ID为空");
return 0;
}
// 获取店铺内部运费
Integer storeFee = shopStoreInfoService.getStoreShippingFeeInner(storeId);
try {
// 根据订单号获取计算配送费参数
OrderCacDeliveryFeeDTO args = shopOrderInfoService.getOrderCacDeliveryFeeArgs(orderId);
if (args == null || args.getStore_id() == null || args.getDelivery_type_id() == null) {
log.warn("[内部配送费] 订单参数获取失败orderId: {}", orderId);
return 0;
}
// 如果店铺未设置有效运费则使用平台默认配置
if (storeFee == null || storeFee <= 0) {
return getDefaultMinDeliveryFee();
// 根据配送方式确定是否有内部配送费(只有同城配送才有内部配送费)
if (!shopOrderInfoService.hasInnerMinDeliveryFee(args.getDelivery_type_id())) {
log.debug("[内部配送费] 非同城配送方式无需计算内部配送费orderId: {}, deliveryTypeId: {}", orderId, args.getDelivery_type_id());
return 0;
}
// 调用通用计算方法
Integer innerDeliveryFee = calculateInnerMinDeliveryFee(
args.getStore_id(),
args.getDelivery_type_id(),
args.getDa_longitude(),
args.getDa_latitude(),
args.getOrder_weight_gram(),
args.getOrder_product_amount(),
args.getOrder_discount_amount(),
args.getOrder_payment_amount()
);
log.debug("[内部配送费] 计算完成orderId: {}, storeId: {}, fee: {}", orderId, args.getStore_id(), innerDeliveryFee);
return innerDeliveryFee;
} catch (Exception e) {
log.error("[内部配送费] 计算异常orderId: {}", orderId, e);
return 0;
}
return storeFee;
}
/**
* (下单前获取店铺或平台内部最低配送费单位
*
* @param deliveryTypeId 配送方式ID
* @param storeId 店铺ID
* @param orderLongitude 订单经度
* @param orderLatitude 订单纬度
* @param orderWeightGram 订单重量()
* @param orderProductAmount 订单商品金额
* @param orderDiscountAmount 订单折扣金额
* @param orderPayAmount 订单支付金额
* @return 内部配送费(单位 : )如果不需要内部配送费则返回0
*/
@Override
public Integer getInnerMinDeliveryFee(Integer deliveryTypeId, Integer storeId, String orderLongitude,
String orderLatitude, Integer orderWeightGram, BigDecimal orderProductAmount,
BigDecimal orderDiscountAmount, BigDecimal orderPayAmount) {
// 参数校验
if (deliveryTypeId == null || storeId == null) {
log.warn("[内部配送费] 参数校验失败deliveryTypeId: {}storeId: {}", deliveryTypeId, storeId);
return 0;
}
// 根据配送方式确定是否有内部配送费(只有同城配送才有内部配送费)
if (!shopOrderInfoService.hasInnerMinDeliveryFee(deliveryTypeId)) {
log.debug("[内部配送费] 非同城配送方式无需计算内部配送费deliveryTypeId: {}", deliveryTypeId);
return 0;
}
try {
// 调用通用计算方法
Integer innerDeliveryFee = calculateInnerMinDeliveryFee(
storeId,
deliveryTypeId,
orderLongitude,
orderLatitude,
orderWeightGram,
orderProductAmount,
orderDiscountAmount,
orderPayAmount
);
log.debug("[内部配送费] 计算完成storeId: {}, deliveryTypeId: {}, fee: {}", storeId, deliveryTypeId, innerDeliveryFee);
return innerDeliveryFee;
} catch (Exception e) {
log.error("[内部配送费] 计算异常storeId: {}, deliveryTypeId: {}", storeId, deliveryTypeId, e);
return 0;
}
}
/**
* 通用内部最低配送费计算方法
*
* @param storeId 店铺ID
* @param deliveryTypeId 配送方式ID
* @param orderLongitude 订单经度
* @param orderLatitude 订单纬度
* @param orderWeightGram 订单重量()
* @param orderProductAmount 订单商品金额
* @param orderDiscountAmount 订单折扣金额
* @param orderPayAmount 订单支付金额
* @return 内部配送费(单位 : )
*/
private Integer calculateInnerMinDeliveryFee(Integer storeId, Integer deliveryTypeId, String orderLongitude,
String orderLatitude, Integer orderWeightGram, BigDecimal orderProductAmount,
BigDecimal orderDiscountAmount, BigDecimal orderPayAmount) {
// 根据配置计算平台配送费
Integer innerDeliveryFee = shopStoreSameCityTransportBaseService.computeSameCityInnerDeliveryFee(
storeId,
orderLongitude,
orderLatitude,
orderWeightGram,
orderProductAmount,
orderDiscountAmount,
orderPayAmount
);
// 如果平台配送费为空或0则尝试获取店铺单独配置的内部运费
if (innerDeliveryFee == null || innerDeliveryFee <= 0) {
log.debug("[内部配送费] 平台配送费为空尝试获取店铺单独配置storeId: {}", storeId);
innerDeliveryFee = shopStoreInfoService.getStoreShippingFeeInner(storeId);
}
// 如果店铺单独配置的内部运费也为空或0则使用平台默认最低配送费
if (innerDeliveryFee == null || innerDeliveryFee <= 0) {
log.debug("[内部配送费] 店铺配送费为空使用平台默认配置storeId: {}", storeId);
innerDeliveryFee = getDefaultMinDeliveryFee();
}
return innerDeliveryFee != null ? innerDeliveryFee : 0;
}
/**
* 获取平台默认最低配送费
*

View File

@ -2,6 +2,8 @@ package com.suisung.mall.shop.order.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.suisung.mall.common.modules.order.ShopOrderInfo;
import com.suisung.mall.common.pojo.dto.OrderCacDeliveryFeeDTO;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;
import java.util.List;
@ -35,4 +37,28 @@ public interface ShopOrderInfoMapper extends BaseMapper<ShopOrderInfo> {
*/
Long getOrderCountByStoreId(Integer storeId, List<Integer> orderStatusIdList, List<Integer> orderRefundStatusIdList, List<Integer> deliveryTypeList, Long expireSeconds);
/**
* 根据订单ID获取计算配送费所需的订单信息
* <p>
* 查询逻辑说明:
* 1. 从订单基础信息表获取订单ID店铺ID和商品总额
* 2. 从订单数据表计算实际支付金额(订单支付金额 - 运费金额)
* 3. 从订单数据表计算折扣金额(商品零售总额 - 折扣金额 - 优惠券金额 - 调整金额 - 积分抵扣金额)
* 4. 从订单配送地址表获取配送地址的经纬度
*
* @param orderId 订单ID
* @return OrderCacDeliveryFeeDTO 订单配送费计算参数实体
*/
@Select("SELECT sob.order_id,sob.store_id,sob.order_product_amount,sob.order_payment_amount," +
"(sob.order_product_amount-sod.order_discount_amount-sod.voucher_price-sod.order_adjust_fee-sod.order_points_fee) as order_discount_amount," +
"0 as order_weight_gram," +
"aoda.da_longitude,aoda.da_latitude, soi.delivery_type_id " +
"FROM shop_order_base sob " +
"JOIN shop_order_data sod ON sob.order_id=sod.order_id " +
"JOIN shop_order_info soi ON sob.order_id=soi.order_id " +
"JOIN shop_order_delivery_address aoda ON sob.order_id=aoda.order_id " +
"WHERE sob.order_id=#{orderId}")
OrderCacDeliveryFeeDTO getOrderCacDeliveryFeeArgs(String orderId);
}

View File

@ -3,6 +3,7 @@ package com.suisung.mall.shop.order.service;
import com.suisung.mall.common.api.CommonResult;
import com.suisung.mall.common.modules.order.ShopOrderInfo;
import com.suisung.mall.common.pojo.dto.BookingArgDTO;
import com.suisung.mall.common.pojo.dto.OrderCacDeliveryFeeDTO;
import com.suisung.mall.core.web.service.IBaseService;
import org.springframework.data.util.Pair;
@ -145,11 +146,33 @@ public interface ShopOrderInfoService extends IBaseService<ShopOrderInfo> {
List<BookingArgDTO> genBookingOrderArgList(String storeId);
/**
* 获取某个活动订单成功数量
* 获取某个活动订单成功数量(目前砍价用途)
*
* @param activityId 活动ID
* @param activityTypeId 活动类型ID 可选参数
* @return
*/
long fetchActivityOrderSuccessCount(String activityId, String activityTypeId);
/**
* 获取某个订单是否存在满足内部配送费
*
* @param deliveryTypeId 店铺ID
* @return Pair第一个元素表示是否满足内部配送费条件第二个元素为内部配送费金额
*/
Boolean hasInnerMinDeliveryFee(Integer deliveryTypeId);
/**
* 根据订单ID获取计算配送费所需的订单信息
* <p>
* 查询逻辑说明:
* 1. 从订单基础信息表获取订单ID店铺ID和商品总额
* 2. 从订单数据表计算实际支付金额(订单支付金额 - 运费金额)
* 3. 从订单数据表计算折扣金额(商品总额 - 折扣金额 - 调整金额 - 积分抵扣金额)
* 4. 从订单配送地址表获取配送地址的经纬度
*
* @param orderId 订单ID
* @return OrderCacDeliveryFeeDTO 订单配送费计算参数实体
*/
OrderCacDeliveryFeeDTO getOrderCacDeliveryFeeArgs(String orderId);
}

View File

@ -917,6 +917,8 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
unit_rows = Convert.toList(Map.class, productUnitList);
}
boolean is_denyreturn = true;
for (Map item_row : items) {
Integer product_id = Convert.toInt(item_row.get("product_id"));
Optional<Map> productBaseOpl = product_rows.stream().filter(s -> ObjectUtil.equal(product_id, Convert.toInt(s.get("product_id")))).findFirst();
@ -962,8 +964,7 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
}
// 不支持退货
boolean is_denyreturn = shopOrderReturnService.ifDenyReturn(order_item_id);
is_denyreturn = shopOrderReturnService.ifDenyReturn(order_item_id);
item_row.put("contains", is_denyreturn);
item_row.put("is_denyreturn", is_denyreturn);
@ -1087,7 +1088,8 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
}
base_row.put("if_lock", base_row.get("order_lock_status"));
base_row.put("if_buyer_cancel", isOrderCancelable(order_state_id, order_is_paid));
// 待支付订单可取消商品非禁止退货的也可以取消
base_row.put("if_buyer_cancel", isOrderCancelable(order_state_id, order_is_paid) || !is_denyreturn);
base_row.put("if_logistics", ifLogistics(order_state_id));
base_row.put("if_receive", ifReceive(order_state_id));
@ -4171,7 +4173,7 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
logger.error("用户提交取消订单失败!");
return false;
}
// 提交成功之后再由商家审核通过之后会继续完成以下的操作
return true;
}
@ -6608,7 +6610,8 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
order_payment_amount = NumberUtil.max(order_payment_amount, BigDecimal.valueOf(0));
// 订单原价商品金额
base_row.put("order_product_amount", Convert.toBigDecimal(store_item.get("productMoneyOriginGoods")));
BigDecimal order_product_amount = Convert.toBigDecimal(store_item.get("productMoney"));
base_row.put("order_product_amount", order_product_amount);
//重要应付款金额计算
base_row.put("order_payment_amount", order_payment_amount);
@ -6932,7 +6935,6 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
Integer activity_double_points_id = 0;
//均分组合套餐 其余活动可视情况使用此处
BigDecimal deduct_discount = BigDecimal.ZERO;
BigDecimal reduction_discount = BigDecimal.ZERO;
BigDecimal reduction_again_discount = BigDecimal.ZERO;
@ -6954,7 +6956,6 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
Integer cart_quantity = Convert.toInt(_item.get("cart_quantity"));
BigDecimal item_unit_sp = Convert.toBigDecimal(_item.get("item_unit_sp"));
BigDecimal item_unit_points = Convert.toBigDecimal(_item.get("item_unit_points"));
BigDecimal item_share_redemption = BigDecimal.ZERO;
// 均分优惠券
@ -7858,8 +7859,27 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
// 店铺统一设置的打包费
data_row.setPacking_fee(packingFee);
// 平台最低配送费单位
Integer innerMinDeliverFee = accountBaseConfigService.getInnerMinDeliveryFee(store_id);
Integer innerMinDeliverFee = 0;
Map address = (Map) cart_data.get("address_row");
if (CollUtil.isNotEmpty(address)) {
String longitude = Convert.toStr(address.get("ud_longitude"));
String latitude = Convert.toStr(address.get("ud_latitude"));
// 检查经纬度是否有效
if (StrUtil.isNotBlank(longitude) && StrUtil.isNotBlank(latitude)) {
// 平台最低配送费单位
innerMinDeliverFee = accountBaseConfigService.getInnerMinDeliveryFee(
delivery_type_id,
store_id,
longitude,
latitude,
0,
order_product_amount,
order_payment_amount.subtract(_freight),
order_payment_amount
);
}
}
// 平台最低配送费单位
BigDecimal shoppingFeeInner = Convert.toBigDecimal(innerMinDeliverFee).divide(BigDecimal.valueOf(100));
@ -8399,7 +8419,8 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
Integer payment_type_id = Convert.toInt(order_info_row.get("payment_type_id"));
Integer order_is_paid = Convert.toInt(order_info_row.get("order_is_paid"));
order_info_row.put("if_buyer_cancel", isOrderCancelable(order_state_id, order_is_paid));
boolean is_denyreturn = shopOrderReturnService.ifDenyReturn(Convert.toLong(order_info_row.get("order_item_id")));
order_info_row.put("if_buyer_cancel", isOrderCancelable(order_state_id, order_is_paid) || !is_denyreturn);
order_info_row.put("if_logistics", ifLogistics(order_state_id));
order_info_row.put("order_shipping_fee", order_data_row.get("order_shipping_fee"));
order_info_row.put("order_payment_name", shopBaseStateCodeService.getText(payment_type_id, null));
@ -8943,7 +8964,7 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
ShopStoreBase shopStoreBase = shopStoreBaseService.get(storeId);
ShopStoreInfo shopStoreInfo = shopStoreInfoService.get(storeId);
ShopOrderDeliveryAddress shopOrderDeliveryAddress = shopOrderDeliveryAddressService.selectByOrderId(shopOrderId);
ShopStoreSameCityTransportBase shopStoreSameCityTransportBase = shopStoreSameCityTransportBaseService.getShopStoreSameCityTransportBaseById(storeId.longValue());
ShopStoreSameCityTransportBase shopStoreSameCityTransportBase = shopStoreSameCityTransportBaseService.getShopStoreSameCityTransportBaseById(storeId.longValue(), CommonConstant.Disable2);
if (shopStoreBase == null || shopStoreInfo == null || shopOrderDeliveryAddress == null || shopStoreSameCityTransportBase == null) {
logger.error("构建顺丰订单失败无法获取店铺信息订单ID={}storeId={}", shopOrderId, storeId);
return null;

View File

@ -30,6 +30,7 @@ import com.suisung.mall.common.modules.product.ShopProductComment;
import com.suisung.mall.common.modules.store.ShopStoreBase;
import com.suisung.mall.common.modules.store.ShopStoreInfo;
import com.suisung.mall.common.pojo.dto.BookingArgDTO;
import com.suisung.mall.common.pojo.dto.OrderCacDeliveryFeeDTO;
import com.suisung.mall.common.pojo.res.ThirdApiRes;
import com.suisung.mall.common.utils.CheckUtil;
import com.suisung.mall.common.utils.CommonUtil;
@ -1287,6 +1288,53 @@ public class ShopOrderInfoServiceImpl extends BaseServiceImpl<ShopOrderInfoMappe
}
}
/**
* 判断订单是否满足收取内部配送费条件
* <p>
* 内部配送费仅适用于同城配送方式该方法通过检查配送方式是否为同城配送来判断是否满足条件
*
* @param deliveryTypeId 配送方式ID
* @return Boolean 是否满足内部配送费条件
*/
@Override
public Boolean hasInnerMinDeliveryFee(Integer deliveryTypeId) {
// 参数校验
if (CheckUtil.isEmpty(deliveryTypeId)) {
logger.warn("[获取内部配送费] 配送方式ID为空deliveryTypeId: {}", deliveryTypeId);
return false;
}
// 检查配送方式是否为同城配送只有同城配送才有内部配送费
boolean isSameCityDelivery = StateCode.DELIVERY_TYPE_MAP.containsKey(deliveryTypeId)
&& ObjectUtil.equal(StateCode.DELIVERY_TYPE_SAME_CITY, deliveryTypeId);
logger.debug("[获取内部配送费] 配送方式检查结果, deliveryTypeId: {}, isSameCityDelivery: {}",
deliveryTypeId, isSameCityDelivery);
return isSameCityDelivery;
}
/**
* 根据订单ID获取计算配送费所需的订单信息
* <p>
* 查询逻辑说明:
* 1. 从订单基础信息表获取订单ID店铺ID和商品总额
* 2. 从订单数据表计算实际支付金额(订单支付金额 - 运费金额)
* 3. 从订单数据表计算折扣金额(商品总额 - 折扣金额 - 调整金额 - 积分抵扣金额)
* 4. 从订单配送地址表获取配送地址的经纬度
*
* @param orderId 订单ID
* @return OrderCacDeliveryFeeDTO 订单配送费计算参数实体
*/
@Override
public OrderCacDeliveryFeeDTO getOrderCacDeliveryFeeArgs(String orderId) {
if (StrUtil.isBlank(orderId)) {
return null;
}
return shopOrderInfoMapper.getOrderCacDeliveryFeeArgs(orderId);
}
/**
* 根据一个或多个店铺id获取有效店铺的有效营业时间段

View File

@ -2581,6 +2581,11 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
}
}
if (shopOrderItem != null && CheckUtil.isNotEmpty(shopOrderItem.getOrder_item_id())) {
// 3.2 检查商品退款详情里是否已经提交过退款申请, 且数量大于订单数量或金额大于订单金额
return ifCanReturnOrderItem(shopOrderItem);
}
// 默认允许退货
log.debug("[是否禁止退货] 商品允许退货order_id: {}, product_id: {}", orderId, productIndex.getProduct_id());
return false;
@ -3299,5 +3304,50 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
return "商品不支持退货";
}
/**
* 判断订单子项是否可以退款
* 条件
* 1. 订单子项必须存在
* 2. 可退数量 > 0 (订单商品数量 > 已退货数量)
* 3. 可退金额 > 0 (订单商品金额 > 已同意退款金额)
*
* @param orderItemId 订单子项ID
* @return boolean 是否可以退款
*/
private boolean ifCanReturnOrderItem(Long orderItemId) {
// 查询订单子项是否存在
ShopOrderItem orderItem = shopOrderItemService.get(orderItemId);
return ifCanReturnOrderItem(orderItem);
}
/**
* 判断订单子项是否可以退款
* 条件
* 1. 订单子项必须存在
* 2. 可退数量 > 0 (订单商品数量 > 已退货数量)
* 3. 可退金额 > 0 (订单商品金额 > 已同意退款金额)
*
* @param orderItem 订单子项
* @return boolean 是否可以退款
*/
private boolean ifCanReturnOrderItem(ShopOrderItem orderItem) {
// 如果订单子项不存在不能退款
if (orderItem == null) {
return false;
}
// 获取订单子项的相关字段使用默认值避免空指针
Integer orderItemQuantity = ObjectUtil.defaultIfNull(orderItem.getOrder_item_quantity(), 0);
Integer orderItemReturnNum = ObjectUtil.defaultIfNull(orderItem.getOrder_item_return_num(), 0);
BigDecimal orderItemAmount = ObjectUtil.defaultIfNull(orderItem.getOrder_item_amount(), BigDecimal.ZERO);
BigDecimal orderItemReturnAgreeAmount = ObjectUtil.defaultIfNull(orderItem.getOrder_item_return_agree_amount(), BigDecimal.ZERO);
// 判断是否可以退款
// 1. 可退数量 > 0
// 2. 可退金额 > 0
return orderItemQuantity > orderItemReturnNum
&& orderItemAmount.compareTo(orderItemReturnAgreeAmount) > 0;
}
}

View File

@ -269,12 +269,12 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
// 3. 获取或初始化商家配送信息
ShopStoreSameCityTransportBase transportBase = shopStoreSameCityTransportBaseService
.getShopStoreSameCityTransportBaseById(Long.valueOf(storeId));
.getShopStoreSameCityTransportBaseById(Long.valueOf(storeId), CommonConstant.Disable2);
if (transportBase == null) {
// 如果没有商家配送运费设置则初始化
shopStoreSameCityTransportBaseService.initDefaultSameCityTransport(storeId);
transportBase = shopStoreSameCityTransportBaseService.getShopStoreSameCityTransportBaseById(Long.valueOf(storeId));
transportBase = shopStoreSameCityTransportBaseService.getShopStoreSameCityTransportBaseById(Long.valueOf(storeId), CommonConstant.Disable2);
}
if (transportBase == null) {
@ -963,7 +963,7 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
return new ThirdApiRes().fail(1003, "缺少店铺 Id");
}
ShopStoreSameCityTransportBase shopStoreSameCityTransportBase = shopStoreSameCityTransportBaseService.getShopStoreSameCityTransportBaseById(storeId);
ShopStoreSameCityTransportBase shopStoreSameCityTransportBase = shopStoreSameCityTransportBaseService.getShopStoreSameCityTransportBaseById(storeId, CommonConstant.Disable2);
if (shopStoreSameCityTransportBase == null) {
logger.error("无法获取顺丰店铺 Id");
return new ThirdApiRes().fail(1003, "无法获取店铺Id");

View File

@ -5,10 +5,12 @@ import com.suisung.mall.common.api.CommonResult;
import com.suisung.mall.common.domain.UserDto;
import com.suisung.mall.common.modules.store.ShopStoreInfo;
import com.suisung.mall.common.service.impl.BaseControllerImpl;
import com.suisung.mall.shop.base.service.AccountBaseConfigService;
import com.suisung.mall.shop.store.service.ShopStoreInfoService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
@ -30,6 +32,12 @@ public class ShopStoreInfoController extends BaseControllerImpl {
@Autowired
private ShopStoreInfoService shopStoreInfoService;
@Lazy
@Autowired
private AccountBaseConfigService accountBaseConfigService;
/**
* 分页列表查询
*
@ -83,13 +91,13 @@ public class ShopStoreInfoController extends BaseControllerImpl {
/**
* 获取店铺的内部运费 shopping_fee_inner 远程调用用途
*
* @param store_id
* @param order_id
* @return
*/
@ApiOperation(value = "获取店铺的内部运费 shopping_fee_inner", notes = "获取店铺的内部运费 shopping_fee_inner (远程调用用途)")
@RequestMapping(value = "/shopping-fee-inner", method = RequestMethod.POST)
public Integer storeShoppingFeeInner(@RequestParam(name = "store_id") Integer store_id) {
return shopStoreInfoService.getStoreShippingFeeInner(store_id);
public Integer storeShoppingFeeInner(@RequestParam(name = "order_id") String order_id) {
return accountBaseConfigService.getInnerMinDeliveryFee(order_id);
}
}

View File

@ -10,8 +10,6 @@ import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@Api(tags = "同城配送运费设置控制器")
@RestController
@RequestMapping("/admin/shop/store/same-city-transport")
@ -25,8 +23,8 @@ public class ShopStoreSameCityTransportBaseController {
@ApiOperation(value = "获取同城配送运费设置详情", notes = "获取同城配送运费设置详情")
@RequestMapping(value = "/detail", method = {RequestMethod.GET})
public CommonResult shopStoreSameCityTransportBaseDetail() {
return transportBaseService.ShopStoreSameCityTransportBaseDetail();
public CommonResult shopStoreSameCityTransportBaseDetail(@RequestParam(name = "is_platfrom", defaultValue = "2") Integer isPlatform) {
return transportBaseService.ShopStoreSameCityTransportBaseDetail(isPlatform);
}
@ApiOperation(value = "保存(新增或修改)同城配送运费设置", notes = "保存(新增或修改)同城配送运费设置")

View File

@ -10,8 +10,6 @@ import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@Api(tags = "同城配送运费设置控制器")
@RestController
@RequestMapping("/mobile/shop/store/same-city-transport")
@ -22,7 +20,7 @@ public class ShopStoreSameCityTransportBaseMobileController {
@ApiOperation(value = "下单前检测同城订单配送是否符合要求", notes = "下单前检测同城订单配送是否符合要求")
@RequestMapping(value = "/check/same-city/delivery", method = {RequestMethod.POST})
public CommonResult checkSameCityDelivery(@RequestParam(name = "store_id", defaultValue = "0") Integer storeId) {
return transportBaseService.ShopStoreSameCityTransportBaseDetail();
public CommonResult checkSameCityDelivery(@RequestParam(name = "is_platfrom", defaultValue = "2") Integer isPlatform) {
return transportBaseService.ShopStoreSameCityTransportBaseDetail(isPlatform);
}
}

View File

@ -23,7 +23,7 @@ public interface ShopStoreSameCityTransportBaseService {
*
* @return
*/
CommonResult ShopStoreSameCityTransportBaseDetail();
CommonResult ShopStoreSameCityTransportBaseDetail(Integer isPlatform);
/**
* 保存或更新同城配送各项设置
@ -52,17 +52,19 @@ public interface ShopStoreSameCityTransportBaseService {
* 根据店铺 Id 获取同城配送设置详情信息
*
* @param storeId
* @param isPlatform 1-平台 2-店铺
* @return
*/
ShopStoreSameCityTransportBaseDTO getShopStoreSameCityTransportBaseDTOById(Long storeId);
ShopStoreSameCityTransportBaseDTO getShopStoreSameCityTransportBaseDTOById(Long storeId, Integer isPlatform);
/**
* 根据店铺Id获取同城配送基础运费记录
*
* @param storeId
* @param isPlatform 1-平台 2-店铺
* @return
*/
ShopStoreSameCityTransportBase getShopStoreSameCityTransportBaseById(Long storeId);
ShopStoreSameCityTransportBase getShopStoreSameCityTransportBaseById(Long storeId, Integer isPlatform);
/**
* 保存同城配送基础设置存在更新不存在新增
@ -96,4 +98,25 @@ public interface ShopStoreSameCityTransportBaseService {
*/
SameCityDeliveryFeeRespDTO computeSameCityTransportFee(Long storeId, String orderLongitude, String orderLatitude, Integer weightGram, BigDecimal orderProductAmount, BigDecimal orderDiscountAmount, BigDecimal orderPayAmount, Boolean canThrow);
/**
* 平台计算同城订单的内部配送费仅仅作用于平台内部配送费计算商家配送费忽略此方法只对下单成功的订单起效果
*
* @param orderId 订单ID
* @return 配送费单位为分
*/
Integer computeSameCityInnerDeliveryFeeByOrderId(String orderId);
/**
* 平台计算同城订单的内部配送费仅仅作用于平台内部配送费计算商家配送费忽略此方法下单前可以查询
*
* @param storeId 店铺Id
* @param orderLongitude 订单送达地目的地经度
* @param orderLatitude 订单送达地目的地维度
* @param orderWeightGram 订单重量单位克
* @param orderProductAmount 订单商品原价金额
* @param orderDiscountAmount 订单商品折扣金额订单原价减去每个商品折扣费
* @param orderPayAmount 订单实际支付金额折扣金额-优惠券-积分扣-人工干预扣费不包含运费
* @return 配送费单位为分
*/
Integer computeSameCityInnerDeliveryFee(Integer storeId, String orderLongitude, String orderLatitude, Integer orderWeightGram, BigDecimal orderProductAmount, BigDecimal orderDiscountAmount, BigDecimal orderPayAmount);
}

View File

@ -131,7 +131,7 @@ public class ShopStoreInfoServiceImpl extends BaseServiceImpl<ShopStoreInfoMappe
/**
* 获取店铺的内部运费 shopping_fee_inner
* <p>
* 店铺内部运费单位0-使用平台的内部运费>0 使用店铺的内部运费
* 店铺内部运费单位使用店铺的内部运费<=0 的时候
*
* @param storeId 店铺ID
* @return 内部运费单位分
@ -147,7 +147,6 @@ public class ShopStoreInfoServiceImpl extends BaseServiceImpl<ShopStoreInfoMappe
QueryWrapper<ShopStoreInfo> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("store_id", storeId).select("shopping_fee_inner");
ShopStoreInfo shopStoreInfo = getOne(queryWrapper);
if (shopStoreInfo == null || CheckUtil.isEmpty(shopStoreInfo.getShopping_fee_inner())) {
return 0;
}

View File

@ -25,6 +25,7 @@ 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.DeliveryFeeResultDTO;
import com.suisung.mall.common.pojo.dto.OrderCacDeliveryFeeDTO;
import com.suisung.mall.common.pojo.dto.SameCityDeliveryFeeRespDTO;
import com.suisung.mall.common.pojo.dto.ShopStoreSameCityTransportBaseDTO;
import com.suisung.mall.common.utils.CommonUtil;
@ -32,6 +33,7 @@ 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.base.service.AccountBaseConfigService;
import com.suisung.mall.shop.order.service.ShopOrderInfoService;
import com.suisung.mall.shop.store.mapper.ShopStoreSameCityTransportBaseMapper;
import com.suisung.mall.shop.store.service.ShopStoreBaseService;
import com.suisung.mall.shop.store.service.ShopStoreSameCityTransportBaseService;
@ -64,6 +66,11 @@ public class ShopStoreSameCityTransportBaseServiceImpl extends BaseServiceImpl<S
@Autowired
private ShopStoreBaseService shopStoreBaseService;
@Lazy
@Autowired
private ShopOrderInfoService shopOrderInfoService;
@Resource
private AccountBaseConfigService accountBaseConfigService;
@ -74,15 +81,19 @@ public class ShopStoreSameCityTransportBaseServiceImpl extends BaseServiceImpl<S
* @return
*/
@Override
public CommonResult ShopStoreSameCityTransportBaseDetail() {
public CommonResult ShopStoreSameCityTransportBaseDetail(Integer isPlatform) {
// 判断有没有权限
UserDto user = getCurrentUser();
if (user == null || !user.isStore()) {
return CommonResult.failed(ResultCode.FORBIDDEN.getMessage());
}
if (isPlatform == null || isPlatform < 0 || isPlatform > 2) {
isPlatform = CommonConstant.Disable2;
}
Long storeId = Convert.toLong(user.getStore_id());
ShopStoreSameCityTransportBaseDTO retDTO = getShopStoreSameCityTransportBaseDTOById(storeId);
ShopStoreSameCityTransportBaseDTO retDTO = getShopStoreSameCityTransportBaseDTOById(storeId, isPlatform);
if (retDTO == null) {
return CommonResult.failed("商家未设置店铺地址,请先设置店铺地址!");
}
@ -226,10 +237,11 @@ public class ShopStoreSameCityTransportBaseServiceImpl extends BaseServiceImpl<S
* 根据店铺 Id 获取同城配送设置详情信息
*
* @param storeId
* @param isPlatform
* @return
*/
@Override
public ShopStoreSameCityTransportBaseDTO getShopStoreSameCityTransportBaseDTOById(Long storeId) {
public ShopStoreSameCityTransportBaseDTO getShopStoreSameCityTransportBaseDTOById(Long storeId, Integer isPlatform) {
if (storeId == null || storeId <= 0) {
return null;
}
@ -240,7 +252,7 @@ public class ShopStoreSameCityTransportBaseServiceImpl extends BaseServiceImpl<S
return null;
}
ShopStoreSameCityTransportBase transportBase = getShopStoreSameCityTransportBaseById(storeId);
ShopStoreSameCityTransportBase transportBase = getShopStoreSameCityTransportBaseById(storeId, isPlatform);
if (transportBase == null) {
transportBase = new ShopStoreSameCityTransportBase();
transportBase.setStore_id(storeId);
@ -284,13 +296,18 @@ public class ShopStoreSameCityTransportBaseServiceImpl extends BaseServiceImpl<S
* @return
*/
@Override
public ShopStoreSameCityTransportBase getShopStoreSameCityTransportBaseById(Long storeId) {
public ShopStoreSameCityTransportBase getShopStoreSameCityTransportBaseById(Long storeId, Integer isPlatform) {
if (storeId == null || storeId <= 0) {
return null;
}
if (isPlatform == null || isPlatform < 0 || isPlatform > 2) {
isPlatform = 2;
}
QueryWrapper<ShopStoreSameCityTransportBase> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("store_id", storeId);
queryWrapper.eq("is_platform", isPlatform);
queryWrapper.eq("status", CommonConstant.Enable);
return getOne(queryWrapper);
@ -298,11 +315,19 @@ public class ShopStoreSameCityTransportBaseServiceImpl extends BaseServiceImpl<S
public Pair<Long, String> saveOrUpdateShopStoreSameCityTransportBase(ShopStoreSameCityTransportBase transportBase) {
try {
// 参数校验
if (transportBase == null || transportBase.getStore_id() == null || transportBase.getStore_id() <= 0) {
log.warn("保存或更新同城配送基础信息参数校验失败: transportBase={}", transportBase);
return Pair.of(0L, "缺少店铺Id必要参数");
}
// 设置默认值
Integer isPlatform = transportBase.getIs_platform();
if (isPlatform == null || isPlatform < 0 || isPlatform > 2) {
isPlatform = 2;
transportBase.setIs_platform(isPlatform);
}
// 设置默认值 - 使用更清晰的条件判断
if (transportBase.getDistance_base() == null || transportBase.getDistance_base() < 0) {
transportBase.setDistance_base(0);
}
@ -327,36 +352,51 @@ public class ShopStoreSameCityTransportBaseServiceImpl extends BaseServiceImpl<S
QueryWrapper<ShopStoreSameCityTransportBase> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("store_id", transportBase.getStore_id());
queryWrapper.eq("is_platform", transportBase.getIs_platform());
queryWrapper.eq("status", CommonConstant.Enable);
ShopStoreSameCityTransportBase exist = getOne(queryWrapper);
Date now = new Date();
if (exist == null) {
// 新增
// 新增操作
log.debug("开始新增同城配送基础信息, storeId={}", transportBase.getStore_id());
transportBase.setCreated_by(transportBase.getUpdated_by());
transportBase.setCreated_at(now);
transportBase.setUpdated_at(now);
if (add(transportBase)) {
// 确保获取到ID
Long transportBaseId = transportBase.getTransport_base_id();
if (transportBaseId == null || transportBaseId <= 0) {
// 补偿机制若transportBase.getTransport_base_id()==null重新查询数据
log.debug("新增后ID为空重新查询获取ID, storeId={}", transportBase.getStore_id());
exist = getOne(queryWrapper);
if (exist != null) {
transportBaseId = exist.getTransport_base_id();
}
}
log.info("新增同城配送基础信息成功, transportBaseId={}, storeId={}", transportBaseId, transportBase.getStore_id());
return Pair.of(transportBaseId, "添加成功!");
} else {
log.error("新增同城配送基础信息失败, storeId={}", transportBase.getStore_id());
return Pair.of(0L, "添加失败!");
}
} else {
// 更新
// 更新操作
log.debug("开始更新同城配送基础信息, transportBaseId={}, storeId={}", exist.getTransport_base_id(), transportBase.getStore_id());
transportBase.setTransport_base_id(exist.getTransport_base_id());
transportBase.setUpdated_at(now);
if (updateById(transportBase)) {
log.info("更新同城配送基础信息成功, transportBaseId={}, storeId={}", transportBase.getTransport_base_id(), transportBase.getStore_id());
return Pair.of(transportBase.getTransport_base_id(), "更新成功!");
} else {
log.error("更新同城配送基础信息失败, transportBaseId={}, storeId={}", transportBase.getTransport_base_id(), transportBase.getStore_id());
return Pair.of(0L, "更新失败!");
}
}
} catch (Exception e) {
log.error("保存或更新同城配送基础信息异常: ", e);
log.error("保存或更新同城配送基础信息异常, storeId={}", transportBase != null ? transportBase.getStore_id() : "unknown", e);
return Pair.of(0L, "系统内部错误");
}
}
@ -406,6 +446,11 @@ public class ShopStoreSameCityTransportBaseServiceImpl extends BaseServiceImpl<S
return Pair.of(false, "缺少同城配送基础设置!");
}
Integer isPlatform = transportBase.getIs_platform();
if (isPlatform == null || isPlatform <= 0 || isPlatform > 2) {
isPlatform = 2;
}
transportBase.setIs_platform(isPlatform);
transportBase.setStore_id(Convert.toLong(storeBase.getStore_id()));
transportBase.setStore_longitude(storeBase.getStore_longitude());
transportBase.setStore_latitude(storeBase.getStore_latitude());
@ -461,7 +506,6 @@ public class ShopStoreSameCityTransportBaseServiceImpl extends BaseServiceImpl<S
// 2.如果能配送再订单总重量订单原价金额订单折后金额订单实付金额
// 3.根据两点经纬度计算配送距离结合订单总重量计算基础运费
// 4.查看是否有运费优惠设置如果有就直接从基础运费中扣除优惠运费得出最终的订单配送费
if (storeId == null || orderLongitude == null || orderLatitude == null || storeId <= 0) {
logger.error("同城配送费计算时,缺少必要参数。");
if (canThrow) {
@ -490,8 +534,8 @@ public class ShopStoreSameCityTransportBaseServiceImpl extends BaseServiceImpl<S
return new SameCityDeliveryFeeRespDTO(false, false, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, "无法获取" + storeName + "的具体位置,请联系商家。");
}
// 获取基础运费设置记录
ShopStoreSameCityTransportBase transportBase = getShopStoreSameCityTransportBaseById(storeId);
// 获取店铺商家的基础运费设置记录
ShopStoreSameCityTransportBase transportBase = getShopStoreSameCityTransportBaseById(storeId, CommonConstant.Disable2);
if (transportBase == null) {
logger.error("{}同城配送费计算:无法获取基础运费设置记录。", storeName);
if (canThrow) {
@ -671,7 +715,7 @@ public class ShopStoreSameCityTransportBaseServiceImpl extends BaseServiceImpl<S
BigDecimal times = BigDecimal.ZERO;
if (transportBase.getWeight_increase_kg() > 0 && diffWeightKg.intValue() > transportBase.getWeight_increase_kg()) {
// 末尾非零进位比如2.1将是3 2.0将是22.001将是3
times = NumberUtil.div(diffWeightKg, transportBase.getDistance_increase_km()).setScale(0, RoundingMode.UP);
times = NumberUtil.div(diffWeightKg, transportBase.getWeight_increase_kg()).setScale(0, RoundingMode.UP);
}
deliveryBaseFee = deliveryBaseFee.add(transportBase.getWeight_increase_fee().multiply(times));
@ -690,4 +734,213 @@ public class ShopStoreSameCityTransportBaseServiceImpl extends BaseServiceImpl<S
return new SameCityDeliveryFeeRespDTO(canDelivery, isFee, deliveryBaseFee, reduceDeliveryFee, isFee ? BigDecimal.ZERO : deliveryFee, "");
}
/**
* 平台计算同城订单的内部配送费仅仅作用于平台内部配送费计算商家配送费忽略此方法只对下单成功的订单起效果
*
* @param orderId 订单ID
* @return 配送费单位为分
*/
@Override
public Integer computeSameCityInnerDeliveryFeeByOrderId(String orderId) {
// 参数校验
if (orderId == null || orderId.trim().isEmpty()) {
logger.warn("计算同城配送费失败订单ID不能为空");
return 0;
}
// 获取计算配送费所需的订单信息
OrderCacDeliveryFeeDTO orderCacDeliveryFeeArgs = shopOrderInfoService.getOrderCacDeliveryFeeArgs(orderId);
// 检查返回结果是否为空
if (orderCacDeliveryFeeArgs == null) {
logger.warn("计算同城配送费失败:未能获取订单[{}]的配送费计算参数", orderId);
return 0;
}
// 调用计算方法计算配送费
return computeSameCityInnerDeliveryFee(
orderCacDeliveryFeeArgs.getStore_id(),
orderCacDeliveryFeeArgs.getDa_longitude(),
orderCacDeliveryFeeArgs.getDa_latitude(),
orderCacDeliveryFeeArgs.getOrder_weight_gram(),
orderCacDeliveryFeeArgs.getOrder_product_amount(),
orderCacDeliveryFeeArgs.getOrder_discount_amount(),
orderCacDeliveryFeeArgs.getOrder_payment_amount());
}
/**
* 平台计算同城订单的内部配送费仅仅作用于平台内部配送费计算商家配送费忽略此方法下单前可以查询
*
* @param storeId 店铺Id
* @param orderLongitude 订单送达地目的地经度
* @param orderLatitude 订单送达地目的地维度
* @param orderWeightGram 订单重量单位克
* @param orderProductAmount 订单商品原价金额
* @param orderDiscountAmount 订单商品折扣金额订单原价减去每个商品折扣费
* @param orderPayAmount 订单实际支付金额折扣金额-优惠券-积分扣-人工干预扣费不包含运费
* @return 配送费单位为分
*/
@Override
public Integer computeSameCityInnerDeliveryFee(Integer storeId, String orderLongitude, String orderLatitude, Integer orderWeightGram, BigDecimal orderProductAmount, BigDecimal orderDiscountAmount, BigDecimal orderPayAmount) {
// 参数校验
if (storeId == null || orderLongitude == null || orderLatitude == null || storeId <= 0) {
logger.warn("同城配送缺少必要参数,无法计算配送费。");
return 0;
}
// 获取店铺基本信息
ShopStoreBase storeBase = shopStoreBaseService.get(storeId);
if (storeBase == null) {
logger.warn("同城配送缺少店铺基本信息,无法计算配送费。");
return 0;
}
String storeName = storeBase.getStore_name();
String storeLng = storeBase.getStore_longitude();
String storeLat = storeBase.getStore_latitude();
if (StrUtil.isBlank(storeLng) || StrUtil.isBlank(storeLat)) {
logger.warn("无法获取{}的具体位置,请联系商家。", storeName);
return 0;
}
// 获取平台的基础运费设置记录
ShopStoreSameCityTransportBase transportBase = getShopStoreSameCityTransportBaseById(Convert.toLong(storeId), CommonConstant.Enable);
if (transportBase == null) {
logger.warn("商家{}尚未完成同城配送设置,无法计算配送费。", storeName);
return 0;
}
// 设置默认值
if (transportBase.getDistance_base() == null) {
transportBase.setDistance_base(0);
}
if (transportBase.getWeight_base() == null) {
transportBase.setWeight_base(0);
}
if (transportBase.getDelivery_base_fee() == null) {
transportBase.setDelivery_base_fee(BigDecimal.ZERO);
}
// 计算两点的距离(单位米)
Double distanceD = PositionUtil.getDistance1(Convert.toDouble(storeLng), Convert.toDouble(storeLat), Convert.toDouble(orderLongitude), Convert.toDouble(orderLatitude));
Integer distance = (distanceD != null) ? distanceD.intValue() : 0;
// 基础配送费计算
BigDecimal deliveryBaseFee = Convert.toBigDecimal(transportBase.getDelivery_base_fee(), BigDecimal.ZERO);
// 获取运费配送范围信息
List<ShopStoreSameCityTransport> transportList = shopStoreSameCityTransportService.selectShopStoreSameCityTransportList(Convert.toLong(storeId));
if (CollUtil.isEmpty(transportList)) {
// 没有配送范围规则的时候直接以基础配送费来配送
return deliveryBaseFee.multiply(BigDecimal.valueOf(100)).intValue();
}
// 判断配送范围和起送金额条件
String canNotDeliveryReason = "";
boolean canDelivery = false;
// 优先处理距离和金额都满足的规则
for (ShopStoreSameCityTransport transport : transportList) {
// 判断订单距离是否在配送范围内
if (transport.getMax_delivery_radius() >= distance) {
// 距离在配送范围内判断金额是否符合起配金额额度
boolean moneyPassed = false;
if (CommonConstant.Delivery_Amount_Comput_Type_Original.equals(transport.getMin_delivery_amount_type())) {
moneyPassed = orderProductAmount != null && transport.getMin_delivery_amount().compareTo(orderProductAmount) <= 0;
} else if (CommonConstant.Delivery_Amount_Comput_Type_Discounted.equals(transport.getMin_delivery_amount_type())) {
moneyPassed = orderDiscountAmount != null && transport.getMin_delivery_amount().compareTo(orderDiscountAmount) <= 0;
} else if (CommonConstant.Delivery_Amount_Comput_Type_Payment.equals(transport.getMin_delivery_amount_type())) {
moneyPassed = orderPayAmount != null && transport.getMin_delivery_amount().compareTo(orderPayAmount) <= 0;
}
// 距离和金额都满足条件
if (moneyPassed) {
canDelivery = true;
break;
}
}
}
// 如果没有找到完全满足条件的规则再详细检查找出失败原因
if (!canDelivery) {
for (ShopStoreSameCityTransport transport : transportList) {
// 判断订单距离是否在配送范围内
if (transport.getMax_delivery_radius() < distance) {
// 记录距离不满足的原因
canNotDeliveryReason = storeName + "的订单不在配送范围内,订单无法配送。";
} else {
// 距离在配送范围内判断金额是否符合起配金额额度
if (CommonConstant.Delivery_Amount_Comput_Type_Original.equals(transport.getMin_delivery_amount_type())) {
if (orderProductAmount != null && transport.getMin_delivery_amount().compareTo(orderProductAmount) > 0) {
BigDecimal diffMoney = transport.getMin_delivery_amount().subtract(orderProductAmount);
canNotDeliveryReason = String.format("%s商品原价金额还差%.2f元,才满足配送条件,请检查订单。", storeName, diffMoney);
} else {
canDelivery = true;
break;
}
} else if (CommonConstant.Delivery_Amount_Comput_Type_Discounted.equals(transport.getMin_delivery_amount_type())) {
if (orderDiscountAmount != null && transport.getMin_delivery_amount().compareTo(orderDiscountAmount) > 0) {
BigDecimal diffMoney = transport.getMin_delivery_amount().subtract(orderDiscountAmount);
canNotDeliveryReason = String.format("%s订单折后金额还差%.2f元,才满足配送条件,请检查订单。", storeName, diffMoney);
} else {
canDelivery = true;
break;
}
} else if (CommonConstant.Delivery_Amount_Comput_Type_Payment.equals(transport.getMin_delivery_amount_type())) {
if (orderPayAmount != null && transport.getMin_delivery_amount().compareTo(orderPayAmount) > 0) {
BigDecimal diffMoney = transport.getMin_delivery_amount().subtract(orderPayAmount);
canNotDeliveryReason = String.format("%s订单应支付金额还差%.2f元,才满足配送条件,请检查订单。", storeName, diffMoney);
} else {
canDelivery = true;
break;
}
}
}
}
}
// 如果仍然不能配送记录日志并返回0
if (!canDelivery) {
logger.warn(canNotDeliveryReason.isEmpty() ? (storeName + "订单不在配送范围内或未达起送金额,请检查!") : canNotDeliveryReason);
return 0;
}
// 额外配送费计算
// 每增加一个距离累加运费
if (transportBase.getDistance_increase_km() != null && transportBase.getDistance_increase_fee() != null && distance > transportBase.getDistance_base() * 1000) {
// 实际配送距离超出基础距离单位km
BigDecimal diffDistanceM = CommonUtil.DecimalRoundHalfUp(BigDecimal.valueOf(distance - transportBase.getDistance_base() * 1000).divide(BigDecimal.valueOf(1000)));
// 倍数
BigDecimal times = BigDecimal.ZERO;
if (transportBase.getDistance_increase_km() > 0 && diffDistanceM.intValue() > transportBase.getDistance_increase_km()) {
// 末尾非零进位比如2.1将是3 2.0将是22.001将是3
times = NumberUtil.div(diffDistanceM, transportBase.getDistance_increase_km()).setScale(0, RoundingMode.UP);
}
// 超过基础运费距离后累加上运费
deliveryBaseFee = deliveryBaseFee.add(transportBase.getDistance_increase_fee().multiply(times));
}
// 每增加一个重量累加运费重量暂时忽略,配置的时候设置0
if (transportBase.getWeight_increase_kg() != null && transportBase.getWeight_increase_fee() != null && orderWeightGram != null && orderWeightGram > transportBase.getWeight_base() * 1000) {
// 实际配送重量超出基础重量单位kg
BigDecimal diffWeightKg = CommonUtil.DecimalRoundHalfUp(BigDecimal.valueOf(orderWeightGram - transportBase.getWeight_base() * 1000).divide(BigDecimal.valueOf(1000)));
// 倍数
BigDecimal times = BigDecimal.ZERO;
if (transportBase.getWeight_increase_kg() > 0 && diffWeightKg.intValue() > transportBase.getWeight_increase_kg()) {
// 末尾非零进位比如2.1将是3 2.0将是22.001将是3
times = NumberUtil.div(diffWeightKg, transportBase.getWeight_increase_kg()).setScale(0, RoundingMode.UP); // 修正应该除以weight_increase_kg而不是distance_increase_km
}
deliveryBaseFee = deliveryBaseFee.add(transportBase.getWeight_increase_fee().multiply(times));
}
// 返回单位为分的配送费
return deliveryBaseFee.multiply(BigDecimal.valueOf(100)).intValue();
}
}

View File

@ -2644,7 +2644,7 @@ public class ShopUserCartServiceImpl extends BaseServiceImpl<ShopUserCartMapper,
// 订单折扣后金额
BigDecimal orderSelDiscountAmount = Convert.toBigDecimal(store_row.get("productMoneySelGoods"));
// 订单最终应付金额
BigDecimal orderPaymentAmount = Convert.toBigDecimal(store_row.get("productMoneySelGoods"));
BigDecimal orderPaymentAmount = Convert.toBigDecimal(store_row.get("order_money_select_items"));
// 同城配送运费检查和计算(只返回数据不能配送不抛异常)
SameCityDeliveryFeeRespDTO sameCityDeliveryFeeResp = shopStoreSameCityTransportBaseService.computeSameCityTransportFee(storeId, orderLng, orderLat, 0, productMoneyOriginGoods, orderSelDiscountAmount, orderPaymentAmount, canThrow);
@ -2671,7 +2671,7 @@ public class ShopUserCartServiceImpl extends BaseServiceImpl<ShopUserCartMapper,
}
// RMK 平台最低配送费单位add:2025-09-26
Integer innerMinDeliverFee = accountBaseConfigService.getInnerMinDeliveryFee(Convert.toInt(storeId));
Integer innerMinDeliverFee = accountBaseConfigService.getInnerMinDeliveryFee(delivery_type_id, storeId.intValue(), orderLng, orderLat, 0, productMoneyOriginGoods, orderSelDiscountAmount, orderPaymentAmount);
if (canThrow
&& CheckUtil.isNotEmpty(innerMinDeliverFee)
&& CheckUtil.isNotEmpty(orderSelMoneyAmount)
@ -2681,6 +2681,8 @@ public class ShopUserCartServiceImpl extends BaseServiceImpl<ShopUserCartMapper,
throw new ApiException(I18nUtil._("订单低于平台最低配送金额!"));
}
// 这个店铺订单的平台最低配送费单位
store_row.put("innerMinDeliverFee", innerMinDeliverFee);
}
// 订单总计运费