分账实体类 测试修改
This commit is contained in:
parent
2e96ee97fc
commit
b13eecbb8d
@ -49,9 +49,6 @@ public class LklOrderSeparate {
|
||||
@ApiModelProperty(value = "平台订单Id")
|
||||
private String order_id;
|
||||
|
||||
@ApiModelProperty(value = "分账总金额,单位:分")
|
||||
private String total_amt;
|
||||
|
||||
@ApiModelProperty(value = "分账计算类型:0- 按照指定金额,1- 按照指定比例。默认 0")
|
||||
private String cal_type;
|
||||
|
||||
@ -79,8 +76,14 @@ public class LklOrderSeparate {
|
||||
@ApiModelProperty(value = "最终分账明细,JSON 格式")
|
||||
private String detail_datas;
|
||||
|
||||
@ApiModelProperty(value = "总计分账金额")
|
||||
private Integer total_separate_value;
|
||||
@ApiModelProperty(value = "分账发生总金额")
|
||||
private String total_amt;
|
||||
|
||||
@ApiModelProperty(value = "实际分账金额")
|
||||
private String actual_separate_amt;
|
||||
|
||||
@ApiModelProperty(value = "分账费用")
|
||||
private String total_fee_amt;
|
||||
|
||||
@ApiModelProperty(value = "拉卡拉机构编号")
|
||||
private String lkl_org_no;
|
||||
@ -91,6 +94,9 @@ public class LklOrderSeparate {
|
||||
@ApiModelProperty(value = "处理状态:ACCEPTED-已受理, PROCESSING-处理中, FAIL-失败, SUCCESS-成功")
|
||||
private String final_status;
|
||||
|
||||
@ApiModelProperty(value = "异步通知数据")
|
||||
private String notify_resp;
|
||||
|
||||
@ApiModelProperty(value = "分账(失败后)的标记")
|
||||
private String remark;
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,849 @@
|
||||
package com.suisung.mall.common.pojo.dto;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.data.util.Pair;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
|
||||
/**
|
||||
* 拉卡拉订单分账信息对象
|
||||
* <p>
|
||||
* 分账计算支持两种模式:
|
||||
* 1. 基于可分账金额模式(默认):先扣除拉卡拉手续费和配送费,再对剩余金额进行分账
|
||||
* 2. 基于总金额模式:基于总分账金额进行分账计算
|
||||
* <p>
|
||||
* 分账优先级顺序:拉卡拉 > 平台 > 一级代理商 > 二级代理商 > 商户
|
||||
* 商户作为最后分账方,其金额为剩余金额,不强制遵循分账比例
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@ApiModel(value = "拉卡拉订单分账信息对象", description = "拉卡拉订单分账信息对象")
|
||||
public class LklSeparateDTOBak implements java.io.Serializable {
|
||||
private static final Logger logger = LoggerFactory.getLogger(LklSeparateDTOBak.class);
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
// ================================ 基础金额属性 ================================
|
||||
|
||||
@ApiModelProperty(value = "分账总金额(分)")
|
||||
private Integer totalSeparateAmount;
|
||||
|
||||
@ApiModelProperty(value = "可分账金额(分)")
|
||||
private Integer canSeparateAmount;
|
||||
|
||||
@ApiModelProperty(value = "拉卡拉参考可分账金额(分)")
|
||||
private Integer refCanSeparateAmount;
|
||||
|
||||
@ApiModelProperty(value = "配送费(分)")
|
||||
private Integer shippingFee;
|
||||
|
||||
// ================================ 分账比例属性 ================================
|
||||
|
||||
@ApiModelProperty(value = "拉卡拉分账比例(如 0.0025=0.25%)")
|
||||
private BigDecimal lklRatio;
|
||||
|
||||
@ApiModelProperty(value = "商户分账比例(如 0.96=96%)")
|
||||
private BigDecimal mchRatio;
|
||||
|
||||
@ApiModelProperty(value = "平台分账比例(如 0.01=1%)")
|
||||
private BigDecimal platRatio;
|
||||
|
||||
@ApiModelProperty(value = "一级代理商分账比例(如 0.01=1%)")
|
||||
private BigDecimal agent1stRatio;
|
||||
|
||||
@ApiModelProperty(value = "二级代理商分账比例(如 0.03=3%)")
|
||||
private BigDecimal agent2ndRatio;
|
||||
|
||||
// ================================ 分账金额结果属性 ================================
|
||||
|
||||
@ApiModelProperty(value = "拉卡拉分账金额(分)")
|
||||
private Integer lklAmount;
|
||||
|
||||
@ApiModelProperty(value = "商户分账金额(分)")
|
||||
private Integer mchAmount;
|
||||
|
||||
@ApiModelProperty(value = "平台分账金额(分)")
|
||||
private Integer platAmount;
|
||||
|
||||
@ApiModelProperty(value = "一级代理商分账金额(分)")
|
||||
private Integer agent1stAmount;
|
||||
|
||||
@ApiModelProperty(value = "二级代理商分账金额(分)")
|
||||
private Integer agent2ndAmount;
|
||||
|
||||
// ================================ 内部状态属性 ================================
|
||||
|
||||
/**
|
||||
* 分账计算方法类型
|
||||
* true表示基于总金额分账(calcOnTotalAmount方法被调用)
|
||||
* false表示基于可分账金额分账(calcOnCanAmount方法被调用)
|
||||
*/
|
||||
private boolean isBasedOnTotalAmount = false;
|
||||
|
||||
// ================================ 构造方法 ================================
|
||||
|
||||
public LklSeparateDTOBak() {
|
||||
// 默认构造函数
|
||||
}
|
||||
|
||||
// ================================ 公共方法 ================================
|
||||
|
||||
/**
|
||||
* 测试方法
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
logger.info("开始测试分账计算功能...");
|
||||
|
||||
// 临界点测试用例2: 小金额测试
|
||||
logger.info("\n临界点测试用例2 - 小金额测试:");
|
||||
LklSeparateDTOBak dto2 = new LklSeparateDTOBak();
|
||||
dto2.setTotalSeparateAmount(800);
|
||||
dto2.setShippingFee(600);
|
||||
dto2.setLklRatio(new BigDecimal("0.0025"));
|
||||
dto2.setMchRatio(new BigDecimal("0.96"));
|
||||
dto2.setPlatRatio(new BigDecimal("0.04"));
|
||||
dto2.setBasedOnTotalAmount(true);
|
||||
|
||||
// dto2.setAgent1stRatio(new BigDecimal("0.01"));
|
||||
// dto2.setAgent2ndRatio(new BigDecimal("0.04"));
|
||||
// dto2.setRefCanSeparateAmount(8079); // 设置参考可分账金额
|
||||
|
||||
logger.info("测试参数: 总分账金额={}分, 配送费={}分, 拉卡拉比例={}, 商户比例={}, 平台比例={}",
|
||||
dto2.getTotalSeparateAmount(), dto2.getShippingFee(), dto2.getLklRatio(),
|
||||
dto2.getMchRatio(), dto2.getPlatRatio());
|
||||
|
||||
Pair<Boolean, String> result2 = dto2.calcOnCanSeparateAmount();
|
||||
logger.info("分账计算结果: {}", (result2.getFirst() ? "成功" : "失败"));
|
||||
if (result2.getFirst()) {
|
||||
logger.info("分账结果: 总金额={}分, 拉卡拉={}分, 配送费={}分, 可分账={}分, 参考可分账={}分, 商户={}分, 平台={}分, 一级代理商={}分, 二级代理商={}分",
|
||||
dto2.getTotalSeparateAmount(), dto2.getLklAmount(), dto2.getShippingFee(), dto2.getCanSeparateAmount(), dto2.getRefCanSeparateAmount(),
|
||||
dto2.getMchAmount(), dto2.getPlatAmount(), dto2.getAgent1stAmount(), dto2.getAgent2ndAmount());
|
||||
|
||||
// 计算并打印各分账方占可分账金额和总金额的百分比
|
||||
int canSeparateAmount = dto2.getCanSeparateAmount();
|
||||
int totalSeparateAmount = dto2.getTotalSeparateAmount();
|
||||
|
||||
if (canSeparateAmount > 0) {
|
||||
double lklRatioOfTotal = (double) dto2.getLklAmount() / totalSeparateAmount * 100;
|
||||
double mchRatioOfTotal = (double) dto2.getMchAmount() / totalSeparateAmount * 100;
|
||||
double platRatioOfTotal = (double) dto2.getPlatAmount() / totalSeparateAmount * 100;
|
||||
double agent1stRatioOfTotal = 0.0;
|
||||
double agent2ndRatioOfTotal = 0.0;
|
||||
|
||||
// 安全检查,避免空指针异常
|
||||
if (dto2.getAgent1stAmount() != null) {
|
||||
agent1stRatioOfTotal = (double) dto2.getAgent1stAmount() / totalSeparateAmount * 100;
|
||||
}
|
||||
if (dto2.getAgent2ndAmount() != null) {
|
||||
agent2ndRatioOfTotal = (double) dto2.getAgent2ndAmount() / totalSeparateAmount * 100;
|
||||
}
|
||||
|
||||
double lklRatioOfAvailable = (double) dto2.getLklAmount() / canSeparateAmount * 100;
|
||||
double mchRatioOfAvailable = (double) dto2.getMchAmount() / canSeparateAmount * 100;
|
||||
double platRatioOfAvailable = (double) dto2.getPlatAmount() / canSeparateAmount * 100;
|
||||
double agent1stRatioOfAvailable = 0.0;
|
||||
double agent2ndRatioOfAvailable = 0.0;
|
||||
|
||||
// 安全检查,避免空指针异常
|
||||
if (dto2.getAgent1stAmount() != null) {
|
||||
agent1stRatioOfAvailable = (double) dto2.getAgent1stAmount() / canSeparateAmount * 100;
|
||||
}
|
||||
if (dto2.getAgent2ndAmount() != null) {
|
||||
agent2ndRatioOfAvailable = (double) dto2.getAgent2ndAmount() / canSeparateAmount * 100;
|
||||
}
|
||||
|
||||
logger.info("占比详情 (占总金额/占可分账金额): 拉卡拉={}%/{}%, 商户={}%/{}%, 平台={}%/{}%, 一级代理商={}%/{}%, 二级代理商={}%/{}%",
|
||||
String.format("%.2f", lklRatioOfTotal), String.format("%.2f", lklRatioOfAvailable),
|
||||
String.format("%.2f", mchRatioOfTotal), String.format("%.2f", mchRatioOfAvailable),
|
||||
String.format("%.2f", platRatioOfTotal), String.format("%.2f", platRatioOfAvailable),
|
||||
String.format("%.2f", agent1stRatioOfTotal), String.format("%.2f", agent1stRatioOfAvailable),
|
||||
String.format("%.2f", agent2ndRatioOfTotal), String.format("%.2f", agent2ndRatioOfAvailable));
|
||||
}
|
||||
|
||||
int total = dto2.getLklAmount() + dto2.getMchAmount() + dto2.getPlatAmount() +
|
||||
(dto2.getAgent1stAmount() != null ? dto2.getAgent1stAmount() : 0) +
|
||||
(dto2.getAgent2ndAmount() != null ? dto2.getAgent2ndAmount() : 0) + dto2.getShippingFee();
|
||||
logger.info("金额校验: {} (计算总金额={}分, 原始总金额={}分)", (total == dto2.getTotalSeparateAmount() ? "通过" : "不通过"), total, dto2.getTotalSeparateAmount());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 基于可分账金额的分账计算方法(默认)
|
||||
* <p>
|
||||
* 计算逻辑:
|
||||
* 1. 计算拉卡拉分账金额 = 总分账金额 × 拉卡拉分账比例(向上取整)
|
||||
* 2. 计算可分账金额 = 总分账金额 - 配送费 - 拉卡拉分账金额
|
||||
* 3. 如果refCanSeparateAmount有效且与计算出的canSeparateAmount不一致,则使用refCanSeparateAmount作为分账基数
|
||||
* 4. 调整分账比例,确保有效比例之和等于1.0
|
||||
* 5. 按优先级计算各参与方分账金额(商户 > 平台 > 一级代理商 > 二级代理商)
|
||||
* 6. 确保总额平衡并保障各参与方分账比例
|
||||
*
|
||||
* @return Pair<Boolean, String> 分账结果是否成功和失败的原因
|
||||
*/
|
||||
public Pair<Boolean, String> calcOnCanSeparateAmount() {
|
||||
// 设置分账计算方法类型
|
||||
isBasedOnTotalAmount = false;
|
||||
|
||||
// 检查前提条件
|
||||
if (!validateInputs()) {
|
||||
return Pair.of(false, "分账参数不全");
|
||||
}
|
||||
|
||||
logger.info("开始基于可分账金额的分账计算,总金额={}分,配送费={}分", totalSeparateAmount, shippingFee);
|
||||
|
||||
// 计算拉卡拉分账金额
|
||||
calculateLklAmount();
|
||||
|
||||
// 计算可分账金额
|
||||
calculateCanSeparateAmount();
|
||||
if (canSeparateAmount <= 0) {
|
||||
String errorMsg = "分账计算失败:可分账金额必须大于0,当前值=" + canSeparateAmount;
|
||||
logger.info(errorMsg);
|
||||
return Pair.of(false, errorMsg);
|
||||
}
|
||||
|
||||
// 检查并应用参考可分账金额
|
||||
checkAndApplyRefCanSeparateAmount();
|
||||
|
||||
// 调整分账比例
|
||||
adjustRatios();
|
||||
|
||||
// 按优先级分账
|
||||
performSeparate();
|
||||
|
||||
// 确保总额平衡
|
||||
balanceAmounts();
|
||||
|
||||
// 保障各参与方分账比例
|
||||
guaranteeRatios();
|
||||
|
||||
String successMsg = String.format("基于可分账金额的分账计算完成:拉卡拉=%d分, 平台=%d分, 一级代理商=%d分, 二级代理商=%d分, 商户=%d分",
|
||||
lklAmount, platAmount, agent1stAmount, agent2ndAmount, mchAmount);
|
||||
logger.info(successMsg);
|
||||
return Pair.of(true, successMsg);
|
||||
}
|
||||
|
||||
/**
|
||||
* 基于总金额的分账计算方法
|
||||
* <p>
|
||||
* 计算逻辑:
|
||||
* 1. 计算拉卡拉分账金额 = 总分账金额 × 拉卡拉分账比例(四舍五入保留两位小数)
|
||||
* 2. 计算可分账金额 = 总分账金额 - 配送费 - 拉卡拉分账金额
|
||||
* 3. 如果refCanSeparateAmount有效且与计算出的canSeparateAmount不一致,则使用refCanSeparateAmount作为分账基数
|
||||
* 4. 调整分账比例,确保有效比例之和等于1.0
|
||||
* 5. 按优先级计算各参与方分账金额(平台 > 一级代理商 > 二级代理商 > 商户),基于可分账金额进行分账
|
||||
* 6. 确保总额平衡并保障各参与方分账比例
|
||||
*
|
||||
* @return Pair<Boolean, String> 分账结果是否成功和失败的原因
|
||||
*/
|
||||
public Pair<Boolean, String> calcOnTotalAmount() {
|
||||
// 设置分账计算方法类型
|
||||
isBasedOnTotalAmount = true;
|
||||
|
||||
// 检查前提条件
|
||||
if (!validateInputsForTotalAmount()) {
|
||||
return Pair.of(false, "分账参数不全");
|
||||
}
|
||||
|
||||
logger.info("开始基于总金额的分账计算,总金额={}分,配送费={}分", totalSeparateAmount, shippingFee);
|
||||
|
||||
// 计算拉卡拉分账金额
|
||||
calculateLklAmount();
|
||||
|
||||
// 计算可分账金额
|
||||
calculateCanSeparateAmount();
|
||||
if (canSeparateAmount <= 0) {
|
||||
String errorMsg = "基于总金额的分账计算失败:可分账金额必须大于0,当前值=" + canSeparateAmount;
|
||||
logger.info(errorMsg);
|
||||
return Pair.of(false, errorMsg);
|
||||
}
|
||||
|
||||
// 调整分账比例
|
||||
adjustRatios();
|
||||
|
||||
// 检查并应用参考可分账金额
|
||||
checkAndApplyRefCanSeparateAmount();
|
||||
|
||||
// 按优先级分账(基于总金额)
|
||||
performSeparateBasedOnTotalAmount();
|
||||
|
||||
// 确保总额平衡
|
||||
balanceAmounts();
|
||||
|
||||
// 保障各参与方分账比例(忽略商户比例保障)
|
||||
guaranteeRatiosForTotalAmount();
|
||||
|
||||
String successMsg = String.format("基于总金额的分账计算完成:拉卡拉=%d分, 平台=%d分, 一级代理商=%d分, 二级代理商=%d分, 商户=%d分",
|
||||
lklAmount, platAmount, agent1stAmount, agent2ndAmount, mchAmount);
|
||||
logger.info(successMsg);
|
||||
return Pair.of(true, successMsg);
|
||||
}
|
||||
|
||||
/**
|
||||
* 输出具体的分账结果
|
||||
*
|
||||
* @return 分账结果字符串
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
int canSeparateAmount = getCanSeparateAmount();
|
||||
int totalSeparateAmount = getTotalSeparateAmount();
|
||||
|
||||
// 计算各分账方占总金额和可分账金额的百分比
|
||||
double lklRatioOfTotal = 0.0;
|
||||
double mchRatioOfTotal = 0.0;
|
||||
double platRatioOfTotal = 0.0;
|
||||
double agent1stRatioOfTotal = 0.0;
|
||||
double agent2ndRatioOfTotal = 0.0;
|
||||
double shippingFeeRatioOfTotal = 0.0;
|
||||
|
||||
double lklRatioOfAvailable = 0.0;
|
||||
double mchRatioOfAvailable = 0.0;
|
||||
double platRatioOfAvailable = 0.0;
|
||||
double agent1stRatioOfAvailable = 0.0;
|
||||
double agent2ndRatioOfAvailable = 0.0;
|
||||
double shippingFeeRatioOfAvailable = 0.0;
|
||||
|
||||
if (totalSeparateAmount > 0) {
|
||||
if (getLklAmount() != null) {
|
||||
lklRatioOfTotal = (double) getLklAmount() / totalSeparateAmount * 100;
|
||||
}
|
||||
if (getMchAmount() != null) {
|
||||
mchRatioOfTotal = (double) getMchAmount() / totalSeparateAmount * 100;
|
||||
}
|
||||
if (getPlatAmount() != null) {
|
||||
platRatioOfTotal = (double) getPlatAmount() / totalSeparateAmount * 100;
|
||||
}
|
||||
if (getAgent1stAmount() != null) {
|
||||
agent1stRatioOfTotal = (double) getAgent1stAmount() / totalSeparateAmount * 100;
|
||||
}
|
||||
if (getAgent2ndAmount() != null) {
|
||||
agent2ndRatioOfTotal = (double) getAgent2ndAmount() / totalSeparateAmount * 100;
|
||||
}
|
||||
if (getShippingFee() != null) {
|
||||
shippingFeeRatioOfTotal = (double) getShippingFee() / totalSeparateAmount * 100;
|
||||
}
|
||||
}
|
||||
|
||||
if (canSeparateAmount > 0) {
|
||||
if (getLklAmount() != null) {
|
||||
lklRatioOfAvailable = (double) getLklAmount() / canSeparateAmount * 100;
|
||||
}
|
||||
if (getMchAmount() != null) {
|
||||
mchRatioOfAvailable = (double) getMchAmount() / canSeparateAmount * 100;
|
||||
}
|
||||
if (getPlatAmount() != null) {
|
||||
platRatioOfAvailable = (double) getPlatAmount() / canSeparateAmount * 100;
|
||||
}
|
||||
if (getAgent1stAmount() != null) {
|
||||
agent1stRatioOfAvailable = (double) getAgent1stAmount() / canSeparateAmount * 100;
|
||||
}
|
||||
if (getAgent2ndAmount() != null) {
|
||||
agent2ndRatioOfAvailable = (double) getAgent2ndAmount() / canSeparateAmount * 100;
|
||||
}
|
||||
if (getShippingFee() != null) {
|
||||
shippingFeeRatioOfAvailable = (double) getShippingFee() / canSeparateAmount * 100;
|
||||
}
|
||||
}
|
||||
|
||||
String calculationMethod = isBasedOnTotalAmount ? "基于总交易额方式计算" : "基于可分账额方式计算";
|
||||
|
||||
return String.format("分账结果%s,总交易额=%d分, 可分账额=%d分, 拉卡拉手续费=%d分(%.2f%%/%.2f%%), 配送费=%d分(%.2f%%/%.2f%%), 商户=%d分(%.2f%%/%.2f%%), 平台=%d分(%.2f%%/%.2f%%), 一级代理商=%d分(%.2f%%/%.2f%%), 二级代理商=%d分(%.2f%%/%.2f%%)",
|
||||
calculationMethod,
|
||||
totalSeparateAmount,
|
||||
canSeparateAmount,
|
||||
getLklAmount() != null ? getLklAmount() : 0,
|
||||
lklRatioOfTotal, lklRatioOfAvailable,
|
||||
getShippingFee() != null ? getShippingFee() : 0,
|
||||
shippingFeeRatioOfTotal, shippingFeeRatioOfAvailable,
|
||||
getMchAmount() != null ? getMchAmount() : 0,
|
||||
mchRatioOfTotal, mchRatioOfAvailable,
|
||||
getPlatAmount() != null ? getPlatAmount() : 0,
|
||||
platRatioOfTotal, platRatioOfAvailable,
|
||||
getAgent1stAmount() != null ? getAgent1stAmount() : 0,
|
||||
agent1stRatioOfTotal, agent1stRatioOfAvailable,
|
||||
getAgent2ndAmount() != null ? getAgent2ndAmount() : 0,
|
||||
agent2ndRatioOfTotal, agent2ndRatioOfAvailable);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将对象转换为JSON字符串格式
|
||||
*
|
||||
* @return 包含所有属性的JSON字符串
|
||||
*/
|
||||
public String toJSON() {
|
||||
StringBuilder json = new StringBuilder();
|
||||
json.append("{");
|
||||
|
||||
// 添加基本属性
|
||||
appendProperty(json, "totalSeparateAmount", totalSeparateAmount, true);
|
||||
appendProperty(json, "canSeparateAmount", canSeparateAmount, false);
|
||||
appendProperty(json, "refCanSeparateAmount", refCanSeparateAmount, false);
|
||||
appendProperty(json, "shippingFee", shippingFee, false);
|
||||
|
||||
// 添加比例属性
|
||||
appendProperty(json, "lklRatio", lklRatio, false);
|
||||
appendProperty(json, "mchRatio", mchRatio, false);
|
||||
appendProperty(json, "platRatio", platRatio, false);
|
||||
appendProperty(json, "agent1stRatio", agent1stRatio, false);
|
||||
appendProperty(json, "agent2ndRatio", agent2ndRatio, false);
|
||||
|
||||
// 添加金额属性
|
||||
appendProperty(json, "lklAmount", lklAmount, false);
|
||||
appendProperty(json, "mchAmount", mchAmount, false);
|
||||
appendProperty(json, "platAmount", platAmount, false);
|
||||
appendProperty(json, "agent1stAmount", agent1stAmount, false);
|
||||
appendProperty(json, "agent2ndAmount", agent2ndAmount, false);
|
||||
|
||||
// 移除最后的逗号并关闭JSON对象
|
||||
if (json.charAt(json.length() - 1) == ',') {
|
||||
json.setLength(json.length() - 1);
|
||||
}
|
||||
json.append("}");
|
||||
|
||||
return json.toString();
|
||||
}
|
||||
|
||||
// ================================ 私有方法 ================================
|
||||
|
||||
/**
|
||||
* 验证基于可分账金额分账的输入参数
|
||||
*/
|
||||
private boolean validateInputs() {
|
||||
if (totalSeparateAmount == null || totalSeparateAmount <= 0) {
|
||||
logger.info("分账计算失败:分账总金额必须大于0,当前值={}", totalSeparateAmount);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (shippingFee == null || shippingFee < 0) {
|
||||
logger.info("分账计算失败:配送费不能小于0,当前值={}", shippingFee);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (lklRatio == null || lklRatio.compareTo(BigDecimal.ZERO) <= 0) {
|
||||
logger.info("分账计算失败:拉卡拉分账比例必须大于0,当前值={}", lklRatio);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mchRatio == null || mchRatio.compareTo(BigDecimal.ZERO) <= 0) {
|
||||
logger.info("分账计算失败:商户分账比例必须大于0,当前值={}", mchRatio);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (platRatio == null || platRatio.compareTo(BigDecimal.ZERO) <= 0) {
|
||||
logger.info("分账计算失败:平台分账比例必须大于0,当前值={}", platRatio);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证基于总金额分账的输入参数
|
||||
*/
|
||||
private boolean validateInputsForTotalAmount() {
|
||||
// 基于总金额的分账计算参数验证与基于可分账金额的验证相同
|
||||
return validateInputs();
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算拉卡拉分账金额
|
||||
*/
|
||||
private void calculateLklAmount() {
|
||||
BigDecimal lklAmountDecimal = new BigDecimal(totalSeparateAmount).multiply(lklRatio);
|
||||
lklAmount = lklAmountDecimal.setScale(2, RoundingMode.HALF_UP).intValue();
|
||||
logger.debug("拉卡拉分账计算:总金额{} × 拉卡拉比例{} = {},四舍五入保留两位小数后={}",
|
||||
totalSeparateAmount, lklRatio, lklAmountDecimal, lklAmount);
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算可分账金额
|
||||
*/
|
||||
private void calculateCanSeparateAmount() {
|
||||
canSeparateAmount = totalSeparateAmount - shippingFee - lklAmount;
|
||||
logger.debug("可分账金额计算:总金额{} - 配送费{} - 拉卡拉分账{} = {}",
|
||||
totalSeparateAmount, shippingFee, lklAmount, canSeparateAmount);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查refCanSeparateAmount是否有效
|
||||
* 有效条件:非空且大于0且小于totalSeparateAmount
|
||||
*
|
||||
* @return true表示有效,false表示无效
|
||||
*/
|
||||
private boolean isRefCanSeparateAmountValid() {
|
||||
return refCanSeparateAmount != null && refCanSeparateAmount > 0 && refCanSeparateAmount < totalSeparateAmount;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分账基数金额
|
||||
* 如果refCanSeparateAmount有效,则使用refCanSeparateAmount,否则使用canSeparateAmount
|
||||
*
|
||||
* @return 分账基数金额
|
||||
*/
|
||||
private int getSeparateBaseAmount() {
|
||||
if (isRefCanSeparateAmountValid()) {
|
||||
return refCanSeparateAmount;
|
||||
}
|
||||
return canSeparateAmount;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查并应用参考可分账金额
|
||||
* 当refCanSeparateAmount有效且与计算出的canSeparateAmount不一致时,
|
||||
* 将差额分配给指定优先级的分账对象(平台 > 一级代理商 > 二级代理商 > 商户)
|
||||
*/
|
||||
private void checkAndApplyRefCanSeparateAmount() {
|
||||
// 判断refCanSeparateAmount是否有效(非空且大于0且小于totalSeparateAmount)
|
||||
if (isRefCanSeparateAmountValid()) {
|
||||
// 比较refCanSeparateAmount与计算出的canSeparateAmount
|
||||
if (!refCanSeparateAmount.equals(canSeparateAmount)) {
|
||||
int difference = refCanSeparateAmount - canSeparateAmount;
|
||||
logger.info("检测到refCanSeparateAmount与计算出的canSeparateAmount不一致,差额={}分。" +
|
||||
"refCanSeparateAmount={}分,计算出的canSeparateAmount={}分。",
|
||||
difference, refCanSeparateAmount, canSeparateAmount);
|
||||
|
||||
// 将差额分配给指定优先级的分账对象(商户 > 二级代理商 > 一级代理商 > 平台)
|
||||
if (difference != 0) {
|
||||
if (mchAmount == null) mchAmount = 0;
|
||||
if (agent2ndAmount == null) agent2ndAmount = 0;
|
||||
if (agent1stAmount == null) agent1stAmount = 0;
|
||||
if (platAmount == null) platAmount = 0;
|
||||
|
||||
if (difference > 0) {
|
||||
// 如果差额为正,优先增加高优先级参与方的金额
|
||||
mchAmount += difference;
|
||||
} else {
|
||||
// 如果差额为负,优先从低优先级参与方扣除
|
||||
int diff = -difference;
|
||||
if (mchAmount >= diff) {
|
||||
mchAmount -= diff;
|
||||
} else if (agent2ndAmount > 0 && agent2ndAmount >= diff) {
|
||||
agent2ndAmount -= diff;
|
||||
} else if (agent1stAmount > 0 && agent1stAmount >= diff) {
|
||||
agent1stAmount -= diff;
|
||||
} else {
|
||||
platAmount -= diff;
|
||||
}
|
||||
}
|
||||
logger.debug("已将差额{}分应用于分账金额调整", difference);
|
||||
}
|
||||
} else {
|
||||
logger.debug("refCanSeparateAmount与计算出的canSeparateAmount一致,值={}分", canSeparateAmount);
|
||||
}
|
||||
} else {
|
||||
logger.debug("refCanSeparateAmount无效或未设置,使用计算出的canSeparateAmount={}分作为分账基数", canSeparateAmount);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 调整分账比例,确保有效值比例相加等于1.0
|
||||
*/
|
||||
private void adjustRatios() {
|
||||
// 计算有效的分账比例总和
|
||||
BigDecimal effectiveRatioSum = BigDecimal.ZERO
|
||||
.add(mchRatio)
|
||||
.add(platRatio)
|
||||
.add(agent1stRatio != null ? agent1stRatio : BigDecimal.ZERO)
|
||||
.add(agent2ndRatio != null ? agent2ndRatio : BigDecimal.ZERO);
|
||||
|
||||
logger.debug("调整前各分账比例:商户={},平台={},一级代理商={},二级代理商={},有效比例总和={}",
|
||||
mchRatio, platRatio, agent1stRatio, agent2ndRatio, effectiveRatioSum);
|
||||
|
||||
// 动态调整最后一个分账方的比例,确保总和为1.0
|
||||
BigDecimal adjustmentRatio = BigDecimal.ONE.subtract(effectiveRatioSum);
|
||||
if (agent2ndRatio != null && agent2ndRatio.compareTo(BigDecimal.ZERO) > 0) {
|
||||
// 调整二级代理商比例
|
||||
agent2ndRatio = agent2ndRatio.add(adjustmentRatio);
|
||||
} else if (agent1stRatio != null && agent1stRatio.compareTo(BigDecimal.ZERO) > 0) {
|
||||
// 调整一级代理商比例
|
||||
agent1stRatio = agent1stRatio.add(adjustmentRatio);
|
||||
} else {
|
||||
// 调整平台比例
|
||||
platRatio = platRatio.add(adjustmentRatio);
|
||||
}
|
||||
|
||||
logger.debug("调整后各分账比例:商户={},平台={},一级代理商={},二级代理商={}",
|
||||
mchRatio, platRatio, agent1stRatio, agent2ndRatio);
|
||||
}
|
||||
|
||||
/**
|
||||
* 按优先级进行分账(基于可分账金额)
|
||||
*/
|
||||
private void performSeparate() {
|
||||
// 确定分账基数
|
||||
int separateBaseAmount = getSeparateBaseAmount();
|
||||
|
||||
// 商户分账金额 = 可分账金额 × 商户分账比例(四舍五入)
|
||||
BigDecimal mchAmountDecimal = new BigDecimal(separateBaseAmount).multiply(mchRatio);
|
||||
mchAmount = mchAmountDecimal.setScale(0, RoundingMode.HALF_UP).intValue();
|
||||
logger.debug("商户分账计算:可分账金额{} × 商户比例{} = {},四舍五入后={}", separateBaseAmount, mchRatio, mchAmountDecimal, mchAmount);
|
||||
|
||||
// 平台分账金额 = 可分账金额 × 平台分账比例(四舍五入)
|
||||
BigDecimal platAmountDecimal = new BigDecimal(separateBaseAmount).multiply(platRatio);
|
||||
platAmount = platAmountDecimal.setScale(0, RoundingMode.HALF_UP).intValue();
|
||||
logger.debug("平台分账计算:可分账金额{} × 平台比例{} = {},四舍五入后={}", separateBaseAmount, platRatio, platAmountDecimal, platAmount);
|
||||
|
||||
// 一级代理商分账金额 = 可分账金额 × 一级代理商分账比例(四舍五入)
|
||||
if (agent1stRatio != null && agent1stRatio.compareTo(BigDecimal.ZERO) > 0) {
|
||||
BigDecimal agent1stAmountDecimal = new BigDecimal(separateBaseAmount).multiply(agent1stRatio);
|
||||
agent1stAmount = agent1stAmountDecimal.setScale(0, RoundingMode.HALF_UP).intValue();
|
||||
logger.debug("一级代理商分账计算:可分账金额{} × 一级代理商比例{} = {},四舍五入后={}", separateBaseAmount, agent1stRatio, agent1stAmountDecimal, agent1stAmount);
|
||||
} else {
|
||||
agent1stAmount = 0;
|
||||
}
|
||||
|
||||
// 二级代理商分账金额 = 可分账金额 × 二级代理商分账比例(四舍五入)
|
||||
if (agent2ndRatio != null && agent2ndRatio.compareTo(BigDecimal.ZERO) > 0) {
|
||||
BigDecimal agent2ndAmountDecimal = new BigDecimal(separateBaseAmount).multiply(agent2ndRatio);
|
||||
agent2ndAmount = agent2ndAmountDecimal.setScale(0, RoundingMode.HALF_UP).intValue();
|
||||
logger.debug("二级代理商分账计算:可分账金额{} × 二级代理商比例{} = {},四舍五入后={}", separateBaseAmount, agent2ndRatio, agent2ndAmountDecimal, agent2ndAmount);
|
||||
} else {
|
||||
agent2ndAmount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 按优先级进行分账(基于总金额)
|
||||
*/
|
||||
private void performSeparateBasedOnTotalAmount() {
|
||||
// 确定分账基数
|
||||
int separateBaseAmount = getSeparateBaseAmount();
|
||||
|
||||
// 平台分账金额 = 可分账金额 × 平台分账比例(四舍五入)
|
||||
BigDecimal platAmountDecimal = new BigDecimal(separateBaseAmount).multiply(platRatio);
|
||||
platAmount = platAmountDecimal.setScale(0, RoundingMode.HALF_UP).intValue();
|
||||
logger.debug("平台分账计算:可分账金额{} × 平台比例{} = {},四舍五入后={}", separateBaseAmount, platRatio, platAmountDecimal, platAmount);
|
||||
|
||||
// 一级代理商分账金额 = 可分账金额 × 一级代理商分账比例(四舍五入)
|
||||
if (agent1stRatio != null && agent1stRatio.compareTo(BigDecimal.ZERO) > 0) {
|
||||
BigDecimal agent1stAmountDecimal = new BigDecimal(separateBaseAmount).multiply(agent1stRatio);
|
||||
agent1stAmount = agent1stAmountDecimal.setScale(0, RoundingMode.HALF_UP).intValue();
|
||||
logger.debug("一级代理商分账计算:可分账金额{} × 一级代理商比例{} = {},四舍五入后={}", separateBaseAmount, agent1stRatio, agent1stAmountDecimal, agent1stAmount);
|
||||
} else {
|
||||
agent1stAmount = 0;
|
||||
}
|
||||
|
||||
// 二级代理商分账金额 = 可分账金额 × 二级代理商分账比例(四舍五入)
|
||||
if (agent2ndRatio != null && agent2ndRatio.compareTo(BigDecimal.ZERO) > 0) {
|
||||
BigDecimal agent2ndAmountDecimal = new BigDecimal(separateBaseAmount).multiply(agent2ndRatio);
|
||||
agent2ndAmount = agent2ndAmountDecimal.setScale(0, RoundingMode.HALF_UP).intValue();
|
||||
logger.debug("二级代理商分账计算:可分账金额{} × 二级代理商比例{} = {},四舍五入后={}", separateBaseAmount, agent2ndRatio, agent2ndAmountDecimal, agent2ndAmount);
|
||||
} else {
|
||||
agent2ndAmount = 0;
|
||||
}
|
||||
|
||||
// 商户分账金额 = 可分账金额 - 平台分账金额 - 一级代理商分账金额 - 二级代理商分账金额
|
||||
mchAmount = separateBaseAmount - platAmount - agent1stAmount - agent2ndAmount;
|
||||
logger.debug("商户分账计算:可分账金额{} - 平台分账{} - 一级代理商分账{} - 二级代理商分账{} = {}",
|
||||
separateBaseAmount, platAmount, agent1stAmount, agent2ndAmount, mchAmount);
|
||||
}
|
||||
|
||||
/**
|
||||
* 确保总额平衡
|
||||
*/
|
||||
private void balanceAmounts() {
|
||||
// 确定分账基数
|
||||
int separateBaseAmount = getSeparateBaseAmount();
|
||||
|
||||
int totalAmount = mchAmount + platAmount + agent1stAmount + agent2ndAmount;
|
||||
if (totalAmount != separateBaseAmount) {
|
||||
int diff = separateBaseAmount - totalAmount;
|
||||
logger.debug("分账总额与可分账金额不符,差额={},开始调整", diff);
|
||||
|
||||
// 将差额分配给优先级最低的参与方,确保总额平衡
|
||||
if (mchAmount + diff >= 0) {
|
||||
mchAmount += diff;
|
||||
logger.debug("调整商户分账金额:{} + {} = {}", mchAmount - diff, diff, mchAmount);
|
||||
} else if (agent2ndAmount > 0 && agent2ndAmount + diff >= 0) {
|
||||
agent2ndAmount += diff;
|
||||
logger.debug("调整二级代理商分账金额:{} + {} = {}", agent2ndAmount - diff, diff, agent2ndAmount);
|
||||
} else if (agent1stAmount > 0 && agent1stAmount + diff >= 0) {
|
||||
agent1stAmount += diff;
|
||||
logger.debug("调整一级代理商分账金额:{} + {} = {}", agent1stAmount - diff, diff, agent1stAmount);
|
||||
} else if (platAmount + diff >= 0) {
|
||||
platAmount += diff;
|
||||
logger.debug("调整平台分账金额:{} + {} = {}", platAmount - diff, diff, platAmount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保障各参与方分账比例不低于指定值(基于总金额的分账计算专用)
|
||||
* 忽略商户比例保障,只保障平台、一级代理商、二级代理商的比例
|
||||
*/
|
||||
private void guaranteeRatiosForTotalAmount() {
|
||||
// 平台优先级最高
|
||||
guaranteePlatformRatio();
|
||||
|
||||
// 一级代理商优先级次之
|
||||
guaranteeAgent1stRatio();
|
||||
|
||||
// 不保障商户比例,商户只分到剩余余额
|
||||
}
|
||||
|
||||
/**
|
||||
* 保障各参与方分账比例不低于指定值
|
||||
*/
|
||||
private void guaranteeRatios() {
|
||||
// 商户优先级最高
|
||||
guaranteeMerchantRatio();
|
||||
|
||||
// 平台优先级次之
|
||||
guaranteePlatformRatio();
|
||||
|
||||
// 一级代理商优先级再次之
|
||||
guaranteeAgent1stRatio();
|
||||
|
||||
// 最终验证和调整,确保所有参与方分账比例不低于指定值
|
||||
finalGuaranteeMerchantRatio();
|
||||
}
|
||||
|
||||
/**
|
||||
* 保障商户分账比例
|
||||
*/
|
||||
private void guaranteeMerchantRatio() {
|
||||
// 确定分账基数
|
||||
int separateBaseAmount = getSeparateBaseAmount();
|
||||
|
||||
BigDecimal actualMchRatio = new BigDecimal(mchAmount).divide(new BigDecimal(separateBaseAmount), 6, RoundingMode.HALF_UP);
|
||||
if (actualMchRatio.compareTo(mchRatio) < 0) {
|
||||
int requiredMchAmount = mchRatio.multiply(new BigDecimal(separateBaseAmount)).setScale(0, RoundingMode.HALF_UP).intValue();
|
||||
int diff = requiredMchAmount - mchAmount;
|
||||
if (diff > 0) {
|
||||
logger.debug("商户分账比例不足,需要调整金额={},商户当前金额={},应得金额={}", diff, mchAmount, requiredMchAmount);
|
||||
|
||||
if (agent2ndAmount > 0 && agent2ndAmount >= diff) {
|
||||
agent2ndAmount -= diff;
|
||||
mchAmount += diff;
|
||||
logger.debug("从二级代理商调整{}给商户,调整后:商户={},二级代理商={}", diff, mchAmount, agent2ndAmount);
|
||||
} else if (agent1stAmount > 0 && agent1stAmount >= diff) {
|
||||
agent1stAmount -= diff;
|
||||
mchAmount += diff;
|
||||
logger.debug("从一级代理商调整{}给商户,调整后:商户={},一级代理商={}", diff, mchAmount, agent1stAmount);
|
||||
} else if (platAmount >= diff) {
|
||||
platAmount -= diff;
|
||||
mchAmount += diff;
|
||||
logger.debug("从平台调整{}给商户,调整后:商户={},平台={}", diff, mchAmount, platAmount);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保障平台分账比例
|
||||
*/
|
||||
private void guaranteePlatformRatio() {
|
||||
// 确定分账基数
|
||||
int separateBaseAmount = getSeparateBaseAmount();
|
||||
|
||||
BigDecimal actualPlatRatio = new BigDecimal(platAmount).divide(new BigDecimal(separateBaseAmount), 6, RoundingMode.HALF_UP);
|
||||
if (actualPlatRatio.compareTo(platRatio) < 0) {
|
||||
int requiredPlatAmount = platRatio.multiply(new BigDecimal(separateBaseAmount)).setScale(0, RoundingMode.HALF_UP).intValue();
|
||||
int diff = requiredPlatAmount - platAmount;
|
||||
if (diff > 0) {
|
||||
logger.debug("平台分账比例不足,需要调整金额={},平台当前金额={},应得金额={}", diff, platAmount, requiredPlatAmount);
|
||||
|
||||
if (agent2ndAmount > 0 && agent2ndAmount >= diff) {
|
||||
agent2ndAmount -= diff;
|
||||
platAmount += diff;
|
||||
logger.debug("从二级代理商调整{}给平台,调整后:平台={},二级代理商={}", diff, platAmount, agent2ndAmount);
|
||||
} else if (agent1stAmount > 0 && agent1stAmount >= diff) {
|
||||
agent1stAmount -= diff;
|
||||
platAmount += diff;
|
||||
logger.debug("从一级代理商调整{}给平台,调整后:平台={},一级代理商={}", diff, platAmount, agent1stAmount);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保障一级代理商分账比例
|
||||
*/
|
||||
private void guaranteeAgent1stRatio() {
|
||||
// 确定分账基数
|
||||
int separateBaseAmount = getSeparateBaseAmount();
|
||||
|
||||
if (agent1stRatio != null && agent1stRatio.compareTo(BigDecimal.ZERO) > 0) {
|
||||
BigDecimal actualAgent1stRatio = new BigDecimal(agent1stAmount).divide(new BigDecimal(separateBaseAmount), 6, RoundingMode.HALF_UP);
|
||||
if (actualAgent1stRatio.compareTo(agent1stRatio) < 0) {
|
||||
int requiredAgent1stAmount = agent1stRatio.multiply(new BigDecimal(separateBaseAmount)).setScale(0, RoundingMode.HALF_UP).intValue();
|
||||
int diff = requiredAgent1stAmount - agent1stAmount;
|
||||
if (diff > 0) {
|
||||
logger.debug("一级代理商分账比例不足,需要调整金额={},一级代理商当前金额={},应得金额={}", diff, agent1stAmount, requiredAgent1stAmount);
|
||||
|
||||
if (agent2ndAmount > 0 && agent2ndAmount >= diff) {
|
||||
agent2ndAmount -= diff;
|
||||
agent1stAmount += diff;
|
||||
logger.debug("从二级代理商调整{}给一级代理商,调整后:一级代理商={},二级代理商={}", diff, agent1stAmount, agent2ndAmount);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 最终保障商户分账比例
|
||||
*/
|
||||
private void finalGuaranteeMerchantRatio() {
|
||||
// 确定分账基数
|
||||
int separateBaseAmount = getSeparateBaseAmount();
|
||||
|
||||
BigDecimal finalMchRatio = new BigDecimal(mchAmount).divide(new BigDecimal(separateBaseAmount), 6, RoundingMode.HALF_UP);
|
||||
if (finalMchRatio.compareTo(mchRatio) < 0) {
|
||||
int requiredMchAmount = mchRatio.multiply(new BigDecimal(separateBaseAmount)).setScale(0, RoundingMode.UP).intValue();
|
||||
int diff = requiredMchAmount - mchAmount;
|
||||
if (diff > 0) {
|
||||
logger.debug("商户最终分账比例仍不足,需要调整金额={},商户当前金额={},应得金额={}", diff, mchAmount, requiredMchAmount);
|
||||
|
||||
if (agent2ndAmount > 0 && agent2ndAmount >= diff) {
|
||||
agent2ndAmount -= diff;
|
||||
mchAmount += diff;
|
||||
logger.debug("最终调整:从二级代理商调整{}给商户,调整后:商户={},二级代理商={}", diff, mchAmount, agent2ndAmount);
|
||||
} else {
|
||||
int remainingDiff = diff - agent2ndAmount;
|
||||
if (agent1stAmount > 0 && agent1stAmount >= remainingDiff) {
|
||||
agent1stAmount -= remainingDiff;
|
||||
mchAmount += diff;
|
||||
logger.debug("最终调整:从一级代理商调整{}给商户,调整后:商户={},一级代理商={}", remainingDiff, mchAmount, agent1stAmount);
|
||||
} else {
|
||||
int remainingDiff2 = remainingDiff - agent1stAmount;
|
||||
if (platAmount >= remainingDiff2) {
|
||||
platAmount -= remainingDiff2;
|
||||
mchAmount += diff;
|
||||
logger.debug("最终调整:从平台调整{}给商户,调整后:商户={},平台={}", remainingDiff2, mchAmount, platAmount);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 向JSON字符串中添加属性
|
||||
*
|
||||
* @param json StringBuilder对象
|
||||
* @param key 属性名
|
||||
* @param value 属性值
|
||||
* @param first 是否为第一个属性
|
||||
*/
|
||||
private void appendProperty(StringBuilder json, String key, Object value, boolean first) {
|
||||
if (!first) {
|
||||
json.append(",");
|
||||
}
|
||||
json.append("\"").append(key).append("\":");
|
||||
if (value == null) {
|
||||
json.append("null");
|
||||
} else if (value instanceof String) {
|
||||
json.append("\"").append(value).append("\"");
|
||||
} else {
|
||||
json.append(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -32,7 +32,7 @@ import com.suisung.mall.common.modules.lakala.*;
|
||||
import com.suisung.mall.common.modules.order.ShopOrderLkl;
|
||||
import com.suisung.mall.common.modules.store.ShopMchEntry;
|
||||
import com.suisung.mall.common.modules.store.ShopStoreBase;
|
||||
import com.suisung.mall.common.pojo.dto.LklSeparateDTO;
|
||||
import com.suisung.mall.common.pojo.dto.LklSeparateDTOBak;
|
||||
import com.suisung.mall.common.service.impl.CommonService;
|
||||
import com.suisung.mall.common.utils.*;
|
||||
import com.suisung.mall.shop.lakala.service.*;
|
||||
@ -2064,12 +2064,12 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
separateRecord.setLog_no(separateRequest.getLogNo()); // 发货完成交易流水号后14位 。分账商户用该流水号发起分账
|
||||
separateRecord.setLog_date(separateRequest.getLogDate());
|
||||
separateRecord.setOrder_id(shopOrderLkl.getOrder_id());
|
||||
separateRecord.setTotal_amt(separateRequest.getTotalAmt());
|
||||
separateRecord.setNotify_url(separateRequest.getNotifyUrl());
|
||||
separateRecord.setLkl_org_no(separateRequest.getLklOrgNo());
|
||||
separateRecord.setRecv_datas(JSONUtil.toJsonStr(separateRequest.getRecvDatas()));
|
||||
separateRecord.setStatus(respData.getStr("status"));
|
||||
separateRecord.setTotal_separate_value(platformAmount + agentAmount);
|
||||
separateRecord.setTotal_amt(separateRequest.getTotalAmt());
|
||||
separateRecord.setActual_separate_amt(Convert.toStr(shopOrderLkl.getSplit_amt()));
|
||||
|
||||
try {
|
||||
if (lklOrderSeparateService.addOrUpdateByReceiverNo(separateRecord)) {
|
||||
@ -2160,19 +2160,11 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
LklOrderSeparate existingSeparateRecord = lklOrderSeparateService.getByLogNoAndOutTradeNo(
|
||||
shopOrderLkl.getLkl_receive_log_no(), shopOrderLkl.getOut_separate_no());
|
||||
|
||||
if (existingSeparateRecord != null) {
|
||||
String status = existingSeparateRecord.getStatus();
|
||||
switch (status) {
|
||||
case "SUCCESS":
|
||||
log.info("[分账操作] 订单[{}]交易对账流水号[{}]已完成分账,跳过处理", orderId, shopOrderLkl.getLkl_receive_log_no());
|
||||
return Pair.of(true, "订单已处理");
|
||||
case "PROCESSING":
|
||||
case "ACCEPTED":
|
||||
log.info("[分账操作] 订单[{}]交易对账流水号[{}]分账处理中或已受理,跳过处理", orderId, shopOrderLkl.getLkl_receive_log_no());
|
||||
return Pair.of(true, "订单已处理中或已受理");
|
||||
}
|
||||
} else if (CommonConstant.Enable.equals(shopOrderLkl.getSeparate_status())) {
|
||||
log.warn("[分账操作] 订单[{}]交易流水号[{}]订单已分账,跳过处理", orderId, receiveTradeNo);
|
||||
if (existingSeparateRecord != null
|
||||
&& "SUCCESS".equals(existingSeparateRecord.getStatus())
|
||||
&& "SUCCESS".equals(existingSeparateRecord.getFinal_status())
|
||||
&& CommonConstant.Enable.equals(shopOrderLkl.getSeparate_status())) {
|
||||
log.info("[分账操作] 订单[{}]交易对账流水号[{}]已完成分账,跳过处理", orderId, shopOrderLkl.getLkl_receive_log_no());
|
||||
return Pair.of(true, "订单已分账,请勿重复操作");
|
||||
}
|
||||
|
||||
@ -2229,31 +2221,31 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
BigDecimal wxFeeRatio = StrUtil.isEmpty(wxFee) ? BigDecimal.valueOf(0.0025) : new BigDecimal(wxFee).divide(BigDecimal.valueOf(100));
|
||||
|
||||
// 构建分账参数对象
|
||||
LklSeparateDTO lklSeparateDTO = new LklSeparateDTO();
|
||||
lklSeparateDTO.setTotalSeparateAmount(shopOrderLkl.getTotal_amt());
|
||||
lklSeparateDTO.setShippingFee(shoppingFeeInner);
|
||||
lklSeparateDTO.setLklRatio(wxFeeRatio); // 拉卡拉给的微信分账比例 0.0025 千分之2.5
|
||||
lklSeparateDTO.setMchRatio(mchSplitRatio);
|
||||
lklSeparateDTO.setPlatRatio(platformSplitRatio);
|
||||
LklSeparateDTOBak lklSeparateDTOBak = new LklSeparateDTOBak();
|
||||
lklSeparateDTOBak.setTotalSeparateAmount(shopOrderLkl.getTotal_amt());
|
||||
lklSeparateDTOBak.setShippingFee(shoppingFeeInner);
|
||||
lklSeparateDTOBak.setLklRatio(wxFeeRatio); // 拉卡拉给的微信分账比例 0.0025 千分之2.5
|
||||
lklSeparateDTOBak.setMchRatio(mchSplitRatio);
|
||||
lklSeparateDTOBak.setPlatRatio(platformSplitRatio);
|
||||
if (distributorSplitRatio.compareTo(BigDecimal.ZERO) > 0) { // 二级代理商参与分账
|
||||
lklSeparateDTO.setAgent2ndRatio(distributorSplitRatio);
|
||||
lklSeparateDTOBak.setAgent2ndRatio(distributorSplitRatio);
|
||||
}
|
||||
lklSeparateDTO.setRefCanSeparateAmount(canSeparateAmt); // 拉卡拉实时返回的可分账金额
|
||||
lklSeparateDTOBak.setRefCanSeparateAmount(canSeparateAmt); // 拉卡拉实时返回的可分账金额
|
||||
|
||||
// 分账方式:根据可分账金额分账
|
||||
Pair<Boolean, String> canSeparateAmtResult = lklSeparateDTO.calcOnCanSeparateAmount();
|
||||
Pair<Boolean, String> canSeparateAmtResult = lklSeparateDTOBak.calcOnCanSeparateAmount();
|
||||
if (!canSeparateAmtResult.getFirst()) {
|
||||
log.error("[分账操作] 分账参数评估,结果无法分账 {}", lklSeparateDTO);
|
||||
log.error("[分账操作] 分账参数评估,结果无法分账 {}", lklSeparateDTOBak);
|
||||
return Pair.of(false, "分账参数评估,结果无法分账");
|
||||
}
|
||||
|
||||
log.debug("[分账操作] 分账参数计算结果:{}", lklSeparateDTO);
|
||||
log.debug("[分账操作] 分账参数计算结果:{}", lklSeparateDTOBak);
|
||||
|
||||
// 更新分账计算结果
|
||||
shopOrderLkl.setSeparate_remark(lklSeparateDTO.toString());
|
||||
shopOrderLkl.setSeparate_remark(lklSeparateDTOBak.toString());
|
||||
if (CheckUtil.isEmpty(canSeparateAmt)) {
|
||||
shopOrderLkl.setSplit_amt(lklSeparateDTO.getCanSeparateAmount());
|
||||
canSeparateAmt = lklSeparateDTO.getCanSeparateAmount();
|
||||
shopOrderLkl.setSplit_amt(lklSeparateDTOBak.getCanSeparateAmount());
|
||||
canSeparateAmt = lklSeparateDTOBak.getCanSeparateAmount();
|
||||
} else {
|
||||
shopOrderLkl.setSplit_amt_ref(canSeparateAmt);
|
||||
}
|
||||
@ -2273,9 +2265,9 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
// 构建分账接收方列表
|
||||
List<V3SacsSeparateRecvDatas> recvDatas = new ArrayList<>();
|
||||
|
||||
Integer merchantAmount = lklSeparateDTO.getMchAmount();
|
||||
Integer platformAmount = lklSeparateDTO.getPlatAmount();
|
||||
Integer agentAmount = lklSeparateDTO.getAgent2ndAmount();
|
||||
Integer merchantAmount = lklSeparateDTOBak.getMchAmount();
|
||||
Integer platformAmount = lklSeparateDTOBak.getPlatAmount();
|
||||
Integer agentAmount = lklSeparateDTOBak.getAgent2ndAmount();
|
||||
|
||||
log.info("[分账操作] 金额计算结果:订单={}, 商户={}, 总金额={}分, 可分金额={}分, 商家比例={}, 商家分得={}分, 平台比例={}, 平台分得={}分, 代理商比例={}, 代理商分得={}分",
|
||||
orderId, merchantNo, shopOrderLkl.getTotal_amt(), canSeparateAmt, mchSplitRatio, merchantAmount,
|
||||
@ -2363,12 +2355,14 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
separateRecord.setLog_no(separateRequest.getLogNo());
|
||||
separateRecord.setLog_date(separateRequest.getLogDate());
|
||||
separateRecord.setOrder_id(shopOrderLkl.getOrder_id());
|
||||
separateRecord.setTotal_amt(separateRequest.getTotalAmt());
|
||||
|
||||
separateRecord.setNotify_url(separateRequest.getNotifyUrl());
|
||||
separateRecord.setLkl_org_no(separateRequest.getLklOrgNo());
|
||||
separateRecord.setRecv_datas(JSONUtil.toJsonStr(separateRequest.getRecvDatas()));
|
||||
separateRecord.setStatus(respData.getStr("status"));
|
||||
separateRecord.setTotal_separate_value(canSeparateAmt);
|
||||
separateRecord.setTotal_amt(separateRequest.getTotalAmt());
|
||||
separateRecord.setActual_separate_amt(Convert.toStr(canSeparateAmt));
|
||||
separateRecord.setTotal_fee_amt(Convert.toStr(lklSeparateDTOBak.getLklAmount()));
|
||||
|
||||
if (lklOrderSeparateService.addOrUpdateByReceiverNo(separateRecord)) {
|
||||
log.info("[分账操作] 记录保存成功:订单={}, 分账单号={}, 状态={}, 分账流水号={}",
|
||||
@ -2390,260 +2384,6 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Pair<Boolean, String> innerDoOrderSeparateByMerchantAndLogNoBak(String lklMerchantNo, String receiveTradeNo, String receiveLogNo) {
|
||||
// 1. 输入参数校验
|
||||
if (StrUtil.isBlank(lklMerchantNo) || StrUtil.isBlank(receiveTradeNo) || StrUtil.isBlank(receiveLogNo)) {
|
||||
log.warn("[分账操作] 参数校验失败:缺少必要参数, lklMerchantNo={}, receiveTradeNo={}, receiveLogNo={}",
|
||||
lklMerchantNo, receiveTradeNo, receiveLogNo);
|
||||
return Pair.of(false, "缺少必要参数");
|
||||
}
|
||||
|
||||
try {
|
||||
log.info("[分账操作] 开始处理分账请求, lklMerchantNo={}, receiveTradeNo={}, receiveLogNo={}",
|
||||
lklMerchantNo, receiveTradeNo, receiveLogNo);
|
||||
|
||||
// 2. 查询订单信息
|
||||
ShopOrderLkl shopOrderLkl = shopOrderLklService.getByLklMchNoAndReceiveTradeNoAndReceiveLogNo(lklMerchantNo, receiveTradeNo, receiveLogNo);
|
||||
if (shopOrderLkl == null) {
|
||||
log.warn("[分账操作] 失败:对账流水号[{}]不存在", receiveLogNo);
|
||||
return Pair.of(false, "订单不存在");
|
||||
}
|
||||
|
||||
// TODO 检查可分账余额是否足够?
|
||||
Pair<String, String> balanceCheckResult = queryMchCanSplitAmt(lklMerchantNo, receiveLogNo, shopOrderLkl.getLkl_log_date());
|
||||
if (balanceCheckResult == null) {
|
||||
log.error("[分账操作] 查询可分账余额失败:lklMerchantNo={} logDate={} receiveLogNo={}", lklMerchantNo, shopOrderLkl.getLkl_log_date(), receiveLogNo);
|
||||
}
|
||||
|
||||
log.warn("[分账操作] 可分账余额检查结果:分账总余额={}分 可分账金额={}分", balanceCheckResult.getFirst(), balanceCheckResult.getSecond());
|
||||
Integer canSeparateAmt = Convert.toInt(balanceCheckResult.getSecond());
|
||||
if (canSeparateAmt == null || canSeparateAmt <= 0) {
|
||||
log.warn("[分账操作] lklMerchantNo={} receiveTradeNo={} receiveLogNo={} 可分账金额={}分 可分账余额不足,跳过处理", lklMerchantNo, receiveTradeNo, receiveLogNo, balanceCheckResult.getSecond());
|
||||
return Pair.of(false, "可分账余额不足");
|
||||
}
|
||||
|
||||
String orderId = shopOrderLkl.getOrder_id();
|
||||
log.info("[分账操作] 开始处理订单[{}]的分账", orderId);
|
||||
|
||||
// 3. 检查是否已确认收货
|
||||
if (!CommonConstant.Enable.equals(shopOrderLkl.getReceive_status())) {
|
||||
log.warn("[分账操作] 订单[{}]交易流水号[{}]未被确认收货,跳过处理", orderId, receiveTradeNo);
|
||||
return Pair.of(false, "订单未确认收货,暂无法分账");
|
||||
}
|
||||
|
||||
if (CommonConstant.Enable.equals(shopOrderLkl.getSeparate_status())) {
|
||||
log.warn("[分账操作] 订单[{}]交易流水号[{}]未被确认收货,跳过处理", orderId, receiveTradeNo);
|
||||
return Pair.of(true, "订单已分账,请勿重复操作");
|
||||
}
|
||||
|
||||
// 4. 检查分账状态,避免重复处理
|
||||
LklOrderSeparate existingSeparateRecord = lklOrderSeparateService.getByLogNoAndOutTradeNo(shopOrderLkl.getLkl_receive_log_no(), shopOrderLkl.getOut_separate_no());
|
||||
if (existingSeparateRecord != null) {
|
||||
String status = existingSeparateRecord.getStatus();
|
||||
if ("SUCCESS".equals(status)) {
|
||||
log.info("[分账操作] 订单[{}]交易对账流水号[{}]已完成分账,跳过处理", orderId, shopOrderLkl.getLkl_sub_log_no());
|
||||
return Pair.of(true, "订单已处理");
|
||||
}
|
||||
if ("PROCESSING".equals(status) || "ACCEPTED".equals(status)) {
|
||||
log.info("[分账操作] 订单[{}]交易对账流水号[{}]分账处理中或已受理,跳过处理", orderId, shopOrderLkl.getLkl_sub_log_no());
|
||||
return Pair.of(true, "订单已处理中或已受理");
|
||||
}
|
||||
}
|
||||
|
||||
// 5. 获取订单分账相关参数
|
||||
String merchantNo = shopOrderLkl.getLkl_merchant_no();
|
||||
|
||||
// 分账金额 = 应付总金额-运费(支付时已计算好)
|
||||
Integer splitAmount = shopOrderLkl.getSplit_amt();
|
||||
splitAmount = CheckUtil.isEmpty(splitAmount) ? 0 : splitAmount;
|
||||
|
||||
// 6. 分账金额校验
|
||||
if (splitAmount < 1) {
|
||||
String errorMsg = String.format("[分账操作] 店铺[%s]订单[%s]分账金额[%d]低于1分钱,跳过分账",
|
||||
shopOrderLkl.getStore_id(), orderId, splitAmount);
|
||||
log.error(errorMsg);
|
||||
if (existingSeparateRecord != null) {
|
||||
lklOrderSeparateService.updateRemark(existingSeparateRecord.getId(), errorMsg);
|
||||
}
|
||||
return Pair.of(false, "订单分账金额低于1分钱");
|
||||
}
|
||||
|
||||
// 7. 获取分账平台接收方信息
|
||||
LklLedgerMerReceiverBind platformReceiver = lklLedgerMerReceiverBindService.getPlatformByMerCupNo(merchantNo);
|
||||
if (platformReceiver == null) {
|
||||
String errorMsg = String.format("[分账操作] 店铺[%s]未绑定平台方接收账户,跳过分账", shopOrderLkl.getStore_id());
|
||||
log.error(errorMsg);
|
||||
return Pair.of(false, "平台方未绑定账户");
|
||||
}
|
||||
|
||||
// 8. 构建分账接收方列表
|
||||
List<V3SacsSeparateRecvDatas> recvDatas = new ArrayList<>();
|
||||
|
||||
// 9. 获取商家分账比例并校验
|
||||
BigDecimal merchantSplitRatioRaw = shopOrderLkl.getSplit_ratio();
|
||||
// 判断商家分账比例是否有效(必须在(0, 100]范围内)
|
||||
boolean canSplitForMerchant = merchantSplitRatioRaw != null
|
||||
&& merchantSplitRatioRaw.compareTo(BigDecimal.ZERO) > 0
|
||||
&& merchantSplitRatioRaw.compareTo(new BigDecimal(100)) <= 0;
|
||||
if (!canSplitForMerchant) {
|
||||
String errorMsg = String.format("[分账操作] 店铺[%s]商家分账比例[%s]不在(0-100]范围内,无法分账",
|
||||
shopOrderLkl.getStore_id(), merchantSplitRatioRaw);
|
||||
log.error(errorMsg);
|
||||
return Pair.of(false, "商家分账比例无效");
|
||||
}
|
||||
|
||||
// 10. 计算商家分账比例(转换为小数)
|
||||
BigDecimal merchantSplitRatio = merchantSplitRatioRaw.divide(new BigDecimal(100));
|
||||
|
||||
// 11. 获取代理商分账信息
|
||||
BigDecimal distributorSplitRatio = BigDecimal.ZERO;
|
||||
BigDecimal platformSplitRatio = BigDecimal.ONE;
|
||||
List<LklLedgerMerReceiverBind> distributorReceivers = lklLedgerMerReceiverBindService.selectDistributorByMerCupNo(merchantNo);
|
||||
if (distributorReceivers != null && !distributorReceivers.isEmpty()) {
|
||||
distributorSplitRatio = new BigDecimal("0.8");
|
||||
platformSplitRatio = new BigDecimal("0.2");
|
||||
log.debug("[分账操作] 检测到代理商存在,调整分账比例: 代理商比例={}, 平台比例={}", distributorSplitRatio, platformSplitRatio);
|
||||
}
|
||||
|
||||
// 12. 记录关键分账参数,便于问题排查
|
||||
log.info("[分账操作] 参数信息:订单={}, 商户={}, 总金额={}分, 商家比例={}, 平台比例={}, 代理商比例={}, 是否有代理商={}",
|
||||
orderId, merchantNo, splitAmount, merchantSplitRatio, platformSplitRatio, distributorSplitRatio,
|
||||
(distributorReceivers != null && !distributorReceivers.isEmpty()));
|
||||
|
||||
// 13. 计算各参与方分账金额
|
||||
Map<String, Integer> splitAmountMap = CommonUtil.calculateProfitSharing(splitAmount, merchantSplitRatio, platformSplitRatio, distributorSplitRatio);
|
||||
Integer merchantAmount = splitAmountMap.get("merchantAmount");
|
||||
Integer platformAmount = splitAmountMap.get("platformAmount");
|
||||
Integer agentAmount = splitAmountMap.get("agentAmount");
|
||||
|
||||
// 14. 记录分账结果,便于问题排查
|
||||
log.info("[分账操作] 金额计算结果:订单={}, 商户={}, 总金额={}分, 商家分得={}分, 平台分得={}分, 代理商分得={}分",
|
||||
orderId, merchantNo, splitAmount, merchantAmount, platformAmount, agentAmount);
|
||||
|
||||
// 15. 构建分账接收方列表
|
||||
if (merchantAmount > 0) {
|
||||
V3SacsSeparateRecvDatas receiver = new V3SacsSeparateRecvDatas();
|
||||
receiver.setRecvMerchantNo(merchantNo);
|
||||
receiver.setSeparateValue(merchantAmount.toString());
|
||||
recvDatas.add(receiver);
|
||||
log.debug("[分账操作] 添加商家接收方: merchantNo={}, amount={}", merchantNo, merchantAmount);
|
||||
}
|
||||
|
||||
if (platformAmount > 0) {
|
||||
V3SacsSeparateRecvDatas receiver = new V3SacsSeparateRecvDatas();
|
||||
receiver.setRecvNo(platformReceiver.getReceiver_no());
|
||||
receiver.setSeparateValue(platformAmount.toString());
|
||||
recvDatas.add(receiver);
|
||||
log.debug("[分账操作] 添加平台接收方: receiverNo={}, amount={}", platformReceiver.getReceiver_no(), platformAmount);
|
||||
}
|
||||
|
||||
if (agentAmount > 0 && distributorReceivers != null && !distributorReceivers.isEmpty()) {
|
||||
V3SacsSeparateRecvDatas receiver = new V3SacsSeparateRecvDatas();
|
||||
receiver.setRecvNo(distributorReceivers.get(0).getReceiver_no());
|
||||
receiver.setSeparateValue(agentAmount.toString());
|
||||
recvDatas.add(receiver);
|
||||
log.debug("[分账操作] 添加代理商接收方: receiverNo={}, amount={}", distributorReceivers.get(0).getReceiver_no(), agentAmount);
|
||||
}
|
||||
|
||||
// 16. 初始化拉卡拉SDK
|
||||
log.debug("[分账操作] 初始化拉卡拉SDK");
|
||||
initLKLSDK();
|
||||
|
||||
// 17. 构建分账请求对象
|
||||
V3SacsSeparateRequest separateRequest = new V3SacsSeparateRequest();
|
||||
separateRequest.setMerchantNo(merchantNo);
|
||||
separateRequest.setOutSeparateNo(shopOrderLkl.getOut_separate_no());
|
||||
separateRequest.setLogNo(shopOrderLkl.getLkl_receive_log_no()); // 使用确认收货流水号作为分账流水号
|
||||
separateRequest.setLogDate(shopOrderLkl.getLkl_log_date());
|
||||
separateRequest.setTotalAmt(splitAmount.toString());
|
||||
separateRequest.setLklOrgNo(orgCode);
|
||||
separateRequest.setCalType("0"); // 0- 按照指定金额,1- 按照指定比例。默认 0
|
||||
separateRequest.setNotifyUrl(projectDomain + "/api/mobile/shop/lakala/sacs/separateNotify");
|
||||
|
||||
// 18. 设置分账接收方列表
|
||||
separateRequest.setRecvDatas(recvDatas);
|
||||
log.info("[分账操作] 请求参数: 订单={}, 商户={}, 金额={}分, 分账接收方数量={}",
|
||||
orderId, merchantNo, splitAmount, recvDatas.size());
|
||||
|
||||
log.debug("[分账操作] 请求详细参数: {}", JSONUtil.toJsonStr(separateRequest));
|
||||
|
||||
// 19. 发送分账请求
|
||||
log.info("[分账操作] 向拉卡拉发送分账请求:订单={}, 商户={}, 分账流水号={}",
|
||||
orderId, merchantNo, shopOrderLkl.getLkl_receive_log_no());
|
||||
String response = LKLSDK.httpPost(separateRequest);
|
||||
if (StrUtil.isBlank(response)) {
|
||||
String errorMsg = String.format("[分账操作] 拉卡拉无响应,订单=%s,商户=%s,分账流水号=%s",
|
||||
orderId, merchantNo, shopOrderLkl.getLkl_receive_log_no());
|
||||
// 更改分账状态:分账失败
|
||||
shopOrderLklService.updateSeparateStatusByReceiveLogNo(shopOrderLkl.getLkl_receive_log_no(), CommonConstant.Sta_Separate_Fail, errorMsg);
|
||||
log.error(errorMsg);
|
||||
return Pair.of(false, "拉卡拉无响应");
|
||||
}
|
||||
|
||||
log.debug("[分账操作] 响应结果: {}", response);
|
||||
|
||||
// 20. 解析响应结果
|
||||
JSONObject respJson = JSONUtil.parseObj(response);
|
||||
if (respJson == null || !lklSacsSuccessCode.equals(respJson.getStr("code")) || respJson.getJSONObject("resp_data") == null) {
|
||||
String errorMsg = String.format("[分账操作] 拉卡拉返回格式异常,订单=%s,商户=%s,分账流水号=%s,响应=%s,respJson=%s",
|
||||
orderId, merchantNo, shopOrderLkl.getLkl_receive_log_no(), response, respJson);
|
||||
// 更改分账状态:分账失败
|
||||
shopOrderLklService.updateSeparateStatusByReceiveLogNo(shopOrderLkl.getLkl_receive_log_no(), CommonConstant.Sta_Separate_Fail, errorMsg);
|
||||
log.error(errorMsg);
|
||||
return Pair.of(false, "拉卡拉分账异常:[" + respJson.getStr("code") + "]" + respJson.getStr("msg"));
|
||||
}
|
||||
|
||||
// 21. 保存分账记录
|
||||
JSONObject respData = respJson.getJSONObject("resp_data");
|
||||
LklOrderSeparate separateRecord = new LklOrderSeparate();
|
||||
separateRecord.setSeparate_no(respData.getStr("separate_no"));
|
||||
separateRecord.setOut_separate_no(separateRequest.getOutSeparateNo());
|
||||
separateRecord.setMerchant_no(merchantNo);
|
||||
separateRecord.setLog_no(separateRequest.getLogNo());
|
||||
separateRecord.setLog_date(separateRequest.getLogDate());
|
||||
separateRecord.setOrder_id(shopOrderLkl.getOrder_id());
|
||||
separateRecord.setTotal_amt(separateRequest.getTotalAmt());
|
||||
separateRecord.setNotify_url(separateRequest.getNotifyUrl());
|
||||
separateRecord.setLkl_org_no(separateRequest.getLklOrgNo());
|
||||
separateRecord.setRecv_datas(JSONUtil.toJsonStr(separateRequest.getRecvDatas()));
|
||||
separateRecord.setStatus(respData.getStr("status"));
|
||||
separateRecord.setTotal_separate_value(platformAmount + agentAmount);
|
||||
|
||||
try {
|
||||
if (lklOrderSeparateService.addOrUpdateByReceiverNo(separateRecord)) {
|
||||
log.info("[分账操作] 记录保存成功:订单={}, 分账单号={}, 状态={}, 分账流水号={}",
|
||||
orderId, separateRecord.getSeparate_no(), separateRecord.getStatus(), separateRecord.getLog_no());
|
||||
} else {
|
||||
String errorMsg = String.format("[分账操作] 保存分账记录失败,订单=%s,分账单号=%s,分账流水号=%s",
|
||||
orderId, separateRecord.getSeparate_no(), separateRecord.getLog_no());
|
||||
log.error(errorMsg);
|
||||
lklOrderSeparateService.updateRemark(separateRecord.getLog_no(), separateRecord.getSeparate_no(), errorMsg);
|
||||
return Pair.of(false, "保存分账记录失败");
|
||||
}
|
||||
|
||||
// 保存 shop_order_lkl 关键字段
|
||||
|
||||
String result = "订单分账已提交处理";
|
||||
log.info("[分账操作] 结果:订单[{}] {}", orderId, result);
|
||||
return Pair.of(true, result);
|
||||
} catch (Exception e) {
|
||||
String errorMsg = String.format("[分账操作] 保存分账记录异常,订单=%s,分账单号=%s,流水号=%s,错误=%s",
|
||||
orderId,
|
||||
separateRecord.getSeparate_no(),
|
||||
separateRecord.getLog_no(),
|
||||
e.getMessage());
|
||||
log.error(errorMsg, e);
|
||||
return Pair.of(false, "保存分账记录异常");
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
String errorMsg = String.format("[分账操作] 系统异常,分账对账流水号=%s,错误=%s", receiveLogNo, e.getMessage());
|
||||
log.error(errorMsg, e);
|
||||
return Pair.of(false, "系统异常,请稍后重试");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 拉卡拉分账结果通知处理
|
||||
* <p>
|
||||
@ -2729,15 +2469,6 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
.put("message", "分账已处理成功,请不要重复通知");
|
||||
}
|
||||
|
||||
if (!"FAIL".equals(existingFinalStatus) && StrUtil.isNotBlank(existingFinalStatus)) {
|
||||
String warnMsg = "已受理或处理中,成功后再通知";
|
||||
log.warn("[拉卡拉分账通知] {},订单号={},外部分账单号={},参数详情: {}",
|
||||
warnMsg, logNo, outSeparateNo, paramsJson);
|
||||
return JSONUtil.createObj()
|
||||
.put("code", "FAIL")
|
||||
.put("message", "已受理或处理中,成功后再通知");
|
||||
}
|
||||
|
||||
// 6. 记录关键参数信息,便于问题排查
|
||||
log.info("[拉卡拉分账通知] 接收到分账通知,分账单号={},外部分账单号={},状态={},最终状态={}",
|
||||
separateNo, outSeparateNo, status, finalStatus);
|
||||
@ -2753,9 +2484,12 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
lklOrderSeparate.setSeparate_type(paramsJson.getStr("separate_type"));
|
||||
lklOrderSeparate.setSeparate_date(paramsJson.getStr("separate_date"));
|
||||
// 总计分账金额
|
||||
lklOrderSeparate.setTotal_separate_value(paramsJson.getInt("total_separate_value", 0));
|
||||
lklOrderSeparate.setTotal_amt(paramsJson.getStr("total_amt", "0"));
|
||||
lklOrderSeparate.setActual_separate_amt(paramsJson.getStr("actual_separate_amt", "0"));
|
||||
lklOrderSeparate.setTotal_fee_amt(paramsJson.getStr("total_fee_amt", "0"));
|
||||
lklOrderSeparate.setRemark("分账已完成");
|
||||
lklOrderSeparate.setFinish_date(paramsJson.getStr("finish_date"));
|
||||
lklOrderSeparate.setNotify_resp(signCheckResult.getSecond());
|
||||
|
||||
// 处理detail_datas(避免空指针)
|
||||
JSONArray detailDatas = paramsJson.getJSONArray("detail_datas");
|
||||
@ -2774,7 +2508,7 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
}
|
||||
|
||||
// 更改分账状态:分账成功
|
||||
shopOrderLklService.updateSeparateStatusByReceiveLogNo(logNo, CommonConstant.Sta_Separate_Success, "分账成功");
|
||||
shopOrderLklService.updateSeparateStatusByReceiveLogNo(logNo, CommonConstant.Sta_Separate_Success, "");
|
||||
|
||||
// 9. 记录处理成功日志
|
||||
log.info("[拉卡拉分账通知] 分账通知处理成功, separateNo={}, status={}", separateNo, status);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user