Merge branch 'main' into dev
This commit is contained in:
commit
3a30209005
@ -115,4 +115,10 @@ public class CommonConstant {
|
|||||||
public static final int SeparateCalcMode_CanSeparateAmt = 2;
|
public static final int SeparateCalcMode_CanSeparateAmt = 2;
|
||||||
|
|
||||||
|
|
||||||
|
// 代理商等级:0-平台方;1-一级代理;2-二级代理;
|
||||||
|
public static final Integer Agent_Level_Plat = 0;
|
||||||
|
public static final Integer Agent_Level_1st = 1;
|
||||||
|
public static final Integer Agent_Level_2nd = 2;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,6 +18,7 @@ import lombok.EqualsAndHashCode;
|
|||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.math.BigDecimal;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@ -32,6 +33,9 @@ public class EsignPlatformInfo implements Serializable {
|
|||||||
@ApiModelProperty(value = "自增ID")
|
@ApiModelProperty(value = "自增ID")
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "父代理商 Id(省级代理商Id)")
|
||||||
|
private Long parent_id;
|
||||||
|
|
||||||
@ApiModelProperty(value = "公司邮箱")
|
@ApiModelProperty(value = "公司邮箱")
|
||||||
private String email;
|
private String email;
|
||||||
|
|
||||||
@ -110,6 +114,15 @@ public class EsignPlatformInfo implements Serializable {
|
|||||||
@ApiModelProperty(value = "邀请码,后期跟收益有关")
|
@ApiModelProperty(value = "邀请码,后期跟收益有关")
|
||||||
private String invite_code;
|
private String invite_code;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "县级市代理商设定的配送费(单位:分)")
|
||||||
|
private Integer shipping_fee;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "顺丰商家Id (用于县级代理商创建店铺的商家Id)")
|
||||||
|
private String supplier_id;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "分账比例值,取值范围:[0.01,1.00]")
|
||||||
|
private BigDecimal split_ratio;
|
||||||
|
|
||||||
@ApiModelProperty(value = "记录状态:1-有效;2-无效;")
|
@ApiModelProperty(value = "记录状态:1-有效;2-无效;")
|
||||||
private Integer status;
|
private Integer status;
|
||||||
|
|
||||||
|
|||||||
@ -18,6 +18,7 @@ import lombok.EqualsAndHashCode;
|
|||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.math.BigDecimal;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@ -45,6 +46,9 @@ public class LklLedgerMerReceiverBind implements Serializable {
|
|||||||
private String audit_status;
|
private String audit_status;
|
||||||
private String audit_status_text;
|
private String audit_status_text;
|
||||||
private String remark;
|
private String remark;
|
||||||
|
private Integer level;
|
||||||
|
private BigDecimal split_ratio;
|
||||||
|
private Integer shipping_fee;
|
||||||
private String version;
|
private String version;
|
||||||
private Date created_at;
|
private Date created_at;
|
||||||
private Date updated_at;
|
private Date updated_at;
|
||||||
|
|||||||
@ -18,6 +18,7 @@ import lombok.EqualsAndHashCode;
|
|||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.math.BigDecimal;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@ -54,6 +55,9 @@ public class LklLedgerReceiver implements Serializable {
|
|||||||
private String attach_list;
|
private String attach_list;
|
||||||
private String settle_type;
|
private String settle_type;
|
||||||
private Long platform_id;
|
private Long platform_id;
|
||||||
|
private Integer level;
|
||||||
|
private BigDecimal split_ratio;
|
||||||
|
private Integer shipping_fee;
|
||||||
private String version;
|
private String version;
|
||||||
private Integer status;
|
private Integer status;
|
||||||
private Date created_at;
|
private Date created_at;
|
||||||
|
|||||||
@ -101,6 +101,9 @@ public class ShopOrderData implements Serializable {
|
|||||||
@ApiModelProperty(value = "平台费(分给平台或代理商的费用),根据不同的店铺分类,从商品原价中扣除相应的费用。")
|
@ApiModelProperty(value = "平台费(分给平台或代理商的费用),根据不同的店铺分类,从商品原价中扣除相应的费用。")
|
||||||
private BigDecimal platform_fee;
|
private BigDecimal platform_fee;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "拉卡拉手续费,单位:元")
|
||||||
|
private BigDecimal lkl_fee;
|
||||||
|
|
||||||
@ApiModelProperty(value = "店铺统一设置的打包费")
|
@ApiModelProperty(value = "店铺统一设置的打包费")
|
||||||
private BigDecimal packing_fee;
|
private BigDecimal packing_fee;
|
||||||
|
|
||||||
|
|||||||
@ -74,6 +74,8 @@ public class MchOrderInfoDTO implements Serializable {
|
|||||||
private BigDecimal order_shipping_fee;
|
private BigDecimal order_shipping_fee;
|
||||||
@ApiModelProperty(value = "平台内部配送费")
|
@ApiModelProperty(value = "平台内部配送费")
|
||||||
private BigDecimal order_shipping_fee_inner;
|
private BigDecimal order_shipping_fee_inner;
|
||||||
|
@ApiModelProperty(value = "拉卡拉手续费")
|
||||||
|
private BigDecimal lkl_fee;
|
||||||
@ApiModelProperty(value = "平台费")
|
@ApiModelProperty(value = "平台费")
|
||||||
private BigDecimal platform_fee;
|
private BigDecimal platform_fee;
|
||||||
@ApiModelProperty(value = "店铺统一设置的打包费")
|
@ApiModelProperty(value = "店铺统一设置的打包费")
|
||||||
|
|||||||
@ -0,0 +1,413 @@
|
|||||||
|
package com.suisung.mall.common.pojo.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import org.springframework.data.util.Pair;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.RoundingMode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拉卡拉订单基于总金额分账信息处理类
|
||||||
|
* 实现基于总金额的分账算法,支持平台、代理商和商家的多级分账,类里涉及的金额单位:分
|
||||||
|
* <p>
|
||||||
|
* 分账计算逻辑:
|
||||||
|
* 1、totalSeparateAmount,是必填参数,订单的总金额,必须大于0;lklRatio 是必填参数,拉卡拉的分账比例,如 0.0025
|
||||||
|
* 先减去拉卡拉配送费=lklRatio*totalSeparateAmount(结果四舍五入,保留整数,以下计算结果一律四舍五入),余额得到可分账金额(分) canSeparateAmount
|
||||||
|
* 2、refCanSeparateAmount 是可选参数,如果有效(非空且大于0),往下计算分账基准依据此参数计算(实际的可分账金额A),而不是以 canSeparateAmount 为基准。
|
||||||
|
* 3、shippingFee 是可选参数,如果有效(非空且大于0),往下实际的可分账金额B = 实际的可分账金额A -shippingFee。
|
||||||
|
* 4、实际的可分账金额B 就是平台、一级代理商、二级代理商、商家的可分账金额,按照以下规则进行分账给四个对象。
|
||||||
|
* 5、四个对象之前,需要知道他们的准则:
|
||||||
|
* 6、平台一定参加分账的,如果 platRatio 无效(空值或小于等于0),默认0.01,优先分账,凭条分账金额 =totalSeparateAmount* platRatio。
|
||||||
|
* 7、平台和商家一定参加分账的,一级代理商和二级代理商,如果对应的比例agent1stRatio,agent2ndRatio 有效(非空且大于0)就参与分账,否则不参与。
|
||||||
|
* 8、mchRatio 可以根据分账金额,动态调整到实际比例
|
||||||
|
* 9、所有参与分账的主体,其分账金额都不能为负数,否则将抛出异常。
|
||||||
|
* 10、分账顺序按照优先级:拉卡拉 -> 平台 -> 二级代理商 -> 一级代理商 -> 商家,商家获得剩余的所有金额。
|
||||||
|
* 11、五方分账金额之和不能超过 totalSeparateAmount
|
||||||
|
* 12、分账计算完成后,会计算出 mchRatio 的实际比例
|
||||||
|
* 13、如果商家实际分账比例低于0.2阈值,会抛出异常:商家分账低于阈值
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
public class LklSeparateWithTotalAmountDTO {
|
||||||
|
|
||||||
|
// 常量定义
|
||||||
|
private static final BigDecimal MCH_RATIO_THRESHOLD = new BigDecimal("0.2");
|
||||||
|
|
||||||
|
// 基础金额属性
|
||||||
|
private Integer totalSeparateAmount; // 分账总金额(分)
|
||||||
|
private Integer canSeparateAmount; // 可分账金额(分)
|
||||||
|
private Integer refCanSeparateAmount; // 拉卡拉可分账金额参考(分)
|
||||||
|
private Integer shippingFee; // 配送费(分)
|
||||||
|
|
||||||
|
// 分账比例属性
|
||||||
|
private BigDecimal lklRatio; // 拉卡拉分账比例(如 0.0025=0.25%)
|
||||||
|
private BigDecimal mchRatio; // 商户分账比例(如 0.96=96%)
|
||||||
|
private BigDecimal platRatio; // 平台分账比例(如 0.01=1%)
|
||||||
|
private BigDecimal agent1stRatio; // 一级代理商分账比例(如 0.01=1%)
|
||||||
|
private BigDecimal agent2ndRatio; // 二级代理商分账比例(如 0.03=3%)
|
||||||
|
|
||||||
|
// 分账金额结果属性
|
||||||
|
private Integer lklAmount; // 拉卡拉分账金额(分)
|
||||||
|
private Integer mchAmount; // 商户分账金额(分)
|
||||||
|
private Integer platAmount; // 平台分账金额(分)
|
||||||
|
private Integer agent1stAmount; // 一级代理商分账金额(分)
|
||||||
|
private Integer agent2ndAmount; // 二级代理商分账金额(分)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试方法
|
||||||
|
* 包含多个测试用例,验证分账计算逻辑的正确性和异常处理机制
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) {
|
||||||
|
// 测试用例1: 所有参与方都参与分账(符合比例要求)
|
||||||
|
System.out.println("=== 测试用例1: 所有参与方都参与分账 ===");
|
||||||
|
LklSeparateWithTotalAmountDTO dto1 = new LklSeparateWithTotalAmountDTO();
|
||||||
|
dto1.setTotalSeparateAmount(1500); // 总金额100元(10000分)
|
||||||
|
dto1.setShippingFee(600);
|
||||||
|
// dto1.setRefCanSeparateAmount(1496);
|
||||||
|
dto1.setLklRatio(new BigDecimal("0.0025")); // 拉卡拉分账比例0.25%
|
||||||
|
dto1.setMchRatio(new BigDecimal("0.95")); // 商家分账比例94.75%
|
||||||
|
dto1.setPlatRatio(new BigDecimal("0.01")); // 平台分账比例1%
|
||||||
|
// dto1.setAgent2ndRatio(new BigDecimal("0.04")); // 二级代理商分账比例4%
|
||||||
|
// dto1.setAgent1stRatio(new BigDecimal("0.01")); // 一级代理商分账比例1%
|
||||||
|
|
||||||
|
Pair<Boolean, LklSeparateWithTotalAmountDTO> result = dto1.calculateSeparateAmount();
|
||||||
|
if (result.getFirst()) {
|
||||||
|
System.out.println("分账计算成功:");
|
||||||
|
System.out.println(result.getSecond());
|
||||||
|
System.out.println("JSON格式输出:");
|
||||||
|
System.out.println(result.getSecond().toJSON());
|
||||||
|
} else {
|
||||||
|
System.out.println("分账计算失败");
|
||||||
|
if (result.getSecond() != null) {
|
||||||
|
System.out.println("部分结果:");
|
||||||
|
System.out.println(result.getSecond());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行分账计算逻辑
|
||||||
|
*
|
||||||
|
* @return Pair<Boolean, LklSeparateWithTotalAmountDTO> Boolean表示是否成功,LklSeparateWithTotalAmountDTO为分账结果
|
||||||
|
*/
|
||||||
|
public Pair<Boolean, LklSeparateWithTotalAmountDTO> calculateSeparateAmount() {
|
||||||
|
try {
|
||||||
|
// 参数校验
|
||||||
|
validateInputs();
|
||||||
|
|
||||||
|
// 1. 计算拉卡拉分账金额和可分账金额
|
||||||
|
calculateLklAmountAndCanSeparateAmount();
|
||||||
|
|
||||||
|
// 2. 确定实际可分账金额
|
||||||
|
int actualCanSeparateAmount = determineActualCanSeparateAmount();
|
||||||
|
|
||||||
|
// 3. 计算各参与方分账比例
|
||||||
|
calculateDefaultRatios();
|
||||||
|
|
||||||
|
// 4. 根据优先级顺序计算各参与方分账金额
|
||||||
|
calculateAmountsInPriorityOrder(actualCanSeparateAmount);
|
||||||
|
|
||||||
|
// 5. 校验分账金额总和不能超过总金额
|
||||||
|
validateSeparateAmountTotal();
|
||||||
|
|
||||||
|
// 6. 计算商家实际分账比例
|
||||||
|
calculateActualMchRatio();
|
||||||
|
|
||||||
|
return Pair.of(true, this);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
// 参数校验异常,返回false和当前对象
|
||||||
|
System.err.println("分账计算参数异常: " + e.getMessage());
|
||||||
|
return Pair.of(false, this);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 其他异常,返回false和null
|
||||||
|
System.err.println("分账计算异常: " + e.getMessage());
|
||||||
|
return Pair.of(false, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验必要参数
|
||||||
|
*
|
||||||
|
* @throws IllegalArgumentException 当参数不合法时抛出异常
|
||||||
|
*/
|
||||||
|
private void validateInputs() {
|
||||||
|
// 校验totalSeparateAmount必须为有效值且大于0
|
||||||
|
if (totalSeparateAmount == null || totalSeparateAmount <= 0) {
|
||||||
|
throw new IllegalArgumentException("分账计算缺少必要参数或参数不合法");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 校验必要参数
|
||||||
|
if (lklRatio == null || mchRatio == null) {
|
||||||
|
throw new IllegalArgumentException("分账计算缺少必要参数");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 校验shippingFee不能大于等于totalSeparateAmount
|
||||||
|
if (shippingFee != null && shippingFee >= totalSeparateAmount) {
|
||||||
|
throw new IllegalArgumentException("配送费不能大于等于总金额");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算拉卡拉分账金额和初始可分账金额
|
||||||
|
* 拉卡拉分账金额 = 总金额 * 拉卡拉分账比例(四舍五入)
|
||||||
|
* 可分账金额 = 总金额 - 拉卡拉分账金额
|
||||||
|
*
|
||||||
|
* @throws IllegalArgumentException 当计算出的分账金额为负数时抛出异常
|
||||||
|
*/
|
||||||
|
private void calculateLklAmountAndCanSeparateAmount() {
|
||||||
|
// 拉卡拉分账金额 = 总金额 * 拉卡拉分账比例(四舍五入)
|
||||||
|
lklAmount = lklRatio.multiply(new BigDecimal(totalSeparateAmount))
|
||||||
|
.setScale(0, RoundingMode.HALF_UP)
|
||||||
|
.intValue();
|
||||||
|
|
||||||
|
// 校验拉卡拉分账金额不能为负数
|
||||||
|
if (lklAmount < 0) {
|
||||||
|
// 记录详细日志
|
||||||
|
System.err.println("拉卡拉分账金额计算结果为负数: " + lklAmount);
|
||||||
|
throw new IllegalArgumentException("拉卡拉分账金额计算异常");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 可分账金额 = 总金额 - 拉卡拉分账金额
|
||||||
|
canSeparateAmount = totalSeparateAmount - lklAmount;
|
||||||
|
|
||||||
|
// 校验可分账金额不能为负数
|
||||||
|
if (canSeparateAmount < 0) {
|
||||||
|
// 记录详细日志
|
||||||
|
System.err.println("可分账金额计算结果为负数: " + canSeparateAmount);
|
||||||
|
throw new IllegalArgumentException("可分账金额计算异常");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 确定实际可分账金额
|
||||||
|
* 实际可分账金额A: 如果refCanSeparateAmount有效则使用,否则使用canSeparateAmount
|
||||||
|
* 实际可分账金额B = 实际可分账金额A - 配送费(如果配送费有效)
|
||||||
|
*
|
||||||
|
* @return 实际可分账金额
|
||||||
|
* @throws IllegalArgumentException 当实际可分账金额为负数时抛出异常
|
||||||
|
*/
|
||||||
|
private int determineActualCanSeparateAmount() {
|
||||||
|
// 实际可分账金额A: 如果refCanSeparateAmount有效则使用,否则使用canSeparateAmount
|
||||||
|
int actualCanSeparateAmountA = (refCanSeparateAmount != null && refCanSeparateAmount > 0)
|
||||||
|
? refCanSeparateAmount : canSeparateAmount;
|
||||||
|
|
||||||
|
// 实际可分账金额B = 实际可分账金额A - 配送费(如果配送费有效)
|
||||||
|
int actualCanSeparateAmountB = actualCanSeparateAmountA;
|
||||||
|
if (shippingFee != null && shippingFee > 0) {
|
||||||
|
actualCanSeparateAmountB = actualCanSeparateAmountA - shippingFee;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 校验实际可分账金额不能为负数
|
||||||
|
if (actualCanSeparateAmountB < 0) {
|
||||||
|
// 记录详细日志
|
||||||
|
System.err.println("实际可分账金额计算结果为负数: " + actualCanSeparateAmountB);
|
||||||
|
throw new IllegalArgumentException("实际可分账金额计算异常");
|
||||||
|
}
|
||||||
|
|
||||||
|
return actualCanSeparateAmountB;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算各参与方分账比例
|
||||||
|
* 如果平台比例无效,设置默认值0.01
|
||||||
|
*/
|
||||||
|
private void calculateDefaultRatios() {
|
||||||
|
// 如果平台比例无效,设置默认值0.01
|
||||||
|
if (platRatio == null || platRatio.compareTo(BigDecimal.ZERO) <= 0) {
|
||||||
|
platRatio = new BigDecimal("0.01");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据优先级顺序计算各参与方分账金额
|
||||||
|
* 分账顺序:拉卡拉 -> 平台 -> 二级代理商 -> 一级代理商 -> 商家
|
||||||
|
* 商家获得所有剩余金额
|
||||||
|
*
|
||||||
|
* @param actualCanSeparateAmount 实际可分账金额
|
||||||
|
* @throws IllegalArgumentException 当计算出的分账金额为负数或分账金额超过可用金额时抛出异常
|
||||||
|
*/
|
||||||
|
private void calculateAmountsInPriorityOrder(int actualCanSeparateAmount) {
|
||||||
|
// 重置所有分账金额
|
||||||
|
platAmount = 0;
|
||||||
|
agent1stAmount = 0;
|
||||||
|
agent2ndAmount = 0;
|
||||||
|
mchAmount = 0;
|
||||||
|
|
||||||
|
// 1. 计算拉卡拉分账金额(拉卡拉一定参与分账)
|
||||||
|
lklAmount = lklRatio.multiply(new BigDecimal(totalSeparateAmount))
|
||||||
|
.setScale(0, RoundingMode.HALF_UP)
|
||||||
|
.intValue();
|
||||||
|
|
||||||
|
// 校验拉卡拉分账金额不能为负数
|
||||||
|
if (lklAmount < 0) {
|
||||||
|
throw new IllegalArgumentException("拉卡拉分账金额计算异常");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 校验实际可分账金额不能小于0
|
||||||
|
if (actualCanSeparateAmount < 0) {
|
||||||
|
throw new IllegalArgumentException("实际可分账金额不能为负数");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 初始化剩余金额为实际可分账金额
|
||||||
|
int remainingAmount = actualCanSeparateAmount;
|
||||||
|
|
||||||
|
// 4. 计算平台分账金额(平台一定参与分账)
|
||||||
|
platAmount = platRatio.multiply(new BigDecimal(totalSeparateAmount))
|
||||||
|
.setScale(0, RoundingMode.HALF_UP)
|
||||||
|
.intValue();
|
||||||
|
|
||||||
|
// 校验平台分账金额不能为负数
|
||||||
|
if (platAmount < 0) {
|
||||||
|
throw new IllegalArgumentException("平台分账金额计算异常");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确保不超过剩余金额
|
||||||
|
if (platAmount > remainingAmount) {
|
||||||
|
platAmount = remainingAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新剩余金额
|
||||||
|
remainingAmount -= platAmount;
|
||||||
|
|
||||||
|
// 5. 判断代理商是否参与分账
|
||||||
|
boolean isAgent2ndParticipate = agent2ndRatio != null && agent2ndRatio.compareTo(BigDecimal.ZERO) > 0;
|
||||||
|
boolean isAgent1stParticipate = agent1stRatio != null && agent1stRatio.compareTo(BigDecimal.ZERO) > 0;
|
||||||
|
|
||||||
|
// 6. 按优先级顺序计算代理商分账金额
|
||||||
|
// 优先级:平台 -> 二级代理商 -> 一级代理商
|
||||||
|
if (isAgent2ndParticipate) {
|
||||||
|
// 计算二级代理商分账金额
|
||||||
|
agent2ndAmount = agent2ndRatio.multiply(new BigDecimal(totalSeparateAmount))
|
||||||
|
.setScale(0, RoundingMode.HALF_UP)
|
||||||
|
.intValue();
|
||||||
|
|
||||||
|
// 校验二级代理商分账金额不能为负数
|
||||||
|
if (agent2ndAmount < 0) {
|
||||||
|
throw new IllegalArgumentException("二级代理商分账金额计算异常");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确保不超过剩余金额
|
||||||
|
if (agent2ndAmount > remainingAmount) {
|
||||||
|
agent2ndAmount = remainingAmount;
|
||||||
|
}
|
||||||
|
remainingAmount -= agent2ndAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isAgent1stParticipate) {
|
||||||
|
// 计算一级代理商分账金额
|
||||||
|
agent1stAmount = agent1stRatio.multiply(new BigDecimal(totalSeparateAmount))
|
||||||
|
.setScale(0, RoundingMode.HALF_UP)
|
||||||
|
.intValue();
|
||||||
|
|
||||||
|
// 校验一级代理商分账金额不能为负数
|
||||||
|
if (agent1stAmount < 0) {
|
||||||
|
throw new IllegalArgumentException("一级代理商分账金额计算异常");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确保不超过剩余金额
|
||||||
|
if (agent1stAmount > remainingAmount) {
|
||||||
|
agent1stAmount = remainingAmount;
|
||||||
|
}
|
||||||
|
remainingAmount -= agent1stAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 7. 最后计算商家分账金额(使用剩余所有金额)
|
||||||
|
mchAmount = remainingAmount;
|
||||||
|
|
||||||
|
// 校验商家分账金额不能为负数
|
||||||
|
if (mchAmount < 0) {
|
||||||
|
throw new IllegalArgumentException("商家分账金额计算异常");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算商家实际分账比例
|
||||||
|
*
|
||||||
|
* @throws IllegalArgumentException 当商家实际分账比例低于阈值时抛出异常
|
||||||
|
*/
|
||||||
|
private void calculateActualMchRatio() {
|
||||||
|
if (totalSeparateAmount != null && totalSeparateAmount > 0 && mchAmount != null) {
|
||||||
|
// 计算实际比例,保留6位小数
|
||||||
|
mchRatio = new BigDecimal(mchAmount)
|
||||||
|
.divide(new BigDecimal(totalSeparateAmount), 6, RoundingMode.HALF_UP);
|
||||||
|
|
||||||
|
// 如果计算出的实际比例低于阈值,打印日志并抛出异常
|
||||||
|
if (mchRatio.compareTo(MCH_RATIO_THRESHOLD) < 0) {
|
||||||
|
System.err.println("警告: 商家实际分账比例低于阈值,当前比例: " + mchRatio + ",阈值: " + MCH_RATIO_THRESHOLD);
|
||||||
|
throw new IllegalArgumentException("商家分账低于阈值");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验分账金额总和不能超过总金额
|
||||||
|
*
|
||||||
|
* @throws IllegalArgumentException 当分账金额总和超过总金额时抛出异常
|
||||||
|
*/
|
||||||
|
private void validateSeparateAmountTotal() {
|
||||||
|
int totalAmount = 0;
|
||||||
|
totalAmount += (lklAmount != null ? lklAmount : 0);
|
||||||
|
totalAmount += (platAmount != null ? platAmount : 0);
|
||||||
|
totalAmount += (agent2ndAmount != null ? agent2ndAmount : 0);
|
||||||
|
totalAmount += (agent1stAmount != null ? agent1stAmount : 0);
|
||||||
|
totalAmount += (mchAmount != null ? mchAmount : 0);
|
||||||
|
|
||||||
|
if (totalAmount > totalSeparateAmount) {
|
||||||
|
// 记录详细日志
|
||||||
|
System.err.println("分账金额总和超过总金额,分账金额总和: " + totalAmount + ",总金额: " + totalSeparateAmount);
|
||||||
|
throw new IllegalArgumentException("分账金额总和超过总金额");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成对象的字符串表示
|
||||||
|
*
|
||||||
|
* @return 对象的字符串表示
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "分账计算结果{" +
|
||||||
|
"总分账金额(分) totalSeparateAmount=" + totalSeparateAmount +
|
||||||
|
", 可分账金额(分) canSeparateAmount=" + canSeparateAmount +
|
||||||
|
", 拉卡拉可分账金额参考(分) refCanSeparateAmount=" + refCanSeparateAmount +
|
||||||
|
", 配送费(分) shippingFee=" + shippingFee +
|
||||||
|
", 拉卡拉分账比例 lklRatio=" + lklRatio +
|
||||||
|
", 商户分账比例 mchRatio=" + mchRatio +
|
||||||
|
", 平台分账比例 platRatio=" + platRatio +
|
||||||
|
", 一级代理商分账比例 agent1stRatio=" + agent1stRatio +
|
||||||
|
", 二级代理商分账比例 agent2ndRatio=" + agent2ndRatio +
|
||||||
|
", 拉卡拉分账金额(分) lklAmount=" + lklAmount +
|
||||||
|
", 商户分账金额(分) mchAmount=" + mchAmount +
|
||||||
|
", 平台分账金额(分) platAmount=" + platAmount +
|
||||||
|
", 一级代理商分账金额(分) agent1stAmount=" + agent1stAmount +
|
||||||
|
", 二级代理商分账金额(分) agent2ndAmount=" + agent2ndAmount +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将对象转换为JSON格式字符串
|
||||||
|
*
|
||||||
|
* @return JSON格式字符串
|
||||||
|
*/
|
||||||
|
public String toJSON() {
|
||||||
|
String sb = "{" +
|
||||||
|
"\"totalSeparateAmount\":" + totalSeparateAmount + "," +
|
||||||
|
"\"canSeparateAmount\":" + canSeparateAmount + "," +
|
||||||
|
"\"refCanSeparateAmount\":" + refCanSeparateAmount + "," +
|
||||||
|
"\"shippingFee\":" + shippingFee + "," +
|
||||||
|
"\"lklRatio\":" + (lklRatio != null ? "\"" + lklRatio + "\"" : "null") + "," +
|
||||||
|
"\"mchRatio\":" + (mchRatio != null ? "\"" + mchRatio + "\"" : "null") + "," +
|
||||||
|
"\"platRatio\":" + (platRatio != null ? "\"" + platRatio + "\"" : "null") + "," +
|
||||||
|
"\"agent1stRatio\":" + (agent1stRatio != null ? "\"" + agent1stRatio + "\"" : "null") + "," +
|
||||||
|
"\"agent2ndRatio\":" + (agent2ndRatio != null ? "\"" + agent2ndRatio + "\"" : "null") + "," +
|
||||||
|
"\"lklAmount\":" + lklAmount + "," +
|
||||||
|
"\"mchAmount\":" + mchAmount + "," +
|
||||||
|
"\"platAmount\":" + platAmount + "," +
|
||||||
|
"\"agent1stAmount\":" + agent1stAmount + "," +
|
||||||
|
"\"agent2ndAmount\":" + agent2ndAmount +
|
||||||
|
"}";
|
||||||
|
return sb;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -139,15 +139,27 @@ public class PayController {
|
|||||||
|
|
||||||
@RequestMapping(value = "/saveOrUpdatePayConsumeTrade", method = RequestMethod.POST)
|
@RequestMapping(value = "/saveOrUpdatePayConsumeTrade", method = RequestMethod.POST)
|
||||||
public boolean saveOrUpdatePayConsumeTrade(@RequestBody PayConsumeTrade payConsumeTrade) {
|
public boolean saveOrUpdatePayConsumeTrade(@RequestBody PayConsumeTrade payConsumeTrade) {
|
||||||
boolean flag = false;
|
// 参数校验
|
||||||
try {
|
if (payConsumeTrade == null) {
|
||||||
flag = payConsumeTradeService.saveOrUpdate(payConsumeTrade);
|
logger.warn("[保存或更新交易记录] 参数校验失败:payConsumeTrade 为空");
|
||||||
} catch (Exception e) {
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
boolean flag = payConsumeTradeService.saveOrUpdate(payConsumeTrade);
|
||||||
|
if (flag) {
|
||||||
|
logger.debug("[保存或更新交易记录] 操作成功,tradeId: {}", payConsumeTrade.getConsume_trade_id());
|
||||||
|
} else {
|
||||||
|
logger.warn("[保存或更新交易记录] 操作失败,tradeId: {}", payConsumeTrade.getConsume_trade_id());
|
||||||
|
}
|
||||||
|
return flag;
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("[保存或更新交易记录] 系统异常,tradeId: {}", payConsumeTrade.getConsume_trade_id(), e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return flag;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@RequestMapping(value = "/saveOrUpdatePayUserResource", method = RequestMethod.POST)
|
@RequestMapping(value = "/saveOrUpdatePayUserResource", method = RequestMethod.POST)
|
||||||
public boolean saveOrUpdatePayUserResource(@RequestBody PayUserResource payUserResource) {
|
public boolean saveOrUpdatePayUserResource(@RequestBody PayUserResource payUserResource) {
|
||||||
boolean flag;
|
boolean flag;
|
||||||
|
|||||||
@ -558,25 +558,27 @@ public class LakalaPayServiceImpl implements LakalaPayService {
|
|||||||
log.warn("[拉卡拉退款] 退款金额不合法: refundAmount={}", refundAmount);
|
log.warn("[拉卡拉退款] 退款金额不合法: refundAmount={}", refundAmount);
|
||||||
return Pair.of(false, I18nUtil._("退款金额不合法!"));
|
return Pair.of(false, I18nUtil._("退款金额不合法!"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (StrUtil.hasBlank(lklMerchantNo, lklTermNo)) {
|
||||||
|
// 4. 获取店铺的拉卡拉商户号和终端号
|
||||||
|
ShopStoreBase shopStoreBase = shopService.getLklMerchantNoAndTermNo(storeId);
|
||||||
|
if (shopStoreBase == null) {
|
||||||
|
log.error("[拉卡拉退款] 无法获取店铺信息: storeId={}", storeId);
|
||||||
|
return Pair.of(false, I18nUtil._("无法获取店铺信息,退款失败!"));
|
||||||
|
}
|
||||||
|
|
||||||
// 3. 初始化拉卡拉SDK
|
if (StrUtil.isBlank(shopStoreBase.getLkl_merchant_no()) || StrUtil.isBlank(shopStoreBase.getLkl_term_no())) {
|
||||||
initLKLSDK();
|
log.error("[拉卡拉退款] 无法获取店铺的拉卡拉商户号或终端号: storeId={}, merchantNo={}, termNo={}",
|
||||||
|
storeId, shopStoreBase.getLkl_merchant_no(), shopStoreBase.getLkl_term_no());
|
||||||
|
return Pair.of(false, I18nUtil._("缺少商户号参数,退款失败!"));
|
||||||
|
}
|
||||||
|
|
||||||
// 4. 获取店铺的拉卡拉商户号和终端号
|
// 如果商户号和终端号是空的,
|
||||||
ShopStoreBase shopStoreBase = shopService.getLklMerchantNoAndTermNo(storeId);
|
lklMerchantNo = StrUtil.isBlank(lklMerchantNo) ? shopStoreBase.getLkl_merchant_no() : lklMerchantNo;
|
||||||
if (shopStoreBase == null) {
|
lklTermNo = StrUtil.isBlank(lklTermNo) ? shopStoreBase.getLkl_term_no() : lklTermNo;
|
||||||
log.error("[拉卡拉退款] 无法获取店铺信息: storeId={}", storeId);
|
|
||||||
return Pair.of(false, I18nUtil._("无法获取店铺信息,退款失败!"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (StrUtil.isBlank(shopStoreBase.getLkl_merchant_no()) || StrUtil.isBlank(shopStoreBase.getLkl_term_no())) {
|
|
||||||
log.error("[拉卡拉退款] 无法获取店铺的拉卡拉商户号或终端号: storeId={}, merchantNo={}, termNo={}",
|
|
||||||
storeId, shopStoreBase.getLkl_merchant_no(), shopStoreBase.getLkl_term_no());
|
|
||||||
return Pair.of(false, I18nUtil._("缺少商户号参数,退款失败!"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO 重要的逻辑,获取是否已经分账?已分账:分账退回;查商家账户余额够不够退回?够就执行退回
|
// TODO 重要的逻辑,获取是否已经分账?已分账:分账退回;查商家账户余额够不够退回?够就执行退回
|
||||||
|
|
||||||
if (StrUtil.isBlank(refundReason)) {
|
if (StrUtil.isBlank(refundReason)) {
|
||||||
refundReason = "商家与买方协商退款";
|
refundReason = "商家与买方协商退款";
|
||||||
}
|
}
|
||||||
@ -585,17 +587,16 @@ public class LakalaPayServiceImpl implements LakalaPayService {
|
|||||||
V3LabsRelationRefundRequest refundRequest = new V3LabsRelationRefundRequest();
|
V3LabsRelationRefundRequest refundRequest = new V3LabsRelationRefundRequest();
|
||||||
refundRequest.setOutTradeNo(outTradeNo);
|
refundRequest.setOutTradeNo(outTradeNo);
|
||||||
refundRequest.setOriginTradeNo(originTradeNo);
|
refundRequest.setOriginTradeNo(originTradeNo);
|
||||||
lklMerchantNo = StrUtil.isBlank(lklMerchantNo) ? shopStoreBase.getLkl_merchant_no() : lklMerchantNo;
|
|
||||||
lklTermNo = StrUtil.isBlank(lklTermNo) ? shopStoreBase.getLkl_term_no() : lklTermNo;
|
|
||||||
refundRequest.setMerchantNo(lklMerchantNo);
|
refundRequest.setMerchantNo(lklMerchantNo);
|
||||||
refundRequest.setTermNo(lklTermNo);
|
refundRequest.setTermNo(lklTermNo);
|
||||||
refundRequest.setRefundAmount(refundAmount);
|
refundRequest.setRefundAmount(refundAmount);
|
||||||
refundRequest.setRefundReason(refundReason);
|
refundRequest.setRefundReason(refundReason);
|
||||||
|
|
||||||
refundRequest.setLocationInfo(new V3LabsTradeLocationInfo(requestIp, null, ""));
|
refundRequest.setLocationInfo(new V3LabsTradeLocationInfo(requestIp, null, ""));
|
||||||
|
|
||||||
log.info("[拉卡拉退款] 请求参数: {}", JSONUtil.toJsonStr(refundRequest));
|
log.info("[拉卡拉退款] 请求参数: {}", JSONUtil.toJsonStr(refundRequest));
|
||||||
|
|
||||||
|
// 3. 初始化拉卡拉SDK
|
||||||
|
initLKLSDK();
|
||||||
String responseString = LKLSDK.httpPost(refundRequest);
|
String responseString = LKLSDK.httpPost(refundRequest);
|
||||||
// 6. 处理响应
|
// 6. 处理响应
|
||||||
if (StrUtil.isBlank(responseString)) {
|
if (StrUtil.isBlank(responseString)) {
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@ -291,8 +291,8 @@ public class PayUserPayServiceImpl extends BaseServiceImpl<PayUserPayMapper, Pay
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
if (StrUtil.isBlank(trade_row.getTrade_title())) {
|
if (StrUtil.isBlank(trade_row.getTrade_title())) {
|
||||||
trade_row.setTrade_title("小发同城线上订单商品");
|
trade_row.setTrade_title("小发同城-线上商品");
|
||||||
trade_row.setTrade_desc("小发同城线上订单商品");
|
trade_row.setTrade_desc("小发同城-线上购买的商品");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置店铺ID
|
// 设置店铺ID
|
||||||
@ -671,10 +671,7 @@ public class PayUserPayServiceImpl extends BaseServiceImpl<PayUserPayMapper, Pay
|
|||||||
String requestIP = IpKit.getRealIp(request);
|
String requestIP = IpKit.getRealIp(request);
|
||||||
String notifyUrl = domain + "/lkl_wxPay_notify_url";
|
String notifyUrl = domain + "/lkl_wxPay_notify_url";
|
||||||
String storeIdStr = Convert.toStr(storeId);// 店铺Id
|
String storeIdStr = Convert.toStr(storeId);// 店铺Id
|
||||||
|
|
||||||
// TODO 判断订单有没有运费,有运费请求合单交易,没有运费,请求聚合主扫交易
|
|
||||||
cn.hutool.json.JSONObject lakalaRespJSON = new cn.hutool.json.JSONObject();
|
|
||||||
|
|
||||||
BigDecimal shippingFee = shopService.getOrderShippingFee(out_trade_no);
|
BigDecimal shippingFee = shopService.getOrderShippingFee(out_trade_no);
|
||||||
if (shippingFee == null || shippingFee.intValue() <= 0) {
|
if (shippingFee == null || shippingFee.intValue() <= 0) {
|
||||||
shippingFee = BigDecimal.ZERO;
|
shippingFee = BigDecimal.ZERO;
|
||||||
@ -686,24 +683,25 @@ public class PayUserPayServiceImpl extends BaseServiceImpl<PayUserPayMapper, Pay
|
|||||||
logger.debug("预支付时,查到的订单{},商家配送费:{}元,平台最低配送费要求:{}分", out_trade_no, shippingFee, innerMinDeliverFee);
|
logger.debug("预支付时,查到的订单{},商家配送费:{}元,平台最低配送费要求:{}分", out_trade_no, shippingFee, innerMinDeliverFee);
|
||||||
|
|
||||||
// 平台最低配送费,单位(分)
|
// 平台最低配送费,单位(分)
|
||||||
if (innerMinDeliverFee == null || innerMinDeliverFee.intValue() <= 0) {
|
// if (innerMinDeliverFee == null || innerMinDeliverFee.intValue() <= 0) { // 没有运费
|
||||||
// 没有运费
|
// 内部运费统一由分账接收方收取了 2025-10-11
|
||||||
// 拉卡拉预支付返回参数
|
// 拉卡拉预支付返回参数
|
||||||
lakalaRespJSON = lakalaPayService.lklTransPreOrder(shopStoreBase.getLkl_merchant_no(), shopStoreBase.getLkl_term_no(),
|
|
||||||
appId, openId, storeIdStr, out_trade_no, subject, total_amt,
|
// TODO 判断订单有没有运费,有运费请求合单交易,没有运费,请求聚合主扫交易
|
||||||
notifyUrl,
|
cn.hutool.json.JSONObject lakalaRespJSON = lakalaPayService.lklTransPreOrder(shopStoreBase.getLkl_merchant_no(), shopStoreBase.getLkl_term_no(),
|
||||||
requestIP, trade_remark);
|
appId, openId, storeIdStr, out_trade_no, subject, total_amt,
|
||||||
} else { // 有运费的情况
|
notifyUrl,
|
||||||
// 拉卡拉合单预支付返回参数
|
requestIP, trade_remark);
|
||||||
// RMK 这里只有固定一个运费代理商代收运费,以后代理商模块做好了,要动态读取店铺的运费代理商。
|
// } else { // 有运费的情况
|
||||||
lakalaRespJSON = lakalaPayService.lklTransMergePreOrder(shopStoreBase.getLkl_merchant_no(), shopStoreBase.getLkl_term_no(),
|
// // 拉卡拉合单预支付返回参数
|
||||||
delivery_merchant_no, delivery_term_no, // 以后根据代理商动态分配
|
// // RMK 这里只有固定一个运费代理商代收运费,以后代理商模块做好了,要动态读取店铺的运费代理商。
|
||||||
appId, openId, storeIdStr, out_trade_no, subject, total_amt,
|
// lakalaRespJSON = lakalaPayService.lklTransMergePreOrder(shopStoreBase.getLkl_merchant_no(), shopStoreBase.getLkl_term_no(),
|
||||||
// Convert.toStr(shippingFee.multiply(BigDecimal.valueOf(100)).intValue()),
|
// delivery_merchant_no, delivery_term_no, // 以后根据代理商动态分配
|
||||||
Convert.toStr(innerMinDeliverFee),
|
// appId, openId, storeIdStr, out_trade_no, subject, total_amt,
|
||||||
notifyUrl,
|
// Convert.toStr(innerMinDeliverFee),
|
||||||
requestIP, trade_remark);
|
// notifyUrl,
|
||||||
}
|
// requestIP, trade_remark);
|
||||||
|
// }
|
||||||
|
|
||||||
logger.debug("拉卡拉合单预支付返回参数:{}", lakalaRespJSON);
|
logger.debug("拉卡拉合单预支付返回参数:{}", lakalaRespJSON);
|
||||||
|
|
||||||
|
|||||||
@ -27,12 +27,12 @@ public interface EsignPlatformInfoService {
|
|||||||
EsignPlatformInfo getDistributorInfoById(Long id);
|
EsignPlatformInfo getDistributorInfoById(Long id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据ID获取代理商信息
|
* 根据入驻编号获取平台和代理商信息
|
||||||
*
|
*
|
||||||
* @param ids
|
* @param mchId
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
List<EsignPlatformInfo> getDistributorAndPlatformByIds(Long... ids);
|
List<EsignPlatformInfo> getDistributorAndPlatformByIds(Long mchId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据分类和营业执照号获取平台方信息
|
* 根据分类和营业执照号获取平台方信息
|
||||||
@ -57,4 +57,20 @@ public interface EsignPlatformInfoService {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
Pair<String, String> getEsignPlatformMobileAndLicenseNumber();
|
Pair<String, String> getEsignPlatformMobileAndLicenseNumber();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据入驻编号获取商户的二级代理
|
||||||
|
*
|
||||||
|
* @param mchId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
EsignPlatformInfo getMch2ndAgent(Long mchId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据入驻编号获取商户的二级代理(收运费的代理商)
|
||||||
|
*
|
||||||
|
* @param mchId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
EsignPlatformInfo getMch2ndAgentWithShippingFee(Long mchId);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,18 +13,30 @@ import cn.hutool.core.util.StrUtil;
|
|||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.suisung.mall.common.constant.CommonConstant;
|
import com.suisung.mall.common.constant.CommonConstant;
|
||||||
import com.suisung.mall.common.modules.esign.EsignPlatformInfo;
|
import com.suisung.mall.common.modules.esign.EsignPlatformInfo;
|
||||||
|
import com.suisung.mall.common.modules.store.ShopMchEntry;
|
||||||
|
import com.suisung.mall.common.utils.CheckUtil;
|
||||||
import com.suisung.mall.common.utils.phone.PhoneNumberUtils;
|
import com.suisung.mall.common.utils.phone.PhoneNumberUtils;
|
||||||
import com.suisung.mall.core.web.service.impl.BaseServiceImpl;
|
import com.suisung.mall.core.web.service.impl.BaseServiceImpl;
|
||||||
import com.suisung.mall.shop.esign.mapper.EsignPlatformInfoMapper;
|
import com.suisung.mall.shop.esign.mapper.EsignPlatformInfoMapper;
|
||||||
import com.suisung.mall.shop.esign.service.EsignPlatformInfoService;
|
import com.suisung.mall.shop.esign.service.EsignPlatformInfoService;
|
||||||
|
import com.suisung.mall.shop.store.service.ShopMchEntryService;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.data.util.Pair;
|
import org.springframework.data.util.Pair;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.util.ObjectUtils;
|
import org.springframework.util.ObjectUtils;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
public class EsignPlatformInfoServiceImpl extends BaseServiceImpl<EsignPlatformInfoMapper, EsignPlatformInfo> implements EsignPlatformInfoService {
|
public class EsignPlatformInfoServiceImpl extends BaseServiceImpl<EsignPlatformInfoMapper, EsignPlatformInfo> implements EsignPlatformInfoService {
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
@Resource
|
||||||
|
private ShopMchEntryService shopMchEntryService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据ID获取代理商信息
|
* 根据ID获取代理商信息
|
||||||
*
|
*
|
||||||
@ -51,34 +63,52 @@ public class EsignPlatformInfoServiceImpl extends BaseServiceImpl<EsignPlatformI
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据一个或多个代理商自增ID获取代理商和平台记录,无论怎么都要获取一条平台方的记录
|
* 根据入驻编号获取平台和代理商信息
|
||||||
|
* 无论是否找到代理商,都会返回平台方记录
|
||||||
*
|
*
|
||||||
* @param ids
|
* @param mchId 商户ID
|
||||||
* @return
|
* @return List<EsignPlatformInfo> 平台方和代理商信息列表
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<EsignPlatformInfo> getDistributorAndPlatformByIds(Long... ids) {
|
public List<EsignPlatformInfo> getDistributorAndPlatformByIds(Long mchId) {
|
||||||
|
// 获取平台方记录
|
||||||
QueryWrapper<EsignPlatformInfo> queryWrapper = new QueryWrapper<>();
|
QueryWrapper<EsignPlatformInfo> queryWrapper = new QueryWrapper<>();
|
||||||
queryWrapper.eq("status", CommonConstant.Enable).orderByAsc("level");
|
queryWrapper.eq("level", 0)
|
||||||
if (ids != null && ids.length > 0) {
|
.eq("status", CommonConstant.Enable)
|
||||||
queryWrapper.and(wrapper -> {
|
.orderByAsc("level");
|
||||||
wrapper.in("id", ids).gt("level", 0);
|
|
||||||
wrapper.or(wrapperOr -> {
|
|
||||||
wrapperOr.eq("level", 0);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
queryWrapper.eq("level", 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<EsignPlatformInfo> esignPlatformInfos = list(queryWrapper);
|
List<EsignPlatformInfo> esignPlatformInfos = list(queryWrapper);
|
||||||
if (CollectionUtil.isEmpty(esignPlatformInfos)) {
|
if (CollectionUtil.isEmpty(esignPlatformInfos)) {
|
||||||
|
log.error("[获取平台和代理商信息] 未找到平台方记录");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取商户的二级代理
|
||||||
|
EsignPlatformInfo agent2nd = getMch2ndAgent(mchId);
|
||||||
|
if (agent2nd == null) {
|
||||||
|
return esignPlatformInfos;
|
||||||
|
}
|
||||||
|
|
||||||
|
esignPlatformInfos.add(agent2nd);
|
||||||
|
|
||||||
|
// 获取一级代理(如果存在)
|
||||||
|
if (CheckUtil.isEmpty(agent2nd.getParent_id())) {
|
||||||
|
return esignPlatformInfos;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
EsignPlatformInfo agent1st = get(agent2nd.getParent_id());
|
||||||
|
if (agent1st != null) {
|
||||||
|
esignPlatformInfos.add(agent1st);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("[获取平台和代理商信息] 获取一级代理商时发生异常,parent_id: {}", agent2nd.getParent_id(), e);
|
||||||
|
}
|
||||||
|
|
||||||
return esignPlatformInfos;
|
return esignPlatformInfos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据分类和营业执照号获取平台方信息
|
* 根据分类和营业执照号获取平台方信息
|
||||||
*
|
*
|
||||||
@ -148,4 +178,98 @@ public class EsignPlatformInfoServiceImpl extends BaseServiceImpl<EsignPlatformI
|
|||||||
|
|
||||||
return Pair.of(mobile, esignPlatformInfo.getLicense_number());
|
return Pair.of(mobile, esignPlatformInfo.getLicense_number());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据入驻编号获取商户的二级代理
|
||||||
|
*
|
||||||
|
* @param mchId 商户入驻编号
|
||||||
|
* @return EsignPlatformInfo 二级代理信息,未找到时返回null
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public EsignPlatformInfo getMch2ndAgent(Long mchId) {
|
||||||
|
// 参数校验
|
||||||
|
if (CheckUtil.isEmpty(mchId)) {
|
||||||
|
log.warn("[获取二级代理] 参数校验失败:商户入驻编号为空");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 获取商户入驻信息
|
||||||
|
ShopMchEntry shopMchEntry = shopMchEntryService.shopMerchEntryById(mchId);
|
||||||
|
if (shopMchEntry == null) {
|
||||||
|
log.warn("[获取二级代理] 未找到商户入驻信息,mchId={}", mchId);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否有指定的分销商ID或区域信息
|
||||||
|
if (CheckUtil.isEmpty(shopMchEntry.getDistributor_id()) && StrUtil.isBlank(shopMchEntry.getStore_district())) {
|
||||||
|
log.debug("[获取二级代理] 商户未指定分销商且无区域信息,mchId={}", mchId);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建查询条件
|
||||||
|
QueryWrapper<EsignPlatformInfo> queryWrapper = new QueryWrapper<>();
|
||||||
|
queryWrapper.eq("level", CommonConstant.Agent_Level_2nd)
|
||||||
|
.eq("status", CommonConstant.Enable)
|
||||||
|
.orderByAsc("id");
|
||||||
|
|
||||||
|
// 优先使用指定的分销商ID查询,否则使用区域信息查询
|
||||||
|
if (CheckUtil.isNotEmpty(shopMchEntry.getDistributor_id())) {
|
||||||
|
queryWrapper.eq("id", shopMchEntry.getDistributor_id());
|
||||||
|
log.debug("[获取二级代理] 使用指定分销商ID查询,distributorId={}", shopMchEntry.getDistributor_id());
|
||||||
|
}
|
||||||
|
|
||||||
|
EsignPlatformInfo result = findOne(queryWrapper);
|
||||||
|
if (result == null) {
|
||||||
|
if (StrUtil.isNotBlank(shopMchEntry.getStore_district())) {
|
||||||
|
// 运费代理商
|
||||||
|
queryWrapper.clear();
|
||||||
|
queryWrapper.eq("level", CommonConstant.Agent_Level_2nd)
|
||||||
|
.eq("status", CommonConstant.Enable)
|
||||||
|
.eq("license_district_id", shopMchEntry.getStore_district())
|
||||||
|
.gt("shipping_fee", 0).ne("supplier_id", "")
|
||||||
|
.orderByAsc("id");
|
||||||
|
log.debug("[获取二级代理] 使用区域信息查询,districtId={}", shopMchEntry.getStore_district());
|
||||||
|
|
||||||
|
result = findOne(queryWrapper);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result == null) {
|
||||||
|
log.info("[获取二级代理] 未找到匹配的二级代理信息,mchId={}", mchId);
|
||||||
|
} else {
|
||||||
|
log.debug("[获取二级代理] 成功获取二级代理信息,mchId={}, agentId={}", mchId, result.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("[获取二级代理] 查询过程中发生异常,mchId={}", mchId, e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据入驻编号获取商户的二级代理(收运费的代理商)
|
||||||
|
*
|
||||||
|
* @param mchId 商户入驻编号
|
||||||
|
* @return EsignPlatformInfo 收运费的二级代理信息,未找到或不满足条件时返回null
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public EsignPlatformInfo getMch2ndAgentWithShippingFee(Long mchId) {
|
||||||
|
// 获取商户的二级代理信息
|
||||||
|
EsignPlatformInfo esignPlatformInfo = getMch2ndAgent(mchId);
|
||||||
|
if (esignPlatformInfo == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查该代理是否具备收取运费的条件:设置了运费且有供应商ID
|
||||||
|
if (CheckUtil.isNotEmpty(esignPlatformInfo.getShipping_fee()) &&
|
||||||
|
StrUtil.isNotBlank(esignPlatformInfo.getSupplier_id())) {
|
||||||
|
return esignPlatformInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,7 +11,7 @@ package com.suisung.mall.shop.lakala.service;
|
|||||||
import cn.hutool.json.JSONObject;
|
import cn.hutool.json.JSONObject;
|
||||||
import com.suisung.mall.common.api.CommonResult;
|
import com.suisung.mall.common.api.CommonResult;
|
||||||
import com.suisung.mall.common.modules.store.ShopMchEntry;
|
import com.suisung.mall.common.modules.store.ShopMchEntry;
|
||||||
import com.suisung.mall.common.pojo.dto.LklSeparateDTO;
|
import com.suisung.mall.common.pojo.dto.LklSeparateWithTotalAmountDTO;
|
||||||
import org.springframework.data.util.Pair;
|
import org.springframework.data.util.Pair;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
@ -355,7 +355,6 @@ public interface LakalaApiService {
|
|||||||
/**
|
/**
|
||||||
* 商户分账参数计算及评估
|
* 商户分账参数计算及评估
|
||||||
*
|
*
|
||||||
* @param splitMode 分账模式:1-总金额为基准分账,2-可分账金额基准分账,必填参数
|
|
||||||
* @param orderPayAmount 订单支付总金额(单位:分)必填参数
|
* @param orderPayAmount 订单支付总金额(单位:分)必填参数
|
||||||
* @param shippingFeeInner 平台内部配送费(单位:分)必填参数
|
* @param shippingFeeInner 平台内部配送费(单位:分)必填参数
|
||||||
* @param mchSplitRatioRaw 商户分账比例值(分子值,如10表示10%)必填参数
|
* @param mchSplitRatioRaw 商户分账比例值(分子值,如10表示10%)必填参数
|
||||||
@ -365,13 +364,12 @@ public interface LakalaApiService {
|
|||||||
* @param refCanSeparateAmt 参考可分金额(单位:分) 可选参数
|
* @param refCanSeparateAmt 参考可分金额(单位:分) 可选参数
|
||||||
* @return Pair<Boolean, LklSeparateDTO> 分账参数评估结果,第一个元素表示是否成功,第二个元素为分账参数对象
|
* @return Pair<Boolean, LklSeparateDTO> 分账参数评估结果,第一个元素表示是否成功,第二个元素为分账参数对象
|
||||||
*/
|
*/
|
||||||
Pair<Boolean, LklSeparateDTO> calculateAndEvaluateSharingParams(int splitMode,
|
Pair<Boolean, LklSeparateWithTotalAmountDTO> calculateAndEvaluateSharingParams(Integer orderPayAmount,
|
||||||
Integer orderPayAmount,
|
Integer shippingFeeInner,
|
||||||
Integer shippingFeeInner,
|
BigDecimal mchSplitRatioRaw,
|
||||||
BigDecimal mchSplitRatioRaw,
|
BigDecimal platSplitRatio,
|
||||||
BigDecimal platSplitRatio,
|
BigDecimal agent1stRatio,
|
||||||
BigDecimal agent1stRatio,
|
BigDecimal agent2ndRatio,
|
||||||
BigDecimal agent2ndRatio,
|
Integer refCanSeparateAmt);
|
||||||
Integer refCanSeparateAmt);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -51,6 +51,30 @@ public interface LklLedgerMerReceiverBindService extends IBaseService<LklLedgerM
|
|||||||
*/
|
*/
|
||||||
LklLedgerMerReceiverBind getPlatformByMerCupNo(String merCupNo);
|
LklLedgerMerReceiverBind getPlatformByMerCupNo(String merCupNo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据商户编号查询商户的代理商绑定列表记录
|
||||||
|
*
|
||||||
|
* @param merCupNo
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<LklLedgerMerReceiverBind> selectAgentByMerCupNo(String merCupNo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据商户编号查询商户的一级代理商绑定记录
|
||||||
|
*
|
||||||
|
* @param merCupNo
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
LklLedgerMerReceiverBind getAgent1stByMerCupNo(String merCupNo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据商户编号查询商户的二级代理商绑定记录
|
||||||
|
*
|
||||||
|
* @param merCupNo
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
LklLedgerMerReceiverBind getAgent2ndByMerCupNo(String merCupNo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据申请编号查询一条平台绑定记录
|
* 根据申请编号查询一条平台绑定记录
|
||||||
*
|
*
|
||||||
@ -59,14 +83,6 @@ public interface LklLedgerMerReceiverBindService extends IBaseService<LklLedgerM
|
|||||||
*/
|
*/
|
||||||
LklLedgerMerReceiverBind getMerReceiverByApplyId(String applyId);
|
LklLedgerMerReceiverBind getMerReceiverByApplyId(String applyId);
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据商户编号查询一条代理商绑定记录
|
|
||||||
*
|
|
||||||
* @param merCupNo
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
List<LklLedgerMerReceiverBind> selectDistributorByMerCupNo(String merCupNo);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断商户是否已经绑定了分账接收方
|
* 判断商户是否已经绑定了分账接收方
|
||||||
|
|||||||
@ -43,20 +43,19 @@ public interface LklLedgerReceiverService extends IBaseService<LklLedgerReceiver
|
|||||||
/**
|
/**
|
||||||
* 通过平台方(代理商)记录信息构建申请分账接收方的请求参数
|
* 通过平台方(代理商)记录信息构建申请分账接收方的请求参数
|
||||||
*
|
*
|
||||||
* @param platformId
|
* @param mchId
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
JSONArray buildApplyLedgerReceiverReqParams(Long platformId);
|
JSONArray buildApplyLedgerReceiverReqParams(Long mchId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 内部调用:申请分账接收方
|
* 内部调用:申请分账接收方
|
||||||
*
|
*
|
||||||
* @param mchId
|
* @param mchId
|
||||||
* @param merCupNo
|
* @param merCupNo
|
||||||
* @param platformId
|
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
Boolean innerApplyLedgerReceiver(Long mchId, String merCupNo, Long platformId);
|
Boolean innerApplyLedgerReceiver(Long mchId, String merCupNo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否存在平台方的相关记录信息?
|
* 是否存在平台方的相关记录信息?
|
||||||
|
|||||||
@ -30,16 +30,16 @@ import com.suisung.mall.common.modules.lakala.*;
|
|||||||
import com.suisung.mall.common.modules.order.ShopOrderLkl;
|
import com.suisung.mall.common.modules.order.ShopOrderLkl;
|
||||||
import com.suisung.mall.common.modules.store.ShopMchEntry;
|
import com.suisung.mall.common.modules.store.ShopMchEntry;
|
||||||
import com.suisung.mall.common.modules.store.ShopStoreBase;
|
import com.suisung.mall.common.modules.store.ShopStoreBase;
|
||||||
import com.suisung.mall.common.pojo.dto.LklSeparateDTO;
|
import com.suisung.mall.common.pojo.dto.LklSeparateWithTotalAmountDTO;
|
||||||
import com.suisung.mall.common.service.impl.CommonService;
|
import com.suisung.mall.common.service.impl.CommonService;
|
||||||
import com.suisung.mall.common.utils.*;
|
import com.suisung.mall.common.utils.*;
|
||||||
import com.suisung.mall.core.web.service.RedisService;
|
import com.suisung.mall.core.web.service.RedisService;
|
||||||
|
import com.suisung.mall.shop.esign.service.EsignPlatformInfoService;
|
||||||
import com.suisung.mall.shop.lakala.service.*;
|
import com.suisung.mall.shop.lakala.service.*;
|
||||||
import com.suisung.mall.shop.lakala.utils.LakalaUtil;
|
import com.suisung.mall.shop.lakala.utils.LakalaUtil;
|
||||||
import com.suisung.mall.shop.message.service.PushMessageService;
|
import com.suisung.mall.shop.message.service.PushMessageService;
|
||||||
import com.suisung.mall.shop.message.service.ShopMessageTemplateService;
|
import com.suisung.mall.shop.message.service.ShopMessageTemplateService;
|
||||||
import com.suisung.mall.shop.order.service.ShopOrderBaseService;
|
import com.suisung.mall.shop.order.service.ShopOrderBaseService;
|
||||||
import com.suisung.mall.shop.order.service.ShopOrderInfoService;
|
|
||||||
import com.suisung.mall.shop.order.service.ShopOrderLklService;
|
import com.suisung.mall.shop.order.service.ShopOrderLklService;
|
||||||
import com.suisung.mall.shop.page.service.OssService;
|
import com.suisung.mall.shop.page.service.OssService;
|
||||||
import com.suisung.mall.shop.store.service.ShopMchEntryService;
|
import com.suisung.mall.shop.store.service.ShopMchEntryService;
|
||||||
@ -153,10 +153,14 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
|||||||
@Lazy
|
@Lazy
|
||||||
@Resource
|
@Resource
|
||||||
private ShopOrderBaseService shopOrderBaseService;
|
private ShopOrderBaseService shopOrderBaseService;
|
||||||
|
//
|
||||||
|
// @Lazy
|
||||||
|
// @Resource
|
||||||
|
// private ShopOrderInfoService shopOrderInfoService;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Resource
|
@Resource
|
||||||
private ShopOrderInfoService shopOrderInfoService;
|
private EsignPlatformInfoService esignPlatformInfoService;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Resource
|
@Resource
|
||||||
@ -506,8 +510,8 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
|||||||
ecParams.put("D11", signDate);
|
ecParams.put("D11", signDate);
|
||||||
ecParams.put("D12", signDate);
|
ecParams.put("D12", signDate);
|
||||||
|
|
||||||
Boolean hasAgent = false; // 有无分账代理商?
|
// 如果入驻有代理商推荐码,代理商Id-distributor_id 会大于0(shop_mch_entry->distributor_id)
|
||||||
if (hasAgent) {
|
if (esignPlatformInfoService.getMch2ndAgent(shopMchEntry.getId()) != null) {
|
||||||
ecParams.put("E1", platformName + "和代理商");
|
ecParams.put("E1", platformName + "和代理商");
|
||||||
ecParams.put("E2", "《平台商户入驻服务框架协议》和《小发同城服务费结算》");
|
ecParams.put("E2", "《平台商户入驻服务框架协议》和《小发同城服务费结算》");
|
||||||
} else {
|
} else {
|
||||||
@ -860,7 +864,7 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
|||||||
return JSONUtil.createObj().set("code", "FAIL").set("message", "交易状态未成功,不做任何处理!");
|
return JSONUtil.createObj().set("code", "FAIL").set("message", "交易状态未成功,不做任何处理!");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StrUtil.isBlank(logNo) || StrUtil.isBlank(merchantNo) || StrUtil.isBlank(originTradeNo) || StrUtil.isBlank(originLogNo)) {
|
if (StrUtil.hasBlank(logNo, merchantNo, originTradeNo, originLogNo)) {
|
||||||
log.warn("[确认收货通知] 关键参数为空: logNo={}, merchantNo={}, originTradeNo={}, originLogNo={}",
|
log.warn("[确认收货通知] 关键参数为空: logNo={}, merchantNo={}, originTradeNo={}, originLogNo={}",
|
||||||
logNo, merchantNo, originTradeNo, originLogNo);
|
logNo, merchantNo, originTradeNo, originLogNo);
|
||||||
return JSONUtil.createObj().set("code", "FAIL").set("message", "关键编号返回空值!");
|
return JSONUtil.createObj().set("code", "FAIL").set("message", "关键编号返回空值!");
|
||||||
@ -888,7 +892,7 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
|||||||
}
|
}
|
||||||
log.info("[确认收货通知] 订单信息更新成功: orderId={}", shopOrderLkl.getOrder_id());
|
log.info("[确认收货通知] 订单信息更新成功: orderId={}", shopOrderLkl.getOrder_id());
|
||||||
|
|
||||||
// 发起分账指令
|
// 准备发起分账指令
|
||||||
log.info("[确认收货通知] 开始发起分账指令: merchantNo={}, receiveTradeNo={}, logNo={}",
|
log.info("[确认收货通知] 开始发起分账指令: merchantNo={}, receiveTradeNo={}, logNo={}",
|
||||||
merchantNo, shopOrderLkl.getLkl_receive_trade_no(), logNo);
|
merchantNo, shopOrderLkl.getLkl_receive_trade_no(), logNo);
|
||||||
Pair<Boolean, String> separateResult = innerDoOrderSeparateByMerchantAndLogNo(merchantNo, shopOrderLkl.getLkl_receive_trade_no(), shopOrderLkl.getLkl_receive_log_no());
|
Pair<Boolean, String> separateResult = innerDoOrderSeparateByMerchantAndLogNo(merchantNo, shopOrderLkl.getLkl_receive_trade_no(), shopOrderLkl.getLkl_receive_log_no());
|
||||||
@ -1189,7 +1193,7 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
|||||||
Long receiverCnt = lklLedgerReceiverService.countByCondition("", "", shopMchEntry.getDistributor_id());
|
Long receiverCnt = lklLedgerReceiverService.countByCondition("", "", shopMchEntry.getDistributor_id());
|
||||||
if (receiverCnt <= 0) {
|
if (receiverCnt <= 0) {
|
||||||
// 1:新增一个接收方记录,起码要一个平台方,代理商根据入驻信息新增
|
// 1:新增一个接收方记录,起码要一个平台方,代理商根据入驻信息新增
|
||||||
Boolean success = lklLedgerReceiverService.innerApplyLedgerReceiver(shopMchEntry.getId(), merCupNo, shopMchEntry.getDistributor_id());
|
Boolean success = lklLedgerReceiverService.innerApplyLedgerReceiver(shopMchEntry.getId(), merCupNo);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
return CommonResult.failed("申请分账接收方失败");
|
return CommonResult.failed("申请分账接收方失败");
|
||||||
}
|
}
|
||||||
@ -2274,7 +2278,7 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
|||||||
BigDecimal distributorSplitRatio = BigDecimal.ZERO;
|
BigDecimal distributorSplitRatio = BigDecimal.ZERO;
|
||||||
BigDecimal platformSplitRatio = BigDecimal.ONE;
|
BigDecimal platformSplitRatio = BigDecimal.ONE;
|
||||||
// 分账代理商接收方信息
|
// 分账代理商接收方信息
|
||||||
List<LklLedgerMerReceiverBind> distributorReceivers = lklLedgerMerReceiverBindService.selectDistributorByMerCupNo(merchantNo);
|
List<LklLedgerMerReceiverBind> distributorReceivers = lklLedgerMerReceiverBindService.selectAgentByMerCupNo(merchantNo);
|
||||||
if (distributorReceivers != null && !distributorReceivers.isEmpty()) {
|
if (distributorReceivers != null && !distributorReceivers.isEmpty()) {
|
||||||
distributorSplitRatio = new BigDecimal("0.8");
|
distributorSplitRatio = new BigDecimal("0.8");
|
||||||
platformSplitRatio = new BigDecimal("0.2");
|
platformSplitRatio = new BigDecimal("0.2");
|
||||||
@ -2478,7 +2482,7 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
|||||||
log.info("[分账操作] 查询拉卡拉可分账余额接口:lklMerchantNo={} logDate={} receiveLogNo={} 结果:{}",
|
log.info("[分账操作] 查询拉卡拉可分账余额接口:lklMerchantNo={} logDate={} receiveLogNo={} 结果:{}",
|
||||||
lklMerchantNo, shopOrderLkl.getLkl_log_date(), receiveLogNo, mchCanSplitAmt);
|
lklMerchantNo, shopOrderLkl.getLkl_log_date(), receiveLogNo, mchCanSplitAmt);
|
||||||
|
|
||||||
// 可分账金额
|
// 拉卡拉返回的实际可分账金额
|
||||||
refCanSeparateAmt = Convert.toInt(mchCanSplitAmt.getSecond());
|
refCanSeparateAmt = Convert.toInt(mchCanSplitAmt.getSecond());
|
||||||
if (CheckUtil.isEmpty(refCanSeparateAmt)) {
|
if (CheckUtil.isEmpty(refCanSeparateAmt)) {
|
||||||
log.warn("[分账操作] lklMerchantNo={} receiveTradeNo={} receiveLogNo={} 拉卡拉可分账金额无值或0,系统将自动计算可分账金额",
|
log.warn("[分账操作] lklMerchantNo={} receiveTradeNo={} receiveLogNo={} 拉卡拉可分账金额无值或0,系统将自动计算可分账金额",
|
||||||
@ -2509,35 +2513,39 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
|||||||
return Pair.of(false, "平台方未绑定账户");
|
return Pair.of(false, "平台方未绑定账户");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 获取代理商分账信息
|
// 获取代理商分账信息
|
||||||
BigDecimal platformSplitRatio = BigDecimal.valueOf(0.01);
|
BigDecimal platformSplitRatio = CheckUtil.isEmpty(platformReceiver.getSplit_ratio()) ? BigDecimal.valueOf(0.01) : platformReceiver.getSplit_ratio(); // 默认平台比例 1%
|
||||||
BigDecimal distributorSplitRatio = BigDecimal.ZERO;
|
|
||||||
List<LklLedgerMerReceiverBind> distributorReceivers = lklLedgerMerReceiverBindService.selectDistributorByMerCupNo(merchantNo);
|
LklLedgerMerReceiverBind agent1stReceiver = lklLedgerMerReceiverBindService.getAgent1stByMerCupNo(merchantNo);
|
||||||
if (CollUtil.isNotEmpty(distributorReceivers)) {
|
LklLedgerMerReceiverBind agent2ndReceiver = lklLedgerMerReceiverBindService.getAgent2ndByMerCupNo(merchantNo);
|
||||||
distributorSplitRatio = BigDecimal.valueOf(1).subtract(mchSplitRatio).subtract(platformSplitRatio);
|
|
||||||
log.debug("[分账操作] 检测到代理商存在,调整分账比例: 代理商比例={}, 平台比例={}", distributorSplitRatio, platformSplitRatio);
|
BigDecimal agent1stSplitRatio = null;
|
||||||
} else {
|
BigDecimal agent2ndSplitRatio = null;
|
||||||
platformSplitRatio = BigDecimal.valueOf(1).subtract(mchSplitRatio);
|
if (agent1stReceiver != null) {
|
||||||
distributorSplitRatio = null;
|
agent1stSplitRatio = CheckUtil.isEmpty(agent1stReceiver.getSplit_ratio()) ? BigDecimal.ZERO : agent1stReceiver.getSplit_ratio(); // 默认省级比例
|
||||||
}
|
}
|
||||||
|
|
||||||
// 内部配送费
|
if (agent2ndReceiver != null) {
|
||||||
|
agent2ndSplitRatio = CheckUtil.isEmpty(agent2ndReceiver.getSplit_ratio()) ? BigDecimal.ZERO : agent2ndReceiver.getSplit_ratio(); // 默认市级比例
|
||||||
|
}
|
||||||
|
|
||||||
|
// 内部配送费(单位:分)
|
||||||
Integer shoppingFeeInner = CheckUtil.isEmpty(shopOrderLkl.getShopping_fee_inner()) ? 0 : shopOrderLkl.getShopping_fee_inner();
|
Integer shoppingFeeInner = CheckUtil.isEmpty(shopOrderLkl.getShopping_fee_inner()) ? 0 : shopOrderLkl.getShopping_fee_inner();
|
||||||
|
|
||||||
// 计算拉卡拉手续费、商家分账金额、平台和代理商的分账金额
|
// 计算拉卡拉手续费、商家分账金额、平台和代理商的分账金额
|
||||||
Pair<Boolean, LklSeparateDTO> calcResult = calculateAndEvaluateSharingParams(
|
Pair<Boolean, LklSeparateWithTotalAmountDTO> calcResult = calculateAndEvaluateSharingParams(
|
||||||
CommonConstant.SeparateCalcMode_CanSeparateAmt,
|
|
||||||
shopOrderLkl.getTotal_amt(),
|
shopOrderLkl.getTotal_amt(),
|
||||||
shoppingFeeInner,
|
shoppingFeeInner,
|
||||||
mchSplitRatio,
|
mchSplitRatio,
|
||||||
platformSplitRatio,
|
platformSplitRatio,
|
||||||
null, distributorSplitRatio, refCanSeparateAmt);
|
agent1stSplitRatio, agent2ndSplitRatio, refCanSeparateAmt);
|
||||||
|
|
||||||
if (calcResult == null || !calcResult.getFirst() || calcResult.getSecond() == null) {
|
if (calcResult == null || !calcResult.getFirst() || calcResult.getSecond() == null) {
|
||||||
log.error("[分账操作] 分账参数评估,结果无法分账");
|
log.error("[分账操作] 分账参数评估,结果无法分账");
|
||||||
return Pair.of(false, "分账数据评估,结果无法分账");
|
return Pair.of(false, "分账数据评估,结果无法分账");
|
||||||
}
|
}
|
||||||
LklSeparateDTO lklSeparateDTO = calcResult.getSecond();
|
LklSeparateWithTotalAmountDTO lklSeparateDTO = calcResult.getSecond();
|
||||||
|
|
||||||
log.debug("[分账操作] 分账参数计算结果:{}", lklSeparateDTO);
|
log.debug("[分账操作] 分账参数计算结果:{}", lklSeparateDTO);
|
||||||
|
|
||||||
@ -2550,57 +2558,79 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
|||||||
shopOrderLkl.setSplit_amt_ref(refCanSeparateAmt);
|
shopOrderLkl.setSplit_amt_ref(refCanSeparateAmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 分账金额校验
|
// 可分账金额校验
|
||||||
if (CheckUtil.isEmpty(refCanSeparateAmt)) {
|
if (CheckUtil.isEmpty(refCanSeparateAmt)) {
|
||||||
String errorMsg = String.format("[分账操作] 店铺[%s]订单[%s]分账金额[%d]低于1分钱,跳过分账",
|
String errorMsg = String.format("[分账操作] 店铺[%s]订单[%s]可分账金额[%d]低于1分钱,跳过分账",
|
||||||
shopOrderLkl.getStore_id(), orderId, refCanSeparateAmt);
|
shopOrderLkl.getStore_id(), orderId, refCanSeparateAmt);
|
||||||
log.error(errorMsg);
|
log.error(errorMsg);
|
||||||
if (existingSeparateRecord != null) {
|
if (existingSeparateRecord != null) {
|
||||||
lklOrderSeparateService.updateRemark(existingSeparateRecord.getId(), errorMsg);
|
lklOrderSeparateService.updateRemark(existingSeparateRecord.getId(), errorMsg);
|
||||||
}
|
}
|
||||||
return Pair.of(false, "订单分账金额低于1分钱");
|
return Pair.of(false, "订单可分账金额低于1分钱");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 构建分账接收方列表
|
|
||||||
List<V3SacsSeparateRecvDatas> recvDatas = new ArrayList<>();
|
|
||||||
|
|
||||||
Integer merchantAmount = lklSeparateDTO.getMchAmount();
|
Integer merchantAmount = lklSeparateDTO.getMchAmount();
|
||||||
Integer platformAmount = lklSeparateDTO.getPlatAmount();
|
Integer platformAmount = lklSeparateDTO.getPlatAmount();
|
||||||
Integer agentAmount = lklSeparateDTO.getAgent2ndAmount();
|
Integer agent1stAmount = lklSeparateDTO.getAgent1stAmount();
|
||||||
|
Integer agent2ndAmount = lklSeparateDTO.getAgent2ndAmount();
|
||||||
|
|
||||||
log.info("[分账操作] 金额计算结果:订单={}, 商户={}, 总金额={}分, 可分金额={}分, 商家比例={}, 商家分得={}分, 平台比例={}, 平台分得={}分, 代理商比例={}, 代理商分得={}分",
|
log.info("[分账操作] 金额计算结果:订单={}, 商户={}, 总金额={}分, 可分金额={}分, 商家比例={}, 商家分得={}分, 平台比例={}, 平台分得={}分, 省级代理商比例={}, 省级代理商分得={}分, 县级代理商比例={}, 县级代理商分得={}分",
|
||||||
orderId, merchantNo, shopOrderLkl.getTotal_amt(), refCanSeparateAmt, mchSplitRatio, merchantAmount,
|
orderId, merchantNo, shopOrderLkl.getTotal_amt(), refCanSeparateAmt, mchSplitRatio, merchantAmount,
|
||||||
platformSplitRatio, platformAmount, distributorSplitRatio, agentAmount);
|
platformSplitRatio, platformAmount, agent1stSplitRatio, agent1stAmount, agent2ndSplitRatio, agent2ndAmount);
|
||||||
|
|
||||||
// 构建分账接收方分账参数
|
// 构建分账接收方分账列表参数
|
||||||
|
List<V3SacsSeparateRecvDatas> recvDatas = new ArrayList<>();
|
||||||
// 商家分账参数
|
// 商家分账参数
|
||||||
if (merchantAmount != null && merchantAmount > 0) {
|
if (CheckUtil.isNotEmpty(merchantAmount)) {
|
||||||
V3SacsSeparateRecvDatas receiver = new V3SacsSeparateRecvDatas();
|
V3SacsSeparateRecvDatas receiver = new V3SacsSeparateRecvDatas();
|
||||||
receiver.setRecvMerchantNo(merchantNo);
|
receiver.setRecvMerchantNo(merchantNo);
|
||||||
receiver.setSeparateValue(merchantAmount.toString());
|
receiver.setSeparateValue(Convert.toStr(merchantAmount));
|
||||||
recvDatas.add(receiver);
|
recvDatas.add(receiver);
|
||||||
|
|
||||||
log.debug("[分账操作] 添加商家接收方: merchantNo={}, amount={}", merchantNo, merchantAmount);
|
log.debug("[分账操作] 添加商家接收方: merchantNo={}, amount={}", merchantNo, merchantAmount);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 平台分账参数
|
// 平台分账参数
|
||||||
if (platformAmount != null && platformAmount > 0) {
|
if (CheckUtil.isNotEmpty(platformAmount)) {
|
||||||
V3SacsSeparateRecvDatas receiver = new V3SacsSeparateRecvDatas();
|
V3SacsSeparateRecvDatas receiver = new V3SacsSeparateRecvDatas();
|
||||||
receiver.setRecvNo(platformReceiver.getReceiver_no());
|
receiver.setRecvNo(platformReceiver.getReceiver_no());
|
||||||
receiver.setSeparateValue(platformAmount.toString());
|
receiver.setSeparateValue(Convert.toStr(platformAmount));
|
||||||
recvDatas.add(receiver);
|
recvDatas.add(receiver);
|
||||||
|
|
||||||
log.debug("[分账操作] 添加平台接收方: receiverNo={}, amount={}", platformReceiver.getReceiver_no(), platformAmount);
|
log.debug("[分账操作] 添加平台接收方: receiverNo={}, amount={}", platformReceiver.getReceiver_no(), platformAmount);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 二级代理商(县级)分账参数
|
// 省级代理商分账参数
|
||||||
if (agentAmount != null && agentAmount > 0 && CollUtil.isNotEmpty(distributorReceivers)) {
|
if (agent1stReceiver != null && StrUtil.isNotBlank(agent1stReceiver.getReceiver_no()) && CheckUtil.isNotEmpty(agent1stAmount)) {
|
||||||
LklLedgerMerReceiverBind distributorReceiver = distributorReceivers.get(0);
|
V3SacsSeparateRecvDatas receiver = new V3SacsSeparateRecvDatas();
|
||||||
if (distributorReceiver != null && StrUtil.isNotBlank(distributorReceiver.getReceiver_no())) {
|
receiver.setRecvNo(agent1stReceiver.getReceiver_no());
|
||||||
V3SacsSeparateRecvDatas receiver = new V3SacsSeparateRecvDatas();
|
receiver.setSeparateValue(Convert.toStr(agent1stAmount));
|
||||||
receiver.setRecvNo(distributorReceiver.getReceiver_no());
|
recvDatas.add(receiver);
|
||||||
receiver.setSeparateValue(agentAmount.toString());
|
|
||||||
recvDatas.add(receiver);
|
log.debug("[分账操作] 添加省级代理商接收方: receiverNo={}, amount={}", agent1stReceiver.getReceiver_no(), agent1stAmount);
|
||||||
log.debug("[分账操作] 添加代理商接收方: receiverNo={}, amount={}", distributorReceiver.getReceiver_no(), agentAmount);
|
}
|
||||||
}
|
|
||||||
|
// 县级代理商分账参数
|
||||||
|
if (agent2ndReceiver != null && StrUtil.isNotBlank(agent2ndReceiver.getReceiver_no()) && CheckUtil.isNotEmpty(agent2ndAmount)) {
|
||||||
|
V3SacsSeparateRecvDatas receiver = new V3SacsSeparateRecvDatas();
|
||||||
|
receiver.setRecvNo(agent2ndReceiver.getReceiver_no());
|
||||||
|
receiver.setSeparateValue(Convert.toStr(agent2ndAmount));
|
||||||
|
recvDatas.add(receiver);
|
||||||
|
|
||||||
|
log.debug("[分账操作] 添加县级代理商接收方: receiverNo={}, amount={}", agent2ndReceiver.getReceiver_no(), agent2ndAmount);
|
||||||
|
|
||||||
|
// 有县级代理商的时候,配送费暂由它代收 add 2025-10-11
|
||||||
|
V3SacsSeparateRecvDatas shippingFeeReceiver = new V3SacsSeparateRecvDatas();
|
||||||
|
shippingFeeReceiver.setRecvNo(agent2ndReceiver.getReceiver_no());
|
||||||
|
shippingFeeReceiver.setSeparateValue(Convert.toStr(shoppingFeeInner));
|
||||||
|
recvDatas.add(shippingFeeReceiver);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// 没有县级代理商的时候,配送费暂由平台代收 add 2025-10-11
|
||||||
|
V3SacsSeparateRecvDatas shippingFeeReceiver = new V3SacsSeparateRecvDatas();
|
||||||
|
shippingFeeReceiver.setRecvNo(platformReceiver.getReceiver_no());
|
||||||
|
shippingFeeReceiver.setSeparateValue(Convert.toStr(shoppingFeeInner));
|
||||||
|
recvDatas.add(shippingFeeReceiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 初始化拉卡拉SDK
|
// 初始化拉卡拉SDK
|
||||||
@ -2619,8 +2649,7 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
|||||||
separateRequest.setNotifyUrl(projectDomain + "/api/mobile/shop/lakala/sacs/separateNotify");
|
separateRequest.setNotifyUrl(projectDomain + "/api/mobile/shop/lakala/sacs/separateNotify");
|
||||||
separateRequest.setRecvDatas(recvDatas);
|
separateRequest.setRecvDatas(recvDatas);
|
||||||
|
|
||||||
log.info("[分账操作] 分账接收方数量={}", recvDatas.size());
|
log.debug("[分账操作] 分账接收方数量={},请求详细参数: {}", recvDatas.size(), JSONUtil.toJsonStr(separateRequest));
|
||||||
log.debug("[分账操作] 请求详细参数: {}", JSONUtil.toJsonStr(separateRequest));
|
|
||||||
|
|
||||||
// 发送分账请求
|
// 发送分账请求
|
||||||
log.info("[分账操作] 向拉卡拉发送分账请求:订单={}, 商户={}, 分账流水号={}",
|
log.info("[分账操作] 向拉卡拉发送分账请求:订单={}, 商户={}, 分账流水号={}",
|
||||||
@ -3617,7 +3646,6 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
|||||||
/**
|
/**
|
||||||
* 商户分账参数计算及评估
|
* 商户分账参数计算及评估
|
||||||
*
|
*
|
||||||
* @param splitMode 分账模式:1-总金额为基准分账,2-可分账金额基准分账,必填参数
|
|
||||||
* @param orderPayAmount 订单支付总金额(单位:分)必填参数
|
* @param orderPayAmount 订单支付总金额(单位:分)必填参数
|
||||||
* @param shippingFeeInner 平台内部配送费(单位:分)必填参数
|
* @param shippingFeeInner 平台内部配送费(单位:分)必填参数
|
||||||
* @param mchSplitRatioRaw 商户分账比例值(分子值,如10表示10%)必填参数
|
* @param mchSplitRatioRaw 商户分账比例值(分子值,如10表示10%)必填参数
|
||||||
@ -3628,17 +3656,17 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
|||||||
* @return Pair<Boolean, LklSeparateDTO> 分账参数评估结果,第一个元素表示是否成功,第二个元素为分账参数对象
|
* @return Pair<Boolean, LklSeparateDTO> 分账参数评估结果,第一个元素表示是否成功,第二个元素为分账参数对象
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Pair<Boolean, LklSeparateDTO> calculateAndEvaluateSharingParams(int splitMode,
|
public Pair<Boolean, LklSeparateWithTotalAmountDTO> calculateAndEvaluateSharingParams(
|
||||||
Integer orderPayAmount,
|
Integer orderPayAmount,
|
||||||
Integer shippingFeeInner,
|
Integer shippingFeeInner,
|
||||||
BigDecimal mchSplitRatioRaw,
|
BigDecimal mchSplitRatioRaw,
|
||||||
BigDecimal platSplitRatio,
|
BigDecimal platSplitRatio,
|
||||||
BigDecimal agent1stRatio,
|
BigDecimal agent1stRatio,
|
||||||
BigDecimal agent2ndRatio,
|
BigDecimal agent2ndRatio,
|
||||||
Integer refCanSeparateAmt) {
|
Integer refCanSeparateAmt) {
|
||||||
log.debug("[分账参数计算] 开始计算分账参数: splitMode={}, orderPayAmount={}, shippingFeeInner={}, " +
|
log.debug("[分账参数计算] 开始计算分账参数: orderPayAmount={}, shippingFeeInner={}, " +
|
||||||
"mchSplitRatioRaw={}, platSplitRatio={}, agent1stRatio={}, agent2ndRatio={}, refCanSeparateAmt={}",
|
"mchSplitRatioRaw={}, platSplitRatio={}, agent1stRatio={}, agent2ndRatio={}, refCanSeparateAmt={}",
|
||||||
splitMode, orderPayAmount, shippingFeeInner, mchSplitRatioRaw, platSplitRatio,
|
orderPayAmount, shippingFeeInner, mchSplitRatioRaw, platSplitRatio,
|
||||||
agent1stRatio, agent2ndRatio, refCanSeparateAmt);
|
agent1stRatio, agent2ndRatio, refCanSeparateAmt);
|
||||||
|
|
||||||
// 参数校验
|
// 参数校验
|
||||||
@ -3652,10 +3680,6 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
|||||||
return Pair.of(false, null);
|
return Pair.of(false, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (splitMode != 1 && splitMode != 2) {
|
|
||||||
log.warn("[分账参数计算] 分账模式参数错误: splitMode={}", splitMode);
|
|
||||||
return Pair.of(false, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 计算商家分账比例(转换为小数)
|
// 计算商家分账比例(转换为小数)
|
||||||
BigDecimal mchSplitRatio = mchSplitRatioRaw.divide(new BigDecimal(100));
|
BigDecimal mchSplitRatio = mchSplitRatioRaw.divide(new BigDecimal(100));
|
||||||
@ -3674,7 +3698,7 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
|||||||
log.debug("[分账参数计算] 配送费: {}, 拉卡拉费率: {}", actualShippingFeeInner, wxFeeRatio);
|
log.debug("[分账参数计算] 配送费: {}, 拉卡拉费率: {}", actualShippingFeeInner, wxFeeRatio);
|
||||||
|
|
||||||
// 构建分账参数对象
|
// 构建分账参数对象
|
||||||
LklSeparateDTO lklSeparateDTO = new LklSeparateDTO();
|
LklSeparateWithTotalAmountDTO lklSeparateDTO = new LklSeparateWithTotalAmountDTO();
|
||||||
lklSeparateDTO.setTotalSeparateAmount(orderPayAmount);
|
lklSeparateDTO.setTotalSeparateAmount(orderPayAmount);
|
||||||
lklSeparateDTO.setShippingFee(actualShippingFeeInner);
|
lklSeparateDTO.setShippingFee(actualShippingFeeInner);
|
||||||
lklSeparateDTO.setLklRatio(wxFeeRatio); // 拉卡拉给的微信分账比例 0.0025 千分之2.5
|
lklSeparateDTO.setLklRatio(wxFeeRatio); // 拉卡拉给的微信分账比例 0.0025 千分之2.5
|
||||||
@ -3698,25 +3722,20 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
|||||||
log.debug("[分账参数计算] 设置参考可分账金额: {}", refCanSeparateAmt);
|
log.debug("[分账参数计算] 设置参考可分账金额: {}", refCanSeparateAmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 根据分账模式执行不同的分账计算
|
try {
|
||||||
LklSeparateDTO.SharingResult canSeparateAmtResult;
|
// 根据分账模式执行不同的分账计算
|
||||||
if (splitMode == 1) {
|
Pair<Boolean, LklSeparateWithTotalAmountDTO> canSeparateAmtResult = lklSeparateDTO.calculateSeparateAmount();
|
||||||
// 总金额为基准分账
|
if (!canSeparateAmtResult.getFirst()) {
|
||||||
log.debug("[分账参数计算] 使用总金额为基准分账模式");
|
log.warn("[分账参数计算] 分账参数有误,分账估算失败");
|
||||||
canSeparateAmtResult = lklSeparateDTO.sharingOnTotalAmount();
|
return Pair.of(false, lklSeparateDTO);
|
||||||
} else {
|
}
|
||||||
// 可分金额基准分账
|
|
||||||
log.debug("[分账参数计算] 使用可分账金额基准分账模式");
|
|
||||||
canSeparateAmtResult = lklSeparateDTO.sharingOnCanSeparateAmount();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!canSeparateAmtResult.isSuccess()) {
|
log.info("[分账参数计算] 分账估算成功, result={}", lklSeparateDTO);
|
||||||
log.warn("[分账参数计算] 分账参数评估失败: {}", canSeparateAmtResult.getErrorMessage());
|
return Pair.of(true, lklSeparateDTO);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("[分账参数计算] 分账参数有误,分账估算失败", e);
|
||||||
return Pair.of(false, lklSeparateDTO);
|
return Pair.of(false, lklSeparateDTO);
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info("[分账参数计算] 分账参数计算评估成功, result={}", lklSeparateDTO);
|
|
||||||
return Pair.of(true, lklSeparateDTO);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -112,44 +112,98 @@ public class LklLedgerMerReceiverBindServiceImpl extends BaseServiceImpl<LklLedg
|
|||||||
/**
|
/**
|
||||||
* 根据商户编号查询多条平台或代理商记录
|
* 根据商户编号查询多条平台或代理商记录
|
||||||
*
|
*
|
||||||
* @param merCupNo
|
* @param merCupNo 商户银联编号
|
||||||
* @param isPlatform 是否平台
|
* @param isPlatform 是否平台(true:平台, false:代理商, null:不区分)
|
||||||
* @return
|
* @return 符合条件的记录列表
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<LklLedgerMerReceiverBind> selectListByMerCupNo(String merCupNo, Boolean isPlatform) {
|
public List<LklLedgerMerReceiverBind> selectListByMerCupNo(String merCupNo, Boolean isPlatform) {
|
||||||
if (StrUtil.isBlank(merCupNo)) {
|
if (StrUtil.isBlank(merCupNo)) {
|
||||||
return null;
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
QueryWrapper<LklLedgerMerReceiverBind> queryWrapper = new QueryWrapper<>();
|
QueryWrapper<LklLedgerMerReceiverBind> queryWrapper = new QueryWrapper<>();
|
||||||
queryWrapper.eq("mer_cup_no", merCupNo)
|
queryWrapper.eq("mer_cup_no", merCupNo)
|
||||||
.eq("audit_status", CommonConstant.Enable);
|
.eq("audit_status", CommonConstant.Enable)
|
||||||
if (isPlatform != null && isPlatform) {
|
.orderByAsc("id");
|
||||||
queryWrapper.eq("platform_id", 0);
|
|
||||||
} else if (isPlatform != null && !isPlatform) {
|
if (isPlatform != null) {
|
||||||
queryWrapper.gt("platform_id", 0);
|
if (isPlatform) {
|
||||||
|
queryWrapper.eq("platform_id", 0);
|
||||||
|
} else {
|
||||||
|
queryWrapper.gt("platform_id", 0)
|
||||||
|
.in("level", CommonConstant.Agent_Level_1st, CommonConstant.Agent_Level_2nd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
queryWrapper.orderByAsc("id");
|
|
||||||
|
|
||||||
return list(queryWrapper);
|
return list(queryWrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据商户编号查询一条平台绑定记录
|
* 根据商户编号查询一条平台绑定记录
|
||||||
*
|
*
|
||||||
* @param merCupNo
|
* @param merCupNo 商户银联编号
|
||||||
* @return
|
* @return 平台绑定记录,不存在时返回null
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public LklLedgerMerReceiverBind getPlatformByMerCupNo(String merCupNo) {
|
public LklLedgerMerReceiverBind getPlatformByMerCupNo(String merCupNo) {
|
||||||
List<LklLedgerMerReceiverBind> list = selectListByMerCupNo(merCupNo, true);
|
List<LklLedgerMerReceiverBind> list = selectListByMerCupNo(merCupNo, true);
|
||||||
if (CollectionUtil.isEmpty(list)) {
|
return CollectionUtil.isEmpty(list) ? null : list.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据商户编号查询代理商绑定记录列表
|
||||||
|
*
|
||||||
|
* @param merCupNo 商户银联编号
|
||||||
|
* @return 代理商绑定记录列表,不存在时返回空列表
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<LklLedgerMerReceiverBind> selectAgentByMerCupNo(String merCupNo) {
|
||||||
|
return selectListByMerCupNo(merCupNo, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据商户编号查询一级代理商绑定记录
|
||||||
|
*
|
||||||
|
* @param merCupNo 商户银联编号
|
||||||
|
* @return 一级代理商绑定记录,不存在时返回null
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public LklLedgerMerReceiverBind getAgent1stByMerCupNo(String merCupNo) {
|
||||||
|
if (StrUtil.isBlank(merCupNo)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return list.get(0);
|
QueryWrapper<LklLedgerMerReceiverBind> queryWrapper = new QueryWrapper<>();
|
||||||
|
queryWrapper.eq("mer_cup_no", merCupNo)
|
||||||
|
.eq("audit_status", CommonConstant.Enable)
|
||||||
|
.gt("platform_id", 0)
|
||||||
|
.eq("level", CommonConstant.Agent_Level_1st)
|
||||||
|
.orderByAsc("id");
|
||||||
|
|
||||||
|
return findOne(queryWrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据商户编号查询二级代理商绑定记录
|
||||||
|
*
|
||||||
|
* @param merCupNo 商户银联编号
|
||||||
|
* @return 二级代理商绑定记录,不存在时返回null
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public LklLedgerMerReceiverBind getAgent2ndByMerCupNo(String merCupNo) {
|
||||||
|
if (StrUtil.isBlank(merCupNo)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryWrapper<LklLedgerMerReceiverBind> queryWrapper = new QueryWrapper<>();
|
||||||
|
queryWrapper.eq("mer_cup_no", merCupNo)
|
||||||
|
.eq("audit_status", CommonConstant.Enable)
|
||||||
|
.gt("platform_id", 0)
|
||||||
|
.eq("level", CommonConstant.Agent_Level_2nd)
|
||||||
|
.orderByAsc("id");
|
||||||
|
|
||||||
|
return findOne(queryWrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -170,21 +224,6 @@ public class LklLedgerMerReceiverBindServiceImpl extends BaseServiceImpl<LklLedg
|
|||||||
return findOne(queryWrapper);
|
return findOne(queryWrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据商户编号查询一条代理商绑定记录
|
|
||||||
*
|
|
||||||
* @param merCupNo
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public List<LklLedgerMerReceiverBind> selectDistributorByMerCupNo(String merCupNo) {
|
|
||||||
List<LklLedgerMerReceiverBind> list = selectListByMerCupNo(merCupNo, false);
|
|
||||||
if (CollectionUtil.isEmpty(list)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断商户是否已经绑定了分账接收方
|
* 判断商户是否已经绑定了分账接收方
|
||||||
|
|||||||
@ -32,7 +32,6 @@ import org.springframework.context.annotation.Lazy;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@ -137,21 +136,19 @@ public class LklLedgerReceiverServiceImpl extends BaseServiceImpl<LklLedgerRecei
|
|||||||
* 通过平台方(代理商) ID 记录信息转成 Lakala 接收方记录
|
* 通过平台方(代理商) ID 记录信息转成 Lakala 接收方记录
|
||||||
* 平台方一定要获取,如果有代理商也要获取
|
* 平台方一定要获取,如果有代理商也要获取
|
||||||
*
|
*
|
||||||
* @param distributorId 代理商id(非平台Id)
|
* @param mchId 商户id
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public JSONArray buildApplyLedgerReceiverReqParams(Long distributorId) {
|
public JSONArray buildApplyLedgerReceiverReqParams(Long mchId) {
|
||||||
List<Long> ids = new ArrayList<>();
|
|
||||||
if (distributorId != null && distributorId > 0) {
|
|
||||||
ids.add(distributorId);
|
|
||||||
}
|
|
||||||
// 获取平台记录和代理商记录
|
// 获取平台记录和代理商记录
|
||||||
List<EsignPlatformInfo> esignPlatformInfoList = esignPlatformInfoService.getDistributorAndPlatformByIds(ids.toArray(new Long[0]));
|
List<EsignPlatformInfo> esignPlatformInfoList = esignPlatformInfoService.getDistributorAndPlatformByIds(mchId);
|
||||||
if (CollectionUtil.isEmpty(esignPlatformInfoList)) {
|
if (CollectionUtil.isEmpty(esignPlatformInfoList)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
JSONArray reqParams = new JSONArray();
|
JSONArray reqParams = new JSONArray();
|
||||||
for (EsignPlatformInfo esignPlatformInfo : esignPlatformInfoList) {
|
for (EsignPlatformInfo esignPlatformInfo : esignPlatformInfoList) {
|
||||||
JSONObject reqParam = new JSONObject();
|
JSONObject reqParam = new JSONObject();
|
||||||
@ -216,14 +213,14 @@ public class LklLedgerReceiverServiceImpl extends BaseServiceImpl<LklLedgerRecei
|
|||||||
* 内部调用:申请一个或多个分账接收方(平台方和代理商)
|
* 内部调用:申请一个或多个分账接收方(平台方和代理商)
|
||||||
*
|
*
|
||||||
* @param mchId
|
* @param mchId
|
||||||
* @param merCupNo 用于标记接收方绑定merCupNo商家
|
* @param merCupNo 用于标记接收方绑定merCupNo商家
|
||||||
* @param distributorId 代理商id(非平台id)
|
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Boolean innerApplyLedgerReceiver(Long mchId, String merCupNo, Long distributorId) {
|
public Boolean innerApplyLedgerReceiver(Long mchId, String merCupNo) {
|
||||||
// 接收方至少有一个平台方
|
// 接收方至少有一个平台方
|
||||||
JSONArray buildApplyLedgerReceiverReqParams = buildApplyLedgerReceiverReqParams(distributorId);
|
JSONArray buildApplyLedgerReceiverReqParams = buildApplyLedgerReceiverReqParams(mchId);
|
||||||
|
|
||||||
if (buildApplyLedgerReceiverReqParams == null || buildApplyLedgerReceiverReqParams.isEmpty()) {
|
if (buildApplyLedgerReceiverReqParams == null || buildApplyLedgerReceiverReqParams.isEmpty()) {
|
||||||
log.error("先新增平台或代理商信息");
|
log.error("先新增平台或代理商信息");
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@ -741,7 +741,7 @@ public class LklTkServiceImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 2:新增一个接收方记录,起码要一个平台方,代理商根据入驻信息新增
|
// 2:新增一个接收方记录,起码要一个平台方,代理商根据入驻信息新增
|
||||||
Boolean genSuccess = lklLedgerReceiverService.innerApplyLedgerReceiver(mchId, merCupNo, distributorId);
|
Boolean genSuccess = lklLedgerReceiverService.innerApplyLedgerReceiver(mchId, merCupNo);
|
||||||
if (!genSuccess) {
|
if (!genSuccess) {
|
||||||
logger.error("进件、申请分账业务成功已成功,等待拉卡拉审核分账业务请求,但创建分账接收方失败了,请管理员补偿流程");
|
logger.error("进件、申请分账业务成功已成功,等待拉卡拉审核分账业务请求,但创建分账接收方失败了,请管理员补偿流程");
|
||||||
shopMchEntryService.updateMerchEntryApprovalByMchId(mchId, null,
|
shopMchEntryService.updateMerchEntryApprovalByMchId(mchId, null,
|
||||||
|
|||||||
@ -56,7 +56,7 @@ import com.suisung.mall.common.modules.product.ShopProductItem;
|
|||||||
import com.suisung.mall.common.modules.product.ShopProductValidPeriod;
|
import com.suisung.mall.common.modules.product.ShopProductValidPeriod;
|
||||||
import com.suisung.mall.common.modules.store.*;
|
import com.suisung.mall.common.modules.store.*;
|
||||||
import com.suisung.mall.common.modules.user.*;
|
import com.suisung.mall.common.modules.user.*;
|
||||||
import com.suisung.mall.common.pojo.dto.LklSeparateDTO;
|
import com.suisung.mall.common.pojo.dto.LklSeparateWithTotalAmountDTO;
|
||||||
import com.suisung.mall.common.pojo.dto.StandardAddressDTO;
|
import com.suisung.mall.common.pojo.dto.StandardAddressDTO;
|
||||||
import com.suisung.mall.common.pojo.dto.WxOrderBaseInfoDTO;
|
import com.suisung.mall.common.pojo.dto.WxOrderBaseInfoDTO;
|
||||||
import com.suisung.mall.common.pojo.req.*;
|
import com.suisung.mall.common.pojo.req.*;
|
||||||
@ -3303,7 +3303,7 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
|||||||
|
|
||||||
// RMK 第三方数据同步相关:redis 给这个商品减去对应的库存
|
// RMK 第三方数据同步相关:redis 给这个商品减去对应的库存
|
||||||
Map<String, Integer> stockDeltaMap = new HashMap<>();
|
Map<String, Integer> stockDeltaMap = new HashMap<>();
|
||||||
stockDeltaMap.put(item_src_id+"_"+order_item_row.getOrder_id(), -order_item_quantity);
|
stockDeltaMap.put(item_src_id + "_" + order_item_row.getOrder_id(), -order_item_quantity);
|
||||||
syncThirdDataService.incrProductStockToRedis(stockDeltaMap);
|
syncThirdDataService.incrProductStockToRedis(stockDeltaMap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4226,7 +4226,7 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
|||||||
log.debug("释放库存Item_src_id:{},数量:{}", shopProductItem.getItem_src_id(), order_item_quantity);
|
log.debug("释放库存Item_src_id:{},数量:{}", shopProductItem.getItem_src_id(), order_item_quantity);
|
||||||
// RMK 第三方数据同步相关:redis 给这个商品加上对应的库存
|
// RMK 第三方数据同步相关:redis 给这个商品加上对应的库存
|
||||||
Map<String, Integer> stockDeltaMap = new HashMap<>();
|
Map<String, Integer> stockDeltaMap = new HashMap<>();
|
||||||
stockDeltaMap.put(shopProductItem.getItem_src_id()+"_"+order_item_row.getOrder_id(), order_item_quantity);
|
stockDeltaMap.put(shopProductItem.getItem_src_id() + "_" + order_item_row.getOrder_id(), order_item_quantity);
|
||||||
syncThirdDataService.incrProductStockToRedis(stockDeltaMap);
|
syncThirdDataService.incrProductStockToRedis(stockDeltaMap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6523,7 +6523,20 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
|||||||
|
|
||||||
// 订单信息保存处理
|
// 订单信息保存处理
|
||||||
if (flag) {
|
if (flag) {
|
||||||
String product_item_name = item_items.stream().map(s -> Convert.toStr(s.get("product_item_name"))).collect(Collectors.joining("|"));
|
// 订单商品标题
|
||||||
|
// String product_item_name = item_items.stream().map(s -> Convert.toStr(s.get("product_item_name"))).collect(Collectors.joining("|"));
|
||||||
|
String product_item_name = "";
|
||||||
|
if (CollUtil.isNotEmpty(item_items)) {
|
||||||
|
String firstProductName = Convert.toStr(item_items.get(0).get("product_item_name"));
|
||||||
|
if (StrUtil.isNotBlank(firstProductName)) {
|
||||||
|
// 限制长度,防止超出字段限制
|
||||||
|
if (firstProductName.length() > 100) {
|
||||||
|
firstProductName = firstProductName.substring(0, 100);
|
||||||
|
}
|
||||||
|
product_item_name = firstProductName + "等商品";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Integer subsite_id = (Integer) store_item.get("subsite_id");
|
Integer subsite_id = (Integer) store_item.get("subsite_id");
|
||||||
Integer store_is_selfsupport = (Integer) store_item.get("store_is_selfsupport");
|
Integer store_is_selfsupport = (Integer) store_item.get("store_is_selfsupport");
|
||||||
Integer payment_type_id = (Integer) checkout_row.get("payment_type_id");
|
Integer payment_type_id = (Integer) checkout_row.get("payment_type_id");
|
||||||
@ -7244,7 +7257,7 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
|||||||
// RMK 第三方数据同步相关:redis 给这个商品减去上对应的库存
|
// RMK 第三方数据同步相关:redis 给这个商品减去上对应的库存
|
||||||
log.debug("减库存Item_src_id:{},数量:{}", item_src_id, cart_quantity);
|
log.debug("减库存Item_src_id:{},数量:{}", item_src_id, cart_quantity);
|
||||||
Map<String, Integer> stockDeltaMap = new HashMap<>();
|
Map<String, Integer> stockDeltaMap = new HashMap<>();
|
||||||
stockDeltaMap.put(item_src_id+"_"+order_id, -cart_quantity);
|
stockDeltaMap.put(item_src_id + "_" + order_id, -cart_quantity);
|
||||||
syncThirdDataService.incrProductStockToRedis(stockDeltaMap);
|
syncThirdDataService.incrProductStockToRedis(stockDeltaMap);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -7679,8 +7692,7 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
|||||||
BigDecimal storeSplitRatio = shopStoreBaseService.getStoreSplitRatio(store_id, false);
|
BigDecimal storeSplitRatio = shopStoreBaseService.getStoreSplitRatio(store_id, false);
|
||||||
|
|
||||||
// 计算平台和代理商的分账金额
|
// 计算平台和代理商的分账金额
|
||||||
Pair<Boolean, LklSeparateDTO> calcResult = lakalaApiService.calculateAndEvaluateSharingParams(
|
Pair<Boolean, LklSeparateWithTotalAmountDTO> calcResult = lakalaApiService.calculateAndEvaluateSharingParams(
|
||||||
CommonConstant.SeparateCalcMode_CanSeparateAmt,
|
|
||||||
Convert.toInt(order_payment_amount.multiply(BigDecimal.valueOf(100))),
|
Convert.toInt(order_payment_amount.multiply(BigDecimal.valueOf(100))),
|
||||||
innerMinDeliverFee,
|
innerMinDeliverFee,
|
||||||
storeSplitRatio,
|
storeSplitRatio,
|
||||||
@ -7690,25 +7702,29 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
|||||||
// 计算平台费
|
// 计算平台费
|
||||||
if (calcResult != null && calcResult.getFirst() && calcResult.getSecond() != null) {
|
if (calcResult != null && calcResult.getFirst() && calcResult.getSecond() != null) {
|
||||||
try {
|
try {
|
||||||
LklSeparateDTO lklSeparateDTO = calcResult.getSecond();
|
LklSeparateWithTotalAmountDTO lklSeparateDTO = calcResult.getSecond();
|
||||||
// 确保分账金额不为负数
|
// 确保分账金额不为负数
|
||||||
BigDecimal totalSeparateAmount = BigDecimal.valueOf(lklSeparateDTO.getCanSeparateAmount())
|
BigDecimal totalSeparateAmount = BigDecimal.valueOf(lklSeparateDTO.getCanSeparateAmount())
|
||||||
.divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
|
.divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
|
||||||
BigDecimal platformFee = BigDecimal.valueOf(lklSeparateDTO.getPlatAmount() + lklSeparateDTO.getAgent1stAmount() + lklSeparateDTO.getAgent2ndAmount())
|
BigDecimal platformFee = BigDecimal.valueOf(lklSeparateDTO.getPlatAmount() + lklSeparateDTO.getAgent1stAmount() + lklSeparateDTO.getAgent2ndAmount())
|
||||||
.divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
|
.divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
|
||||||
|
BigDecimal lklFee = BigDecimal.valueOf(lklSeparateDTO.getLklAmount()).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
|
||||||
|
|
||||||
// 防止负值
|
// 防止负值
|
||||||
data_row.setTotal_separate_value(totalSeparateAmount.max(BigDecimal.ZERO));
|
data_row.setTotal_separate_value(totalSeparateAmount.max(BigDecimal.ZERO));
|
||||||
data_row.setPlatform_fee(platformFee.max(BigDecimal.ZERO));
|
data_row.setPlatform_fee(platformFee.max(BigDecimal.ZERO));
|
||||||
|
data_row.setLkl_fee(lklFee.max(BigDecimal.ZERO));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.warn("分账金额计算异常,使用默认值: {}", e.getMessage());
|
log.warn("分账金额计算异常,使用默认值: {}", e.getMessage());
|
||||||
data_row.setTotal_separate_value(BigDecimal.ZERO);
|
data_row.setTotal_separate_value(BigDecimal.ZERO);
|
||||||
data_row.setPlatform_fee(BigDecimal.ZERO);
|
data_row.setPlatform_fee(BigDecimal.ZERO);
|
||||||
|
data_row.setLkl_fee(BigDecimal.ZERO);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.warn("拉卡拉分账参数计算失败,使用默认值");
|
log.warn("拉卡拉分账参数计算失败,使用默认值");
|
||||||
data_row.setTotal_separate_value(BigDecimal.ZERO);
|
data_row.setTotal_separate_value(BigDecimal.ZERO);
|
||||||
data_row.setPlatform_fee(BigDecimal.ZERO);
|
data_row.setPlatform_fee(BigDecimal.ZERO);
|
||||||
|
data_row.setLkl_fee(BigDecimal.ZERO);
|
||||||
}
|
}
|
||||||
|
|
||||||
Integer voucher_id = (Integer) order_voucher_row.get("voucher_id");
|
Integer voucher_id = (Integer) order_voucher_row.get("voucher_id");
|
||||||
@ -7874,7 +7890,6 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
|||||||
consume_trade_row.setTrade_day(info_row.getOrder_day()); // 日
|
consume_trade_row.setTrade_day(info_row.getOrder_day()); // 日
|
||||||
consume_trade_row.setTrade_title(info_row.getOrder_title()); // 标题
|
consume_trade_row.setTrade_title(info_row.getOrder_title()); // 标题
|
||||||
|
|
||||||
|
|
||||||
if (!payService.saveOrUpdatePayConsumeTrade(consume_trade_row)) {
|
if (!payService.saveOrUpdatePayConsumeTrade(consume_trade_row)) {
|
||||||
throw new ApiException(I18nUtil._("订单支付信息失败!"));
|
throw new ApiException(I18nUtil._("订单支付信息失败!"));
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -1619,10 +1619,15 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
|||||||
logger.debug("最后一个商品,已添加打包费到退款金额,订单ID: {}", order_id);
|
logger.debug("最后一个商品,已添加打包费到退款金额,订单ID: {}", order_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 有运费的,重新生成一个运费退单
|
// 有运费的,重新生成一个运费退单
|
||||||
|
// if (order_data_row != null &&
|
||||||
|
// order_data_row.getOrder_shipping_fee_inner() != null &&
|
||||||
|
// order_data_row.getOrder_shipping_fee_inner().compareTo(BigDecimal.ZERO) > 0) {
|
||||||
|
// 注意:商家配置的配送费
|
||||||
if (order_data_row != null &&
|
if (order_data_row != null &&
|
||||||
order_data_row.getOrder_shipping_fee_inner() != null &&
|
order_data_row.getOrder_shipping_fee() != null &&
|
||||||
order_data_row.getOrder_shipping_fee_inner().compareTo(BigDecimal.ZERO) > 0) {
|
order_data_row.getOrder_shipping_fee().compareTo(BigDecimal.ZERO) > 0) {
|
||||||
// 运费大于0的, 执行退运费操作, 有两种方案,1、生成退运费售后服务单; 2、直接执行退款
|
// 运费大于0的, 执行退运费操作, 有两种方案,1、生成退运费售后服务单; 2、直接执行退款
|
||||||
// 1、生成独立退运费售后服务单,需注意运费是退给运费代理商的,需要获取代理商的交易单号
|
// 1、生成独立退运费售后服务单,需注意运费是退给运费代理商的,需要获取代理商的交易单号
|
||||||
|
|
||||||
@ -1631,13 +1636,16 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
|||||||
Integer buyer_user_id = info_row.getBuyer_user_id();
|
Integer buyer_user_id = info_row.getBuyer_user_id();
|
||||||
Integer storeId = info_row.getStore_id();
|
Integer storeId = info_row.getStore_id();
|
||||||
|
|
||||||
// 平台内部订单运费
|
// // 平台内部订单配送费
|
||||||
BigDecimal orderShippingFeeInner = order_data_row.getOrder_shipping_fee_inner();
|
// BigDecimal orderShippingFeeInner = order_data_row.getOrder_shipping_fee_inner();
|
||||||
if (orderShippingFeeInner == null || orderShippingFeeInner.compareTo(BigDecimal.ZERO) <= 0) {
|
// if (orderShippingFeeInner == null || orderShippingFeeInner.compareTo(BigDecimal.ZERO) <= 0) {
|
||||||
orderShippingFeeInner = shopOrderLklService.getOrderShippingFeeInnerToDecimal(storeId, order_id);
|
// orderShippingFeeInner = shopOrderLklService.getOrderShippingFeeInnerToDecimal(storeId, order_id);
|
||||||
}
|
// }
|
||||||
|
|
||||||
return_order_shipping_fee_row.setReturn_refund_amount(orderShippingFeeInner); // 平台内部配送费退款金额
|
// 商家设置的配送费
|
||||||
|
BigDecimal orderShippingFee = order_data_row.getOrder_shipping_fee();
|
||||||
|
|
||||||
|
return_order_shipping_fee_row.setReturn_refund_amount(orderShippingFee); // 平台内部配送费退款金额
|
||||||
|
|
||||||
BigDecimal order_points_fee = ObjectUtil.defaultIfNull(order_data_row.getOrder_points_fee(), BigDecimal.ZERO);
|
BigDecimal order_points_fee = ObjectUtil.defaultIfNull(order_data_row.getOrder_points_fee(), BigDecimal.ZERO);
|
||||||
BigDecimal order_refund_agree_points = ObjectUtil.defaultIfNull(order_data_row.getOrder_refund_agree_points(), BigDecimal.ZERO);
|
BigDecimal order_refund_agree_points = ObjectUtil.defaultIfNull(order_data_row.getOrder_refund_agree_points(), BigDecimal.ZERO);
|
||||||
@ -1649,7 +1657,7 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
|||||||
return_order_shipping_fee_row.setReturn_reason_id(0);
|
return_order_shipping_fee_row.setReturn_reason_id(0);
|
||||||
return_order_shipping_fee_row.setReturn_buyer_message(I18nUtil._("订单(配送费)退款"));
|
return_order_shipping_fee_row.setReturn_buyer_message(I18nUtil._("订单(配送费)退款"));
|
||||||
return_order_shipping_fee_row.setStore_id(storeId);
|
return_order_shipping_fee_row.setStore_id(storeId);
|
||||||
return_order_shipping_fee_row.setReturn_refund_point(NumberUtil.min(return_refund_point, orderShippingFeeInner));
|
return_order_shipping_fee_row.setReturn_refund_point(NumberUtil.min(return_refund_point, orderShippingFee));
|
||||||
return_order_shipping_fee_row.setReturn_add_time(now); // 添加时间
|
return_order_shipping_fee_row.setReturn_add_time(now); // 添加时间
|
||||||
return_order_shipping_fee_row.setReturn_tel("");
|
return_order_shipping_fee_row.setReturn_tel("");
|
||||||
|
|
||||||
@ -1733,12 +1741,12 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
|
|||||||
try {
|
try {
|
||||||
if (!payService.doRefund(returnOrder)) {
|
if (!payService.doRefund(returnOrder)) {
|
||||||
logger.error("执行退款操作失败!退单列表: {}", return_ids);
|
logger.error("执行退款操作失败!退单列表: {}", return_ids);
|
||||||
throw new ApiException(ResultCode.FAILED);
|
throw new ApiException("余额不足,请稍后重试");
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error("执行退款操作异常!退单列表: {}", return_ids, e);
|
logger.error("执行退款操作异常!退单列表: {}", return_ids, e);
|
||||||
// 根据业务需要决定是抛出异常触发回滚,还是其他处理方式
|
// 根据业务需要决定是抛出异常触发回滚,还是其他处理方式
|
||||||
throw new ApiException("退款服务调用异常: " + e.getMessage());
|
throw new ApiException("余额不足,请稍后重试");
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info("退款操作执行成功,退单列表: {}", return_ids);
|
logger.info("退款操作执行成功,退单列表: {}", return_ids);
|
||||||
|
|||||||
@ -521,10 +521,10 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
|
|||||||
shopOrderInfoService.changeOrderStatus(shopOrderId, StateCode.ORDER_STATE_PICKING, 0, 0);
|
shopOrderInfoService.changeOrderStatus(shopOrderId, StateCode.ORDER_STATE_PICKING, 0, 0);
|
||||||
|
|
||||||
// 个推推送消息
|
// 个推推送消息
|
||||||
JSONObject payload = new JSONObject();
|
// JSONObject payload = new JSONObject();
|
||||||
payload.put("category", CommonConstant.PUSH_MSG_CATE_MCH_ORDER_DETAIL);
|
// payload.put("category", CommonConstant.PUSH_MSG_CATE_MCH_ORDER_DETAIL);
|
||||||
payload.put("orderId", shopOrderId);
|
// payload.put("orderId", shopOrderId);
|
||||||
pushMessageService.noticeMerchantEmployeeOrderAction(null, shopOrderId, "您有一笔新的订单", "您有一笔同城订单[" + shopOrderId + "],请及时处理。", payload);
|
// pushMessageService.noticeMerchantEmployeeOrderAction(null, shopOrderId, "您有一笔新的订单", "您有一笔同城订单[" + shopOrderId + "],请及时处理。", payload);
|
||||||
|
|
||||||
return Pair.of(true, "顺丰同城下单成功!");
|
return Pair.of(true, "顺丰同城下单成功!");
|
||||||
}
|
}
|
||||||
@ -988,6 +988,7 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
|
|||||||
|
|
||||||
// 上传发货信息到微信
|
// 上传发货信息到微信
|
||||||
wxOrderShippingService.uploadShippingInfoToWx(2, shopOrderId);
|
wxOrderShippingService.uploadShippingInfoToWx(2, shopOrderId);
|
||||||
|
|
||||||
} else if (shopStoreSfOrder.getOrder_status().equals(StateCode.SF_ORDER_STATUS_ARRIVED)) {
|
} else if (shopStoreSfOrder.getOrder_status().equals(StateCode.SF_ORDER_STATUS_ARRIVED)) {
|
||||||
// 顺丰同城状态:12-配送员到店;
|
// 顺丰同城状态:12-配送员到店;
|
||||||
// 商城订单状态:从 2020-待配货 到 2030; //待发货
|
// 商城订单状态:从 2020-待配货 到 2030; //待发货
|
||||||
@ -1007,6 +1008,7 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
|
|||||||
pushRemark = "配送员已取货。";
|
pushRemark = "配送员已取货。";
|
||||||
// 上传发货信息到微信
|
// 上传发货信息到微信
|
||||||
wxOrderShippingService.uploadShippingInfoToWx(2, shopOrderId);
|
wxOrderShippingService.uploadShippingInfoToWx(2, shopOrderId);
|
||||||
|
|
||||||
} else if (shopStoreSfOrder.getOrder_status().equals(StateCode.SF_ORDER_STATUS_FINISH)) {
|
} else if (shopStoreSfOrder.getOrder_status().equals(StateCode.SF_ORDER_STATUS_FINISH)) {
|
||||||
// 顺丰同城状态:17-配送员妥投完单;
|
// 顺丰同城状态:17-配送员妥投完单;
|
||||||
// orderStatus = StateCode.ORDER_STATE_FINISH;
|
// orderStatus = StateCode.ORDER_STATE_FINISH;
|
||||||
@ -1028,10 +1030,10 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
|
|||||||
shopOrderInfoService.changeOrderStatus(shopOrderId, orderStatus, orderIsOutStatus, orderIsShippedStatus);
|
shopOrderInfoService.changeOrderStatus(shopOrderId, orderStatus, orderIsOutStatus, orderIsShippedStatus);
|
||||||
|
|
||||||
// 消息推送
|
// 消息推送
|
||||||
JSONObject payload = new JSONObject();
|
// JSONObject payload = new JSONObject();
|
||||||
payload.put("category", CommonConstant.PUSH_MSG_CATE_MCH_ORDER_DETAIL);
|
// payload.put("category", CommonConstant.PUSH_MSG_CATE_MCH_ORDER_DETAIL);
|
||||||
payload.put("orderId", shopOrderId);
|
// payload.put("orderId", shopOrderId);
|
||||||
pushMessageService.noticeMerchantEmployeeOrderAction(null, shopOrderId, "", "顺丰同城订单[" + shopOrderId + "]" + pushRemark, payload);
|
// pushMessageService.noticeMerchantEmployeeOrderAction(null, shopOrderId, "", "顺丰同城订单[" + shopOrderId + "]" + pushRemark, payload);
|
||||||
|
|
||||||
return new ThirdApiRes().success("success");
|
return new ThirdApiRes().success("success");
|
||||||
}
|
}
|
||||||
@ -1118,10 +1120,10 @@ public class SFExpressApiServiceImpl implements SFExpressApiService {
|
|||||||
String orderId = shopStoreSfOrder.getShop_order_id();
|
String orderId = shopStoreSfOrder.getShop_order_id();
|
||||||
|
|
||||||
// 消息推送
|
// 消息推送
|
||||||
JSONObject payload = new JSONObject();
|
// JSONObject payload = new JSONObject();
|
||||||
payload.put("category", CommonConstant.PUSH_MSG_CATE_MCH_ORDER_DETAIL);
|
// payload.put("category", CommonConstant.PUSH_MSG_CATE_MCH_ORDER_DETAIL);
|
||||||
payload.put("orderId", orderId);
|
// payload.put("orderId", orderId);
|
||||||
pushMessageService.noticeMerchantEmployeeOrderAction(null, orderId, "", "顺丰同城订单[" + orderId + "]已完成配送。", null);
|
// pushMessageService.noticeMerchantEmployeeOrderAction(null, orderId, "", "顺丰同城订单[" + orderId + "]已完成配送。", null);
|
||||||
|
|
||||||
|
|
||||||
return new ThirdApiRes().success("success");
|
return new ThirdApiRes().success("success");
|
||||||
|
|||||||
@ -576,6 +576,7 @@
|
|||||||
<result property="order_payment_amount" column="order_payment_amount"/>
|
<result property="order_payment_amount" column="order_payment_amount"/>
|
||||||
<result property="order_shipping_fee" column="order_shipping_fee"/>
|
<result property="order_shipping_fee" column="order_shipping_fee"/>
|
||||||
<result property="order_shipping_fee_inner" column="order_shipping_fee_inner"/>
|
<result property="order_shipping_fee_inner" column="order_shipping_fee_inner"/>
|
||||||
|
<result property="lkl_fee" column="lkl_fee"/>
|
||||||
<result property="packing_fee" column="packing_fee"/>
|
<result property="packing_fee" column="packing_fee"/>
|
||||||
<!--总计优惠金额 order_discount_amount + order_voucher_price + order_points_fee + order_adjust_fee-->
|
<!--总计优惠金额 order_discount_amount + order_voucher_price + order_points_fee + order_adjust_fee-->
|
||||||
<result property="total_discount_amount" column="total_discount_amount"/>
|
<result property="total_discount_amount" column="total_discount_amount"/>
|
||||||
@ -782,13 +783,14 @@
|
|||||||
oi.payment_time,
|
oi.payment_time,
|
||||||
od.order_shipping_fee,
|
od.order_shipping_fee,
|
||||||
IFNULL(od.order_shipping_fee_inner, 0) as order_shipping_fee_inner,
|
IFNULL(od.order_shipping_fee_inner, 0) as order_shipping_fee_inner,
|
||||||
|
IFNULL(od.lkl_fee, 0) as lkl_fee,
|
||||||
<!--总计优惠金额 order_discount_amount + order_voucher_price + order_points_fee + order_adjust_fee-->
|
<!--总计优惠金额 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
|
(od.order_discount_amount + od.voucher_price + od.order_points_fee + od.order_adjust_fee) as
|
||||||
total_discount_amount,
|
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)
|
(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-lkl_fee+od.packing_fee)
|
||||||
as order_income_amount,
|
as order_income_amount,
|
||||||
od.platform_fee,
|
(od.platform_fee+lkl_fee) as platform_fee,
|
||||||
od.packing_fee,
|
od.packing_fee,
|
||||||
od.order_message,
|
od.order_message,
|
||||||
sb.store_id,
|
sb.store_id,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user