分账计算使用了公共方法
This commit is contained in:
parent
57504c9458
commit
1d4b884215
@ -37,5 +37,8 @@ public class RedisConstant {
|
||||
public static final String SF_Order_Proc_WillExpire_Key = ConstantRedis.Cache_NameSpace + "sf_order_proc_will_expire_key__";
|
||||
|
||||
public static final String Order_Pay_Retry_Count_Key = ConstantRedis.Cache_NameSpace + "order_pay_retry_count:";
|
||||
|
||||
|
||||
// 您有新的订单来了
|
||||
public static final String New_Order_Push_Flag_Key = ConstantRedis.Cache_NameSpace + "new:order:comimg:";
|
||||
|
||||
}
|
||||
|
||||
@ -61,15 +61,15 @@ public class LklSeparateDTO {
|
||||
// 测试基于可分账金额的分账算法(正常情况)
|
||||
System.out.println("\n=== 基于可分账金额的分账算法测试(正常情况) ===");
|
||||
LklSeparateDTO dto2 = new LklSeparateDTO();
|
||||
dto2.setTotalSeparateAmount(1500); // 分账总额 1000分
|
||||
dto2.setTotalSeparateAmount(900); // 分账总额 1000分
|
||||
dto2.setShippingFee(500); // 配送费 100分
|
||||
// dto2.setRefCanSeparateAmount(null);
|
||||
dto2.setLklRatio(new BigDecimal("0.0025")); // 拉卡拉分账比例 0.0025
|
||||
dto2.setMchRatio(new BigDecimal("0.95")); // 商家分账比例 0.857 (会产生小数)
|
||||
dto2.setPlatRatio(new BigDecimal("0.06")); // 平台分账比例 0.01
|
||||
dto2.setPlatRatio(new BigDecimal("0.01")); // 平台分账比例 0.01
|
||||
// 不设置一级和二级代理商分账比例,测试不参与分账的情况
|
||||
dto2.setAgent1stRatio(new BigDecimal("0.11")); // 一级代理商分账比例 0.023 (会产生小数)
|
||||
dto2.setAgent2ndRatio(new BigDecimal("0.04")); // 二级代理商分账比例 0.031 (会产生小数)
|
||||
// dto2.setAgent1stRatio(new BigDecimal("0.11")); // 一级代理商分账比例 0.023 (会产生小数)
|
||||
// dto2.setAgent2ndRatio(new BigDecimal("0.04")); // 二级代理商分账比例 0.031 (会产生小数)
|
||||
|
||||
SharingResult result2 = dto2.sharingOnCanSeparateAmount();
|
||||
System.out.println(result2);
|
||||
|
||||
@ -19,6 +19,7 @@ import org.springframework.web.client.RestTemplate;
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@ -125,16 +126,6 @@ public class UniCloudPushServiceImpl implements UniCloudPushService {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
return headers;
|
||||
|
||||
// HttpHeaders headers = new HttpHeaders();
|
||||
// headers.setContentType(MediaType.APPLICATION_JSON); // Content-Type: application/json
|
||||
// headers.add("Accept", "*/*");
|
||||
// headers.add("Host", "fc-mp-39e3d50a-2d2b-415a-9664-2e48974bcfbd.next.bspapp.com");
|
||||
// headers.add("Connection", "keep-alive");
|
||||
// headers.add("Authorization", "Basic ZWxhc3TiYzpQQjI1NkZFTjBPaDY0cFZV");
|
||||
// headers.add("User-Agent", "Apifox/1.0.0 (https://apifox.com)");
|
||||
// headers.add("Cookie", "aliyungf_tc=3a871d6048f74707aa0ac71c13f654c4d0fba0471c40625f4c120b6aca248dcf; acw_tc=ac11000117529360358682662e17bea869dfc6fb823bd2d372dbf9eca1c342");
|
||||
// return headers;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -150,21 +141,23 @@ public class UniCloudPushServiceImpl implements UniCloudPushService {
|
||||
clientIds.size(), distinctClientIds.size());
|
||||
}
|
||||
|
||||
// 新增:生成消息唯一标识符
|
||||
String messageId = UUID.randomUUID().toString().replace("-", "");
|
||||
|
||||
request.put("push_clientid", distinctClientIds)
|
||||
.put("title", title)
|
||||
.put("content", content);
|
||||
.put("content", content)
|
||||
.put("message_id", messageId); // 添加唯一消息ID
|
||||
|
||||
if (payload != null) {
|
||||
request.put("payload", payload);
|
||||
}
|
||||
|
||||
request.put("settings", new JSONObject().set("ttl", DEFAULT_TTL));
|
||||
|
||||
log.debug("[推送服务] 请求参数: {}", request);
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 处理推送响应
|
||||
*/
|
||||
|
||||
@ -2471,16 +2471,16 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
return Pair.of(true, "订单已分账,请勿重复操作");
|
||||
}
|
||||
|
||||
// 5. 检查可分账余额
|
||||
Integer canSeparateAmt = null;
|
||||
// 5. 从拉卡拉平台检查可分账余额
|
||||
Integer refCanSeparateAmt = null;
|
||||
Pair<String, String> mchCanSplitAmt = queryMchCanSplitAmt(lklMerchantNo, receiveLogNo, shopOrderLkl.getLkl_log_date());
|
||||
if (mchCanSplitAmt != null) {
|
||||
log.info("[分账操作] 查询拉卡拉可分账余额接口:lklMerchantNo={} logDate={} receiveLogNo={}",
|
||||
lklMerchantNo, shopOrderLkl.getLkl_log_date(), receiveLogNo);
|
||||
log.info("[分账操作] 查询拉卡拉可分账余额接口:lklMerchantNo={} logDate={} receiveLogNo={} 结果:{}",
|
||||
lklMerchantNo, shopOrderLkl.getLkl_log_date(), receiveLogNo, mchCanSplitAmt);
|
||||
|
||||
// 可分账金额
|
||||
canSeparateAmt = Convert.toInt(mchCanSplitAmt.getSecond());
|
||||
if (canSeparateAmt == null || canSeparateAmt <= 0) {
|
||||
refCanSeparateAmt = Convert.toInt(mchCanSplitAmt.getSecond());
|
||||
if (CheckUtil.isEmpty(refCanSeparateAmt)) {
|
||||
log.warn("[分账操作] lklMerchantNo={} receiveTradeNo={} receiveLogNo={} 拉卡拉可分账金额无值或0,系统将自动计算可分账金额",
|
||||
lklMerchantNo, receiveTradeNo, receiveLogNo);
|
||||
}
|
||||
@ -2493,7 +2493,7 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
BigDecimal mchSplitRatioRaw = shopOrderLkl.getSplit_ratio();
|
||||
if (mchSplitRatioRaw == null ||
|
||||
mchSplitRatioRaw.compareTo(BigDecimal.ZERO) <= 0 ||
|
||||
mchSplitRatioRaw.compareTo(new BigDecimal(100)) > 0) {
|
||||
mchSplitRatioRaw.compareTo(new BigDecimal(100)) >= 0) {
|
||||
log.error("[分账操作] 店铺[{}]商家分账比例[{}]不在(0-100]范围内,无法分账",
|
||||
shopOrderLkl.getStore_id(), mchSplitRatioRaw);
|
||||
return Pair.of(false, "商家分账比例有误");
|
||||
@ -2505,60 +2505,55 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
// 获取分账平台接收方信息
|
||||
LklLedgerMerReceiverBind platformReceiver = lklLedgerMerReceiverBindService.getPlatformByMerCupNo(merchantNo);
|
||||
if (platformReceiver == null) {
|
||||
log.error("[分账操作] 店铺[{}]未绑定平台方接收账户,跳过分账", shopOrderLkl.getStore_id());
|
||||
log.error("[分账操作] 商户号{} 未绑定平台方接收账户,跳过分账", merchantNo);
|
||||
return Pair.of(false, "平台方未绑定账户");
|
||||
}
|
||||
|
||||
// 获取代理商分账信息
|
||||
BigDecimal platformSplitRatio = BigDecimal.valueOf(0.01);
|
||||
BigDecimal distributorSplitRatio = BigDecimal.ZERO;
|
||||
|
||||
List<LklLedgerMerReceiverBind> distributorReceivers = lklLedgerMerReceiverBindService.selectDistributorByMerCupNo(merchantNo);
|
||||
if (CollUtil.isNotEmpty(distributorReceivers)) {
|
||||
distributorSplitRatio = BigDecimal.valueOf(1).subtract(platformSplitRatio).subtract(mchSplitRatio);
|
||||
distributorSplitRatio = BigDecimal.valueOf(1).subtract(mchSplitRatio).subtract(platformSplitRatio);
|
||||
log.debug("[分账操作] 检测到代理商存在,调整分账比例: 代理商比例={}, 平台比例={}", distributorSplitRatio, platformSplitRatio);
|
||||
} else {
|
||||
platformSplitRatio = BigDecimal.valueOf(1).subtract(mchSplitRatio);
|
||||
distributorSplitRatio = null;
|
||||
}
|
||||
|
||||
// 内部配送费
|
||||
Integer shoppingFeeInner = CheckUtil.isEmpty(shopOrderLkl.getShopping_fee_inner()) ? 0 : shopOrderLkl.getShopping_fee_inner();
|
||||
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);
|
||||
// 计算拉卡拉手续费、商家分账金额、平台和代理商的分账金额
|
||||
Pair<Boolean, LklSeparateDTO> calcResult = calculateAndEvaluateSharingParams(
|
||||
CommonConstant.SeparateCalcMode_CanSeparateAmt,
|
||||
shopOrderLkl.getTotal_amt(),
|
||||
shoppingFeeInner,
|
||||
mchSplitRatio,
|
||||
platformSplitRatio,
|
||||
null, distributorSplitRatio, refCanSeparateAmt);
|
||||
|
||||
if (distributorSplitRatio.compareTo(BigDecimal.ZERO) > 0) { // 二级代理商参与分账
|
||||
lklSeparateDTO.setAgent2ndRatio(distributorSplitRatio);
|
||||
}
|
||||
lklSeparateDTO.setRefCanSeparateAmount(canSeparateAmt); // 拉卡拉实时返回的可分账金额
|
||||
|
||||
// 分账方式:根据可分账金额分账
|
||||
LklSeparateDTO.SharingResult canSeparateAmtResult = lklSeparateDTO.sharingOnCanSeparateAmount();
|
||||
if (!canSeparateAmtResult.isSuccess()) {
|
||||
log.error("[分账操作] 分账参数评估,结果无法分账 {}", lklSeparateDTO);
|
||||
return Pair.of(false, "分账参数评估,结果无法分账");
|
||||
if (calcResult == null || !calcResult.getFirst() || calcResult.getSecond() == null) {
|
||||
log.error("[分账操作] 分账参数评估,结果无法分账");
|
||||
return Pair.of(false, "分账数据评估,结果无法分账");
|
||||
}
|
||||
LklSeparateDTO lklSeparateDTO = calcResult.getSecond();
|
||||
|
||||
log.debug("[分账操作] 分账参数计算结果:{}", lklSeparateDTO);
|
||||
|
||||
// 更新分账计算结果
|
||||
shopOrderLkl.setSeparate_remark(lklSeparateDTO.toString()); // 写入分账具体情况
|
||||
if (CheckUtil.isEmpty(canSeparateAmt)) {
|
||||
if (CheckUtil.isEmpty(refCanSeparateAmt)) {
|
||||
shopOrderLkl.setSplit_amt(lklSeparateDTO.getCanSeparateAmount());
|
||||
canSeparateAmt = lklSeparateDTO.getCanSeparateAmount();
|
||||
refCanSeparateAmt = lklSeparateDTO.getCanSeparateAmount();
|
||||
} else {
|
||||
shopOrderLkl.setSplit_amt_ref(canSeparateAmt);
|
||||
shopOrderLkl.setSplit_amt_ref(refCanSeparateAmt);
|
||||
}
|
||||
shopOrderLklService.safeUpdate(shopOrderLkl);
|
||||
|
||||
// 分账金额校验
|
||||
if (canSeparateAmt <= 0) {
|
||||
if (CheckUtil.isEmpty(refCanSeparateAmt)) {
|
||||
String errorMsg = String.format("[分账操作] 店铺[%s]订单[%s]分账金额[%d]低于1分钱,跳过分账",
|
||||
shopOrderLkl.getStore_id(), orderId, canSeparateAmt);
|
||||
shopOrderLkl.getStore_id(), orderId, refCanSeparateAmt);
|
||||
log.error(errorMsg);
|
||||
if (existingSeparateRecord != null) {
|
||||
lklOrderSeparateService.updateRemark(existingSeparateRecord.getId(), errorMsg);
|
||||
@ -2574,7 +2569,7 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
Integer agentAmount = lklSeparateDTO.getAgent2ndAmount();
|
||||
|
||||
log.info("[分账操作] 金额计算结果:订单={}, 商户={}, 总金额={}分, 可分金额={}分, 商家比例={}, 商家分得={}分, 平台比例={}, 平台分得={}分, 代理商比例={}, 代理商分得={}分",
|
||||
orderId, merchantNo, shopOrderLkl.getTotal_amt(), canSeparateAmt, mchSplitRatio, merchantAmount,
|
||||
orderId, merchantNo, shopOrderLkl.getTotal_amt(), refCanSeparateAmt, mchSplitRatio, merchantAmount,
|
||||
platformSplitRatio, platformAmount, distributorSplitRatio, agentAmount);
|
||||
|
||||
// 构建分账接收方分账参数
|
||||
@ -2598,11 +2593,14 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
|
||||
// 二级代理商(县级)分账参数
|
||||
if (agentAmount != null && agentAmount > 0 && CollUtil.isNotEmpty(distributorReceivers)) {
|
||||
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);
|
||||
LklLedgerMerReceiverBind distributorReceiver = distributorReceivers.get(0);
|
||||
if (distributorReceiver != null && StrUtil.isNotBlank(distributorReceiver.getReceiver_no())) {
|
||||
V3SacsSeparateRecvDatas receiver = new V3SacsSeparateRecvDatas();
|
||||
receiver.setRecvNo(distributorReceiver.getReceiver_no());
|
||||
receiver.setSeparateValue(agentAmount.toString());
|
||||
recvDatas.add(receiver);
|
||||
log.debug("[分账操作] 添加代理商接收方: receiverNo={}, amount={}", distributorReceiver.getReceiver_no(), agentAmount);
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化拉卡拉SDK
|
||||
@ -2615,7 +2613,7 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
separateRequest.setOutSeparateNo(shopOrderLkl.getOut_separate_no());
|
||||
separateRequest.setLogNo(shopOrderLkl.getLkl_receive_log_no()); // 使用确认收货流水号作为分账流水号
|
||||
separateRequest.setLogDate(shopOrderLkl.getLkl_log_date());
|
||||
separateRequest.setTotalAmt(canSeparateAmt.toString());
|
||||
separateRequest.setTotalAmt(refCanSeparateAmt.toString());
|
||||
separateRequest.setLklOrgNo(orgCode);
|
||||
separateRequest.setCalType("0"); // 0- 按照指定金额,1- 按照指定比例。默认 0
|
||||
separateRequest.setNotifyUrl(projectDomain + "/api/mobile/shop/lakala/sacs/separateNotify");
|
||||
@ -2650,6 +2648,9 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
(respJson != null ? respJson.getStr("msg") : "未知错误"));
|
||||
}
|
||||
|
||||
// 只有在分账请求成功发送后才更新分账备注
|
||||
shopOrderLklService.safeUpdate(shopOrderLkl);
|
||||
|
||||
// 保存分账记录
|
||||
JSONObject respData = respJson.getJSONObject("resp_data");
|
||||
LklOrderSeparate separateRecord = new LklOrderSeparate();
|
||||
@ -2665,7 +2666,7 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
separateRecord.setRecv_datas(JSONUtil.toJsonStr(separateRequest.getRecvDatas()));
|
||||
separateRecord.setStatus(respData.getStr("status"));
|
||||
separateRecord.setTotal_amt(separateRequest.getTotalAmt());
|
||||
separateRecord.setActual_separate_amt(Convert.toStr(canSeparateAmt));
|
||||
separateRecord.setActual_separate_amt(Convert.toStr(refCanSeparateAmt));
|
||||
separateRecord.setTotal_fee_amt(Convert.toStr(lklSeparateDTO.getLklAmount()));
|
||||
|
||||
if (lklOrderSeparateService.addOrUpdateByReceiverNo(separateRecord)) {
|
||||
|
||||
@ -172,6 +172,13 @@ public class OrderPayedListener {
|
||||
|
||||
// 处理异常,不抛出,以免影响到主流程
|
||||
try {
|
||||
// 检查是否已发送过推送消息(幂等性检查)
|
||||
String pushFlagKey = RedisConstant.New_Order_Push_Flag_Key + orderId;
|
||||
if (redisService.get(pushFlagKey) != null) {
|
||||
logger.info("[订单支付监听] 推送消息已发送,跳过重复推送. 订单ID: {}", orderId);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 同城配送或普通快递,都发送 unipush 推送:您有一个新的订单,请查收!
|
||||
String orderType = orderInfoOld.getDelivery_type_id() == StateCode.DELIVERY_TYPE_SAME_CITY ? "同城" : "";
|
||||
String title = String.format("您有一笔新的%s订单,请注意查收。", orderType);
|
||||
@ -189,9 +196,13 @@ public class OrderPayedListener {
|
||||
mchOrderExpireSeconds = shopOrderBaseService.sameCityOrderExpireSeconds(1500L);
|
||||
redisService.set(RedisConstant.SF_Order_Proc_Expire_Key + String.format("%d&%s", orderInfoOld.getStore_id(), orderId), orderId, mchOrderExpireSeconds);
|
||||
|
||||
// 记录推送已发送状态,避免重复推送
|
||||
redisService.set(pushFlagKey, "1", 24 * 3600); // 24小时过期
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("[订单支付监听] 发送推送消息失败. 订单ID: {}", orderId, e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user