可用分账金额查询接口开发

This commit is contained in:
Jack 2025-09-17 22:22:20 +08:00
parent 2a26e37d62
commit fc4f4c408d

View File

@ -79,13 +79,16 @@ public class LklSeparateDTO implements java.io.Serializable {
logger.info("开始测试分账计算功能..."); logger.info("开始测试分账计算功能...");
// 临界点测试用例2: 小金额测试 // 临界点测试用例2: 小金额测试
logger.info("\n\n临界点测试用例2 - 小金额测试:"); logger.info("\n临界点测试用例2 - 小金额测试:");
LklSeparateDTO dto2 = new LklSeparateDTO(); LklSeparateDTO dto2 = new LklSeparateDTO();
dto2.setTotalSeparateAmount(800); dto2.setTotalSeparateAmount(2);
dto2.setShippingFee(500); dto2.setShippingFee(0);
dto2.setLklRatio(new BigDecimal("0.0025")); dto2.setLklRatio(new BigDecimal("0.0025"));
dto2.setMchRatio(new BigDecimal("0.94")); dto2.setMchRatio(new BigDecimal("0.96"));
dto2.setPlatRatio(new BigDecimal("0.06")); dto2.setPlatRatio(new BigDecimal("0.01"));
dto2.setAgent1stRatio(new BigDecimal("0.01"));
dto2.setAgent2ndRatio(new BigDecimal("0.04"));
dto2.setRefCanSeparateAmount(8079); // 设置参考可分账金额
logger.info("测试参数: 总分账金额={}分, 配送费={}分, 拉卡拉比例={}, 商户比例={}, 平台比例={}", logger.info("测试参数: 总分账金额={}分, 配送费={}分, 拉卡拉比例={}, 商户比例={}, 平台比例={}",
dto2.getTotalSeparateAmount(), dto2.getShippingFee(), dto2.getLklRatio(), dto2.getTotalSeparateAmount(), dto2.getShippingFee(), dto2.getLklRatio(),
@ -98,116 +101,111 @@ public class LklSeparateDTO implements java.io.Serializable {
dto2.getTotalSeparateAmount(), dto2.getLklAmount(), dto2.getShippingFee(), dto2.getCanSeparateAmount(), dto2.getRefCanSeparateAmount(), dto2.getTotalSeparateAmount(), dto2.getLklAmount(), dto2.getShippingFee(), dto2.getCanSeparateAmount(), dto2.getRefCanSeparateAmount(),
dto2.getMchAmount(), dto2.getPlatAmount(), dto2.getAgent1stAmount(), dto2.getAgent2ndAmount()); dto2.getMchAmount(), dto2.getPlatAmount(), dto2.getAgent1stAmount(), dto2.getAgent2ndAmount());
double lklRatioOfTotal = (double) dto2.getLklAmount() / dto2.getTotalSeparateAmount() * 100; // 计算并打印各分账方占可分账金额和总金额的百分比
double mchRatioOfTotal = (double) dto2.getMchAmount() / dto2.getTotalSeparateAmount() * 100; int canSeparateAmount = dto2.getCanSeparateAmount();
double platRatioOfTotal = (double) dto2.getPlatAmount() / dto2.getTotalSeparateAmount() * 100; int totalSeparateAmount = dto2.getTotalSeparateAmount();
double agent1stRatioOfTotal = 0.0;
double agent2ndRatioOfTotal = 0.0;
// 安全检查避免空指针异常 if (canSeparateAmount > 0) {
if (dto2.getAgent1stAmount() != null) { double lklRatioOfTotal = (double) dto2.getLklAmount() / totalSeparateAmount * 100;
agent1stRatioOfTotal = (double) dto2.getAgent1stAmount() / dto2.getTotalSeparateAmount() * 100; double mchRatioOfTotal = (double) dto2.getMchAmount() / totalSeparateAmount * 100;
} double platRatioOfTotal = (double) dto2.getPlatAmount() / totalSeparateAmount * 100;
if (dto2.getAgent2ndAmount() != null) { double agent1stRatioOfTotal = 0.0;
agent2ndRatioOfTotal = (double) dto2.getAgent2ndAmount() / dto2.getTotalSeparateAmount() * 100; double agent2ndRatioOfTotal = 0.0;
}
double lklRatioOfAvailable = (double) dto2.getLklAmount() / dto2.getCanSeparateAmount() * 100; // 安全检查避免空指针异常
double mchRatioOfAvailable = (double) dto2.getMchAmount() / dto2.getCanSeparateAmount() * 100; if (dto2.getAgent1stAmount() != null) {
double platRatioOfAvailable = (double) dto2.getPlatAmount() / dto2.getCanSeparateAmount() * 100; agent1stRatioOfTotal = (double) dto2.getAgent1stAmount() / totalSeparateAmount * 100;
double agent1stRatioOfAvailable = 0.0; }
double agent2ndRatioOfAvailable = 0.0; if (dto2.getAgent2ndAmount() != null) {
agent2ndRatioOfTotal = (double) dto2.getAgent2ndAmount() / totalSeparateAmount * 100;
}
// 安全检查避免空指针异常 double lklRatioOfAvailable = (double) dto2.getLklAmount() / canSeparateAmount * 100;
if (dto2.getAgent1stAmount() != null) { double mchRatioOfAvailable = (double) dto2.getMchAmount() / canSeparateAmount * 100;
agent1stRatioOfAvailable = (double) dto2.getAgent1stAmount() / dto2.getCanSeparateAmount() * 100; double platRatioOfAvailable = (double) dto2.getPlatAmount() / canSeparateAmount * 100;
} double agent1stRatioOfAvailable = 0.0;
if (dto2.getAgent2ndAmount() != null) { double agent2ndRatioOfAvailable = 0.0;
agent2ndRatioOfAvailable = (double) dto2.getAgent2ndAmount() / dto2.getCanSeparateAmount() * 100;
}
logger.info("占比详情 (总金额占比 / 可分账金额占比): 拉卡拉={}% / {}%, 商户={}% / {}%, 平台={}% / {}%, 一级代理商={}% / {}%, 二级代理商={}% / {}%", // 安全检查避免空指针异常
String.format("%.4f", lklRatioOfTotal), String.format("%.4f", lklRatioOfAvailable), if (dto2.getAgent1stAmount() != null) {
String.format("%.4f", mchRatioOfTotal), String.format("%.4f", mchRatioOfAvailable), agent1stRatioOfAvailable = (double) dto2.getAgent1stAmount() / canSeparateAmount * 100;
String.format("%.4f", platRatioOfTotal), String.format("%.4f", platRatioOfAvailable), }
String.format("%.4f", agent1stRatioOfTotal), String.format("%.4f", agent1stRatioOfAvailable), if (dto2.getAgent2ndAmount() != null) {
String.format("%.4f", agent2ndRatioOfTotal), String.format("%.4f", agent2ndRatioOfAvailable)); 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() + int total = dto2.getLklAmount() + dto2.getMchAmount() + dto2.getPlatAmount() +
(dto2.getAgent1stAmount() != null ? dto2.getAgent1stAmount() : 0) + (dto2.getAgent1stAmount() != null ? dto2.getAgent1stAmount() : 0) +
(dto2.getAgent2ndAmount() != null ? dto2.getAgent2ndAmount() : 0) + dto2.getShippingFee(); (dto2.getAgent2ndAmount() != null ? dto2.getAgent2ndAmount() : 0) + dto2.getShippingFee();
logger.info("金额校验: {} (计算总金额={}分, 原始总金额={}分)", (total == dto2.getTotalSeparateAmount() ? "通过" : "不通过"), total, dto2.getTotalSeparateAmount()); logger.info("金额校验: {} (计算总金额={}分, 原始总金额={}分)", (total == dto2.getTotalSeparateAmount() ? "通过" : "不通过"), total, dto2.getTotalSeparateAmount());
} }
}
// 基于总金额的分账计算测试用例带refCanSeparateAmount /**
logger.info("\n\n基于总金额的分账计算测试用例 - 带参考可分账金额:"); * 将对象转换为JSON字符串格式
LklSeparateDTO dto7 = new LklSeparateDTO(); *
dto7.setTotalSeparateAmount(1); * @return 包含所有属性的JSON字符串
dto7.setShippingFee(0); */
dto7.setLklRatio(new BigDecimal("0.0025")); // 拉卡拉比例0.25% public String toJSON() {
dto7.setMchRatio(new BigDecimal("0.94")); // 商户比例90% StringBuilder json = new StringBuilder();
dto7.setPlatRatio(new BigDecimal("0.01")); // 平台比例5% json.append("{");
// dto7.setAgent1stRatio(new BigDecimal("0.01"));
// dto7.setAgent2ndRatio(new BigDecimal("0.04"));
// dto7.setRefCanSeparateAmount(8079); // 设置参考可分账金额
logger.info("测试参数: 总分账金额={}分, 配送费={}分, 拉卡拉比例={}, 商户比例={}, 平台比例={}, 一级代理商比例={}, 二级代理商比例={}, 参考可分账金额={}分", // 添加基本属性
dto7.getTotalSeparateAmount(), dto7.getShippingFee(), dto7.getLklRatio(), dto7.getMchRatio(), appendProperty(json, "totalSeparateAmount", totalSeparateAmount, true);
dto7.getPlatRatio(), dto7.getAgent1stRatio(), dto7.getAgent2ndRatio(), dto7.getRefCanSeparateAmount()); appendProperty(json, "canSeparateAmount", canSeparateAmount, false);
appendProperty(json, "refCanSeparateAmount", refCanSeparateAmount, false);
appendProperty(json, "shippingFee", shippingFee, false);
boolean result7 = dto7.calcOnTotalAmount(); // 添加比例属性
logger.info("基于总金额的分账计算结果(带参考可分账金额): {}", (result7 ? "成功" : "失败")); appendProperty(json, "lklRatio", lklRatio, false);
if (result7) { appendProperty(json, "mchRatio", mchRatio, false);
logger.info("分账结果: 总金额={}分, 拉卡拉={}分, 配送费={}分, 可分账={}分, 参考可分账={}分, 商户={}分, 平台={}分, 一级代理商={}分, 二级代理商={}分", appendProperty(json, "platRatio", platRatio, false);
dto7.getTotalSeparateAmount(), dto7.getLklAmount(), dto7.getShippingFee(), dto7.getCanSeparateAmount(), dto7.getRefCanSeparateAmount(), appendProperty(json, "agent1stRatio", agent1stRatio, false);
dto7.getMchAmount(), dto7.getPlatAmount(), dto7.getAgent1stAmount(), dto7.getAgent2ndAmount()); appendProperty(json, "agent2ndRatio", agent2ndRatio, false);
double lklRatioOfTotal = (double) dto7.getLklAmount() / dto7.getTotalSeparateAmount() * 100; // 添加金额属性
double mchRatioOfTotal = (double) dto7.getMchAmount() / dto7.getTotalSeparateAmount() * 100; appendProperty(json, "lklAmount", lklAmount, false);
double platRatioOfTotal = (double) dto7.getPlatAmount() / dto7.getTotalSeparateAmount() * 100; appendProperty(json, "mchAmount", mchAmount, false);
double agent1stRatioOfTotal = 0.0; appendProperty(json, "platAmount", platAmount, false);
double agent2ndRatioOfTotal = 0.0; appendProperty(json, "agent1stAmount", agent1stAmount, false);
appendProperty(json, "agent2ndAmount", agent2ndAmount, false);
// 安全检查避免空指针异常 // 移除最后的逗号并关闭JSON对象
if (dto7.getAgent1stAmount() != null) { if (json.charAt(json.length() - 1) == ',') {
agent1stRatioOfTotal = (double) dto7.getAgent1stAmount() / dto7.getTotalSeparateAmount() * 100; json.setLength(json.length() - 1);
} }
if (dto7.getAgent2ndAmount() != null) { json.append("}");
agent2ndRatioOfTotal = (double) dto7.getAgent2ndAmount() / dto7.getTotalSeparateAmount() * 100;
}
double lklRatioOfAvailable = (double) dto7.getLklAmount() / dto7.getCanSeparateAmount() * 100; return json.toString();
double mchRatioOfAvailable = (double) dto7.getMchAmount() / dto7.getCanSeparateAmount() * 100; }
double platRatioOfAvailable = (double) dto7.getPlatAmount() / dto7.getCanSeparateAmount() * 100;
double agent1stRatioOfAvailable = 0.0;
double agent2ndRatioOfAvailable = 0.0;
// 安全检查避免空指针异常 /**
if (dto7.getAgent1stAmount() != null) { * 向JSON字符串中添加属性
agent1stRatioOfAvailable = (double) dto7.getAgent1stAmount() / dto7.getCanSeparateAmount() * 100; *
} * @param json StringBuilder对象
if (dto7.getAgent2ndAmount() != null) { * @param key 属性名
agent2ndRatioOfAvailable = (double) dto7.getAgent2ndAmount() / dto7.getCanSeparateAmount() * 100; * @param value 属性值
} * @param first 是否为第一个属性
*/
logger.info("占比详情 (总金额占比 / 可分账金额占比): 拉卡拉={}% / {}%, 商户={}% / {}%, 平台={}% / {}%, 一级代理商={}% / {}%, 二级代理商={}% / {}%", private void appendProperty(StringBuilder json, String key, Object value, boolean first) {
String.format("%.4f", lklRatioOfTotal), String.format("%.4f", lklRatioOfAvailable), if (!first) {
String.format("%.4f", mchRatioOfTotal), String.format("%.4f", mchRatioOfAvailable), json.append(",");
String.format("%.4f", platRatioOfTotal), String.format("%.4f", platRatioOfAvailable), }
String.format("%.4f", agent1stRatioOfTotal), String.format("%.4f", agent1stRatioOfAvailable), json.append("\"").append(key).append("\":");
String.format("%.4f", agent2ndRatioOfTotal), String.format("%.4f", agent2ndRatioOfAvailable)); if (value == null) {
json.append("null");
int total = dto7.getLklAmount() + dto7.getMchAmount() + dto7.getPlatAmount() + } else if (value instanceof String) {
(dto7.getAgent1stAmount() != null ? dto7.getAgent1stAmount() : 0) + json.append("\"").append(value).append("\"");
(dto7.getAgent2ndAmount() != null ? dto7.getAgent2ndAmount() : 0) + dto7.getShippingFee(); } else {
logger.info("金额校验: {} (计算总金额={}分, 原始总金额={}分)", (total == dto7.getTotalSeparateAmount() ? "通过" : "不通过"), total, dto7.getTotalSeparateAmount()); json.append(value);
// 验证refCanSeparateAmount是否生效
if (dto7.getCanSeparateAmount().equals(dto7.getRefCanSeparateAmount())) {
logger.info("参考可分账金额生效: 计算出的可分账金额={}分, 参考可分账金额={}分", dto7.getCanSeparateAmount(), dto7.getRefCanSeparateAmount());
} else {
logger.info("参考可分账金额未生效: 计算出的可分账金额={}分, 参考可分账金额={}分", dto7.getCanSeparateAmount(), dto7.getRefCanSeparateAmount());
}
} }
} }
@ -372,14 +370,37 @@ public class LklSeparateDTO implements java.io.Serializable {
totalSeparateAmount, shippingFee, lklAmount, canSeparateAmount); 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不一致时 * 当refCanSeparateAmount有效且与计算出的canSeparateAmount不一致时
* 将差额分配给指定优先级的分账对象平台 > 一级代理商 > 二级代理商 > 商户 * 将差额分配给指定优先级的分账对象平台 > 一级代理商 > 二级代理商 > 商户
*/ */
private void checkAndApplyRefCanSeparateAmount() { private void checkAndApplyRefCanSeparateAmount() {
// 判断refCanSeparateAmount是否有效(大于0且小于等于totalSeparateAmount) // 判断refCanSeparateAmount是否有效(非空且大于0且小于totalSeparateAmount)
if (refCanSeparateAmount != null && refCanSeparateAmount > 0 && refCanSeparateAmount <= totalSeparateAmount) { if (isRefCanSeparateAmountValid()) {
// 比较refCanSeparateAmount与计算出的canSeparateAmount // 比较refCanSeparateAmount与计算出的canSeparateAmount
if (!refCanSeparateAmount.equals(canSeparateAmount)) { if (!refCanSeparateAmount.equals(canSeparateAmount)) {
int difference = refCanSeparateAmount - canSeparateAmount; int difference = refCanSeparateAmount - canSeparateAmount;
@ -387,9 +408,6 @@ public class LklSeparateDTO implements java.io.Serializable {
"refCanSeparateAmount={}分计算出的canSeparateAmount={}分。", "refCanSeparateAmount={}分计算出的canSeparateAmount={}分。",
difference, refCanSeparateAmount, canSeparateAmount); difference, refCanSeparateAmount, canSeparateAmount);
// 使用refCanSeparateAmount作为分账基数
canSeparateAmount = refCanSeparateAmount;
// 将差额分配给指定优先级的分账对象商户 > 二级代理商 > 一级代理商 > 平台 // 将差额分配给指定优先级的分账对象商户 > 二级代理商 > 一级代理商 > 平台
if (difference != 0) { if (difference != 0) {
if (mchAmount == null) mchAmount = 0; if (mchAmount == null) mchAmount = 0;
@ -458,30 +476,33 @@ public class LklSeparateDTO implements java.io.Serializable {
* 按优先级进行分账基于可分账金额 * 按优先级进行分账基于可分账金额
*/ */
private void performSeparate() { private void performSeparate() {
// 确定分账基数
int separateBaseAmount = getSeparateBaseAmount();
// 商户分账金额 = 可分账金额 × 商户分账比例四舍五入 // 商户分账金额 = 可分账金额 × 商户分账比例四舍五入
BigDecimal mchAmountDecimal = new BigDecimal(canSeparateAmount).multiply(mchRatio); BigDecimal mchAmountDecimal = new BigDecimal(separateBaseAmount).multiply(mchRatio);
mchAmount = mchAmountDecimal.setScale(0, RoundingMode.HALF_UP).intValue(); mchAmount = mchAmountDecimal.setScale(0, RoundingMode.HALF_UP).intValue();
logger.debug("商户分账计算:可分账金额{} × 商户比例{} = {},四舍五入后={}", canSeparateAmount, mchRatio, mchAmountDecimal, mchAmount); logger.debug("商户分账计算:可分账金额{} × 商户比例{} = {},四舍五入后={}", separateBaseAmount, mchRatio, mchAmountDecimal, mchAmount);
// 平台分账金额 = 可分账金额 × 平台分账比例四舍五入 // 平台分账金额 = 可分账金额 × 平台分账比例四舍五入
BigDecimal platAmountDecimal = new BigDecimal(canSeparateAmount).multiply(platRatio); BigDecimal platAmountDecimal = new BigDecimal(separateBaseAmount).multiply(platRatio);
platAmount = platAmountDecimal.setScale(0, RoundingMode.HALF_UP).intValue(); platAmount = platAmountDecimal.setScale(0, RoundingMode.HALF_UP).intValue();
logger.debug("平台分账计算:可分账金额{} × 平台比例{} = {},四舍五入后={}", canSeparateAmount, platRatio, platAmountDecimal, platAmount); logger.debug("平台分账计算:可分账金额{} × 平台比例{} = {},四舍五入后={}", separateBaseAmount, platRatio, platAmountDecimal, platAmount);
// 一级代理商分账金额 = 可分账金额 × 一级代理商分账比例四舍五入 // 一级代理商分账金额 = 可分账金额 × 一级代理商分账比例四舍五入
if (agent1stRatio != null && agent1stRatio.compareTo(BigDecimal.ZERO) > 0) { if (agent1stRatio != null && agent1stRatio.compareTo(BigDecimal.ZERO) > 0) {
BigDecimal agent1stAmountDecimal = new BigDecimal(canSeparateAmount).multiply(agent1stRatio); BigDecimal agent1stAmountDecimal = new BigDecimal(separateBaseAmount).multiply(agent1stRatio);
agent1stAmount = agent1stAmountDecimal.setScale(0, RoundingMode.HALF_UP).intValue(); agent1stAmount = agent1stAmountDecimal.setScale(0, RoundingMode.HALF_UP).intValue();
logger.debug("一级代理商分账计算:可分账金额{} × 一级代理商比例{} = {},四舍五入后={}", canSeparateAmount, agent1stRatio, agent1stAmountDecimal, agent1stAmount); logger.debug("一级代理商分账计算:可分账金额{} × 一级代理商比例{} = {},四舍五入后={}", separateBaseAmount, agent1stRatio, agent1stAmountDecimal, agent1stAmount);
} else { } else {
agent1stAmount = 0; agent1stAmount = 0;
} }
// 二级代理商分账金额 = 可分账金额 × 二级代理商分账比例四舍五入 // 二级代理商分账金额 = 可分账金额 × 二级代理商分账比例四舍五入
if (agent2ndRatio != null && agent2ndRatio.compareTo(BigDecimal.ZERO) > 0) { if (agent2ndRatio != null && agent2ndRatio.compareTo(BigDecimal.ZERO) > 0) {
BigDecimal agent2ndAmountDecimal = new BigDecimal(canSeparateAmount).multiply(agent2ndRatio); BigDecimal agent2ndAmountDecimal = new BigDecimal(separateBaseAmount).multiply(agent2ndRatio);
agent2ndAmount = agent2ndAmountDecimal.setScale(0, RoundingMode.HALF_UP).intValue(); agent2ndAmount = agent2ndAmountDecimal.setScale(0, RoundingMode.HALF_UP).intValue();
logger.debug("二级代理商分账计算:可分账金额{} × 二级代理商比例{} = {},四舍五入后={}", canSeparateAmount, agent2ndRatio, agent2ndAmountDecimal, agent2ndAmount); logger.debug("二级代理商分账计算:可分账金额{} × 二级代理商比例{} = {},四舍五入后={}", separateBaseAmount, agent2ndRatio, agent2ndAmountDecimal, agent2ndAmount);
} else { } else {
agent2ndAmount = 0; agent2ndAmount = 0;
} }
@ -491,42 +512,48 @@ public class LklSeparateDTO implements java.io.Serializable {
* 按优先级进行分账基于总金额 * 按优先级进行分账基于总金额
*/ */
private void performSeparateBasedOnTotalAmount() { private void performSeparateBasedOnTotalAmount() {
// 确定分账基数
int separateBaseAmount = getSeparateBaseAmount();
// 平台分账金额 = 可分账金额 × 平台分账比例四舍五入 // 平台分账金额 = 可分账金额 × 平台分账比例四舍五入
BigDecimal platAmountDecimal = new BigDecimal(canSeparateAmount).multiply(platRatio); BigDecimal platAmountDecimal = new BigDecimal(separateBaseAmount).multiply(platRatio);
platAmount = platAmountDecimal.setScale(0, RoundingMode.HALF_UP).intValue(); platAmount = platAmountDecimal.setScale(0, RoundingMode.HALF_UP).intValue();
logger.debug("平台分账计算:可分账金额{} × 平台比例{} = {},四舍五入后={}", canSeparateAmount, platRatio, platAmountDecimal, platAmount); logger.debug("平台分账计算:可分账金额{} × 平台比例{} = {},四舍五入后={}", separateBaseAmount, platRatio, platAmountDecimal, platAmount);
// 一级代理商分账金额 = 可分账金额 × 一级代理商分账比例四舍五入 // 一级代理商分账金额 = 可分账金额 × 一级代理商分账比例四舍五入
if (agent1stRatio != null && agent1stRatio.compareTo(BigDecimal.ZERO) > 0) { if (agent1stRatio != null && agent1stRatio.compareTo(BigDecimal.ZERO) > 0) {
BigDecimal agent1stAmountDecimal = new BigDecimal(canSeparateAmount).multiply(agent1stRatio); BigDecimal agent1stAmountDecimal = new BigDecimal(separateBaseAmount).multiply(agent1stRatio);
agent1stAmount = agent1stAmountDecimal.setScale(0, RoundingMode.HALF_UP).intValue(); agent1stAmount = agent1stAmountDecimal.setScale(0, RoundingMode.HALF_UP).intValue();
logger.debug("一级代理商分账计算:可分账金额{} × 一级代理商比例{} = {},四舍五入后={}", canSeparateAmount, agent1stRatio, agent1stAmountDecimal, agent1stAmount); logger.debug("一级代理商分账计算:可分账金额{} × 一级代理商比例{} = {},四舍五入后={}", separateBaseAmount, agent1stRatio, agent1stAmountDecimal, agent1stAmount);
} else { } else {
agent1stAmount = 0; agent1stAmount = 0;
} }
// 二级代理商分账金额 = 可分账金额 × 二级代理商分账比例四舍五入 // 二级代理商分账金额 = 可分账金额 × 二级代理商分账比例四舍五入
if (agent2ndRatio != null && agent2ndRatio.compareTo(BigDecimal.ZERO) > 0) { if (agent2ndRatio != null && agent2ndRatio.compareTo(BigDecimal.ZERO) > 0) {
BigDecimal agent2ndAmountDecimal = new BigDecimal(canSeparateAmount).multiply(agent2ndRatio); BigDecimal agent2ndAmountDecimal = new BigDecimal(separateBaseAmount).multiply(agent2ndRatio);
agent2ndAmount = agent2ndAmountDecimal.setScale(0, RoundingMode.HALF_UP).intValue(); agent2ndAmount = agent2ndAmountDecimal.setScale(0, RoundingMode.HALF_UP).intValue();
logger.debug("二级代理商分账计算:可分账金额{} × 二级代理商比例{} = {},四舍五入后={}", canSeparateAmount, agent2ndRatio, agent2ndAmountDecimal, agent2ndAmount); logger.debug("二级代理商分账计算:可分账金额{} × 二级代理商比例{} = {},四舍五入后={}", separateBaseAmount, agent2ndRatio, agent2ndAmountDecimal, agent2ndAmount);
} else { } else {
agent2ndAmount = 0; agent2ndAmount = 0;
} }
// 商户分账金额 = 可分账金额 - 平台分账金额 - 一级代理商分账金额 - 二级代理商分账金额 // 商户分账金额 = 可分账金额 - 平台分账金额 - 一级代理商分账金额 - 二级代理商分账金额
mchAmount = canSeparateAmount - platAmount - agent1stAmount - agent2ndAmount; mchAmount = separateBaseAmount - platAmount - agent1stAmount - agent2ndAmount;
logger.debug("商户分账计算:可分账金额{} - 平台分账{} - 一级代理商分账{} - 二级代理商分账{} = {}", logger.debug("商户分账计算:可分账金额{} - 平台分账{} - 一级代理商分账{} - 二级代理商分账{} = {}",
canSeparateAmount, platAmount, agent1stAmount, agent2ndAmount, mchAmount); separateBaseAmount, platAmount, agent1stAmount, agent2ndAmount, mchAmount);
} }
/** /**
* 确保总额平衡 * 确保总额平衡
*/ */
private void balanceAmounts() { private void balanceAmounts() {
// 确定分账基数
int separateBaseAmount = getSeparateBaseAmount();
int totalAmount = mchAmount + platAmount + agent1stAmount + agent2ndAmount; int totalAmount = mchAmount + platAmount + agent1stAmount + agent2ndAmount;
if (totalAmount != canSeparateAmount) { if (totalAmount != separateBaseAmount) {
int diff = canSeparateAmount - totalAmount; int diff = separateBaseAmount - totalAmount;
logger.debug("分账总额与可分账金额不符,差额={},开始调整", diff); logger.debug("分账总额与可分账金额不符,差额={},开始调整", diff);
// 将差额分配给优先级最低的参与方确保总额平衡 // 将差额分配给优先级最低的参与方确保总额平衡
@ -581,9 +608,12 @@ public class LklSeparateDTO implements java.io.Serializable {
* 保障商户分账比例 * 保障商户分账比例
*/ */
private void guaranteeMerchantRatio() { private void guaranteeMerchantRatio() {
BigDecimal actualMchRatio = new BigDecimal(mchAmount).divide(new BigDecimal(canSeparateAmount), 6, RoundingMode.HALF_UP); // 确定分账基数
int separateBaseAmount = getSeparateBaseAmount();
BigDecimal actualMchRatio = new BigDecimal(mchAmount).divide(new BigDecimal(separateBaseAmount), 6, RoundingMode.HALF_UP);
if (actualMchRatio.compareTo(mchRatio) < 0) { if (actualMchRatio.compareTo(mchRatio) < 0) {
int requiredMchAmount = mchRatio.multiply(new BigDecimal(canSeparateAmount)).setScale(0, RoundingMode.HALF_UP).intValue(); int requiredMchAmount = mchRatio.multiply(new BigDecimal(separateBaseAmount)).setScale(0, RoundingMode.HALF_UP).intValue();
int diff = requiredMchAmount - mchAmount; int diff = requiredMchAmount - mchAmount;
if (diff > 0) { if (diff > 0) {
logger.debug("商户分账比例不足,需要调整金额={},商户当前金额={},应得金额={}", diff, mchAmount, requiredMchAmount); logger.debug("商户分账比例不足,需要调整金额={},商户当前金额={},应得金额={}", diff, mchAmount, requiredMchAmount);
@ -609,9 +639,12 @@ public class LklSeparateDTO implements java.io.Serializable {
* 保障平台分账比例 * 保障平台分账比例
*/ */
private void guaranteePlatformRatio() { private void guaranteePlatformRatio() {
BigDecimal actualPlatRatio = new BigDecimal(platAmount).divide(new BigDecimal(canSeparateAmount), 6, RoundingMode.HALF_UP); // 确定分账基数
int separateBaseAmount = getSeparateBaseAmount();
BigDecimal actualPlatRatio = new BigDecimal(platAmount).divide(new BigDecimal(separateBaseAmount), 6, RoundingMode.HALF_UP);
if (actualPlatRatio.compareTo(platRatio) < 0) { if (actualPlatRatio.compareTo(platRatio) < 0) {
int requiredPlatAmount = platRatio.multiply(new BigDecimal(canSeparateAmount)).setScale(0, RoundingMode.HALF_UP).intValue(); int requiredPlatAmount = platRatio.multiply(new BigDecimal(separateBaseAmount)).setScale(0, RoundingMode.HALF_UP).intValue();
int diff = requiredPlatAmount - platAmount; int diff = requiredPlatAmount - platAmount;
if (diff > 0) { if (diff > 0) {
logger.debug("平台分账比例不足,需要调整金额={},平台当前金额={},应得金额={}", diff, platAmount, requiredPlatAmount); logger.debug("平台分账比例不足,需要调整金额={},平台当前金额={},应得金额={}", diff, platAmount, requiredPlatAmount);
@ -633,10 +666,13 @@ public class LklSeparateDTO implements java.io.Serializable {
* 保障一级代理商分账比例 * 保障一级代理商分账比例
*/ */
private void guaranteeAgent1stRatio() { private void guaranteeAgent1stRatio() {
// 确定分账基数
int separateBaseAmount = getSeparateBaseAmount();
if (agent1stRatio != null && agent1stRatio.compareTo(BigDecimal.ZERO) > 0) { if (agent1stRatio != null && agent1stRatio.compareTo(BigDecimal.ZERO) > 0) {
BigDecimal actualAgent1stRatio = new BigDecimal(agent1stAmount).divide(new BigDecimal(canSeparateAmount), 6, RoundingMode.HALF_UP); BigDecimal actualAgent1stRatio = new BigDecimal(agent1stAmount).divide(new BigDecimal(separateBaseAmount), 6, RoundingMode.HALF_UP);
if (actualAgent1stRatio.compareTo(agent1stRatio) < 0) { if (actualAgent1stRatio.compareTo(agent1stRatio) < 0) {
int requiredAgent1stAmount = agent1stRatio.multiply(new BigDecimal(canSeparateAmount)).setScale(0, RoundingMode.HALF_UP).intValue(); int requiredAgent1stAmount = agent1stRatio.multiply(new BigDecimal(separateBaseAmount)).setScale(0, RoundingMode.HALF_UP).intValue();
int diff = requiredAgent1stAmount - agent1stAmount; int diff = requiredAgent1stAmount - agent1stAmount;
if (diff > 0) { if (diff > 0) {
logger.debug("一级代理商分账比例不足,需要调整金额={},一级代理商当前金额={},应得金额={}", diff, agent1stAmount, requiredAgent1stAmount); logger.debug("一级代理商分账比例不足,需要调整金额={},一级代理商当前金额={},应得金额={}", diff, agent1stAmount, requiredAgent1stAmount);
@ -655,9 +691,12 @@ public class LklSeparateDTO implements java.io.Serializable {
* 最终保障商户分账比例 * 最终保障商户分账比例
*/ */
private void finalGuaranteeMerchantRatio() { private void finalGuaranteeMerchantRatio() {
BigDecimal finalMchRatio = new BigDecimal(mchAmount).divide(new BigDecimal(canSeparateAmount), 6, RoundingMode.HALF_UP); // 确定分账基数
int separateBaseAmount = getSeparateBaseAmount();
BigDecimal finalMchRatio = new BigDecimal(mchAmount).divide(new BigDecimal(separateBaseAmount), 6, RoundingMode.HALF_UP);
if (finalMchRatio.compareTo(mchRatio) < 0) { if (finalMchRatio.compareTo(mchRatio) < 0) {
int requiredMchAmount = mchRatio.multiply(new BigDecimal(canSeparateAmount)).setScale(0, RoundingMode.UP).intValue(); int requiredMchAmount = mchRatio.multiply(new BigDecimal(separateBaseAmount)).setScale(0, RoundingMode.UP).intValue();
int diff = requiredMchAmount - mchAmount; int diff = requiredMchAmount - mchAmount;
if (diff > 0) { if (diff > 0) {
logger.debug("商户最终分账比例仍不足,需要调整金额={},商户当前金额={},应得金额={}", diff, mchAmount, requiredMchAmount); logger.debug("商户最终分账比例仍不足,需要调整金额={},商户当前金额={},应得金额={}", diff, mchAmount, requiredMchAmount);
@ -685,10 +724,4 @@ public class LklSeparateDTO implements java.io.Serializable {
} }
} }
/**
* 获取BigDecimal值如果为null则返回默认值
*/
private BigDecimal getOrDefault(BigDecimal value, BigDecimal defaultValue) {
return value != null ? value : defaultValue;
}
} }