分账计算代码优化

This commit is contained in:
Jack 2025-11-13 10:16:16 +08:00
parent 6ca0af397b
commit 040c6d3cb1

View File

@ -33,8 +33,10 @@ import java.math.RoundingMode;
@Slf4j @Slf4j
public class LklSeparateWithTotalAmountDTO { public class LklSeparateWithTotalAmountDTO {
// 常量定义 // 商家最低分账比例阈值 20%
private static final BigDecimal MCH_RATIO_THRESHOLD = BigDecimal.valueOf(0.2); private static final BigDecimal MCH_RATIO_THRESHOLD = BigDecimal.valueOf(0.2);
// 默认平台比例 1%
private static final BigDecimal DEFAULT_PLAT_RATIO = BigDecimal.valueOf(0.01);
// 基础金额属性 // 基础金额属性
private Integer totalSeparateAmount; // 分账总金额() private Integer totalSeparateAmount; // 分账总金额()
@ -237,25 +239,21 @@ public class LklSeparateWithTotalAmountDTO {
private Pair<Boolean, String> validateInputs() { private Pair<Boolean, String> validateInputs() {
// 校验totalSeparateAmount必须为有效值且大于0 // 校验totalSeparateAmount必须为有效值且大于0
if (totalSeparateAmount == null || totalSeparateAmount <= 0) { if (totalSeparateAmount == null || totalSeparateAmount <= 0) {
log.error("分账计算:总分账金额小于等于0"); return Pair.of(false, "分账计算:总分账金额必须大于0");
return Pair.of(false, "分账计算:总分账金额小于等于0");
} }
// 校验必要参数 // 校验必要参数
if (lklRatio == null || lklRatio.compareTo(BigDecimal.ZERO) <= 0) { if (lklRatio == null || lklRatio.compareTo(BigDecimal.ZERO) <= 0) {
log.error("分账计算:拉卡拉分账比例小于等于0"); return Pair.of(false, "分账计算:拉卡拉分账比例必须大于0");
return Pair.of(false, "分账计算:拉卡拉分账比例小于等于0");
} }
if (mchRatio == null || mchRatio.compareTo(BigDecimal.ZERO) <= 0) { if (mchRatio == null || mchRatio.compareTo(BigDecimal.ZERO) <= 0) {
log.error("分账计算:商户分账比例小于等于0"); return Pair.of(false, "分账计算:商户分账比例必须大于0");
return Pair.of(false, "分账计算:商户分账比例小于等于0");
} }
// 校验shippingFee不能大于等于totalSeparateAmount // 校验shippingFee不能大于等于totalSeparateAmount
if (shippingFee != null && shippingFee >= totalSeparateAmount) { if (shippingFee != null && shippingFee > 0 && shippingFee >= totalSeparateAmount) {
log.error("分账计算:分账总金额低于平台内部运费"); return Pair.of(false, "分账计算:配送费用不能大于等于总金额");
return Pair.of(false, "分账计算:分账总金额低于平台内部运费");
} }
return Pair.of(true, ""); return Pair.of(true, "");
@ -276,9 +274,6 @@ public class LklSeparateWithTotalAmountDTO {
// 校验拉卡拉分账金额不能为负数 // 校验拉卡拉分账金额不能为负数
if (lklAmount < 0) { if (lklAmount < 0) {
// 记录详细日志
String errorMsg = "拉卡拉分账金额计算结果为负数: " + lklAmount;
log.error(errorMsg);
return Pair.of(false, "拉卡拉分账金额计算异常"); return Pair.of(false, "拉卡拉分账金额计算异常");
} }
@ -287,9 +282,6 @@ public class LklSeparateWithTotalAmountDTO {
// 校验可分账金额不能为负数 // 校验可分账金额不能为负数
if (canSeparateAmount < 0) { if (canSeparateAmount < 0) {
// 记录详细日志
String errorMsg = "可分账金额计算结果为负数: " + canSeparateAmount;
log.error(errorMsg);
return Pair.of(false, "可分账金额计算异常"); return Pair.of(false, "可分账金额计算异常");
} }
@ -316,9 +308,6 @@ public class LklSeparateWithTotalAmountDTO {
// 校验实际可分账金额不能为负数 // 校验实际可分账金额不能为负数
if (actualCanSeparateAmountB < 0) { if (actualCanSeparateAmountB < 0) {
// 记录详细日志
String errorMsg = "实际可分账金额计算结果为负数: " + actualCanSeparateAmountB;
log.error(errorMsg);
return Pair.of(false, "实际可分账金额计算异常"); return Pair.of(false, "实际可分账金额计算异常");
} }
@ -333,7 +322,7 @@ public class LklSeparateWithTotalAmountDTO {
private Pair<Boolean, String> calculateDefaultRatios() { private Pair<Boolean, String> calculateDefaultRatios() {
// 如果平台比例无效设置默认值0.01 // 如果平台比例无效设置默认值0.01
if (platRatio == null || platRatio.compareTo(BigDecimal.ZERO) <= 0) { if (platRatio == null || platRatio.compareTo(BigDecimal.ZERO) <= 0) {
platRatio = new BigDecimal("0.01"); platRatio = DEFAULT_PLAT_RATIO;
} }
return Pair.of(true, ""); return Pair.of(true, "");
@ -356,9 +345,7 @@ public class LklSeparateWithTotalAmountDTO {
// 2. 校验实际可分账金额不能小于0 // 2. 校验实际可分账金额不能小于0
if (actualCanSeparateAmount < 0) { if (actualCanSeparateAmount < 0) {
String errorMsg = "实际可分账金额不能为负数"; return Pair.of(false, "实际可分账金额不能为负数");
log.error(errorMsg);
return Pair.of(false, errorMsg);
} }
// 3. 初始化剩余金额为实际可分账金额 // 3. 初始化剩余金额为实际可分账金额
@ -371,9 +358,7 @@ public class LklSeparateWithTotalAmountDTO {
// 校验平台分账金额不能为负数 // 校验平台分账金额不能为负数
if (platAmount < 0) { if (platAmount < 0) {
String errorMsg = "平台分账金额计算异常"; return Pair.of(false, "平台分账金额计算异常");
log.error(errorMsg);
return Pair.of(false, errorMsg);
} }
// 确保不超过剩余金额 // 确保不超过剩余金额
@ -398,9 +383,7 @@ public class LklSeparateWithTotalAmountDTO {
// 校验二级代理商分账金额不能为负数 // 校验二级代理商分账金额不能为负数
if (agent2ndAmount < 0) { if (agent2ndAmount < 0) {
String errorMsg = "二级代理商分账金额计算异常"; return Pair.of(false, "二级代理商分账金额计算异常");
log.error(errorMsg);
return Pair.of(false, errorMsg);
} }
// 确保不超过剩余金额 // 确保不超过剩余金额
@ -418,9 +401,7 @@ public class LklSeparateWithTotalAmountDTO {
// 校验一级代理商分账金额不能为负数 // 校验一级代理商分账金额不能为负数
if (agent1stAmount < 0) { if (agent1stAmount < 0) {
String errorMsg = "一级代理商分账金额计算异常"; return Pair.of(false, "一级代理商分账金额计算异常");
log.error(errorMsg);
return Pair.of(false, errorMsg);
} }
// 确保不超过剩余金额 // 确保不超过剩余金额
@ -435,9 +416,7 @@ public class LklSeparateWithTotalAmountDTO {
// 校验商家分账金额不能为负数 // 校验商家分账金额不能为负数
if (mchAmount < 0) { if (mchAmount < 0) {
String errorMsg = "商家分账金额计算异常"; return Pair.of(false, "商家分账金额计算异常");
log.error(errorMsg);
return Pair.of(false, errorMsg);
} }
return Pair.of(true, ""); return Pair.of(true, "");
@ -450,14 +429,15 @@ public class LklSeparateWithTotalAmountDTO {
* @return Pair<Boolean, String> Boolean表示是否成功String为错误信息 * @return Pair<Boolean, String> Boolean表示是否成功String为错误信息
*/ */
private Pair<Boolean, String> calculateActualMchRatio() { private Pair<Boolean, String> calculateActualMchRatio() {
if (totalSeparateAmount != null && totalSeparateAmount > 0 && mchAmount != null) { if (totalSeparateAmount != null && totalSeparateAmount > 0 && mchAmount != null && mchAmount >= 0) {
// 计算实际比例保留6位小数 // 计算实际比例保留6位小数
mchRatio = BigDecimal.valueOf(mchAmount) mchRatio = BigDecimal.valueOf(mchAmount)
.divide(BigDecimal.valueOf(totalSeparateAmount), 6, RoundingMode.HALF_UP); .divide(BigDecimal.valueOf(totalSeparateAmount), 6, RoundingMode.HALF_UP);
// 如果计算出的实际比例低于阈值打印日志并返回错误 // 如果计算出的实际比例低于阈值打印日志并返回错误
if (mchRatio.compareTo(MCH_RATIO_THRESHOLD) < 0) { if (mchRatio.compareTo(MCH_RATIO_THRESHOLD) < 0) {
String errorMsg = "警告: 商家实际分账比例低于阈值,当前比例: " + mchRatio + ",阈值: " + MCH_RATIO_THRESHOLD; String errorMsg = String.format("警告: 商家实际分账比例低于阈值,当前比例: %s阈值: %s",
mchRatio.toPlainString(), MCH_RATIO_THRESHOLD.toPlainString());
log.warn(errorMsg); log.warn(errorMsg);
return Pair.of(false, "商家分账低于阈值"); return Pair.of(false, "商家分账低于阈值");
} }
@ -472,23 +452,28 @@ public class LklSeparateWithTotalAmountDTO {
* @return Pair<Boolean, String> Boolean表示是否成功String为错误信息 * @return Pair<Boolean, String> Boolean表示是否成功String为错误信息
*/ */
private Pair<Boolean, String> validateSeparateAmountTotal() { private Pair<Boolean, String> validateSeparateAmountTotal() {
long totalAmount = 0; long totalAmount = getValueOrZero(lklAmount) +
totalAmount += (lklAmount != null ? lklAmount : 0); getValueOrZero(platAmount) +
totalAmount += (platAmount != null ? platAmount : 0); getValueOrZero(agent2ndAmount) +
totalAmount += (agent2ndAmount != null ? agent2ndAmount : 0); getValueOrZero(agent1stAmount) +
totalAmount += (agent1stAmount != null ? agent1stAmount : 0); getValueOrZero(mchAmount);
totalAmount += (mchAmount != null ? mchAmount : 0);
if (totalAmount > totalSeparateAmount) { if (totalAmount > getValueOrZero(totalSeparateAmount)) {
// 记录详细日志 String errorMsg = String.format("分账金额总和(%d)超过总金额(%d)",
String errorMsg = "分账金额总和超过总金额,分账金额总和: " + totalAmount + ",总金额: " + totalSeparateAmount; totalAmount, getValueOrZero(totalSeparateAmount));
log.error(errorMsg); return Pair.of(false, "分账金额总和超过总金额: " + errorMsg);
return Pair.of(false, "分账金额总和超过总金额");
} }
return Pair.of(true, ""); return Pair.of(true, "");
} }
/**
* 安全获取Integer值避免空指针
*/
private int getValueOrZero(Integer value) {
return value != null ? value : 0;
}
/** /**
* 生成对象的字符串表示 * 生成对象的字符串表示
* *
@ -520,22 +505,42 @@ public class LklSeparateWithTotalAmountDTO {
* @return JSON格式字符串 * @return JSON格式字符串
*/ */
public String toJSON() { public String toJSON() {
String sb = "{" + "\"totalSeparateAmount\":" + totalSeparateAmount + "," + StringBuilder sb = new StringBuilder("{");
"\"canSeparateAmount\":" + canSeparateAmount + "," + appendJsonField(sb, "totalSeparateAmount", totalSeparateAmount);
"\"refCanSeparateAmount\":" + refCanSeparateAmount + "," + appendJsonField(sb, "canSeparateAmount", canSeparateAmount);
"\"shippingFee\":" + shippingFee + "," + appendJsonField(sb, "refCanSeparateAmount", refCanSeparateAmount);
"\"lklRatio\":" + (lklRatio != null ? "\"" + lklRatio + "\"" : "null") + "," + appendJsonField(sb, "shippingFee", shippingFee);
"\"mchRatio\":" + (mchRatio != null ? "\"" + mchRatio + "\"" : "null") + "," + appendJsonField(sb, "lklRatio", lklRatio);
"\"platRatio\":" + (platRatio != null ? "\"" + platRatio + "\"" : "null") + "," + appendJsonField(sb, "mchRatio", mchRatio);
"\"agent1stRatio\":" + (agent1stRatio != null ? "\"" + agent1stRatio + "\"" : "null") + "," + appendJsonField(sb, "platRatio", platRatio);
"\"agent2ndRatio\":" + (agent2ndRatio != null ? "\"" + agent2ndRatio + "\"" : "null") + "," + appendJsonField(sb, "agent1stRatio", agent1stRatio);
"\"lklAmount\":" + lklAmount + "," + appendJsonField(sb, "agent2ndRatio", agent2ndRatio);
"\"mchAmount\":" + mchAmount + "," + appendJsonField(sb, "lklAmount", lklAmount);
"\"platAmount\":" + platAmount + "," + appendJsonField(sb, "mchAmount", mchAmount);
"\"agent1stAmount\":" + agent1stAmount + "," + appendJsonField(sb, "platAmount", platAmount);
"\"agent2ndAmount\":" + agent2ndAmount + appendJsonField(sb, "agent1stAmount", agent1stAmount);
"}"; appendJsonField(sb, "agent2ndAmount", agent2ndAmount);
return sb; // 移除最后的逗号并添加结束括号
if (sb.charAt(sb.length() - 1) == ',') {
sb.setLength(sb.length() - 1);
}
sb.append("}");
return sb.toString();
}
/**
* 添加JSON字段的辅助方法
*/
private void appendJsonField(StringBuilder sb, String fieldName, Object fieldValue) {
sb.append("\"").append(fieldName).append("\":");
if (fieldValue instanceof BigDecimal) {
sb.append("\"").append(fieldValue).append("\"");
} else if (fieldValue == null) {
sb.append("null");
} else {
sb.append(fieldValue);
}
sb.append(",");
} }
/** /**
@ -544,11 +549,7 @@ public class LklSeparateWithTotalAmountDTO {
* @return SeparateResult 包含成功状态分账结果和错误信息的包装类 * @return SeparateResult 包含成功状态分账结果和错误信息的包装类
*/ */
public SeparateResult getSeparateResult() { public SeparateResult getSeparateResult() {
SeparateResult result = new SeparateResult(); return new SeparateResult(Boolean.TRUE, this, this.errMsg);
result.setIsSuccess(true);
result.setData(this);
result.setErrMsg(this.errMsg);
return result;
} }
/** /**
@ -610,5 +611,4 @@ public class LklSeparateWithTotalAmountDTO {
return new SeparateResult(Boolean.TRUE, data, errMsg != null ? errMsg : ""); return new SeparateResult(Boolean.TRUE, data, errMsg != null ? errMsg : "");
} }
} }
}
}