Merge branch 'main' into dev
This commit is contained in:
commit
0d58584b13
@ -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")
|
||||
|
||||
@ -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;
|
||||
}
|
||||
@ -90,11 +90,19 @@ public class CommonService {
|
||||
* @return 配送方式名称
|
||||
*/
|
||||
public static String getDeliveryExpressName(Integer deliveryTypeId) {
|
||||
if (deliveryTypeId == null) return "其他配送";
|
||||
String name = StateCode.DELIVERY_TYPE_MAP.get(deliveryTypeId);
|
||||
return name != null ? name : "其他配送";
|
||||
// 当配送方式ID为空时,默认返回顺丰同城
|
||||
if (deliveryTypeId == null) {
|
||||
log.debug("配送方式ID为空,返回默认配送方式:顺丰同城");
|
||||
return "顺丰同城";
|
||||
}
|
||||
|
||||
// 从配送方式映射表中获取名称,如果未找到则返回默认值顺丰同城
|
||||
String deliveryName = StateCode.DELIVERY_TYPE_MAP.getOrDefault(deliveryTypeId, "顺丰同城");
|
||||
log.debug("获取配送方式名称:deliveryTypeId={} deliveryName={}", deliveryTypeId, deliveryName);
|
||||
return deliveryName;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 判断配送方式是否为同城配送
|
||||
*
|
||||
|
||||
@ -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);
|
||||
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取平台默认最低配送费
|
||||
*
|
||||
|
||||
@ -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 表
|
||||
|
||||
@ -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);
|
||||
|
||||
// 平台最低配送费,单位(分)
|
||||
|
||||
@ -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);
|
||||
|
||||
}
|
||||
|
||||
@ -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.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) {
|
||||
log.debug("[内部配送费] 计算开始,deliveryTypeId: {}, storeId: {}, orderLongitude: {}, orderLatitude: {}, orderWeightGram: {}, orderProductAmount: {}, orderDiscountAmount: {}, orderPayAmount: {}",
|
||||
deliveryTypeId, storeId, orderLongitude, orderLatitude, orderWeightGram, orderProductAmount, orderDiscountAmount, 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,
|
||||
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 orderLongitude 订单经度
|
||||
* @param orderLatitude 订单纬度
|
||||
* @param orderWeightGram 订单重量(克)
|
||||
* @param orderProductAmount 订单商品金额
|
||||
* @param orderDiscountAmount 订单折扣金额
|
||||
* @param orderPayAmount 订单支付金额
|
||||
* @return 内部配送费(单位 : 分)
|
||||
*/
|
||||
private Integer calculateInnerMinDeliveryFee(Integer storeId, 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;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取平台默认最低配送费
|
||||
*
|
||||
|
||||
@ -91,7 +91,7 @@ public class EsignContractFillingFileServiceImpl extends BaseServiceImpl<EsignCo
|
||||
|
||||
@Resource
|
||||
private OssService ossService;
|
||||
|
||||
|
||||
/**
|
||||
* 根据双方营业执照号码(或个人身份证)填充合同模版,生成合同文件地址
|
||||
* <p>
|
||||
@ -109,47 +109,47 @@ public class EsignContractFillingFileServiceImpl extends BaseServiceImpl<EsignCo
|
||||
}
|
||||
|
||||
// 2. 获取平台方信息
|
||||
EsignPlatformInfo esignPlatformInfo = esignPlatformInfoService.getEsignPlatformInfo(0, "");
|
||||
if (ObjectUtils.isEmpty(esignPlatformInfo)) {
|
||||
EsignPlatformInfo platformInfo = esignPlatformInfoService.getEsignPlatformInfo(0, "");
|
||||
if (ObjectUtils.isEmpty(platformInfo)) {
|
||||
log.error("[合同生成] 平台方(代理商方)信息缺失,请先配置平台信息");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (StrUtil.isBlank(esignPlatformInfo.getDoc_template())) {
|
||||
if (StrUtil.isBlank(platformInfo.getDoc_template())) {
|
||||
log.error("[合同生成] 平台方合同模板信息为空,无法继续生成合同");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 3. 获取入驻商家(审批通过的)的信息
|
||||
ShopMchEntry shopMchEntry = shopMchEntryService.getShopMerchEntryByStoreId(storeId);
|
||||
if (shopMchEntry == null) {
|
||||
ShopMchEntry mchEntry = shopMchEntryService.getShopMerchEntryByStoreId(storeId);
|
||||
if (mchEntry == null) {
|
||||
log.error("[合同生成] 找不到商家入驻信息, storeId: {}", storeId);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 4. 检查商家审批状态
|
||||
if (!CommonConstant.MCH_APPR_STA_PASS.equals(shopMchEntry.getApproval_status())) {
|
||||
log.error("[合同生成] 商家入驻审批未通过,当前状态: {}, storeId: {}", shopMchEntry.getApproval_status(), storeId);
|
||||
if (!CommonConstant.MCH_APPR_STA_PASS.equals(mchEntry.getApproval_status())) {
|
||||
log.error("[合同生成] 商家入驻审批未通过,当前状态: {}, storeId: {}", mchEntry.getApproval_status(), storeId);
|
||||
return false;
|
||||
}
|
||||
|
||||
ShopStoreBase shopStoreBase = shopStoreBaseService.getShopStoreBaseByStoreId(storeId);
|
||||
if (ObjectUtils.isEmpty(shopStoreBase)) {
|
||||
ShopStoreBase storeBase = shopStoreBaseService.getShopStoreBaseByStoreId(storeId);
|
||||
if (ObjectUtils.isEmpty(storeBase)) {
|
||||
log.error("[合同生成] 缺少商家店铺信息, storeId: {}", storeId);
|
||||
return false;
|
||||
}
|
||||
|
||||
BigDecimal splitRatio = shopStoreBase.getSplit_ratio();
|
||||
BigDecimal splitRatio = storeBase.getSplit_ratio();
|
||||
if (CheckUtil.isEmpty(splitRatio)) {
|
||||
log.warn("[合同生成] 店铺分账比例为空,将使用入驻申请时设置的比例, storeId: {}", storeId);
|
||||
splitRatio = shopMchEntry.getSplit_ratio();
|
||||
splitRatio = mchEntry.getSplit_ratio();
|
||||
}
|
||||
|
||||
// 5. 获取代理商信息
|
||||
EsignPlatformInfo distributor = esignPlatformInfoService.getDistributorInfoById(shopMchEntry.getDistributor_id());
|
||||
EsignPlatformInfo distributor = esignPlatformInfoService.getDistributorInfoById(mchEntry.getDistributor_id());
|
||||
|
||||
// 6. 获取平台方合同模版信息
|
||||
JSONArray templates = JSONUtil.parseArray(esignPlatformInfo.getDoc_template());
|
||||
JSONArray templates = JSONUtil.parseArray(platformInfo.getDoc_template());
|
||||
if (templates == null || templates.isEmpty()) {
|
||||
log.error("[合同生成] 平台方(代理商方)合同模板信息缺失");
|
||||
return false;
|
||||
@ -158,27 +158,27 @@ public class EsignContractFillingFileServiceImpl extends BaseServiceImpl<EsignCo
|
||||
// 7. 准备基础数据
|
||||
String today = DateUtil.format(new Date(), "yyyy年MM月dd日");
|
||||
// 甲方公司名称,甲方是个人的时候,没有公司名,直接用店铺名(个人实名)
|
||||
String mchCompany = CommonConstant.MCH_ENTITY_TYPE_QY.equals(shopMchEntry.getEntity_type())
|
||||
? shopMchEntry.getBiz_license_company()
|
||||
: shopMchEntry.getStore_name() + "(" + shopMchEntry.getContact_name() + ")";
|
||||
String platCompany = esignPlatformInfo.getLicense_company();
|
||||
String mchCompany = CommonConstant.MCH_ENTITY_TYPE_QY.equals(mchEntry.getEntity_type())
|
||||
? mchEntry.getBiz_license_company()
|
||||
: mchEntry.getStore_name() + "(" + mchEntry.getContact_name() + ")";
|
||||
String platCompany = platformInfo.getLicense_company();
|
||||
// 甲方法人姓名,甲方是个人的时候,没有法人,直接用个人实名
|
||||
String legalPersonName = CommonConstant.MCH_ENTITY_TYPE_QY.equals(shopMchEntry.getEntity_type())
|
||||
? shopMchEntry.getLegal_person_name()
|
||||
: shopMchEntry.getContact_name();
|
||||
String legalPersonMobile = CommonConstant.MCH_ENTITY_TYPE_QY.equals(shopMchEntry.getEntity_type())
|
||||
? shopMchEntry.getLegal_person_mobile()
|
||||
: shopMchEntry.getLogin_mobile();
|
||||
String legalPersonName = CommonConstant.MCH_ENTITY_TYPE_QY.equals(mchEntry.getEntity_type())
|
||||
? mchEntry.getLegal_person_name()
|
||||
: mchEntry.getContact_name();
|
||||
String legalPersonMobile = CommonConstant.MCH_ENTITY_TYPE_QY.equals(mchEntry.getEntity_type())
|
||||
? mchEntry.getLegal_person_mobile()
|
||||
: mchEntry.getLogin_mobile();
|
||||
|
||||
// 甲方法人身份证号,甲方是个人的时候,没有法人,直接用个人身份证
|
||||
String legalPersonIdNumber = CommonConstant.MCH_ENTITY_TYPE_QY.equals(shopMchEntry.getEntity_type())
|
||||
? shopMchEntry.getLegal_person_id_number()
|
||||
: shopMchEntry.getIndividual_id_number();
|
||||
String legalPersonIdNumber = CommonConstant.MCH_ENTITY_TYPE_QY.equals(mchEntry.getEntity_type())
|
||||
? mchEntry.getLegal_person_id_number()
|
||||
: mchEntry.getIndividual_id_number();
|
||||
|
||||
String contractNumber = StringUtils.genLklOrderNo(4);
|
||||
int successCnt = 0;
|
||||
|
||||
log.info("[合同生成] 开始为商家生成入驻合同文件, storeId: {}, 商家手机号: {}", storeId, shopMchEntry.getLogin_mobile());
|
||||
log.info("[合同生成] 开始为商家生成入驻合同文件, storeId: {}, 商家手机号: {}", storeId, mchEntry.getLogin_mobile());
|
||||
|
||||
// 8. 遍历模版文件生成合同(模版文件里有三份合同,顺序排列的: 1.平台商户入驻服务框架协议 2.小发同城服务费结算 3.结算授权委托书)
|
||||
for (JSONObject template : templates.jsonIter()) {
|
||||
@ -195,11 +195,11 @@ public class EsignContractFillingFileServiceImpl extends BaseServiceImpl<EsignCo
|
||||
fillJson.put("docTemplateId", templateId)
|
||||
.put("fileName", fileName);
|
||||
|
||||
JSONArray list = new JSONArray();
|
||||
JSONArray componentList = new JSONArray();
|
||||
|
||||
// 10. 填充合同组件数据
|
||||
// 平台合同名称
|
||||
list.add(new HashMap<String, Object>() {{
|
||||
componentList.add(new HashMap<String, Object>() {{
|
||||
put("componentKey", "plat_contracts");
|
||||
put("componentValue", "《平台商户入驻服务框架协议》和《小发同城服务费结算》");
|
||||
}});
|
||||
@ -207,7 +207,7 @@ public class EsignContractFillingFileServiceImpl extends BaseServiceImpl<EsignCo
|
||||
// 签署时间(甲方)
|
||||
for (int i = 1; i <= 3; i++) {
|
||||
int finalI = i;
|
||||
list.add(new HashMap<String, Object>() {{
|
||||
componentList.add(new HashMap<String, Object>() {{
|
||||
put("componentKey", "mch_sign_date" + finalI);
|
||||
put("componentValue", today);
|
||||
}});
|
||||
@ -216,34 +216,34 @@ public class EsignContractFillingFileServiceImpl extends BaseServiceImpl<EsignCo
|
||||
// 签署时间(乙方)
|
||||
for (int i = 1; i <= 3; i++) {
|
||||
int finalI = i;
|
||||
list.add(new HashMap<String, Object>() {{
|
||||
componentList.add(new HashMap<String, Object>() {{
|
||||
put("componentKey", "plat_sign_date" + finalI);
|
||||
put("componentValue", today);
|
||||
}});
|
||||
}
|
||||
|
||||
// 甲方公司名称
|
||||
int mchCompanyCount = CommonConstant.MCH_ENTITY_TYPE_QY.equals(shopMchEntry.getEntity_type()) ? 17 : 16;
|
||||
int mchCompanyCount = CommonConstant.MCH_ENTITY_TYPE_QY.equals(mchEntry.getEntity_type()) ? 17 : 16;
|
||||
for (int i = 1; i <= mchCompanyCount; i++) {
|
||||
int finalI = i;
|
||||
list.add(new HashMap<String, Object>() {{
|
||||
componentList.add(new HashMap<String, Object>() {{
|
||||
put("componentKey", "mch_company" + finalI);
|
||||
put("componentValue", mchCompany);
|
||||
}});
|
||||
}
|
||||
|
||||
// 特殊处理:甲方收款账户方(企业是公司名,个人是个人实名)
|
||||
if (!CommonConstant.MCH_ENTITY_TYPE_QY.equals(shopMchEntry.getEntity_type())) {
|
||||
list.add(new HashMap<String, Object>() {{
|
||||
if (!CommonConstant.MCH_ENTITY_TYPE_QY.equals(mchEntry.getEntity_type())) {
|
||||
componentList.add(new HashMap<String, Object>() {{
|
||||
put("componentKey", "mch_company17");
|
||||
put("componentValue", shopMchEntry.getContact_name());
|
||||
put("componentValue", mchEntry.getContact_name());
|
||||
}});
|
||||
}
|
||||
|
||||
// 甲方法人姓名
|
||||
for (int i = 1; i <= 4; i++) {
|
||||
int finalI = i;
|
||||
list.add(new HashMap<String, Object>() {{
|
||||
componentList.add(new HashMap<String, Object>() {{
|
||||
put("componentKey", "mch_legal_person_name" + finalI);
|
||||
put("componentValue", legalPersonName);
|
||||
}});
|
||||
@ -252,63 +252,63 @@ public class EsignContractFillingFileServiceImpl extends BaseServiceImpl<EsignCo
|
||||
// 甲方法人手机号
|
||||
for (int i = 1; i <= 3; i++) {
|
||||
int finalI = i;
|
||||
list.add(new HashMap<String, Object>() {{
|
||||
componentList.add(new HashMap<String, Object>() {{
|
||||
put("componentKey", "mch_legal_person_mobile" + finalI);
|
||||
put("componentValue", legalPersonMobile);
|
||||
}});
|
||||
}
|
||||
|
||||
// 甲方身份证号码
|
||||
list.add(new HashMap<String, Object>() {{
|
||||
componentList.add(new HashMap<String, Object>() {{
|
||||
put("componentKey", "mch_legal_person_id_number1");
|
||||
put("componentValue", legalPersonIdNumber);
|
||||
}});
|
||||
|
||||
// 甲方店铺名称
|
||||
list.add(new HashMap<String, Object>() {{
|
||||
componentList.add(new HashMap<String, Object>() {{
|
||||
put("componentKey", "mch_store_name1");
|
||||
put("componentValue", shopMchEntry.getStore_name());
|
||||
put("componentValue", mchEntry.getStore_name());
|
||||
}});
|
||||
|
||||
// 规则编号
|
||||
list.add(new HashMap<String, Object>() {{
|
||||
componentList.add(new HashMap<String, Object>() {{
|
||||
put("componentKey", "rule_no");
|
||||
put("componentValue", 3);
|
||||
}});
|
||||
|
||||
// 分账比例
|
||||
BigDecimal finalSplitRatio = splitRatio;
|
||||
list.add(new HashMap<String, Object>() {{
|
||||
componentList.add(new HashMap<String, Object>() {{
|
||||
put("componentKey", "mch_ratio");
|
||||
put("componentValue", finalSplitRatio);
|
||||
}});
|
||||
|
||||
// 结算方式
|
||||
list.add(new HashMap<String, Object>() {{
|
||||
componentList.add(new HashMap<String, Object>() {{
|
||||
put("componentKey", "settlement_method");
|
||||
put("componentValue", shopMchEntry.getSettlement_method());
|
||||
put("componentValue", mchEntry.getSettlement_method());
|
||||
}});
|
||||
|
||||
// 甲方地址
|
||||
list.add(new HashMap<String, Object>() {{
|
||||
componentList.add(new HashMap<String, Object>() {{
|
||||
put("componentKey", "mch_address1");
|
||||
put("componentValue", shopMchEntry.getStore_address());
|
||||
put("componentValue", mchEntry.getStore_address());
|
||||
}});
|
||||
|
||||
// 甲方银行
|
||||
list.add(new HashMap<String, Object>() {{
|
||||
componentList.add(new HashMap<String, Object>() {{
|
||||
put("componentKey", "mch_bank1");
|
||||
put("componentValue", shopMchEntry.getBank_name());
|
||||
put("componentValue", mchEntry.getBank_name());
|
||||
}});
|
||||
|
||||
// 甲方账户号
|
||||
list.add(new HashMap<String, Object>() {{
|
||||
componentList.add(new HashMap<String, Object>() {{
|
||||
put("componentKey", "mch_account_number1");
|
||||
put("componentValue", shopMchEntry.getAccount_number());
|
||||
put("componentValue", mchEntry.getAccount_number());
|
||||
}});
|
||||
|
||||
// 乙方公司名称
|
||||
list.add(new HashMap<String, Object>() {{
|
||||
componentList.add(new HashMap<String, Object>() {{
|
||||
put("componentKey", "plat_company1");
|
||||
put("componentValue", platCompany + "和代理商");
|
||||
}});
|
||||
@ -316,7 +316,7 @@ public class EsignContractFillingFileServiceImpl extends BaseServiceImpl<EsignCo
|
||||
// 其他乙方公司名称
|
||||
for (int i = 2; i <= 5; i++) {
|
||||
int finalI = i;
|
||||
list.add(new HashMap<String, Object>() {{
|
||||
componentList.add(new HashMap<String, Object>() {{
|
||||
put("componentKey", "plat_company" + finalI);
|
||||
put("componentValue", platCompany);
|
||||
}});
|
||||
@ -325,58 +325,58 @@ public class EsignContractFillingFileServiceImpl extends BaseServiceImpl<EsignCo
|
||||
// 乙方手机号
|
||||
for (int i = 1; i <= 2; i++) {
|
||||
int finalI = i;
|
||||
list.add(new HashMap<String, Object>() {{
|
||||
componentList.add(new HashMap<String, Object>() {{
|
||||
put("componentKey", "plat_mobile" + finalI);
|
||||
put("componentValue", esignPlatformInfo.getLegal_person_mobile());
|
||||
put("componentValue", platformInfo.getLegal_person_mobile());
|
||||
}});
|
||||
}
|
||||
|
||||
// 乙方邮箱(重复填充,但保持原逻辑)
|
||||
for (int i = 0; i < 6; i++) {
|
||||
list.add(new HashMap<String, Object>() {{
|
||||
componentList.add(new HashMap<String, Object>() {{
|
||||
put("componentKey", "plat_email1");
|
||||
put("componentValue", esignPlatformInfo.getEmail());
|
||||
put("componentValue", platformInfo.getEmail());
|
||||
}});
|
||||
}
|
||||
|
||||
// 乙方银行
|
||||
list.add(new HashMap<String, Object>() {{
|
||||
componentList.add(new HashMap<String, Object>() {{
|
||||
put("componentKey", "plat_bank1");
|
||||
put("componentValue", esignPlatformInfo.getRec_acc_bank_name());
|
||||
put("componentValue", platformInfo.getRec_acc_bank_name());
|
||||
}});
|
||||
|
||||
// 乙方账户号
|
||||
list.add(new HashMap<String, Object>() {{
|
||||
componentList.add(new HashMap<String, Object>() {{
|
||||
put("componentKey", "plat_account_number1");
|
||||
put("componentValue", esignPlatformInfo.getRec_acc_card_no());
|
||||
put("componentValue", platformInfo.getRec_acc_card_no());
|
||||
}});
|
||||
|
||||
// 11. 处理代理商相关数据
|
||||
if (distributor != null) {
|
||||
// 有代理商的时候,填充代理商的信息
|
||||
list.add(new HashMap<String, Object>() {{
|
||||
componentList.add(new HashMap<String, Object>() {{
|
||||
put("componentKey", "distr_company1");
|
||||
put("componentValue", distributor.getLicense_company());
|
||||
}});
|
||||
list.add(new HashMap<String, Object>() {{
|
||||
componentList.add(new HashMap<String, Object>() {{
|
||||
put("componentKey", "distr_mobile1");
|
||||
put("componentValue", distributor.getLegal_person_mobile());
|
||||
}});
|
||||
list.add(new HashMap<String, Object>() {{
|
||||
componentList.add(new HashMap<String, Object>() {{
|
||||
put("componentKey", "distr_company2");
|
||||
put("componentValue", distributor.getLicense_company());
|
||||
}});
|
||||
list.add(new HashMap<String, Object>() {{
|
||||
componentList.add(new HashMap<String, Object>() {{
|
||||
put("componentKey", "distr_bank1");
|
||||
put("componentValue", distributor.getRec_acc_bank_name());
|
||||
}});
|
||||
|
||||
list.add(new HashMap<String, Object>() {{
|
||||
componentList.add(new HashMap<String, Object>() {{
|
||||
put("componentKey", "distr_account_number1");
|
||||
put("componentValue", distributor.getRec_acc_card_no());
|
||||
}});
|
||||
|
||||
list.add(new HashMap<String, Object>() {{
|
||||
componentList.add(new HashMap<String, Object>() {{
|
||||
put("componentKey", "distr_sign_date1");
|
||||
put("componentValue", today);
|
||||
}});
|
||||
@ -384,24 +384,24 @@ public class EsignContractFillingFileServiceImpl extends BaseServiceImpl<EsignCo
|
||||
log.debug("[合同生成] 已填充代理商信息: {}", distributor.getLicense_company());
|
||||
} else {
|
||||
// 无代理商时填充默认值
|
||||
list.add(new HashMap<String, Object>() {{
|
||||
componentList.add(new HashMap<String, Object>() {{
|
||||
put("componentKey", "distr_company1");
|
||||
put("componentValue", "无");
|
||||
}});
|
||||
list.add(new HashMap<String, Object>() {{
|
||||
componentList.add(new HashMap<String, Object>() {{
|
||||
put("componentKey", "distr_mobile1");
|
||||
put("componentValue", "无");
|
||||
}});
|
||||
list.add(new HashMap<String, Object>() {{
|
||||
componentList.add(new HashMap<String, Object>() {{
|
||||
put("componentKey", "distr_company2");
|
||||
put("componentValue", "无");
|
||||
}});
|
||||
list.add(new HashMap<String, Object>() {{
|
||||
componentList.add(new HashMap<String, Object>() {{
|
||||
put("componentKey", "distr_bank1");
|
||||
put("componentValue", "无");
|
||||
}});
|
||||
|
||||
list.add(new HashMap<String, Object>() {{
|
||||
componentList.add(new HashMap<String, Object>() {{
|
||||
put("componentKey", "distr_account_number1");
|
||||
put("componentValue", "无");
|
||||
}});
|
||||
@ -409,7 +409,7 @@ public class EsignContractFillingFileServiceImpl extends BaseServiceImpl<EsignCo
|
||||
log.debug("[合同生成] 未配置代理商信息,使用默认值");
|
||||
}
|
||||
|
||||
fillJson.put("components", list);
|
||||
fillJson.put("components", componentList);
|
||||
String jsonParam = fillJson.toString();
|
||||
|
||||
String apiAddr = "/v3/files/create-by-doc-template";
|
||||
@ -420,19 +420,19 @@ public class EsignContractFillingFileServiceImpl extends BaseServiceImpl<EsignCo
|
||||
appId, appSecret, jsonParam, requestType.name(), apiAddr, debug);
|
||||
|
||||
// 发起接口请求
|
||||
EsignHttpResponse createByDocTemplate = EsignHttpHelper.doCommHttp(
|
||||
EsignHttpResponse response = EsignHttpHelper.doCommHttp(
|
||||
serverUrl, apiAddr, requestType, jsonParam, header, debug);
|
||||
|
||||
log.info("[合同生成] 调用电子签约服务生成合同文件: status={}, response={}",
|
||||
createByDocTemplate.getStatus(), createByDocTemplate.getBody());
|
||||
response.getStatus(), response.getBody());
|
||||
|
||||
if (createByDocTemplate.getStatus() != 200) {
|
||||
log.error("[合同生成] 调用电子签约服务生成合同文件失败, HTTP状态码: {}", createByDocTemplate.getStatus());
|
||||
if (response.getStatus() != 200) {
|
||||
log.error("[合同生成] 调用电子签约服务生成合同文件失败, HTTP状态码: {}", response.getStatus());
|
||||
continue; // 继续处理下一个模版
|
||||
}
|
||||
|
||||
// 13. 解析API返回结果
|
||||
JSONObject jsonObject = JSONUtil.parseObj(createByDocTemplate.getBody()).getJSONObject("data");
|
||||
JSONObject jsonObject = JSONUtil.parseObj(response.getBody()).getJSONObject("data");
|
||||
String fileDownloadUrl = jsonObject.getStr("fileDownloadUrl");
|
||||
String fileId = jsonObject.getStr("fileId");
|
||||
|
||||
@ -442,13 +442,13 @@ public class EsignContractFillingFileServiceImpl extends BaseServiceImpl<EsignCo
|
||||
}
|
||||
|
||||
// 14. 创建合同填充文件记录
|
||||
EsignContractFillingFile esignContractFillingFile = new EsignContractFillingFile();
|
||||
esignContractFillingFile.setUnsigned_contract_url(fileDownloadUrl);
|
||||
esignContractFillingFile.setFile_id(fileId);
|
||||
EsignContractFillingFile contractFillingFile = new EsignContractFillingFile();
|
||||
contractFillingFile.setUnsigned_contract_url(fileDownloadUrl);
|
||||
contractFillingFile.setFile_id(fileId);
|
||||
|
||||
// 15. 上传合同文件到OSS
|
||||
String cosFileName = TENGXUN_DEFAULT_DIR.concat("/contract/")
|
||||
.concat(shopMchEntry.getLogin_mobile()).concat("/")
|
||||
.concat(mchEntry.getLogin_mobile()).concat("/")
|
||||
.concat(fileId).concat(".pdf");
|
||||
|
||||
String localFileUrl = ossService.uploadObject4OSS(fileDownloadUrl, cosFileName);
|
||||
@ -457,42 +457,42 @@ public class EsignContractFillingFileServiceImpl extends BaseServiceImpl<EsignCo
|
||||
continue;
|
||||
}
|
||||
|
||||
esignContractFillingFile.setUnsigned_contract_local_url(localFileUrl);
|
||||
esignContractFillingFile.setDoc_template_id(templateId);
|
||||
esignContractFillingFile.setContract_number(contractNumber + seq);
|
||||
esignContractFillingFile.setContract_name("商户入驻小发同城平台合同协议");
|
||||
esignContractFillingFile.setStore_id(Convert.toStr(storeId));
|
||||
esignContractFillingFile.setMobile(shopMchEntry.getLogin_mobile());
|
||||
esignContractFillingFile.setDoc_template_filling_values(jsonParam);
|
||||
esignContractFillingFile.setSeq(seq);
|
||||
esignContractFillingFile.setStatus(CommonConstant.Enable);
|
||||
contractFillingFile.setUnsigned_contract_local_url(localFileUrl);
|
||||
contractFillingFile.setDoc_template_id(templateId);
|
||||
contractFillingFile.setContract_number(contractNumber + seq);
|
||||
contractFillingFile.setContract_name("商户入驻小发同城平台合同协议");
|
||||
contractFillingFile.setStore_id(Convert.toStr(storeId));
|
||||
contractFillingFile.setMobile(mchEntry.getLogin_mobile());
|
||||
contractFillingFile.setDoc_template_filling_values(jsonParam);
|
||||
contractFillingFile.setSeq(seq);
|
||||
contractFillingFile.setStatus(CommonConstant.Enable);
|
||||
|
||||
// 16. 获取印章位置信息
|
||||
Map<String, JSONArray> signPositionMap = getSignPosition(templateId, fileId);
|
||||
if (signPositionMap != null) {
|
||||
if (signPositionMap.get("mch") != null) {
|
||||
esignContractFillingFile.setMch_sign_position(signPositionMap.get("mch").toString());
|
||||
contractFillingFile.setMch_sign_position(signPositionMap.get("mch").toString());
|
||||
}
|
||||
if (signPositionMap.get("plat") != null) {
|
||||
esignContractFillingFile.setPlat_sign_position(signPositionMap.get("plat").toString());
|
||||
contractFillingFile.setPlat_sign_position(signPositionMap.get("plat").toString());
|
||||
}
|
||||
|
||||
if (distributor != null && signPositionMap.get("distr") != null) {
|
||||
// 如果有代理商,则把代理商的印章位置信息写入数据库
|
||||
esignContractFillingFile.setDistri_sign_position(signPositionMap.get("distr").toString());
|
||||
contractFillingFile.setDistri_sign_position(signPositionMap.get("distr").toString());
|
||||
}
|
||||
}
|
||||
|
||||
// 17. 保存合同填充记录并预创建签署流程
|
||||
if (esignContractFillingFileService.trySaveRecord(esignContractFillingFile)) {
|
||||
if (esignContractFillingFileService.trySaveRecord(contractFillingFile)) {
|
||||
successCnt += 1;
|
||||
log.debug("[合同生成] 合同记录保存成功, fileId: {}", fileId);
|
||||
|
||||
// 预新增一个签署合同记录
|
||||
boolean preCreateResult = esignContractService.preCreateSignFlow(
|
||||
esignContractFillingFile.getMobile(), esignContractFillingFile.getDoc_template_id());
|
||||
contractFillingFile.getMobile(), contractFillingFile.getDoc_template_id());
|
||||
log.debug("[合同生成] 预创建签署流程结果: {}, 商家手机号: {}, 模板ID: {}",
|
||||
preCreateResult, esignContractFillingFile.getMobile(), esignContractFillingFile.getDoc_template_id());
|
||||
preCreateResult, contractFillingFile.getMobile(), contractFillingFile.getDoc_template_id());
|
||||
} else {
|
||||
log.error("[合同生成] 保存合同记录失败, fileId: {}", fileId);
|
||||
}
|
||||
|
||||
@ -167,61 +167,77 @@ public class EsignContractServiceImpl extends BaseServiceImpl<EsignContractMappe
|
||||
|
||||
@Override
|
||||
public Pair<Boolean, String> innerSignFlowCreateByFile(Integer storeId) {
|
||||
// 1. 参数校验
|
||||
if (CheckUtil.isEmpty(storeId)) {
|
||||
return Pair.of(false, "缺少必要参数!");
|
||||
}
|
||||
|
||||
// 组织和填充商家店铺的模版数据
|
||||
// 2. 组织和填充商家店铺的模版数据
|
||||
Boolean isFill = esignContractFillingFileService.fillDocTemplate(storeId);
|
||||
if (!isFill) {
|
||||
return Pair.of(false, "合同信息未准备好,请检查商家入驻手续是否已完成!");
|
||||
}
|
||||
|
||||
// 3. 获取商家合同信息
|
||||
EsignContract esignContract = getEsignContractByStoreId(storeId);
|
||||
if (esignContract == null) {
|
||||
return Pair.of(false, "未找到商家合同信息");
|
||||
}
|
||||
|
||||
// 检查商户入驻信息是否被审核通过
|
||||
// 检查店铺是否已经申请过入驻
|
||||
// 4. 检查商户入驻信息是否被审核通过
|
||||
Integer apprStatus = shopMchEntryService.getApprovalStatus(esignContract.getMch_mobile());
|
||||
if (!CommonConstant.MCH_APPR_STA_PASS.equals(apprStatus)) {
|
||||
return Pair.of(false, "请先审核商家入驻信息");
|
||||
}
|
||||
|
||||
//"{\"docs\":[{\"fileId\":\"ab30d2c5600441f4a7daf512e4d69157\",\"fileName\":\"小发同城平台商户合作协议.pdf\"}],\"signFlowConfig\":{\"signFlowTitle\":\"小发同城平台商户合作协议\",\"signFlowExpireTime\":1746844718000,\"autoFinish\":true,\"notifyUrl\":\"https://mall.gpxscs.cn/asyn/notify\",\"redirectConfig\":{\"redirectUrl\":\"https://mall.gpxscs.cn/\"}},\"signers\":[{\"signConfig\":{\"signOrder\":1},\"noticeConfig\":{\"noticeTypes\":\"1\"},\"signerType\":0,\"psnSignerInfo\":{\"psnAccount\":\"13128997057\",\"psnInfo\":{\"psnName\":\"潘军杰\"}},\"signFields\":[{\"fileId\":\"ab30d2c5600441f4a7daf512e4d69157\",\"normalSignFieldConfig\":{\"signFieldStyle\":1,\"signFieldPosition\":{\"positionPage\":40,\"positionX\":472.3607,\"positionY\":277.19104}}},{\"fileId\":\"ab30d2c5600441f4a7daf512e4d69157\",\"normalSignFieldConfig\":{\"signFieldStyle\":1,\"signFieldPosition\":{\"positionPage\":5,\"positionX\":470.58798,\"positionY\":589.14496}}}]},{\"signConfig\":{\"signOrder\":2},\"noticeConfig\":{\"noticeTypes\":\"1\"},\"signerType\":1,\"orgSignerInfo\":{\"orgName\":\"桂平发发网络有限公司\",\"orgInfo\":{\"orgIDCardNum\":\"91450881MADEQ92533\",\"orgIDCardType\":\"CRED_ORG_USCC\"},\"transactorInfo\":{\"psnAccount\":\"17777525395\",\"psnInfo\":{\"psnName\":\"谢能坤\"}}},\"signFields\":[{\"fileId\":\"ab30d2c5600441f4a7daf512e4d69157\",\"normalSignFieldConfig\":{\"signFieldStyle\":1,\"signFieldPosition\":{\"positionPage\":2,\"positionX\":479.04996,\"positionY\":357.2327}}},{\"fileId\":\"ab30d2c5600441f4a7daf512e4d69157\",\"normalSignFieldConfig\":{\"signFieldStyle\":1,\"signFieldPosition\":{\"positionPage\":5,\"positionX\":255.96832,\"positionY\":588.4553}}}]}]}";
|
||||
// esignContractService.
|
||||
// 5. 获取签署请求参数
|
||||
String jsonParams = esignContract.getReq_params();
|
||||
if (StrUtil.isBlank(jsonParams)) {
|
||||
return Pair.of(false, "合同请求参数为空");
|
||||
}
|
||||
|
||||
try {
|
||||
//请求方法
|
||||
// 6. 调用E签宝API创建签署流程
|
||||
EsignRequestType requestType = EsignRequestType.POST;
|
||||
|
||||
String apiAddr = "/v3/sign-flow/create-by-file";
|
||||
Map<String, String> header = EsignHttpHelper.signAndBuildSignAndJsonHeader(appId, appSecret, jsonParams, requestType.name(), apiAddr, true);
|
||||
|
||||
//发起接口请求
|
||||
EsignHttpResponse createByDocTemplate = EsignHttpHelper.doCommHttp(serverUrl, apiAddr, requestType, jsonParams, header, debug);
|
||||
log.info("发起合同签署流程返回消息:{},{}", createByDocTemplate.getStatus(), createByDocTemplate.getBody());
|
||||
if (createByDocTemplate.getStatus() != 200) {
|
||||
if (createByDocTemplate.getBody() != null) {
|
||||
JSONObject resBody = JSONUtil.parseObj(createByDocTemplate.getBody());
|
||||
log.error("e签宝请求失败,返回状态码:{}, {}", createByDocTemplate.getStatus(), resBody.getStr("message"));
|
||||
return Pair.of(false, "e签宝请求失败,{}" + resBody.getStr("message"));
|
||||
Map<String, String> header = EsignHttpHelper.signAndBuildSignAndJsonHeader(
|
||||
appId, appSecret, jsonParams, requestType.name(), apiAddr, true);
|
||||
|
||||
EsignHttpResponse response = EsignHttpHelper.doCommHttp(
|
||||
serverUrl, apiAddr, requestType, jsonParams, header, debug);
|
||||
|
||||
log.info("发起合同签署流程返回消息:status={}, body={}", response.getStatus(), response.getBody());
|
||||
|
||||
// 7. 处理API响应结果
|
||||
if (response.getStatus() != HttpStatus.OK.value()) {
|
||||
String errorMsg = "E签宝请求失败";
|
||||
if (response.getBody() != null) {
|
||||
try {
|
||||
JSONObject resBody = JSONUtil.parseObj(response.getBody());
|
||||
errorMsg += "," + resBody.getStr("message", "未知错误");
|
||||
} catch (Exception parseException) {
|
||||
log.warn("解析E签宝错误响应失败:{}", response.getBody());
|
||||
}
|
||||
}
|
||||
return Pair.of(false, "e签宝请求失败!");
|
||||
log.error("E签宝请求失败,返回状态码:{}", response.getStatus());
|
||||
return Pair.of(false, errorMsg);
|
||||
}
|
||||
|
||||
JSONObject jsonObject = JSONUtil.parseObj(createByDocTemplate.getBody());
|
||||
// 8. 解析成功响应数据
|
||||
JSONObject jsonObject = JSONUtil.parseObj(response.getBody());
|
||||
Integer code = jsonObject.getInt("code");
|
||||
String signFlowId = (String) jsonObject.getByPath("data.signFlowId");
|
||||
String signFlowId = jsonObject.getByPath("data.signFlowId", String.class);
|
||||
|
||||
if (code == null || code != 0 || StrUtil.isBlank(signFlowId)) {
|
||||
log.error("e签宝请求失败,返回status码:{}", code);
|
||||
return Pair.of(false, "e签宝请求失败!");
|
||||
log.error("E签宝请求失败,返回 code 码:{}", code);
|
||||
return Pair.of(false, "E签宝请求失败!");
|
||||
}
|
||||
|
||||
//合同签署状态:-1:预备数据阶段;0-等待签署;1-已部分签署;2-已完成(所有签署方完成签署)3-已撤销(发起方撤销签署任务)5-已过期(签署截止日到期后触发)7-已拒签(签署方拒绝签署)
|
||||
Boolean success = updateContractFlowIdAndFileUrl(esignContract.getId(), signFlowId, CommonConstant.CONTRACT_SIGN_STA_ING, null);
|
||||
// 9. 更新合同流程状态
|
||||
Boolean success = updateContractFlowIdAndFileUrl(
|
||||
esignContract.getId(), signFlowId, CommonConstant.CONTRACT_SIGN_STA_ING, null);
|
||||
|
||||
if (!success) {
|
||||
log.error("更新合同流程状态失败");
|
||||
return Pair.of(false, "更新合同流程状态失败");
|
||||
@ -229,12 +245,13 @@ public class EsignContractServiceImpl extends BaseServiceImpl<EsignContractMappe
|
||||
|
||||
return Pair.of(true, "合同流程创建成功,合同流程ID:" + signFlowId);
|
||||
|
||||
} catch (EsignDemoException e) {
|
||||
} catch (Exception e) {
|
||||
log.error("发起签署电子合同请求失败:", e);
|
||||
return Pair.of(false, "发起签署电子合同请求失败!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 签署流程结束通知
|
||||
*
|
||||
@ -251,14 +268,14 @@ public class EsignContractServiceImpl extends BaseServiceImpl<EsignContractMappe
|
||||
String timestamp = request.getHeader("X-Tsign-Open-TIMESTAMP");
|
||||
|
||||
if (StrUtil.isBlank(reqAppId) || StrUtil.isBlank(signature) || StrUtil.isBlank(timestamp)) {
|
||||
log.warn("e签宝异步通知缺少必要参数: reqAppId={}, signature={}, timestamp={}", reqAppId, signature, timestamp);
|
||||
log.warn("E签宝异步通知缺少必要参数: reqAppId={}, signature={}, timestamp={}", reqAppId, signature, timestamp);
|
||||
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
|
||||
.body(new JSONObject().put("code", 400).put("msg", "缺少必要参数").toString());
|
||||
}
|
||||
|
||||
// 2. 验证AppId是否匹配
|
||||
if (!reqAppId.equals(appId)) {
|
||||
log.warn("e签宝异步通知AppId不匹配: 请求AppId={}, 配置AppId={}", reqAppId, appId);
|
||||
log.warn("E签宝异步通知AppId不匹配: 请求AppId={}, 配置AppId={}", reqAppId, appId);
|
||||
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
|
||||
.body(new JSONObject().put("code", 400).put("msg", "appId 有误").toString());
|
||||
}
|
||||
@ -278,7 +295,7 @@ public class EsignContractServiceImpl extends BaseServiceImpl<EsignContractMappe
|
||||
log.debug("header里面的签名值:---------->>>>>> {}", signature);
|
||||
|
||||
if (!mySignature.equals(signature)) {
|
||||
log.warn("e签宝异步通知签名校验失败: 计算签名={}, 请求签名={}", mySignature, signature);
|
||||
log.warn("E签宝异步通知签名校验失败: 计算签名={}, 请求签名={}", mySignature, signature);
|
||||
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
|
||||
.body(new JSONObject().put("code", 400).put("msg", "签名校验失败").toString());
|
||||
}
|
||||
@ -288,7 +305,7 @@ public class EsignContractServiceImpl extends BaseServiceImpl<EsignContractMappe
|
||||
try {
|
||||
reqBodyJSON = JSONUtil.parseObj(requestBody);
|
||||
} catch (Exception e) {
|
||||
log.error("解析e签宝异步通知请求体失败: requestBody={}", requestBody, e);
|
||||
log.error("解析E签宝异步通知请求体失败: requestBody={}", requestBody, e);
|
||||
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
|
||||
.body(new JSONObject().put("code", 400).put("msg", "请求体格式错误").toString());
|
||||
}
|
||||
@ -298,7 +315,7 @@ public class EsignContractServiceImpl extends BaseServiceImpl<EsignContractMappe
|
||||
Integer signResult = reqBodyJSON.getInt("signResult");
|
||||
|
||||
if (StrUtil.isBlank(action) || StrUtil.isBlank(signFlowId)) {
|
||||
log.warn("e签宝异步通知缺少必要业务参数: action={}, signFlowId={}", action, signFlowId);
|
||||
log.warn("E签宝异步通知缺少必要业务参数: action={}, signFlowId={}", action, signFlowId);
|
||||
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
|
||||
.body(new JSONObject().put("code", 400).put("msg", "返回数据有误").toString());
|
||||
}
|
||||
@ -391,7 +408,7 @@ public class EsignContractServiceImpl extends BaseServiceImpl<EsignContractMappe
|
||||
return ResponseEntity.ok(new JSONObject().put("code", 200).put("msg", "success").toString());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("处理e签宝异步通知异常: action={}, signFlowId={}", action, signFlowId, e);
|
||||
log.error("处理E签宝异步通知异常: action={}, signFlowId={}", action, signFlowId, e);
|
||||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
|
||||
.body(new JSONObject().put("code", 500).put("msg", "处理通知异常").toString());
|
||||
}
|
||||
@ -728,7 +745,7 @@ public class EsignContractServiceImpl extends BaseServiceImpl<EsignContractMappe
|
||||
}
|
||||
|
||||
/**
|
||||
* 到 e签宝官网,根据合同流程ID,获取完成签署生效的合同文件地址
|
||||
* 到 E签宝官网,根据合同流程ID,获取完成签署生效的合同文件地址
|
||||
* <p>
|
||||
* 收到异步通知,签署完成之后,获取合同文件地址,保存并上传到 oss
|
||||
*
|
||||
@ -837,7 +854,7 @@ public class EsignContractServiceImpl extends BaseServiceImpl<EsignContractMappe
|
||||
}
|
||||
|
||||
|
||||
// e签宝签名相关方法
|
||||
// E签宝签名相关方法
|
||||
|
||||
/**
|
||||
* 根据商家的注册手机号,新增或更新签署合同记录。
|
||||
|
||||
@ -137,33 +137,47 @@ public class ShopNumberSeqServiceImpl extends BaseServiceImpl<ShopNumberSeqMappe
|
||||
@Transactional(propagation = Propagation.NOT_SUPPORTED)
|
||||
@DistributedLock(
|
||||
key = "CREATENEXTSEQ_LOCK", // 锁的key
|
||||
waitTime = 3, // 等待3秒
|
||||
leaseTime = 10, // 锁持有10秒
|
||||
waitTime = 3, // 等待3秒
|
||||
leaseTime = 10, // 锁持有10秒
|
||||
errorMsg = "生成ID繁忙,请稍后重试" // 自定义错误消息
|
||||
)
|
||||
public synchronized Pair<Long, String> createNextSeqPair(String prefix) {
|
||||
String ymd = DateUtil.format(new Date(), "yyyyMMdd");
|
||||
String id = String.format("%s_%s_", prefix, ymd);
|
||||
ShopNumberSeq shopNumberSeq = this.baseMapper.selectById(id);
|
||||
if (shopNumberSeq == null) {
|
||||
shopNumberSeq = new ShopNumberSeq();
|
||||
shopNumberSeq.setPrefix(id);
|
||||
shopNumberSeq.setNumber(1L);
|
||||
if (!save(shopNumberSeq)) {
|
||||
return null;
|
||||
// 参数校验
|
||||
if (prefix == null || prefix.trim().isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
String ymd = DateUtil.format(new Date(), "yyyyMMdd");
|
||||
String seqId = String.format("%s_%s_", prefix, ymd);
|
||||
|
||||
// 查询或创建序列记录
|
||||
ShopNumberSeq shopNumberSeq = this.baseMapper.selectById(seqId);
|
||||
if (shopNumberSeq == null) {
|
||||
shopNumberSeq = new ShopNumberSeq();
|
||||
shopNumberSeq.setPrefix(seqId);
|
||||
shopNumberSeq.setNumber(1L);
|
||||
if (!save(shopNumberSeq)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String order_id = String.format("%s_%s_%s", prefix, ymd, shopNumberSeq.getNumber());
|
||||
shopNumberSeq.setPrefix(id);
|
||||
boolean flag = edit(shopNumberSeq);
|
||||
if (flag) {
|
||||
return Pair.of(shopNumberSeq.getNumber(), order_id);
|
||||
}
|
||||
// 获取当前序列号
|
||||
Long number = shopNumberSeq.getNumber();
|
||||
String orderId = String.format("%s_%s_%s", prefix, ymd, number);
|
||||
|
||||
return null;
|
||||
// 增加序列号并更新
|
||||
// shopNumberSeq.setNumber(number + 1);
|
||||
shopNumberSeq.setPrefix(seqId);
|
||||
return edit(shopNumberSeq) ? Pair.of(number, orderId) : null;
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("生成序列号失败,prefix: {}", prefix, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 得到下一个Id
|
||||
*
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
package com.suisung.mall.shop.order.controller.mobile;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.suisung.mall.common.api.CommonResult;
|
||||
import com.suisung.mall.common.api.ResultCode;
|
||||
@ -15,10 +17,7 @@ import com.suisung.mall.shop.order.vo.OrderReturnVo;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@ -57,7 +56,7 @@ public class UserReturnController extends BaseControllerImpl {
|
||||
return shopOrderReturnService.returnItem();
|
||||
}
|
||||
|
||||
@ApiOperation(value = "添加退款退货-部分退货,卖家也可以决定不退货退款,买家申请退款不支持。卖家可以主动退款。", notes = "添加退款退货-发货退货,卖家也可以决定不退货退款,买家申请退款不支持。卖家可以主动退款。")
|
||||
@ApiOperation(value = "添加退款退货-部分退货", notes = "添加退款退货-发货退货,卖家也可以决定不退货退款,买家申请退款不支持。卖家可以主动退款。")
|
||||
@RequestMapping(value = "/addItem", method = RequestMethod.GET)
|
||||
public CommonResult addItem(OrderReturnVo orderReturnVo) {
|
||||
UserDto user = getCurrentUser();
|
||||
@ -77,6 +76,26 @@ public class UserReturnController extends BaseControllerImpl {
|
||||
return shopOrderReturnService.addItem(orderReturnInputVo, true);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "批量添加退款退货(支持多个商品)", notes = "添加退款退货-发货退货,卖家也可以决定不退货退款,买家申请退款不支持。卖家可以主动退款。")
|
||||
@RequestMapping(value = "/addItemBatch", method = RequestMethod.POST)
|
||||
public CommonResult addItemBatch(@RequestBody JSONObject orderReturnVoJSON) {
|
||||
if (orderReturnVoJSON == null) {
|
||||
return CommonResult.failed("请求参数不能为空");
|
||||
}
|
||||
|
||||
OrderReturnInputVo orderReturnInputVo = JSONUtil.toBean(orderReturnVoJSON, OrderReturnInputVo.class);
|
||||
if (orderReturnInputVo == null) {
|
||||
return CommonResult.failed("请求参数格式不正确");
|
||||
}
|
||||
|
||||
UserDto user = getCurrentUser();
|
||||
if (user == null) {
|
||||
return CommonResult.failed(ResultCode.NEED_LOGIN);
|
||||
}
|
||||
|
||||
return shopOrderReturnService.tryAddItemBatch(orderReturnInputVo);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "添加退款退货-整单退货", notes = "添加退款退货-整单退货")
|
||||
@RequestMapping(value = "/addWholeItems", method = RequestMethod.POST)
|
||||
public CommonResult addWholeItems(@RequestParam(name = "order_id") String order_id) {
|
||||
|
||||
@ -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);
|
||||
|
||||
}
|
||||
|
||||
@ -459,20 +459,20 @@ public interface ShopOrderBaseService extends IBaseService<ShopOrderBase> {
|
||||
*
|
||||
* @param order_id
|
||||
* @param shopOrderInfo
|
||||
* @param check_paid_flag
|
||||
* @param checkPaidState 订单是否未支付,默认值 true
|
||||
* @return
|
||||
*/
|
||||
boolean cancel(String order_id, ShopOrderInfo shopOrderInfo, boolean check_paid_flag);
|
||||
boolean cancel(String order_id, ShopOrderInfo shopOrderInfo, boolean checkPaidState);
|
||||
|
||||
/**
|
||||
* 取消订单
|
||||
*
|
||||
* @param order_ids
|
||||
* @param order_rows
|
||||
* @param check_paid_flag
|
||||
* @param isNotPaid 订单是否未支付,默认值 true
|
||||
* @return
|
||||
*/
|
||||
boolean cancel(List<String> order_ids, List<Map> order_rows, boolean check_paid_flag);
|
||||
boolean cancel(List<String> order_ids, List<Map> order_rows, boolean isNotPaid);
|
||||
|
||||
void exportFile(HttpServletResponse response, ShopOrderBase shopOrderBase, List<String> order_ids);
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -50,6 +50,14 @@ public interface ShopOrderReturnService extends IBaseService<ShopOrderReturn> {
|
||||
*/
|
||||
CommonResult addItem(OrderReturnInputVo orderReturnInputVo, Boolean needSendMsg);
|
||||
|
||||
/**
|
||||
* 尝试批量添加退款退货申请(自动使用最大可退数量和金额),等待商家审核处理(同意或不同意)
|
||||
*
|
||||
* @param orderReturnInputVo 退款申请输入参数,支持订单多个商品退款
|
||||
* @return CommonResult 退款申请结果
|
||||
*/
|
||||
CommonResult tryAddItemBatch(OrderReturnInputVo orderReturnInputVo);
|
||||
|
||||
Map getReturnDetail(String return_id);
|
||||
|
||||
boolean processReviewList(ShopOrderReturn shopOrderReturn, Integer receiving_address);
|
||||
|
||||
@ -768,7 +768,7 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
throw new ApiException(I18nUtil._("无该订单访问权限!"));
|
||||
}
|
||||
|
||||
// 是否禁止退款
|
||||
// 订单是否禁止退款
|
||||
int isOrderDenyReturn = shopOrderReturnService.isOrderDenyReturn(order_id) ? 1 : 2;
|
||||
data.put("is_deny_return", isOrderDenyReturn);
|
||||
|
||||
@ -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();
|
||||
@ -961,9 +963,8 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
item_row.put("product_number", product_number);
|
||||
}
|
||||
|
||||
// 不支持退货
|
||||
boolean is_denyreturn = shopOrderReturnService.ifDenyReturn(order_item_id);
|
||||
|
||||
// 订单是否禁止退货
|
||||
is_denyreturn = shopOrderReturnService.isOrderDenyReturn(order_id); //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", ifCancel(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));
|
||||
|
||||
@ -4127,114 +4129,138 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
* 取消订单
|
||||
* 流程:订单状态;积分、众宝、库存、礼包、优惠券 有就统统退还
|
||||
*
|
||||
* @param order_ids 订单id
|
||||
* @param order_rows 订单数据
|
||||
* @param check_paid_flag 默认值 true
|
||||
* @param orderIds 订单id列表
|
||||
* @param orderRows 订单数据
|
||||
* @param checkPaidState 实付检查订单支付状态,默认值 true
|
||||
*/
|
||||
@Transactional
|
||||
public boolean cancel(List<String> order_ids, List<Map> order_rows, boolean check_paid_flag) {
|
||||
List<String> cancel_id_row = new ArrayList<>(order_ids.size());
|
||||
public boolean cancel(List<String> orderIds, List<Map> orderRows, boolean checkPaidState) {
|
||||
List<String> cancelIdRow = new ArrayList<>(orderIds.size());
|
||||
|
||||
// 检测数据是否合法,过滤允许修改的数据
|
||||
if (CollUtil.isEmpty(order_ids)) {
|
||||
if (CollUtil.isEmpty(orderIds)) {
|
||||
throw new ApiException(I18nUtil._("请选择需要取消的订单"));
|
||||
}
|
||||
|
||||
if (CollUtil.isEmpty(order_rows)) {
|
||||
order_rows = Convert.toList(Map.class, shopOrderInfoService.gets(order_ids));
|
||||
if (CollUtil.isEmpty(orderRows)) {
|
||||
orderRows = Convert.toList(Map.class, shopOrderInfoService.gets(orderIds));
|
||||
}
|
||||
|
||||
for (String order_id : order_ids) {
|
||||
Optional<Map> orderOpl = order_rows.stream().filter(s -> ObjectUtil.equal(order_id, Convert.toStr(s.get("order_id")))).findFirst();
|
||||
Map order = orderOpl.orElseGet(HashMap::new);
|
||||
// 筛选可取消的订单
|
||||
for (String orderId : orderIds) {
|
||||
Optional<Map> orderOpt = orderRows.stream()
|
||||
.filter(s -> ObjectUtil.equal(orderId, Convert.toStr(s.get("order_id"))))
|
||||
.findFirst();
|
||||
Map order = orderOpt.orElseGet(HashMap::new);
|
||||
|
||||
// 订单状态(LIST):2011-待订单审核;2013-待财务审核;2020-待配货/待出库审核;2030-待发货;2040-已发货/待收货确认;2060-已完成/已签收;2070-已取消/已作废;
|
||||
Integer order_state_id = (Integer) order.get("order_state_id");
|
||||
Integer orderStateId = (Integer) order.get("order_state_id");
|
||||
// 付款状态(ENUM):3010-未付款;3011-付款待审核;3012-部分付款;3013-已付款
|
||||
Integer order_is_paid = (Integer) order.get("order_is_paid");
|
||||
// 要检查订单付款状态
|
||||
if (check_paid_flag) {
|
||||
if (ifCancel(order_state_id, order_is_paid)) {
|
||||
// 未付款,未配送的订单才能取消订单
|
||||
cancel_id_row.add(order_id);
|
||||
Integer orderIsPaid = (Integer) order.get("order_is_paid");
|
||||
|
||||
// 根据是否检查支付状态来判断订单是否可取消
|
||||
if (checkPaidState) {
|
||||
// 检查订单是否可以取消(未付款且处于特定状态)
|
||||
if (isOrderCancelable(orderStateId, orderIsPaid)) {
|
||||
cancelIdRow.add(orderId);
|
||||
} else {
|
||||
// 订单已支付,检查是否允许退款
|
||||
boolean isOrderDenyReturn = shopOrderReturnService.isOrderDenyReturn(orderId);
|
||||
if (!isOrderDenyReturn) {
|
||||
// 支付的订单允许退款,立即发起退款流程,再由商家审核
|
||||
CommonResult refundResult = shopOrderReturnService.addRemainingItems(orderId, false, "用户取消订单");
|
||||
if (refundResult == null || refundResult.getStatus() != 200L) {
|
||||
logger.error("用户提交取消订单失败!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 提交成功之后,再由商家审核,通过之后,会继续完成以下的操作。
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 不检查订单付款状态
|
||||
cancel_id_row.add(order_id);
|
||||
// 不检查订单付款状态,直接加入可取消列表
|
||||
cancelIdRow.add(orderId);
|
||||
}
|
||||
}
|
||||
|
||||
if (CollUtil.isEmpty(cancel_id_row)) {
|
||||
if (CollUtil.isEmpty(cancelIdRow)) {
|
||||
throw new ApiException(I18nUtil._("无符合取消条件的订单!"));
|
||||
}
|
||||
|
||||
order_ids = cancel_id_row;
|
||||
orderIds = cancelIdRow;
|
||||
|
||||
// 更新订单主表状态为已取消
|
||||
ShopOrderBase orderBase = new ShopOrderBase();
|
||||
orderBase.setOrder_state_id(StateCode.ORDER_STATE_CANCEL);
|
||||
|
||||
QueryWrapper<ShopOrderBase> baseQueryWrapper = new QueryWrapper<>();
|
||||
baseQueryWrapper.in("order_id", order_ids);
|
||||
baseQueryWrapper.in("order_id", orderIds);
|
||||
baseQueryWrapper.ne("order_state_id", StateCode.ORDER_STATE_CANCEL); // 2070-已取消
|
||||
if (!edit(orderBase, baseQueryWrapper)) {// 批量更改状态
|
||||
if (!edit(orderBase, baseQueryWrapper)) { // 批量更改状态
|
||||
throw new ApiException(ResultCode.FAILED);
|
||||
}
|
||||
|
||||
// 更新订单信息表状态为已取消
|
||||
ShopOrderInfo shopOrderInfo = new ShopOrderInfo();
|
||||
shopOrderInfo.setOrder_state_id(StateCode.ORDER_STATE_CANCEL);
|
||||
|
||||
QueryWrapper<ShopOrderInfo> infoQueryWrapper = new QueryWrapper<>();
|
||||
infoQueryWrapper.in("order_id", cancel_id_row);
|
||||
infoQueryWrapper.in("order_id", cancelIdRow);
|
||||
infoQueryWrapper.ne("order_state_id", StateCode.ORDER_STATE_CANCEL);
|
||||
if (!shopOrderInfoService.edit(shopOrderInfo, infoQueryWrapper)) {
|
||||
throw new ApiException(String.format("订单:%s 取消状态有误!", CollUtil.join(cancel_id_row, ",")));
|
||||
throw new ApiException(String.format("订单:%s 取消状态有误!", CollUtil.join(cancelIdRow, ",")));
|
||||
}
|
||||
|
||||
// 积分退还 order_resource_ext1 默认为积分。
|
||||
List<ShopOrderData> order_data_rows = shopOrderDataService.gets(order_ids);
|
||||
for (ShopOrderData order_data_row : order_data_rows) {
|
||||
String orderId = order_data_row.getOrder_id();
|
||||
List<ShopOrderData> orderDataRows = shopOrderDataService.gets(orderIds);
|
||||
for (ShopOrderData orderDataRow : orderDataRows) {
|
||||
String orderId = orderDataRow.getOrder_id();
|
||||
|
||||
Optional<Map> orderOpl = order_rows.stream().filter(s -> ObjectUtil.equal(orderId, Convert.toStr(s.get("order_id")))).findFirst();
|
||||
Map order = orderOpl.orElseGet(HashMap::new);
|
||||
Optional<Map> orderOpt = orderRows.stream()
|
||||
.filter(s -> ObjectUtil.equal(orderId, Convert.toStr(s.get("order_id"))))
|
||||
.findFirst();
|
||||
Map order = orderOpt.orElseGet(HashMap::new);
|
||||
|
||||
Integer buyer_user_id = (Integer) order.get("buyer_user_id");
|
||||
BigDecimal order_resource_ext1 = order_data_row.getOrder_resource_ext1();// 积分
|
||||
BigDecimal order_resource_ext2 = order_data_row.getOrder_resource_ext2();// 众宝
|
||||
Integer buyerUserId = (Integer) order.get("buyer_user_id");
|
||||
BigDecimal orderResourceExt1 = orderDataRow.getOrder_resource_ext1(); // 积分
|
||||
BigDecimal orderResourceExt2 = orderDataRow.getOrder_resource_ext2(); // 众宝
|
||||
|
||||
if (ObjectUtil.compare(order_resource_ext1, BigDecimal.ZERO) > 0 && CheckUtil.isNotEmpty(buyer_user_id)) {
|
||||
Integer store_id = (Integer) order.get("store_id");
|
||||
// 退还积分
|
||||
if (ObjectUtil.compare(orderResourceExt1, BigDecimal.ZERO) > 0 && CheckUtil.isNotEmpty(buyerUserId)) {
|
||||
Integer storeId = (Integer) order.get("store_id");
|
||||
// 扣除积分
|
||||
String desc = String.format("%s 积分退还,订单号 %s", order_resource_ext1, order_data_row.getOrder_id());
|
||||
if (!payService.points(buyer_user_id, order_resource_ext1, PointsType.POINTS_TYPE_CONSUME_RETRUN, desc, store_id, null, order_data_row.getOrder_id())) {
|
||||
String desc = String.format("%s 积分退还,订单号 %s", orderResourceExt1, orderDataRow.getOrder_id());
|
||||
if (!payService.points(buyerUserId, orderResourceExt1, PointsType.POINTS_TYPE_CONSUME_RETRUN, desc, storeId, null, orderDataRow.getOrder_id())) {
|
||||
throw new ApiException(I18nUtil._("积分操作失败!"));
|
||||
}
|
||||
}
|
||||
|
||||
// 程序没有编写完成,缺失众宝积分退回功能
|
||||
//if (ObjectUtil.compare(order_resource_ext2, BigDecimal.ZERO) > 0 && CheckUtil.isNotEmpty(buyer_user_id)) {
|
||||
// String desc = String.format("%s 众宝退还", order_resource_ext2);
|
||||
// todo shopUserPointsHistoryService.sp(buyer_user_id,order_resource_ext2,SpType.SP_TYPE_CONSUME_RETRUN, desc);
|
||||
//}
|
||||
// if (ObjectUtil.compare(orderResourceExt2, BigDecimal.ZERO) > 0 && CheckUtil.isNotEmpty(buyerUserId)) {
|
||||
// String desc = String.format("%s 众宝退还", orderResourceExt2);
|
||||
// todo shopUserPointsHistoryService.sp(buyerUserId, orderResourceExt2, SpType.SP_TYPE_CONSUME_RETRUN, desc);
|
||||
// }
|
||||
}
|
||||
|
||||
// 限购商品数量退还
|
||||
QueryWrapper<ShopOrderItem> itemQueryWrapper = new QueryWrapper<>();
|
||||
itemQueryWrapper.in("order_id", order_ids);
|
||||
List<ShopOrderItem> order_item_rows = shopOrderItemService.find(itemQueryWrapper);
|
||||
|
||||
for (ShopOrderItem order_item_row : order_item_rows) {
|
||||
itemQueryWrapper.in("order_id", orderIds);
|
||||
List<ShopOrderItem> orderItemRows = shopOrderItemService.find(itemQueryWrapper);
|
||||
|
||||
for (ShopOrderItem orderItemRow : orderItemRows) {
|
||||
// 退还用户购买数量限制
|
||||
QueryWrapper<ShopUserProductBuy> buyQueryWrapper = new QueryWrapper<>();
|
||||
buyQueryWrapper.eq("product_id", order_item_row.getProduct_id());
|
||||
buyQueryWrapper.eq("item_id", order_item_row.getItem_id());
|
||||
buyQueryWrapper.eq("user_id", order_item_row.getBuyer_id());
|
||||
buyQueryWrapper.eq("product_id", orderItemRow.getProduct_id());
|
||||
buyQueryWrapper.eq("item_id", orderItemRow.getItem_id());
|
||||
buyQueryWrapper.eq("user_id", orderItemRow.getBuyer_id());
|
||||
List<ShopUserProductBuy> productBuyList = shopUserProductBuyService.find(buyQueryWrapper);
|
||||
|
||||
Integer order_item_quantity = order_item_row.getOrder_item_quantity();
|
||||
Integer orderItemQuantity = orderItemRow.getOrder_item_quantity();
|
||||
if (CollUtil.isNotEmpty(productBuyList)) {
|
||||
|
||||
// 减少用户的已购买数量
|
||||
for (ShopUserProductBuy productBuy : productBuyList) {
|
||||
productBuy.setProduct_buy_num(productBuy.getProduct_buy_num() - order_item_quantity);
|
||||
productBuy.setProduct_buy_num(productBuy.getProduct_buy_num() - orderItemQuantity);
|
||||
}
|
||||
|
||||
if (!shopUserProductBuyService.saveOrUpdate(productBuyList)) {
|
||||
@ -4242,29 +4268,29 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
}
|
||||
}
|
||||
|
||||
// start 释放冻结库存
|
||||
// 释放冻结库存
|
||||
// order_item_inventory_lock: 库存锁定(ENUM):1001-下单锁定;1002-支付锁定;
|
||||
Integer order_item_inventory_lock = order_item_row.getOrder_item_inventory_lock();
|
||||
if (ObjectUtil.equal(order_item_inventory_lock, 1001) || ObjectUtil.equal(order_item_inventory_lock, 1002)) {
|
||||
Long item_id = order_item_row.getItem_id();
|
||||
ShopProductItem shopProductItem = shopProductItemService.get(item_id);
|
||||
Integer orderItemInventoryLock = orderItemRow.getOrder_item_inventory_lock();
|
||||
if (ObjectUtil.equal(orderItemInventoryLock, 1001) || ObjectUtil.equal(orderItemInventoryLock, 1002)) {
|
||||
Long itemId = orderItemRow.getItem_id();
|
||||
ShopProductItem shopProductItem = shopProductItemService.get(itemId);
|
||||
if (shopProductItem != null && CheckUtil.isNotEmpty(shopProductItem.getItem_src_id())) {
|
||||
shopProductItem.setItem_quantity_frozen(shopProductItem.getItem_quantity_frozen() - order_item_quantity);
|
||||
shopProductItem.setItem_quantity_frozen(shopProductItem.getItem_quantity_frozen() - orderItemQuantity);
|
||||
if (!shopProductItemService.edit(shopProductItem)) {
|
||||
throw new ApiException(String.format(I18nUtil._("释放: %s 冻结库存失败!"), order_item_row.getItem_id()));
|
||||
throw new ApiException(String.format(I18nUtil._("释放: %s 冻结库存失败!"), orderItemRow.getItem_id()));
|
||||
}
|
||||
log.debug("释放库存Item_src_id:{},数量:{}", shopProductItem.getItem_src_id(), order_item_quantity);
|
||||
log.debug("释放库存Item_src_id:{},数量:{}", shopProductItem.getItem_src_id(), orderItemQuantity);
|
||||
// RMK 第三方数据同步相关:redis 给这个商品加上对应的库存
|
||||
// Map<String, Integer> stockDeltaMap = new HashMap<>();
|
||||
// stockDeltaMap.put(shopProductItem.getItem_src_id() + "-" + order_item_row.getOrder_id(), order_item_quantity);
|
||||
// syncThirdDataService.incrProductStockToRedis(stockDeltaMap);
|
||||
// Map<String, Integer> stockDeltaMap = new HashMap<>();
|
||||
// stockDeltaMap.put(shopProductItem.getItem_src_id() + "-" + orderItemRow.getOrder_id(), orderItemQuantity);
|
||||
// syncThirdDataService.incrProductStockToRedis(stockDeltaMap);
|
||||
}
|
||||
}
|
||||
|
||||
// 退还礼包活动
|
||||
if (order_item_row.getActivity_type_id().equals(StateCode.ACTIVITY_TYPE_GIFTPACK)) {
|
||||
if (orderItemRow.getActivity_type_id().equals(StateCode.ACTIVITY_TYPE_GIFTPACK)) {
|
||||
QueryWrapper<ShopStoreActivityCode> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("exchange_code", order_item_row.getActivity_code());
|
||||
queryWrapper.eq("exchange_code", orderItemRow.getActivity_code());
|
||||
ShopStoreActivityCode shopStoreActivityCode = shopStoreActivityCodeService.findOne(queryWrapper);
|
||||
shopStoreActivityCode.setUser_id(0);
|
||||
shopStoreActivityCode.setOrder_id("");
|
||||
@ -4277,18 +4303,21 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
|
||||
// 退还优惠券
|
||||
QueryWrapper<ShopUserVoucher> voucherQueryWrapper = new QueryWrapper<>();
|
||||
voucherQueryWrapper.in("order_id", order_ids);
|
||||
voucherQueryWrapper.in("order_id", orderIds);
|
||||
List<ShopUserVoucher> userVouchers = shopUserVoucherService.find(voucherQueryWrapper);
|
||||
if (CollUtil.isNotEmpty(userVouchers)) {
|
||||
userVouchers = userVouchers.stream().map(userVoucher -> userVoucher.setVoucher_state_id(StateCode.VOUCHER_STATE_UNUSED)).collect(Collectors.toList());
|
||||
// 将已使用的优惠券状态重置为未使用
|
||||
userVouchers = userVouchers.stream()
|
||||
.map(userVoucher -> userVoucher.setVoucher_state_id(StateCode.VOUCHER_STATE_UNUSED))
|
||||
.collect(Collectors.toList());
|
||||
if (!shopUserVoucherService.edit(userVouchers)) {
|
||||
throw new ApiException(I18nUtil._("退还优惠券失败!"));
|
||||
}
|
||||
}
|
||||
|
||||
// 取消拼团
|
||||
for (String order_id : order_ids) {
|
||||
cancelActivity(order_id);
|
||||
// 取消拼团活动
|
||||
for (String orderId : orderIds) {
|
||||
cancelActivity(orderId);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -5227,7 +5256,7 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消订单
|
||||
* 用户C端发起取消订单操作(2025年改进:支付前后都可以取消订单)
|
||||
*
|
||||
* @param order_id
|
||||
* @return
|
||||
@ -5250,7 +5279,8 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
List<ShopOrderInfo> shopOrderInfos = shopOrderInfoService.gets(order_ids);
|
||||
List<Map> rows = Convert.toList(Map.class, shopOrderInfos);
|
||||
// 检查登录用户和订单店铺是否有权限操作取消动作
|
||||
if (CheckUtil.checkDataRights(user_id, rows, "buyer_user_id") || CheckUtil.checkDataRights(Convert.toInt(user.getStore_id()), rows, "store_id")) {
|
||||
if (CheckUtil.checkDataRights(user_id, rows, "buyer_user_id")
|
||||
|| CheckUtil.checkDataRights(Convert.toInt(user.getStore_id()), rows, "store_id")) {
|
||||
cancel(order_ids, rows, true);
|
||||
} else {
|
||||
throw new ApiException(ResultCode.FORBIDDEN);
|
||||
@ -5267,12 +5297,12 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
*
|
||||
* @param order_id
|
||||
* @param shopOrderInfo
|
||||
* @param check_paid_flag 默认true
|
||||
* @param checkPaidState 是否检查订单支付状态? 默认true
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@Transactional
|
||||
public boolean cancel(String order_id, ShopOrderInfo shopOrderInfo, boolean check_paid_flag) {
|
||||
public boolean cancel(String order_id, ShopOrderInfo shopOrderInfo, boolean checkPaidState) {
|
||||
// 检测数据是否合法,过滤允许修改的数据
|
||||
if (StrUtil.isBlank(order_id)) {
|
||||
throw new ApiException(I18nUtil._("请选择需要取消的订单!"));
|
||||
@ -5285,7 +5315,7 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
Integer order_state_id = shopOrderInfo.getOrder_state_id();
|
||||
Integer order_is_paid = shopOrderInfo.getOrder_is_paid();
|
||||
|
||||
if (check_paid_flag && !ifCancel(order_state_id, order_is_paid)) {
|
||||
if (checkPaidState && !isOrderCancelable(order_state_id, order_is_paid)) {
|
||||
throw new ApiException(I18nUtil._("无符合取消条件的订单!"));
|
||||
}
|
||||
|
||||
@ -5315,7 +5345,6 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
|
||||
// 取消顺丰同城配送订单
|
||||
// === 7. 特殊场景:顺丰同城配送、且全单退的时候,才触发顺丰同城订单取消 ===
|
||||
|
||||
if (shopOrderInfo.getDelivery_type_id() != null
|
||||
&& StateCode.DELIVERY_TYPE_SAME_CITY == shopOrderInfo.getDelivery_type_id().intValue()) {
|
||||
try {
|
||||
@ -5329,7 +5358,6 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("顺丰同城取消订单异常,orderId: {}", order_id, e);
|
||||
// 可以考虑添加补偿机制或异步重试
|
||||
}
|
||||
}
|
||||
|
||||
@ -6421,7 +6449,7 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
type_code = StrUtil.isBlank(type_code) ? "DD" : type_code;
|
||||
String xid = RootContext.getXID();
|
||||
RootContext.unbind();
|
||||
Pair<Long, String> seqPair = shopNumberSeqService.createNextSeqPair(type_code);// 位数的序号: DD_20251205_1 2025-12-05 1
|
||||
Pair<Long, String> seqPair = shopNumberSeqService.createNextSeqPair(type_code);// 位数的序号: DD_20251205_12-> pair 12, 2025-12-05
|
||||
String order_id = seqPair.getSecond();
|
||||
Long seqNo = seqPair.getFirst(); // 序号: DD_20251205_1 得出 1
|
||||
RootContext.bind(xid);
|
||||
@ -6582,7 +6610,9 @@ 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("productMoneyOriginGoods"));
|
||||
// log.info("订单原价商品金额计算:{}", order_payment_amount);
|
||||
base_row.put("order_product_amount", order_product_amount);
|
||||
|
||||
//【重要】应付款金额计算
|
||||
base_row.put("order_payment_amount", order_payment_amount);
|
||||
@ -6622,6 +6652,7 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
base_row.put("buyer_user_name", buyer_user_name);
|
||||
|
||||
ShopOrderBase baseRow = Convert.convert(ShopOrderBase.class, base_row);
|
||||
// logger.info("【重要】订单基础信息保存:{}", base_row);
|
||||
// (重要)订单基础信息保存
|
||||
boolean flag = saveOrUpdate(baseRow);
|
||||
|
||||
@ -6906,7 +6937,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;
|
||||
@ -6928,7 +6958,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;
|
||||
|
||||
// 均分优惠券
|
||||
@ -7832,8 +7861,29 @@ 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"));
|
||||
|
||||
log.info("平台内部配送费计算:经纬度:{}", longitude + ":" + 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));
|
||||
@ -8373,7 +8423,9 @@ 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", ifCancel(order_state_id, order_is_paid));
|
||||
// 订单是否禁止退货?
|
||||
boolean is_denyreturn = shopOrderReturnService.isOrderDenyReturn(Convert.toStr(order_info_row.get("order_id"))); //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));
|
||||
@ -8408,17 +8460,26 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否可以取消?
|
||||
* 检查订单是否可以取消
|
||||
* 只有未付款且处于特定状态的订单才能取消
|
||||
*
|
||||
* @param order_state_id 订单状态
|
||||
* @param order_is_paid
|
||||
* @return boolean true-可,false-不可
|
||||
* @param orderStateId 订单状态ID
|
||||
* @param orderIsPaid 订单付款状态
|
||||
* @return boolean true-可以取消,false-不可以取消
|
||||
*/
|
||||
private boolean ifCancel(Integer order_state_id, Integer order_is_paid) {
|
||||
// 订单状态:2010-待付款;2011-待订单审核;2013-待财务审核;2020-待配货;2030-待发货
|
||||
List<Integer> order_states = Arrays.asList(StateCode.ORDER_STATE_WAIT_PAY, StateCode.ORDER_STATE_WAIT_REVIEW, StateCode.ORDER_STATE_WAIT_FINANCE_REVIEW, StateCode.ORDER_STATE_PICKING, StateCode.ORDER_STATE_WAIT_SHIPPING);
|
||||
// 3010-未付款,未付款的订单才能取消
|
||||
return order_states.contains(order_state_id) && ObjectUtil.equal(order_is_paid, StateCode.ORDER_PAID_STATE_NO);
|
||||
private boolean isOrderCancelable(Integer orderStateId, Integer orderIsPaid) {
|
||||
// 可以取消订单的状态列表:待付款、待审核、待财务审核、待配货、待发货
|
||||
List<Integer> cancelableStates = Arrays.asList(
|
||||
StateCode.ORDER_STATE_WAIT_PAY,
|
||||
StateCode.ORDER_STATE_WAIT_REVIEW,
|
||||
StateCode.ORDER_STATE_WAIT_FINANCE_REVIEW,
|
||||
StateCode.ORDER_STATE_PICKING,
|
||||
StateCode.ORDER_STATE_WAIT_SHIPPING
|
||||
);
|
||||
|
||||
// 订单必须处于可取消状态且未付款才能取消
|
||||
return cancelableStates.contains(orderStateId) &&
|
||||
ObjectUtil.equal(orderIsPaid, StateCode.ORDER_PAID_STATE_NO);
|
||||
}
|
||||
|
||||
// QueryWrapper<ShopOrderInfo> queryWrapper,
|
||||
@ -8855,7 +8916,7 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
m.put("delivery_time", DateUtil.offsetSecond(paymentTime, mchOrderExpireSeconds.intValue()));
|
||||
|
||||
// 配送方式
|
||||
String deliveryTypeName = StateCode.DELIVERY_TYPE_MAP.getOrDefault(m.getOrDefault("delivery_type_id", StateCode.DELIVERY_TYPE_SAME_CITY), "普通快递");
|
||||
String deliveryTypeName = CommonService.getDeliveryExpressName(Convert.toInt(m.get("delivery_type_id")));
|
||||
m.put("delivery_type_name", deliveryTypeName);
|
||||
|
||||
// 预留字段
|
||||
@ -8908,7 +8969,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;
|
||||
|
||||
@ -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;
|
||||
@ -376,7 +377,7 @@ public class ShopOrderInfoServiceImpl extends BaseServiceImpl<ShopOrderInfoMappe
|
||||
* @param orderId 订单ID
|
||||
* @return 取货单号
|
||||
*/
|
||||
// @Transactional
|
||||
@Transactional
|
||||
@Override
|
||||
public Long isPaidOrderGenPickNumAndPrint(Integer storeId, String orderId) {
|
||||
logger.info("####开始处理订单{}的取单号生成和打印####", orderId);
|
||||
@ -426,7 +427,6 @@ public class ShopOrderInfoServiceImpl extends BaseServiceImpl<ShopOrderInfoMappe
|
||||
orderInfo.setOrder_id(orderId);
|
||||
orderInfo.setOrder_pickup_num(orderPickupNum);
|
||||
orderInfo.setOrder_express_print(CommonConstant.Enable); // 打印标记 1-已打印
|
||||
|
||||
if (!edit(orderInfo)) {
|
||||
logger.error("更新订单取单号失败: orderId={}", orderId);
|
||||
return 0L;
|
||||
@ -1287,6 +1287,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获取有效店铺的有效营业时间段
|
||||
|
||||
@ -488,7 +488,6 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
returnItemQueryWrapper.in("order_item_id", order_item_ids)
|
||||
.in("return_id", return_ids);
|
||||
List<ShopOrderReturnItem> order_return_items = orderReturnItemService.find(returnItemQueryWrapper);
|
||||
|
||||
if (CollUtil.isNotEmpty(order_return_items)) {
|
||||
throw new ApiException(I18nUtil._("此订单商品正在退款审核!"));
|
||||
}
|
||||
@ -568,17 +567,16 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
|
||||
// 构建退款单明细
|
||||
ShopOrderReturnItem orderReturnItem = new ShopOrderReturnItem();
|
||||
Integer return_item_num = returnItemInputVo.getReturn_item_num();
|
||||
|
||||
Integer return_item_num = returnItemInputVo.getReturn_item_num(); //用户当前申请退款的商品数量
|
||||
if (return_item_num <= 0) {
|
||||
throw new ApiException("退款数量必须大于0,请检查商品 " + shopOrderItem.getItem_name() + " 的退款数量");
|
||||
}
|
||||
|
||||
// 检查退款数量是否超过可退数量
|
||||
Integer order_item_quantity = shopOrderItem.getOrder_item_quantity();
|
||||
Integer order_item_return_agree_num = ObjectUtil.defaultIfNull(shopOrderItem.getOrder_item_return_agree_num(), 0);
|
||||
Integer available_return_num = order_item_quantity - order_item_return_agree_num;
|
||||
|
||||
Integer order_item_quantity = shopOrderItem.getOrder_item_quantity(); // 订单中该商品的原始购买数量
|
||||
Integer order_item_return_agree_num = ObjectUtil.defaultIfNull(shopOrderItem.getOrder_item_return_agree_num(), 0); // 订单中该商品已经同意退货的数量
|
||||
Integer available_return_num = order_item_quantity - order_item_return_agree_num; // 当前还可以申请退款的商品数量
|
||||
if (return_item_num > available_return_num) {
|
||||
throw new ApiException(String.format("商品 %s 的退款数量超过可退数量,最多可退 %d 件",
|
||||
shopOrderItem.getItem_name(), available_return_num));
|
||||
@ -650,6 +648,208 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
return CommonResult.success(data);
|
||||
}
|
||||
|
||||
// @Override
|
||||
|
||||
/**
|
||||
* 尝试批量添加退款退货申请(自动使用最大可退数量和金额)
|
||||
*
|
||||
* @param orderReturnInputVo 退款申请输入参数,支持订单多个商品退款
|
||||
* @return CommonResult 退款申请结果
|
||||
*/
|
||||
@Override
|
||||
@Transactional
|
||||
public CommonResult tryAddItemBatch(OrderReturnInputVo orderReturnInputVo) {
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
|
||||
// 获取用户ID
|
||||
Integer user_id = orderReturnInputVo.getUser_id();
|
||||
if (CheckUtil.isEmpty(user_id)) {
|
||||
UserDto user = getCurrentUser();
|
||||
if (user == null) {
|
||||
throw new ApiUserException(I18nUtil._("用户信息异常!"));
|
||||
}
|
||||
user_id = user.getId();
|
||||
}
|
||||
|
||||
// 获取买家店铺ID(如果有)
|
||||
Integer buyer_store_id = shopStoreBaseService.getStoreId(user_id);
|
||||
|
||||
// 获取订单信息
|
||||
String order_id = orderReturnInputVo.getOrder_id();
|
||||
List<Long> order_item_ids = orderReturnInputVo.getReturn_items().stream()
|
||||
.map(OrderReturnItemInputVo::getOrder_item_id)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
|
||||
ShopOrderInfo shopOrderInfo = shopOrderInfoService.get(order_id);
|
||||
if (shopOrderInfo == null) {
|
||||
throw new ApiException(I18nUtil._("此订单信息数据有误!"));
|
||||
}
|
||||
|
||||
ShopOrderBase orderBase = shopOrderBaseService.get(order_id);
|
||||
if (orderBase == null) {
|
||||
throw new ApiException(I18nUtil._("此订单详细信息数据有误!"));
|
||||
}
|
||||
|
||||
// 判断此订单商品是否有正在审核的退款单
|
||||
QueryWrapper<ShopOrderReturn> returnQueryWrapper = new QueryWrapper<>();
|
||||
returnQueryWrapper.eq("order_id", order_id)
|
||||
.eq("return_state_id", StateCode.RETURN_PROCESS_CHECK);
|
||||
List<ShopOrderReturn> order_return_rows = find(returnQueryWrapper);
|
||||
|
||||
if (CollUtil.isNotEmpty(order_return_rows)) {
|
||||
List<String> return_ids = order_return_rows.stream()
|
||||
.map(ShopOrderReturn::getReturn_id)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
QueryWrapper<ShopOrderReturnItem> returnItemQueryWrapper = new QueryWrapper<>();
|
||||
returnItemQueryWrapper.in("order_item_id", order_item_ids)
|
||||
.in("return_id", return_ids);
|
||||
List<ShopOrderReturnItem> order_return_items = orderReturnItemService.find(returnItemQueryWrapper);
|
||||
if (CollUtil.isNotEmpty(order_return_items)) {
|
||||
throw new ApiException(I18nUtil._("此订单商品正在退款审核!"));
|
||||
}
|
||||
}
|
||||
|
||||
// 检查数据权限
|
||||
if (!CheckUtil.checkDataRights(user_id, orderBase, ShopOrderBase::getBuyer_user_id)) {
|
||||
throw new ApiException(ResultCode.FORBIDDEN);
|
||||
}
|
||||
|
||||
// 获取退款申请参数
|
||||
String return_id = orderReturnInputVo.getReturn_id();
|
||||
Integer return_reason_id = orderReturnInputVo.getReturn_reason_id() == null ? 0 : orderReturnInputVo.getReturn_reason_id();
|
||||
String return_buyer_message = orderReturnInputVo.getReturn_buyer_message();
|
||||
Integer store_id = Convert.toInt(orderBase.getStore_id());
|
||||
String return_tel = orderReturnInputVo.getReturn_tel();
|
||||
|
||||
// 手机号验证
|
||||
if (StrUtil.isNotBlank(return_tel) && !PhoneUtil.isMobile(return_tel)) {
|
||||
throw new ApiException(I18nUtil._("手机号输入有误!"));
|
||||
}
|
||||
|
||||
Date curTime = new Date();
|
||||
|
||||
// 构建退款单主表信息
|
||||
ShopOrderReturn orderReturn = new ShopOrderReturn();
|
||||
orderReturn.setReturn_id(return_id);
|
||||
orderReturn.setOrder_id(order_id);
|
||||
orderReturn.setBuyer_user_id(user_id);
|
||||
orderReturn.setBuyer_store_id(buyer_store_id);
|
||||
orderReturn.setReturn_reason_id(return_reason_id);
|
||||
orderReturn.setReturn_buyer_message(return_buyer_message);
|
||||
orderReturn.setStore_id(store_id);
|
||||
orderReturn.setReturn_refund_amount(BigDecimal.ZERO);
|
||||
orderReturn.setReturn_commision_fee(BigDecimal.ZERO);
|
||||
orderReturn.setReturn_state_id(StateCode.RETURN_PROCESS_CHECK);
|
||||
orderReturn.setReturn_tel(return_tel);
|
||||
orderReturn.setReturn_year(DateUtil.year(curTime)); // 退单年份-索引查询
|
||||
orderReturn.setReturn_month(DateUtil.month(curTime) + 1); // 退单月份-索引查询
|
||||
orderReturn.setReturn_day(DateUtil.dayOfMonth(curTime)); // 退单日-索引查询
|
||||
orderReturn.setReturn_reason_id(0); // 注意:这里覆盖了前面设置的return_reason_id
|
||||
orderReturn.setReturn_store_user_id(0);
|
||||
orderReturn.setReturn_mobile(0L);
|
||||
orderReturn.setReturn_telephone("");
|
||||
orderReturn.setSubsite_id(shopOrderInfo.getSubsite_id());
|
||||
|
||||
// 构建退款单明细信息
|
||||
List<ShopOrderReturnItem> shopOrderReturnItems = new ArrayList<>();
|
||||
for (OrderReturnItemInputVo returnItemInputVo : orderReturnInputVo.getReturn_items()) {
|
||||
// 获取订单商品信息
|
||||
ShopOrderItem shopOrderItem = shopOrderItemService.get(returnItemInputVo.getOrder_item_id());
|
||||
if (shopOrderItem == null) {
|
||||
throw new ApiException("订单商品不存在,请检查商品ID是否正确: " + returnItemInputVo.getOrder_item_id());
|
||||
}
|
||||
|
||||
// 验证是否为当前订单的商品
|
||||
if (!order_id.equals(shopOrderItem.getOrder_id())) {
|
||||
throw new ApiException("商品ID " + returnItemInputVo.getOrder_item_id() + " 不属于订单 " + order_id);
|
||||
}
|
||||
|
||||
// 获取商品索引信息
|
||||
ShopProductIndex shopProductIndex = shopProductIndexService.get(shopOrderItem.getProduct_id());
|
||||
if (shopProductIndex == null) {
|
||||
throw new ApiException("商品信息不存在,请检查商品ID是否正确: " + shopOrderItem.getProduct_id());
|
||||
}
|
||||
|
||||
// 检查是否允许退货
|
||||
boolean is_denyreturn = ifDenyReturn(shopOrderInfo, shopOrderItem, shopProductIndex);
|
||||
if (is_denyreturn) {
|
||||
// 获取更详细的拒绝退货原因
|
||||
String denyReason = getDenyReturnReason(shopOrderInfo, shopOrderItem, shopProductIndex);
|
||||
if (StrUtil.isBlank(denyReason)) {
|
||||
denyReason = "此商品不允许退货!";
|
||||
}
|
||||
throw new ApiException(denyReason);
|
||||
}
|
||||
|
||||
// 构建退款单明细
|
||||
ShopOrderReturnItem orderReturnItem = new ShopOrderReturnItem();
|
||||
|
||||
// 检查退款数量是否超过可退数量
|
||||
Integer order_item_quantity = shopOrderItem.getOrder_item_quantity(); // 订单中该商品的原始购买数量
|
||||
Integer order_item_return_agree_num = ObjectUtil.defaultIfNull(shopOrderItem.getOrder_item_return_agree_num(), 0); // 订单中该商品已经同意退货的数量
|
||||
Integer available_return_num = order_item_quantity - order_item_return_agree_num; // 当前还可以申请退款的商品数量
|
||||
if (available_return_num <= 0) {
|
||||
throw new ApiException(String.format("商品 %s 已无可退数量", shopOrderItem.getItem_name()));
|
||||
}
|
||||
|
||||
// 检查退款金额是否合理
|
||||
BigDecimal order_item_payment_amount = shopOrderItem.getOrder_item_payment_amount();
|
||||
BigDecimal order_item_return_agree_amount = ObjectUtil.defaultIfNull(shopOrderItem.getOrder_item_return_agree_amount(), BigDecimal.ZERO);
|
||||
BigDecimal available_return_amount = order_item_payment_amount.subtract(order_item_return_agree_amount);
|
||||
if (available_return_amount.compareTo(BigDecimal.ZERO) <= 0) {
|
||||
throw new ApiException(String.format("商品 %s 已无可退金额", shopOrderItem.getItem_name()));
|
||||
}
|
||||
|
||||
String return_item_image = ObjectUtil.defaultIfBlank(
|
||||
orderReturnInputVo.getRefund_pic(),
|
||||
orderReturnInputVo.getUpload_img());
|
||||
|
||||
orderReturnItem.setOrder_item_id(returnItemInputVo.getOrder_item_id());
|
||||
orderReturnItem.setOrder_id(order_id);
|
||||
orderReturnItem.setReturn_item_num(available_return_num);
|
||||
orderReturnItem.setReturn_item_subtotal(available_return_amount);
|
||||
orderReturnItem.setReturn_reason_id(return_reason_id);
|
||||
orderReturnItem.setReturn_item_note(return_buyer_message);
|
||||
orderReturnItem.setReturn_item_image(return_item_image);
|
||||
orderReturnItem.setReturn_state_id(StateCode.RETURN_PROCESS_CHECK);
|
||||
|
||||
shopOrderReturnItems.add(orderReturnItem);
|
||||
}
|
||||
|
||||
// 保存退款单
|
||||
if (!addReturnByItem(orderReturn, shopOrderReturnItems)) {
|
||||
throw new ApiException(ResultCode.FAILED);
|
||||
}
|
||||
|
||||
data.put("return", orderReturn);
|
||||
data.put("items", shopOrderReturnItems);
|
||||
|
||||
// 打票机打印退款订单到店(异步执行)
|
||||
shopStorePrinterService.printShopStoreReturnOrder(return_id);
|
||||
|
||||
// 发送消息通知, 退款提醒商家
|
||||
String message_id = "refund-reminder";
|
||||
Map<String, Object> args = new HashMap<>();
|
||||
args.put("order_id", orderReturn.getReturn_id());
|
||||
messageService.sendNoticeMsg(0, store_id, message_id, args);
|
||||
|
||||
// 发送unipush消息
|
||||
String title = "您有一个退款的订单,请及时前往后台审核!";
|
||||
String content = String.format("订单号:%s 退单号:[%s],时间:%s,请及时前往后台审核!",
|
||||
order_id, orderReturn.getReturn_id(),
|
||||
DateTimeUtils.formatDateTime(LocalDateTime.now(), "yyyy-MM-dd HH:mm:ss"));
|
||||
JSONObject payload = JSONUtil.createObj();
|
||||
payload.set("category", CommonConstant.PUSH_MSG_CATE_MCH_RETURN_ORDER_LIST);
|
||||
payload.set("orderId", order_id);
|
||||
payload.set("returnId", orderReturn.getReturn_id());
|
||||
pushMessageService.noticeMerchantEmployeeOrderAction(store_id, order_id, title, content, payload);
|
||||
|
||||
data.put("order_item_ids", order_item_ids);
|
||||
return CommonResult.success(data);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 取消退货
|
||||
@ -2287,20 +2487,20 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
public boolean ifDenyReturn(ShopOrderInfo shopOrderInfo, ShopOrderItem shopOrderItem, ShopProductIndex shopProductIndex) {
|
||||
// 1. 参数校验
|
||||
if (shopOrderInfo == null) {
|
||||
log.debug("[是否禁止退货] 订单信息为空,禁止退货");
|
||||
log.info("[是否禁止退货] 订单信息为空,禁止退货");
|
||||
return true;
|
||||
}
|
||||
|
||||
String orderId = shopOrderInfo.getOrder_id();
|
||||
Integer orderStateId = shopOrderInfo.getOrder_state_id();
|
||||
if (StrUtil.isBlank(orderId) || CheckUtil.isEmpty(orderStateId)) {
|
||||
log.debug("[是否禁止退货] 订单ID或订单状态为空,禁止退货");
|
||||
log.info("[是否禁止退货] 订单ID或订单状态为空,禁止退货");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (orderStateId.intValue() == StateCode.ORDER_STATE_CANCEL ||
|
||||
orderStateId.intValue() == StateCode.ORDER_STATE_WAIT_PAY) {
|
||||
log.debug("[是否禁止退货] 订单状态为已取消或未支付,禁止退货,order_id: {}, orderStateId: {}", orderId, orderStateId);
|
||||
log.info("[是否禁止退货] 订单状态为已取消或未支付,禁止退货,order_id: {}, orderStateId: {}", orderId, orderStateId);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2315,12 +2515,12 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
|
||||
// 检查是否超过退货期限
|
||||
if (orderDealTime != null && withdrawTime.compareTo(orderDealTime) > 0) {
|
||||
log.debug("[是否禁止退货] 订单已超过退货期限,禁止退货,order_id: {}, orderDealTime: {}, withdrawTime: {}",
|
||||
log.info("[是否禁止退货] 订单已超过退货期限,禁止退货,order_id: {}, orderDealTime: {}, withdrawTime: {}",
|
||||
orderId, orderDealTime, withdrawTime);
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("[是否禁止退货] 检查订单退货期限时发生异常,禁止退货,order_id: {}", orderId, e);
|
||||
log.info("[是否禁止退货] 检查订单退货期限时发生异常,禁止退货,order_id: {}", orderId, e);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -2333,19 +2533,19 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
boolean isLklProcessed = isSeparated && isDrawn;
|
||||
|
||||
if (isLklProcessed) {
|
||||
log.debug("[是否禁止退货] 拉卡拉分账订单已提现,禁止退货,order_id: {}, separated: {}, drawed: {}",
|
||||
log.info("[是否禁止退货] 拉卡拉分账订单已提现,禁止退货,order_id: {}, separated: {}, drawed: {}",
|
||||
orderId, isSeparated, isDrawn);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("[是否禁止退货] 检查拉卡拉分账状态时发生异常,禁止退货,order_id: {}", orderId, e);
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// 如果没有商品相关信息,则只检查订单级别
|
||||
if (shopOrderItem == null && shopProductIndex == null) {
|
||||
log.debug("[是否禁止退货] 无商品信息,仅检查订单级别,允许退货,order_id: {}", orderId);
|
||||
log.info("[是否禁止退货] 无商品信息,仅检查订单级别,允许退货,order_id: {}", orderId);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2362,7 +2562,7 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
}
|
||||
|
||||
if (productIndex == null) {
|
||||
log.debug("[是否禁止退货] 商品索引信息不存在,允许退货,order_id: {}", orderId);
|
||||
log.info("[是否禁止退货] 商品索引信息不存在,允许退货,order_id: {}", orderId);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2372,7 +2572,7 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
try {
|
||||
List<Integer> contractTypeIds = Convert.toList(Integer.class, contractTypeIdsStr);
|
||||
if (contractTypeIds != null && contractTypeIds.contains(StateCode.CONTRACT_TYPE_DENY_RETURN)) {
|
||||
log.debug("[是否禁止退货] 商品设置了禁止退货标识,禁止退货,order_id: {}, product_id: {}", orderId, productIndex.getProduct_id());
|
||||
log.info("[是否禁止退货] 商品设置了禁止退货标识,禁止退货,order_id: {}, product_id: {}", orderId, productIndex.getProduct_id());
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
@ -2381,8 +2581,13 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
}
|
||||
}
|
||||
|
||||
if (shopOrderItem != null && CheckUtil.isNotEmpty(shopOrderItem.getOrder_item_id()) && !ifCanReturnOrderItem(shopOrderItem)) {
|
||||
// 3.2 检查商品退款详情里是否已经提交过退款申请, 且数量大于订单数量,或金额大于订单金额
|
||||
return true;
|
||||
}
|
||||
|
||||
// 默认允许退货
|
||||
log.debug("[是否禁止退货] 商品允许退货,order_id: {}, product_id: {}", orderId, productIndex.getProduct_id());
|
||||
log.info("[是否禁止退货] 商品允许退货,order_id: {}, product_id: {}", orderId, productIndex.getProduct_id());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2488,26 +2693,52 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
||||
* 若商品索引为空,抛出异常;
|
||||
* 调用另一个重载方法 ifDenyReturn(...) 进行具体的退货规则判断。
|
||||
*
|
||||
* @param order_item_id
|
||||
* @return
|
||||
* @param order_item_id 订单商品ID
|
||||
* @return 是否禁止退货
|
||||
*/
|
||||
@Override
|
||||
public boolean ifDenyReturn(Long order_item_id) {
|
||||
ShopOrderItem shopOrderItem = shopOrderItemService.get(order_item_id);
|
||||
if (shopOrderItem == null) {
|
||||
throw new ApiException(I18nUtil._("此订单商品订单数据有误!"));
|
||||
// 参数校验
|
||||
if (order_item_id == null) {
|
||||
logger.warn("[禁止退货检查] 订单商品ID为空");
|
||||
return true;
|
||||
}
|
||||
|
||||
String order_id = shopOrderItem.getOrder_id();
|
||||
try {
|
||||
ShopOrderItem shopOrderItem = shopOrderItemService.get(order_item_id);
|
||||
if (shopOrderItem == null) {
|
||||
logger.warn("[禁止退货检查] 订单商品不存在,orderItemId: {}", order_item_id);
|
||||
// throw new ApiException(I18nUtil._("此订单商品订单数据有误!"));
|
||||
return true;
|
||||
}
|
||||
|
||||
ShopOrderInfo shopOrderInfo = shopOrderInfoService.get(order_id);
|
||||
ShopProductIndex shopProductIndex = shopProductIndexService.get(shopOrderItem.getProduct_id());
|
||||
String order_id = shopOrderItem.getOrder_id();
|
||||
if (StrUtil.isBlank(order_id)) {
|
||||
logger.warn("[禁止退货检查] 订单ID为空,orderItemId: {}", order_item_id);
|
||||
// throw new ApiException(I18nUtil._("订单信息异常!"));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (shopProductIndex == null) {
|
||||
throw new ApiException(I18nUtil._("此订单商品数据有误!"));
|
||||
ShopOrderInfo shopOrderInfo = shopOrderInfoService.get(order_id);
|
||||
if (shopOrderInfo == null) {
|
||||
logger.warn("[禁止退货检查] 订单信息不存在,orderId: {}", order_id);
|
||||
// throw new ApiException(I18nUtil._("订单信息不存在!"));
|
||||
return true;
|
||||
}
|
||||
|
||||
ShopProductIndex shopProductIndex = shopProductIndexService.get(shopOrderItem.getProduct_id());
|
||||
if (shopProductIndex == null) {
|
||||
logger.warn("[禁止退货检查] 商品索引信息不存在,productId: {}", shopOrderItem.getProduct_id());
|
||||
// throw new ApiException(I18nUtil._("此订单商品数据有误!"));
|
||||
return true;
|
||||
}
|
||||
|
||||
return ifDenyReturn(shopOrderInfo, shopOrderItem, shopProductIndex);
|
||||
} catch (Exception e) {
|
||||
logger.error("[禁止退货检查] 处理异常,orderItemId: {}", order_item_id, e);
|
||||
// 为保证系统稳定性,异常情况下默认禁止退货
|
||||
return true;
|
||||
}
|
||||
|
||||
return ifDenyReturn(shopOrderInfo, shopOrderItem, shopProductIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3099,4 +3330,59 @@ 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) {
|
||||
log.info("订单子项为空,无法退款");
|
||||
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);
|
||||
|
||||
// 记录调试信息
|
||||
log.info("订单子项退款检查 - 商品ID: {}, 订单数量: {}, 已退数量: {}, 商品金额: {}, 已同意退款金额: {}",
|
||||
orderItem.getProduct_id(), orderItemQuantity, orderItemReturnNum, orderItemAmount, orderItemReturnAgreeAmount);
|
||||
|
||||
// 判断是否可以退款:
|
||||
// 1. 可退数量 > 0 (订单商品数量 > 已退货数量)
|
||||
boolean canReturnQuantity = orderItemQuantity > orderItemReturnNum;
|
||||
// 2. 可退金额 > 0 (订单商品金额 > 已同意退款金额)
|
||||
boolean canReturnAmount = orderItemAmount.compareTo(orderItemReturnAgreeAmount) > 0;
|
||||
|
||||
log.info("退款条件检查结果 - 可退数量: {}, 可退金额: {}", canReturnQuantity, canReturnAmount);
|
||||
|
||||
return canReturnQuantity && canReturnAmount;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -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");
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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 = "store_id", required = false, defaultValue = "0") Long store_id) {
|
||||
return transportBaseService.ShopStoreSameCityTransportBaseDetail(store_id);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "保存(新增或修改)同城配送运费设置", notes = "保存(新增或修改)同城配送运费设置")
|
||||
|
||||
@ -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 = "store_id", required = false, defaultValue = "0") Long store_id) {
|
||||
return transportBaseService.ShopStoreSameCityTransportBaseDetail(store_id);
|
||||
}
|
||||
}
|
||||
@ -21,9 +21,10 @@ public interface ShopStoreSameCityTransportBaseService {
|
||||
/**
|
||||
* 获取同城配送设置详情信息
|
||||
*
|
||||
* @param storeId
|
||||
* @return
|
||||
*/
|
||||
CommonResult ShopStoreSameCityTransportBaseDetail();
|
||||
CommonResult ShopStoreSameCityTransportBaseDetail(Long storeId);
|
||||
|
||||
/**
|
||||
* 保存或更新同城配送各项设置
|
||||
@ -52,17 +53,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 +99,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);
|
||||
}
|
||||
@ -22,13 +22,21 @@ public interface ShopStoreSameCityTransportService {
|
||||
*/
|
||||
CommonResult deleteShopStoreSameCityTransport(Long transportId);
|
||||
|
||||
/**
|
||||
* 根据店铺 Id 获取同城配送扩展设置列表
|
||||
*
|
||||
* @param storeId
|
||||
* @return
|
||||
*/
|
||||
List<ShopStoreSameCityTransport> selectShopStoreSameCityTransportList(Long storeId);
|
||||
|
||||
/**
|
||||
* 根据同城配送基础配置自增 Id 获取同城配送扩展设置列表
|
||||
*
|
||||
* @param transportBaseId
|
||||
* @return
|
||||
*/
|
||||
List<ShopStoreSameCityTransport> selectShopStoreSameCityTransportList(Long transportBaseId);
|
||||
List<ShopStoreSameCityTransport> selectShopStoreSameCityTransportListByTransportBaseId(Long transportBaseId);
|
||||
|
||||
/**
|
||||
* 保存同城配送扩展设置列表(存在就更新,不存在就新增)
|
||||
|
||||
@ -1564,7 +1564,15 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl<ShopStoreBaseMappe
|
||||
public Map getBase(Integer store_id) {
|
||||
|
||||
UserDto user = getCurrentUser();
|
||||
if (store_id == null) {
|
||||
if (user == null) {
|
||||
throw new ApiException(ResultCode.NEED_LOGIN);
|
||||
}
|
||||
|
||||
if (user.isPlatform()) {
|
||||
if (CheckUtil.isEmpty(store_id)) {
|
||||
throw new ApiException("平台操作,请传入店铺 Id");
|
||||
}
|
||||
} else {
|
||||
store_id = Convert.toInt(user.getStore_id());
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -25,13 +25,16 @@ 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.CheckUtil;
|
||||
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.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 +67,11 @@ public class ShopStoreSameCityTransportBaseServiceImpl extends BaseServiceImpl<S
|
||||
@Autowired
|
||||
private ShopStoreBaseService shopStoreBaseService;
|
||||
|
||||
@Lazy
|
||||
@Autowired
|
||||
private ShopOrderInfoService shopOrderInfoService;
|
||||
|
||||
|
||||
@Resource
|
||||
private AccountBaseConfigService accountBaseConfigService;
|
||||
|
||||
@ -71,74 +79,123 @@ public class ShopStoreSameCityTransportBaseServiceImpl extends BaseServiceImpl<S
|
||||
/**
|
||||
* 获取同城配送设置详情信息
|
||||
*
|
||||
* @return
|
||||
* @param storeId 店铺ID,平台操作时必传
|
||||
* @return 同城配送设置详情
|
||||
*/
|
||||
@Override
|
||||
public CommonResult ShopStoreSameCityTransportBaseDetail() {
|
||||
// 判断有没有权限
|
||||
public CommonResult ShopStoreSameCityTransportBaseDetail(Long storeId) {
|
||||
// 权限校验
|
||||
UserDto user = getCurrentUser();
|
||||
if (user == null || !user.isStore()) {
|
||||
if (user == null) {
|
||||
logger.warn("用户未登录,无法获取同城配送设置详情");
|
||||
return CommonResult.failed(ResultCode.FORBIDDEN.getMessage());
|
||||
}
|
||||
|
||||
Long storeId = Convert.toLong(user.getStore_id());
|
||||
ShopStoreSameCityTransportBaseDTO retDTO = getShopStoreSameCityTransportBaseDTOById(storeId);
|
||||
if (retDTO == null) {
|
||||
return CommonResult.failed("商家未设置店铺地址,请先设置店铺地址!");
|
||||
// 平台用户必须传入店铺ID,商户用户自动获取自己的店铺ID
|
||||
Integer isPlatform = CommonConstant.Disable2;
|
||||
if (user.isPlatform()) {
|
||||
if (CheckUtil.isEmpty(storeId)) {
|
||||
logger.warn("平台用户操作时未传入店铺ID");
|
||||
return CommonResult.failed("平台操作,请传入店铺Id");
|
||||
}
|
||||
isPlatform = CommonConstant.Enable;
|
||||
} else {
|
||||
storeId = Convert.toLong(user.getStore_id());
|
||||
if (storeId == null || storeId <= 0) {
|
||||
logger.error("商户用户店铺ID无效: {}", user.getStore_id());
|
||||
return CommonResult.failed("用户店铺信息异常");
|
||||
}
|
||||
}
|
||||
|
||||
// 获取同城配送设置详情
|
||||
ShopStoreSameCityTransportBaseDTO retDTO = getShopStoreSameCityTransportBaseDTOById(storeId, isPlatform);
|
||||
if (retDTO == null) {
|
||||
logger.warn("店铺 {} 未设置店铺地址及经纬度相关信息", storeId);
|
||||
return CommonResult.failed("商家未设置店铺地址及经纬度相关信息,请先设置再试!");
|
||||
}
|
||||
|
||||
logger.debug("成功获取店铺 {} 的同城配送设置详情", storeId);
|
||||
return CommonResult.success(retDTO);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 保存或更新同城配送各项设置
|
||||
*
|
||||
* @param shopStoreSameCityTransportBaseDTO
|
||||
* @return
|
||||
* @param shopStoreSameCityTransportBaseDTO 同城配送设置数据传输对象
|
||||
* @return 操作结果
|
||||
*/
|
||||
@Override
|
||||
public CommonResult saveOrUpdateSameCityTransport(ShopStoreSameCityTransportBaseDTO shopStoreSameCityTransportBaseDTO) {
|
||||
// 判断有没有权限
|
||||
UserDto user = getCurrentUser();
|
||||
if (user == null || !user.isStore()) {
|
||||
return CommonResult.failed("无权限操作!");
|
||||
}
|
||||
|
||||
Integer userId = user.getId();
|
||||
Long storeId = Convert.toLong(user.getStore_id());
|
||||
|
||||
shopStoreSameCityTransportBaseDTO.getTransportBase().setStore_id(storeId);
|
||||
|
||||
// 参数校验
|
||||
if (shopStoreSameCityTransportBaseDTO == null || shopStoreSameCityTransportBaseDTO.getTransportBase() == null) {
|
||||
logger.warn("保存或更新同城配送设置参数校验失败: DTO为空或基础设置为空");
|
||||
return CommonResult.failed("参数有误");
|
||||
}
|
||||
|
||||
ShopStoreBase store = shopStoreBaseService.getById(storeId);
|
||||
if (store == null || StrUtil.isBlank(store.getStore_longitude()) || StrUtil.isBlank(store.getStore_latitude())) {
|
||||
CommonResult.failed("无法获取店铺信息!");
|
||||
// 权限校验
|
||||
UserDto user = getCurrentUser();
|
||||
if (user == null) {
|
||||
logger.warn("用户未登录,无法保存或更新同城配送设置");
|
||||
return CommonResult.failed("无权限操作!");
|
||||
}
|
||||
|
||||
// 获取店铺ID并校验用户权限
|
||||
Long storeId;
|
||||
int isPlatform = user.isPlatform() ? CommonConstant.Enable : CommonConstant.Disable2;
|
||||
|
||||
if (isPlatform == CommonConstant.Enable) {
|
||||
// 平台用户必须传入店铺ID
|
||||
if (CheckUtil.isEmpty(shopStoreSameCityTransportBaseDTO.getTransportBase().getStore_id())) {
|
||||
logger.warn("平台用户操作时未传入店铺ID");
|
||||
return CommonResult.failed("平台管理,请传入店铺Id");
|
||||
}
|
||||
storeId = Convert.toLong(shopStoreSameCityTransportBaseDTO.getTransportBase().getStore_id());
|
||||
} else {
|
||||
// 商户用户使用自己的店铺ID
|
||||
storeId = Convert.toLong(user.getStore_id());
|
||||
if (storeId == null || storeId <= 0) {
|
||||
logger.error("商户用户店铺ID无效: {}", user.getStore_id());
|
||||
return CommonResult.failed("用户店铺信息异常");
|
||||
}
|
||||
shopStoreSameCityTransportBaseDTO.getTransportBase().setStore_id(storeId);
|
||||
}
|
||||
|
||||
// 获取店铺基本信息并校验
|
||||
ShopStoreBase store = shopStoreBaseService.getById(storeId);
|
||||
if (store == null || StrUtil.isBlank(store.getStore_longitude()) || StrUtil.isBlank(store.getStore_latitude())) {
|
||||
logger.warn("无法获取店铺 {} 的位置信息", storeId);
|
||||
return CommonResult.failed("无法获取店铺信息!");
|
||||
}
|
||||
|
||||
// 设置基础信息
|
||||
ShopStoreSameCityTransportBase transportBase = shopStoreSameCityTransportBaseDTO.getTransportBase();
|
||||
transportBase.setUpdated_by(userId);
|
||||
transportBase.setUpdated_by(user.getId());
|
||||
transportBase.setStore_longitude(store.getStore_longitude());
|
||||
transportBase.setStore_latitude(store.getStore_latitude());
|
||||
transportBase.setStore_address(store.getStore_address());
|
||||
transportBase.setIs_platform(isPlatform);
|
||||
|
||||
// 新增或更新同城配送基础设置
|
||||
Pair<Long, String> pair = saveOrUpdateShopStoreSameCityTransportBase(transportBase);
|
||||
|
||||
// 新增或更新同城配送扩展设置列表
|
||||
shopStoreSameCityTransportBaseDTO.setTransportBase(transportBase);
|
||||
shopStoreSameCityTransportBaseDTO.rebuildTransportList();
|
||||
shopStoreSameCityTransportService.saveOrUpdateShopStoreSameCityTransportList(shopStoreSameCityTransportBaseDTO.getTransportList());
|
||||
|
||||
if (pair.getFirst() > 0) {
|
||||
return CommonResult.success(null, pair.getSecond());
|
||||
// 保存或更新同城配送基础设置
|
||||
Pair<Long, String> saveResult = saveOrUpdateShopStoreSameCityTransportBase(transportBase);
|
||||
if (saveResult.getFirst() <= 0) {
|
||||
logger.error("保存或更新同城配送基础设置失败, storeId={}, errorMsg={}", storeId, saveResult.getSecond());
|
||||
return CommonResult.failed(saveResult.getSecond());
|
||||
}
|
||||
|
||||
return CommonResult.failed(pair.getSecond());
|
||||
// 更新DTO中的基础设置和运输列表
|
||||
shopStoreSameCityTransportBaseDTO.setTransportBase(transportBase);
|
||||
shopStoreSameCityTransportBaseDTO.rebuildTransportList();
|
||||
|
||||
// 保存或更新同城配送扩展设置列表
|
||||
int updateCount = shopStoreSameCityTransportService.saveOrUpdateShopStoreSameCityTransportList(shopStoreSameCityTransportBaseDTO.getTransportList());
|
||||
logger.debug("保存或更新同城配送扩展设置列表完成, storeId={}, 更新条数={}", storeId, updateCount);
|
||||
|
||||
logger.info("成功保存或更新店铺 {} 的同城配送设置", storeId);
|
||||
return CommonResult.success(shopStoreSameCityTransportBaseDTO, saveResult.getSecond());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 店铺主营商品类型
|
||||
*
|
||||
@ -225,58 +282,93 @@ public class ShopStoreSameCityTransportBaseServiceImpl extends BaseServiceImpl<S
|
||||
/**
|
||||
* 根据店铺 Id 获取同城配送设置详情信息
|
||||
*
|
||||
* @param storeId
|
||||
* @return
|
||||
* @param storeId 店铺ID
|
||||
* @param isPlatform 是否平台操作标识
|
||||
* @return 同城配送设置详情DTO
|
||||
*/
|
||||
@Override
|
||||
public ShopStoreSameCityTransportBaseDTO getShopStoreSameCityTransportBaseDTOById(Long storeId) {
|
||||
public ShopStoreSameCityTransportBaseDTO getShopStoreSameCityTransportBaseDTOById(Long storeId, Integer isPlatform) {
|
||||
// 参数校验
|
||||
if (storeId == null || storeId <= 0) {
|
||||
logger.warn("获取同城配送设置详情失败:店铺ID无效,storeId={}", storeId);
|
||||
return null;
|
||||
}
|
||||
|
||||
// 店铺基本信息
|
||||
// 获取店铺基本信息
|
||||
ShopStoreBase shopStoreBase = shopStoreBaseService.getShopStoreBaseByStoreId(storeId.intValue());
|
||||
if (shopStoreBase == null) {
|
||||
logger.warn("获取同城配送设置详情失败:店铺基本信息不存在,storeId={}", storeId);
|
||||
return null;
|
||||
}
|
||||
|
||||
ShopStoreSameCityTransportBase transportBase = getShopStoreSameCityTransportBaseById(storeId);
|
||||
// 获取同城配送基础设置记录
|
||||
ShopStoreSameCityTransportBase transportBase = getShopStoreSameCityTransportBaseById(storeId, isPlatform);
|
||||
|
||||
// 如果未找到对应记录,则根据不同角色处理
|
||||
if (transportBase == null) {
|
||||
transportBase = new ShopStoreSameCityTransportBase();
|
||||
transportBase.setStore_id(storeId);
|
||||
if (isPlatform == CommonConstant.Enable) {
|
||||
// 平台用户:尝试从商家店铺配送设置中获取记录
|
||||
transportBase = getShopStoreSameCityTransportBaseById(storeId, CommonConstant.Disable2);
|
||||
if (transportBase == null) {
|
||||
logger.warn("获取同城配送设置详情失败:平台和商家配送设置均不存在,storeId={}", storeId);
|
||||
return null;
|
||||
} else {
|
||||
// 复用商家设置,但需要重置平台相关字段
|
||||
transportBase.setIs_platform(CommonConstant.Disable);
|
||||
transportBase.setTransport_base_id(null);
|
||||
transportBase.setStore_id(storeId);
|
||||
logger.debug("平台用户复用商家配送设置,storeId={}", storeId);
|
||||
}
|
||||
} else {
|
||||
// 商家用户:创建默认配送设置
|
||||
transportBase = new ShopStoreSameCityTransportBase();
|
||||
transportBase.setStore_id(storeId);
|
||||
transportBase.setIs_platform(isPlatform);
|
||||
|
||||
// 没有记录时,指定默认值
|
||||
transportBase.setArea_type(1);
|
||||
transportBase.setBasis(1);
|
||||
transportBase.setDistance_base(5);
|
||||
transportBase.setWeight_base(5);
|
||||
transportBase.setDelivery_base_fee(BigDecimal.valueOf(5));
|
||||
transportBase.setDistance_increase_km(1);
|
||||
transportBase.setDistance_increase_fee(BigDecimal.valueOf(1));
|
||||
transportBase.setWeight_increase_kg(1);
|
||||
transportBase.setWeight_increase_fee(BigDecimal.valueOf(1));
|
||||
transportBase.setStatus(CommonConstant.Enable);
|
||||
// 设置默认值
|
||||
transportBase.setArea_type(1);
|
||||
transportBase.setBasis(1);
|
||||
transportBase.setDistance_base(5);
|
||||
transportBase.setWeight_base(5);
|
||||
transportBase.setDelivery_base_fee(BigDecimal.valueOf(5));
|
||||
transportBase.setDistance_increase_km(1);
|
||||
transportBase.setDistance_increase_fee(BigDecimal.valueOf(1));
|
||||
transportBase.setWeight_increase_kg(1);
|
||||
transportBase.setWeight_increase_fee(BigDecimal.valueOf(1));
|
||||
transportBase.setStatus(CommonConstant.Enable);
|
||||
|
||||
Date now = new Date();
|
||||
transportBase.setCreated_at(now);
|
||||
transportBase.setUpdated_at(transportBase.getCreated_at());
|
||||
// 设置时间戳
|
||||
Date now = new Date();
|
||||
transportBase.setCreated_at(now);
|
||||
transportBase.setUpdated_at(now);
|
||||
|
||||
// 从 shop_store_base 表获取店铺的地址和经纬度
|
||||
transportBase.setStore_address(StrUtil.removeAll(shopStoreBase.getStore_area(), "/") + shopStoreBase.getStore_address());
|
||||
transportBase.setStore_longitude(shopStoreBase.getStore_longitude());
|
||||
transportBase.setStore_latitude(shopStoreBase.getStore_latitude());
|
||||
// 从店铺基本信息中获取地址和经纬度
|
||||
transportBase.setStore_address(StrUtil.removeAll(shopStoreBase.getStore_area(), "/") + shopStoreBase.getStore_address());
|
||||
transportBase.setStore_longitude(shopStoreBase.getStore_longitude());
|
||||
transportBase.setStore_latitude(shopStoreBase.getStore_latitude());
|
||||
|
||||
logger.debug("为商家创建默认配送设置,storeId={}", storeId);
|
||||
}
|
||||
}
|
||||
|
||||
// 构造返回DTO
|
||||
ShopStoreSameCityTransportBaseDTO shopStoreSameCityTransportBaseDTO = new ShopStoreSameCityTransportBaseDTO();
|
||||
shopStoreSameCityTransportBaseDTO.setTransportBase(transportBase);
|
||||
|
||||
// 多个店铺同城快递运费设置(起送条件+优惠条件)
|
||||
List<ShopStoreSameCityTransport> transportList = shopStoreSameCityTransportService.selectShopStoreSameCityTransportList(transportBase.getStore_id());
|
||||
// 获取配送扩展设置列表
|
||||
List<ShopStoreSameCityTransport> transportList;
|
||||
if (CheckUtil.isEmpty(transportBase.getTransport_base_id())) {
|
||||
transportList = shopStoreSameCityTransportService.selectShopStoreSameCityTransportList(transportBase.getStore_id());
|
||||
} else {
|
||||
transportList = shopStoreSameCityTransportService.selectShopStoreSameCityTransportListByTransportBaseId(transportBase.getTransport_base_id());
|
||||
}
|
||||
shopStoreSameCityTransportBaseDTO.setTransportList(transportList);
|
||||
|
||||
logger.debug("成功获取店铺 {} 的同城配送设置详情", storeId);
|
||||
return shopStoreSameCityTransportBaseDTO;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据店铺Id获取同城配送基础运费记录
|
||||
*
|
||||
@ -284,25 +376,46 @@ 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存或更新同城配送基础设置
|
||||
* 注意:同一个 store_id + is_platform + status=Enable 的组合只能存在一条记录
|
||||
*
|
||||
* @param transportBase 同城配送基础设置实体
|
||||
* @return 操作结果 Pair<记录ID, 操作消息>
|
||||
*/
|
||||
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 = CommonConstant.Disable2; // 默认为商户级别
|
||||
transportBase.setIs_platform(isPlatform);
|
||||
}
|
||||
|
||||
// 设置默认值 - 确保数值合理性
|
||||
if (transportBase.getDistance_base() == null || transportBase.getDistance_base() < 0) {
|
||||
transportBase.setDistance_base(0);
|
||||
}
|
||||
@ -325,38 +438,58 @@ public class ShopStoreSameCityTransportBaseServiceImpl extends BaseServiceImpl<S
|
||||
transportBase.setWeight_increase_fee(BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
// 构建查询条件:确保同一店铺同一平台标识下只有一条启用记录
|
||||
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={}, isPlatform={}", transportBase.getStore_id(), transportBase.getIs_platform());
|
||||
transportBase.setCreated_by(transportBase.getUpdated_by());
|
||||
transportBase.setCreated_at(now);
|
||||
transportBase.setUpdated_at(now);
|
||||
transportBase.setStatus(CommonConstant.Enable); // 确保状态为启用
|
||||
|
||||
if (add(transportBase)) {
|
||||
// 确保获取到ID
|
||||
Long transportBaseId = transportBase.getTransport_base_id();
|
||||
if (transportBaseId == null || transportBaseId <= 0) {
|
||||
// 补偿机制:若transportBase.getTransport_base_id()==null,重新查询数据
|
||||
// 补偿机制:若新增后ID仍为空,重新查询获取ID
|
||||
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);
|
||||
transportBase.setStatus(CommonConstant.Enable); // 确保状态为启用
|
||||
|
||||
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 +539,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 +599,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 +627,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 +808,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将是2,2.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 +827,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将是2,2.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将是2,2.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();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -62,6 +62,31 @@ public class ShopStoreSameCityTransportServiceImpl extends BaseServiceImpl<ShopS
|
||||
return CommonResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据同城配送基础配置自增 Id 获取同城配送扩展设置列表
|
||||
*
|
||||
* @param transportBaseId
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public List<ShopStoreSameCityTransport> selectShopStoreSameCityTransportListByTransportBaseId(Long transportBaseId) {
|
||||
if (transportBaseId == null || transportBaseId <= 0) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
QueryWrapper<ShopStoreSameCityTransport> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("transport_base_id", transportBaseId);
|
||||
queryWrapper.eq("status", CommonConstant.Enable);
|
||||
queryWrapper.orderByAsc("transport_id");
|
||||
|
||||
List<ShopStoreSameCityTransport> shopStoreSameCityTransportList = list(queryWrapper);
|
||||
if (CollectionUtil.isEmpty(shopStoreSameCityTransportList)) {
|
||||
shopStoreSameCityTransportList = Collections.emptyList();
|
||||
}
|
||||
|
||||
return shopStoreSameCityTransportList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据同城配送基础配置自增 Id 获取同城配送扩展设置列表
|
||||
*
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
// 订单总计运费
|
||||
|
||||
@ -819,10 +819,10 @@
|
||||
<!--总计优惠金额 order_discount_amount + order_voucher_price + order_points_fee + order_adjust_fee-->
|
||||
(od.order_discount_amount + od.voucher_price + od.order_points_fee + od.order_adjust_fee) as
|
||||
total_discount_amount,
|
||||
<!--预计收入:订单原价金额-总计优惠金额-配送费-平台费+打包费-->
|
||||
(ob.order_product_amount-od.order_discount_amount-od.voucher_price-od.order_points_fee-od.order_adjust_fee-od.platform_fee-order_shipping_fee_inner+od.packing_fee)
|
||||
<!--预计收入:订单原价金额-总计优惠金额-配送费-平台费-拉卡拉手续费+打包费-->
|
||||
(od.order_item_amount-od.order_discount_amount-od.voucher_price-od.order_points_fee-od.order_adjust_fee-od.platform_fee-order_shipping_fee_inner-lkl_fee+od.packing_fee)
|
||||
as order_income_amount,
|
||||
(od.platform_fee+lkl_fee) as platform_fee,
|
||||
od.platform_fee,
|
||||
od.packing_fee,
|
||||
od.order_message,
|
||||
sb.store_id,
|
||||
|
||||
@ -62,7 +62,7 @@
|
||||
订单编号:${order_id}<BR>
|
||||
订单来源:微信小程序<BR>
|
||||
支付方式:微信支付<BR>
|
||||
配送来源:顺丰同城<BR>
|
||||
配送来源:${deliver_type_name!'顺丰同城'}<BR>
|
||||
付款时间:${payment_time?string('yyyy-MM-dd HH:mm:ss')}<BR>
|
||||
--------------------------------<BR>
|
||||
<L>商品名称 数量 金额</L><BR>
|
||||
@ -103,4 +103,4 @@
|
||||
<CB>${store_name}</CB><BR>--------------------------------<BR><CB>#${order_pickup_num_str}</CB><BR><L>买家备注:${order_message!'-'}</L><BR><BOLD>配送时间:${payment_time?string('MM-dd HH:mm')}~${delivery_time?string('HH:mm')}</BOLD><BR>--------------------------------<BR>订单编号:${order_id}<BR>订单来源:微信小程序<BR>支付方式:微信支付<BR>配送来源:顺丰同城<BR>付款时间:${payment_time?string('yyyy-MM-dd HH:mm:ss')}<BR>--------------------------------<BR><L>商品名称 数量 金额</L><BR>--------------------------------<BR><#list order_items as item><L>${item.s_name}</L><L><BOLD>${item.s_quantity}</BOLD></L><L>${item.s_amount}</L><BR><#if item.s_name_segs??><#list item.s_name_segs as seg><L>${seg}</L><BR></#list></#if><BOLD><#if item.product_sn?default("")?trim?length gt 1>${item.product_sn}</BOLD><BR></#if></#list>--------------------------------<BR>商品总件数:<BOLD>${order_items_count!0}</BOLD><BR>商品总额:<BOLD>¥${order_product_amount?string('0.00')}</BOLD><BR>运费:<BOLD>¥${order_shipping_fee?string('0.00')}</BOLD><BR><#if packing_fee?? && (packing_fee > 0)>打包费:<BOLD>¥${packing_fee?string('0.00')}</BOLD><BR></#if>优惠金额:<BOLD>-¥${(quanyi!0)?string('0.00')}</BOLD><BR>实付金额:<BOLD>¥${order_payment_amount?string('0.00')}</BOLD><BR><#if seller_message?default("")?trim?length gt 1>--------------------------------<BR><BOLD>商家备注:${seller_message!'-'}</BOLD><BR></#if>--------------------------------<BR><BOLD>收货人:${buyer_user_name!''}</BOLD><BR><BOLD>收货人手机:${da_mobile!'-'}</BOLD><BR><BOLD>收货地址:${da_province!'-'}${da_city!'-'}${da_address!'-'}</BOLD><BR>--------------------------------<BR>门店:${store_name}<BR>门店电话:<BOLD>${store_tel!'-'}</BOLD><BR>收银员:${cashier!'店长'}<BR>
|
||||
|
||||
第三版带变量的模版(有预约订单)
|
||||
<#if is_booking_order><CB><B>【预约订单】<BR></B></CB></#if><CB>${store_name}</CB><BR>--------------------------------<BR><CB>#${order_pickup_num_str}</CB><BR><L>买家备注:${order_message!'-'}</L><BR><BOLD>配送时间:${payment_time?string('MM-dd HH:mm')}~${delivery_time?string('HH:mm')}</BOLD><BR>--------------------------------<BR>订单编号:${order_id}<BR>订单来源:微信小程序<BR>支付方式:微信支付<BR>配送来源:顺丰同城<BR>付款时间:${payment_time?string('yyyy-MM-dd HH:mm:ss')}<BR>--------------------------------<BR><L>商品名称 数量 金额</L><BR>--------------------------------<BR><#list order_items as item><L>${item.s_name}</L><L><BOLD>${item.s_quantity}</BOLD></L><L>${item.s_amount}</L><BR><#if item.s_name_segs??><#list item.s_name_segs as seg><L>${seg}</L><BR></#list></#if><BOLD><#if item.product_sn?default("")?trim?length gt 1>${item.product_sn}</BOLD><BR></#if><BR></#list>--------------------------------<BR>商品总件数:<BOLD>${order_items_count!0}</BOLD><BR>商品总额:<BOLD>¥${order_product_amount?string('0.00')}</BOLD><BR>运费:<BOLD>¥${order_shipping_fee?string('0.00')}</BOLD><BR><#if packing_fee?? && (packing_fee > 0)>打包费:<BOLD>¥${packing_fee?string('0.00')}</BOLD><BR></#if>优惠金额:<BOLD>-¥${(quanyi!0)?string('0.00')}</BOLD><BR>实付金额:<BOLD>¥${order_payment_amount?string('0.00')}</BOLD><BR><#if seller_message?default("")?trim?length gt 1>--------------------------------<BR><BOLD>商家备注:${seller_message!'-'}</BOLD><BR></#if>--------------------------------<BR><BOLD>收货人:${buyer_user_name!''}</BOLD><BR><BOLD>收货人手机:${da_mobile!'-'}</BOLD><BR><BOLD>收货地址:${da_province!'-'}${da_city!'-'}${da_address!'-'}</BOLD><BR>--------------------------------<BR>门店:${store_name}<BR>门店电话:<BOLD>${store_tel!'-'}</BOLD><BR>收银员:${cashier!'店长'}<BR>
|
||||
<#if is_booking_order><CB><B>【预约订单】<BR></B></CB></#if><CB>${store_name}</CB><BR>--------------------------------<BR><CB>#${order_pickup_num_str}</CB><BR><L>买家备注:${order_message!'-'}</L><BR><BOLD>配送时间:${payment_time?string('MM-dd HH:mm')}~${delivery_time?string('HH:mm')}</BOLD><BR>--------------------------------<BR>订单编号:${order_id}<BR>订单来源:微信小程序<BR>支付方式:微信支付<BR>配送来源:${deliver_type_name!'顺丰同城'}<BR>付款时间:${payment_time?string('yyyy-MM-dd HH:mm:ss')}<BR>--------------------------------<BR><L>商品名称 数量 金额</L><BR>--------------------------------<BR><#list order_items as item><L>${item.s_name}</L><L><BOLD>${item.s_quantity}</BOLD></L><L>${item.s_amount}</L><BR><#if item.s_name_segs??><#list item.s_name_segs as seg><L>${seg}</L><BR></#list></#if><BOLD><#if item.product_sn?default("")?trim?length gt 1>${item.product_sn}</BOLD><BR></#if><BR></#list>--------------------------------<BR>商品总件数:<BOLD>${order_items_count!0}</BOLD><BR>商品总额:<BOLD>¥${order_product_amount?string('0.00')}</BOLD><BR>运费:<BOLD>¥${order_shipping_fee?string('0.00')}</BOLD><BR><#if packing_fee?? && (packing_fee > 0)>打包费:<BOLD>¥${packing_fee?string('0.00')}</BOLD><BR></#if>优惠金额:<BOLD>-¥${(quanyi!0)?string('0.00')}</BOLD><BR>实付金额:<BOLD>¥${order_payment_amount?string('0.00')}</BOLD><BR><#if seller_message?default("")?trim?length gt 1>--------------------------------<BR><BOLD>商家备注:${seller_message!'-'}</BOLD><BR></#if>--------------------------------<BR><BOLD>收货人:${buyer_user_name!''}</BOLD><BR><BOLD>收货人手机:${da_mobile!'-'}</BOLD><BR><BOLD>收货地址:${da_province!'-'}${da_city!'-'}${da_address!'-'}</BOLD><BR>--------------------------------<BR>门店:${store_name}<BR>门店电话:<BOLD>${store_tel!'-'}</BOLD><BR>收银员:${cashier!'店长'}<BR>
|
||||
12
pom.xml
12
pom.xml
@ -539,11 +539,6 @@
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>com.spotify</groupId>
|
||||
<artifactId>docker-maven-plugin</artifactId>
|
||||
@ -571,7 +566,9 @@
|
||||
<goal>build</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
|
||||
</executions>
|
||||
|
||||
<configuration>
|
||||
<!--定义镜像名称-->
|
||||
<imageName>${docker.registry}/mall/${project.artifactId}:${project.version}</imageName>
|
||||
@ -592,7 +589,7 @@
|
||||
<forceTags>true</forceTags>
|
||||
<imageTags>
|
||||
<imageTag>${project.version}</imageTag>
|
||||
<!-- <imageTag>latest</imageTag>-->
|
||||
<imageTag>latest</imageTag>
|
||||
</imageTags>
|
||||
|
||||
<!--定义容器启动命令,注意不能换行-->
|
||||
@ -609,6 +606,7 @@
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user