分账指令方法优化日志,增加接收异步通知
This commit is contained in:
parent
34a8d7655d
commit
814f905e34
@ -26,6 +26,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
@ -66,8 +67,8 @@ public class AnalyticsUserServiceImpl implements AnalyticsUserService {
|
||||
// 计算日环比 日环比 = (当日数据 - 前一日数据) / 前一日数据 * 100%
|
||||
BigDecimal daym2m = BigDecimal.ZERO;
|
||||
if (yestodayRegUser.getNum().compareTo(BigDecimal.ZERO) != 0) {
|
||||
daym2m = (todayRegUser.getNum().subtract(yestodayRegUser.getNum())).divide(yestodayRegUser.getNum(), 2, BigDecimal.ROUND_HALF_UP);
|
||||
//.multiply(new BigDecimal("100"));
|
||||
daym2m = (todayRegUser.getNum().subtract(yestodayRegUser.getNum())).divide(yestodayRegUser.getNum(), 2, RoundingMode.HALF_UP);
|
||||
//.multiply(new BigDecimal(100));
|
||||
} else {
|
||||
|
||||
}
|
||||
@ -126,8 +127,8 @@ public class AnalyticsUserServiceImpl implements AnalyticsUserService {
|
||||
// 计算日环比 日环比 = (当日数据 - 前一日数据) / 前一日数据 * 100%
|
||||
BigDecimal daym2m = BigDecimal.ZERO;
|
||||
if (preRegNum.getNum().compareTo(BigDecimal.ZERO) != 0) {
|
||||
daym2m = (currentRegNum.getNum().subtract(preRegNum.getNum())).divide(preRegNum.getNum(), 2, BigDecimal.ROUND_HALF_UP);
|
||||
//.multiply(new BigDecimal("100"));
|
||||
daym2m = (currentRegNum.getNum().subtract(preRegNum.getNum())).divide(preRegNum.getNum(), 2, RoundingMode.HALF_UP);
|
||||
//.multiply(new BigDecimal(100));
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
@ -94,4 +94,8 @@ public class CommonConstant {
|
||||
|
||||
public static final String SPLIT_ = "diffCityOrderExpireSeconds";
|
||||
|
||||
// 订单分拆后 运费和商品子订单前缀
|
||||
public static final String Sep_DeliveryFee_Prefix = "DF-";
|
||||
public static final String Sep_GoodsFee_Prefix = "ORD-";
|
||||
|
||||
}
|
||||
|
||||
@ -38,8 +38,12 @@ public class ShopOrderLkl implements Serializable {
|
||||
|
||||
private String order_id;
|
||||
|
||||
private String out_separate_no;
|
||||
|
||||
private Integer total_amt;
|
||||
|
||||
private Integer split_amt;
|
||||
|
||||
private Integer shopping_fee;
|
||||
|
||||
private BigDecimal split_ratio;
|
||||
@ -56,6 +60,8 @@ public class ShopOrderLkl implements Serializable {
|
||||
|
||||
private String lkl_log_date;
|
||||
|
||||
private String lkl_split_log_no;
|
||||
|
||||
private String lkl_trade_no;
|
||||
|
||||
private String lkl_merchant_no;
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package com.suisung.mall.pay.service;
|
||||
|
||||
import cn.hutool.json.JSONObject;
|
||||
import com.suisung.mall.common.api.CommonResult;
|
||||
import com.suisung.mall.common.modules.order.ShopOrderReturn;
|
||||
import com.suisung.mall.common.modules.pay.PayConsumeTrade;
|
||||
@ -61,4 +62,44 @@ public interface PayConsumeTradeService extends IBaseService<PayConsumeTrade> {
|
||||
*/
|
||||
Boolean updateTradeByPrimaryKey(PayConsumeTrade payConsumeTrade);
|
||||
|
||||
|
||||
/**
|
||||
* 从拉卡拉分账响应信息中提取合单运费或商品订单信息
|
||||
* <p>该方法用于处理合单支付场景,从拉卡拉返回的分账信息中筛选出运费子单或商品子单信息</p>
|
||||
*
|
||||
* @param outSplitRspInfos 拉卡拉分账响应信息,格式为JSON数组字符串:
|
||||
* [
|
||||
* {
|
||||
* "sub_trade_no":"20250830110113130266250034401288", // 子交易流水号
|
||||
* "merchant_no":"822584059990FYP", // 商户号
|
||||
* "amount":"1", // 分账金额
|
||||
* "settle_type":"0", // 结算类型
|
||||
* "sub_log_no":"66250034401288", // 子流水号
|
||||
* "out_sub_trade_no":"DF-DD-20250830-21", // 外部子交易订单号(DF开头为运费订单)
|
||||
* "term_no":"N5811590" // 终端设备号
|
||||
* },
|
||||
* {
|
||||
* "sub_trade_no":"20250830110113130266250034401289", // 子交易流水号
|
||||
* "merchant_no":"8226330541100GU", // 商户号
|
||||
* "amount":"1", // 分账金额
|
||||
* "settle_type":"0", // 结算类型
|
||||
* "sub_log_no":"66250034401289", // 子流水号
|
||||
* "out_sub_trade_no":"ORD-DD-20250830-21", // 外部子交易订单号(ORD开头为商品订单)
|
||||
* "term_no":"N5817779" // 终端设备号
|
||||
* }
|
||||
* ]
|
||||
* @param isDeliveryFee true: 提取运费子单信息, false: 提取商品子单信息
|
||||
* @return JSONObject 返回匹配的子单信息,格式如下:
|
||||
* {
|
||||
* "sub_trade_no":"20250830110113130266250034401288",
|
||||
* "merchant_no":"822584059990FYP",
|
||||
* "amount":"1",
|
||||
* "settle_type":"0",
|
||||
* "sub_log_no":"66250034401288",
|
||||
* "out_sub_trade_no":"DF-DD-20250830-21",
|
||||
* "term_no":"N5811590"
|
||||
* }
|
||||
*/
|
||||
JSONObject getLklCombineSplitRespInfo(String outSplitRspInfos, boolean isDeliveryFee);
|
||||
|
||||
}
|
||||
|
||||
@ -83,7 +83,7 @@ public class AnalytiscTradeServiceImpl implements AnalytiscTradeService {
|
||||
BigDecimal daym2m = BigDecimal.ZERO;
|
||||
if (yestodayTradeAmount.getAmount().compareTo(BigDecimal.ZERO) != 0) {
|
||||
daym2m = (todayTradeAmount.getAmount().subtract(yestodayTradeAmount.getAmount())).divide(yestodayTradeAmount.getAmount(), 2, RoundingMode.HALF_UP);
|
||||
//.multiply(new BigDecimal("100"));
|
||||
//.multiply(new BigDecimal(100));
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
@ -23,6 +23,7 @@ import com.lkl.laop.sdk.request.V3LabsRelationRefundRequest;
|
||||
import com.lkl.laop.sdk.request.V3LabsTransPreorderRequest;
|
||||
import com.lkl.laop.sdk.request.model.V3LabsTradeLocationInfo;
|
||||
import com.lkl.laop.sdk.request.model.V3LabsTradePreorderWechatBus;
|
||||
import com.suisung.mall.common.constant.CommonConstant;
|
||||
import com.suisung.mall.common.exception.ApiException;
|
||||
import com.suisung.mall.common.feignService.ShopService;
|
||||
import com.suisung.mall.common.modules.store.ShopStoreBase;
|
||||
@ -265,7 +266,7 @@ public class LakalaPayServiceImpl implements LakalaPayService {
|
||||
// 重要约定,订单号规则:商品订单:ORD-订单号,运费订单:DF-订单号
|
||||
// 分单信息
|
||||
JSONObject goodsSplitInfo = new JSONObject();
|
||||
goodsSplitInfo.put("out_sub_trade_no", "ORD-" + orderId); // 子订单号
|
||||
goodsSplitInfo.put("out_sub_trade_no", CommonConstant.Sep_GoodsFee_Prefix + orderId); // 商品子订单号
|
||||
goodsSplitInfo.put("merchant_no", merchantNo); // 分账商户号
|
||||
goodsSplitInfo.put("term_no", termNo); // 分账终端号
|
||||
int totalAmountInt = Convert.toInt(totalAmount) - Convert.toInt(agentAmount);
|
||||
@ -274,7 +275,7 @@ public class LakalaPayServiceImpl implements LakalaPayService {
|
||||
goodsSplitInfo.put("sub_remark", "商品订单金额"); // 子单备注信息
|
||||
|
||||
JSONObject deliverySplitInfo = new JSONObject();
|
||||
deliverySplitInfo.put("out_sub_trade_no", "DF-" + orderId); // 子订单号
|
||||
deliverySplitInfo.put("out_sub_trade_no", CommonConstant.Sep_DeliveryFee_Prefix + orderId); // 运费子订单号
|
||||
deliverySplitInfo.put("merchant_no", agentMerchantNo); // 分账商户号
|
||||
deliverySplitInfo.put("term_no", agentTermNo); // 分账终端号
|
||||
deliverySplitInfo.put("amount", agentAmount); // 分账金额
|
||||
@ -320,6 +321,8 @@ public class LakalaPayServiceImpl implements LakalaPayService {
|
||||
JSONObject lklPayReqAndRespJson = new JSONObject();
|
||||
lklPayReqAndRespJson.put("req", reqData);
|
||||
lklPayReqAndRespJson.put("resp", respBody); // 返回原始响应数据
|
||||
|
||||
// 新增 shopOrderLkl 记录
|
||||
shopService.lklPayAddShopOrderLkl(lklPayReqAndRespJson);
|
||||
|
||||
// 8. 返回响应结果
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -1360,12 +1360,20 @@ public class PayUserPayServiceImpl extends BaseServiceImpl<PayUserPayMapper, Pay
|
||||
|
||||
// 敏感头信息脱敏打印
|
||||
logger.info("拉卡拉支付异步通知回调 body:{} \n authorization: {}", body, authorization);
|
||||
// 异步通知返回的body json数据:{"out_trade_no":"202203151637334864280014","trade_no":"2022031566210203291925","log_no":"66210203291925",
|
||||
// 非合单返回的数据异步通知返回的 body json数据:{"out_trade_no":"202203151637334864280014","trade_no":"2022031566210203291925","log_no":"66210203291925",
|
||||
// "acc_trade_no":"2022031522001483661454130929 ","trade_status":"SUCCESS","trade_state":"SUCCESS","total_amount":"1",
|
||||
// "payer_amount":"1","acc_settle_amount":"1","trade_time":"20220315163808","user_id1":"app***@163.com",
|
||||
// "user_id2":"2088432881453660","notify_url":"https://www.baidu.com","account_type":"ALIPAY","card_type":"99"}
|
||||
|
||||
// 合单返回的数据:{"out_trade_no":"DD-20250830-10","trade_no":"20250830110113130266250034160499","log_no":"66250034160499","acc_trade_no":"4200002826202508306761393882","trade_status":"SUCCESS","trade_state":"SUCCESS","total_amount":"2","payer_amount":"2","acc_settle_amount":"2","acc_mdiscount_amount":"0","acc_discount_amount":"0","trade_time":"20250830180435","user_id1":"oDVKR7T0qxg6O8tqIL9SgY6LXqqQ","user_id2":"oVxsc1QRAqDRv_gAmXuLZwSVSL18","notify_url":"https://mall.gpxscs.cn/mobile/pay/index/lkl_wxPay_notify_url","account_type":"WECHAT","bank_type":"OTHERS","card_type":"02","merchant_no":"8226330541100GU","remark":"","sub_mch_id":"803819329","out_split_rsp_infos":[{"sub_trade_no":"20250830110113130266250034112794","sub_log_no":"66250034112794","out_sub_trade_no":"ORD_DD-20250830-10","merchant_no":"8226330541100GU","term_no":"N5817779","amount":"1","settle_type":"0"},{"sub_trade_no":"20250830110113130266250034160498","sub_log_no":"66250034160498","out_sub_trade_no":"DF_DD-20250830-10","merchant_no":"822584059990FYP","term_no":"N5811590","amount":"1","settle_type":"0"}],"trade_req_date":"20250830","gb_amount":"","qb_amount":""}
|
||||
// 合单返回的数据异步通知返回的 body json数据:{"out_trade_no":"DD-20250830-10","trade_no":"20250830110113130266250034160499","log_no":"66250034160499",
|
||||
// "acc_trade_no":"4200002826202508306761393882","trade_status":"SUCCESS","trade_state":"SUCCESS","total_amount":"2","payer_amount":"2","acc_settle_amount":"2",
|
||||
// "acc_mdiscount_amount":"0","acc_discount_amount":"0","trade_time":"20250830180435","user_id1":"oDVKR7T0qxg6O8tqIL9SgY6LXqqQ",
|
||||
// "user_id2":"oVxsc1QRAqDRv_gAmXuLZwSVSL18","notify_url":"https://mall.gpxscs.cn/mobile/pay/index/lkl_wxPay_notify_url","account_type":"WECHAT",
|
||||
// "bank_type":"OTHERS","card_type":"02","merchant_no":"8226330541100GU","remark":"","sub_mch_id":"803819329",
|
||||
// "out_split_rsp_infos":[{"sub_trade_no":"20250830110113130266250034112794","sub_log_no":"66250034112794","out_sub_trade_no":"ORD-DD-20250830-10",
|
||||
// "merchant_no":"8226330541100GU","term_no":"N5817779","amount":"1","settle_type":"0"},{"sub_trade_no":"20250830110113130266250034160498","sub_log_no":"66250034160498",
|
||||
// "out_sub_trade_no":"DF-DD-20250830-10","merchant_no":"822584059990FYP","term_no":"N5811590","amount":"1","settle_type":"0"}],"trade_req_date":"20250830","gb_amount":"",
|
||||
// "qb_amount":""}
|
||||
|
||||
// 解析JSON格式响应
|
||||
cn.hutool.json.JSONObject lklNotifyRespJSON = JSONUtil.parseObj(body);
|
||||
@ -1425,6 +1433,9 @@ public class PayUserPayServiceImpl extends BaseServiceImpl<PayUserPayMapper, Pay
|
||||
payConsumeDeposit.setDeposit_body(orderSubject);
|
||||
payConsumeDeposit.setUser_id(userId);
|
||||
|
||||
lklNotifyRespJSON.set("out_separate_no", orderId);// 默认非合单主单订单号
|
||||
lklNotifyRespJSON.set("lkl_split_log_no", lklNotifyRespJSON.getStr("log_no")); // 默认非合单主单的流水号
|
||||
lklNotifyRespJSON.set("split_amt", lklNotifyRespJSON.getStr("total_amount")); // 默认非合单主单支付金额
|
||||
// 拉卡拉订单合单信息
|
||||
if (StrUtil.isNotBlank(outSplitRspInfos)) {
|
||||
// [{"sub_trade_no":"20250830110113130266250034401288","merchant_no":"822584059990FYP","amount":"1","settle_type":"0","sub_log_no":"66250034401288","out_sub_trade_no":"DF-DD-20250830-21","term_no":"N5811590"},{"sub_trade_no":"20250830110113130266250034401289","merchant_no":"8226330541100GU","amount":"1","settle_type":"0","sub_log_no":"66250034401289","out_sub_trade_no":"ORD-DD-20250830-21","term_no":"N5817779"}]
|
||||
@ -1432,9 +1443,19 @@ public class PayUserPayServiceImpl extends BaseServiceImpl<PayUserPayMapper, Pay
|
||||
|
||||
Pair<String, String> subTradeNos = getLklSubTradeNo(outSplitRspInfos);
|
||||
if (subTradeNos != null) {
|
||||
// 商品子订单号
|
||||
payConsumeDeposit.setOrd_sub_trade_no(subTradeNos.getFirst());
|
||||
// 商品运费子订单号
|
||||
payConsumeDeposit.setDf_sub_trade_no(subTradeNos.getSecond());
|
||||
}
|
||||
|
||||
// 获取拉卡拉订单合单商品信息
|
||||
cn.hutool.json.JSONObject goodsOrderInfo = payConsumeTradeService.getLklCombineSplitRespInfo(outSplitRspInfos, false);
|
||||
if (goodsOrderInfo != null) {
|
||||
lklNotifyRespJSON.set("out_separate_no", goodsOrderInfo.getStr("out_sub_trade_no"));// 合单子订单号
|
||||
lklNotifyRespJSON.set("lkl_split_log_no", lklNotifyRespJSON.getStr("sub_log_no")); // 合单子商品订单的流水号
|
||||
lklNotifyRespJSON.set("split_amt", lklNotifyRespJSON.getStr("amount")); // 合单子商品订单支付金额
|
||||
}
|
||||
}
|
||||
|
||||
// 判断是否联合支付
|
||||
@ -1900,13 +1921,13 @@ public class PayUserPayServiceImpl extends BaseServiceImpl<PayUserPayMapper, Pay
|
||||
}
|
||||
|
||||
// 6. 根据前缀分类处理
|
||||
if (outSubTradeNo.startsWith("ORD-")) {
|
||||
if (outSubTradeNo.startsWith(CommonConstant.Sep_GoodsFee_Prefix)) {
|
||||
// 处理商品订单
|
||||
if (productSubTradeNo != null) {
|
||||
logger.warn("检测到重复的商品订单子流水号:{}", outSubTradeNo);
|
||||
}
|
||||
productSubTradeNo = item.getStr("sub_trade_no");
|
||||
} else if (outSubTradeNo.startsWith("DF-")) {
|
||||
} else if (outSubTradeNo.startsWith(CommonConstant.Sep_DeliveryFee_Prefix)) {
|
||||
// 处理运费订单
|
||||
if (shippingSubTradeNo != null) {
|
||||
logger.warn("检测到重复的运费子流水号:{}", outSubTradeNo);
|
||||
|
||||
@ -39,6 +39,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
@ -239,8 +240,8 @@ public class AnalyticsOrderServiceImpl implements AnalyticsOrderService {
|
||||
// 计算日环比 日环比 = (当日数据 - 前一日数据) / 前一日数据 * 100%
|
||||
BigDecimal daym2m = BigDecimal.ZERO;
|
||||
if (yestodayOrderNum.getOrderNum().compareTo(BigDecimal.ZERO) != 0) {
|
||||
daym2m = (todayOrderNum.getOrderNum().subtract(yestodayOrderNum.getOrderNum())).divide(yestodayOrderNum.getOrderNum(), 2, BigDecimal.ROUND_HALF_UP);
|
||||
//.multiply(new BigDecimal("100"));
|
||||
daym2m = (todayOrderNum.getOrderNum().subtract(yestodayOrderNum.getOrderNum())).divide(yestodayOrderNum.getOrderNum(), 2, RoundingMode.HALF_UP);
|
||||
//.multiply(new BigDecimal(100));
|
||||
} else {
|
||||
|
||||
}
|
||||
@ -316,8 +317,8 @@ public class AnalyticsOrderServiceImpl implements AnalyticsOrderService {
|
||||
// 计算日环比 日环比 = (当日数据 - 前一日数据) / 前一日数据 * 100%
|
||||
BigDecimal daym2m = BigDecimal.ZERO;
|
||||
if (preRegNum.getNum().compareTo(BigDecimal.ZERO) != 0) {
|
||||
daym2m = (currentRegNum.getNum().subtract(preRegNum.getNum())).divide(preRegNum.getNum(), 2, BigDecimal.ROUND_HALF_UP);
|
||||
//.multiply(new BigDecimal("100"));
|
||||
daym2m = (currentRegNum.getNum().subtract(preRegNum.getNum())).divide(preRegNum.getNum(), 2, RoundingMode.HALF_UP);
|
||||
//.multiply(new BigDecimal(100));
|
||||
} else {
|
||||
|
||||
}
|
||||
@ -370,8 +371,8 @@ public class AnalyticsOrderServiceImpl implements AnalyticsOrderService {
|
||||
// 计算日环比 日环比 = (当日数据 - 前一日数据) / 前一日数据 * 100%
|
||||
BigDecimal daym2m = BigDecimal.ZERO;
|
||||
if (preRegNum.getNum().compareTo(BigDecimal.ZERO) != 0) {
|
||||
daym2m = (currentRegNum.getNum().subtract(preRegNum.getNum())).divide(preRegNum.getNum(), 2, BigDecimal.ROUND_HALF_UP);
|
||||
//.multiply(new BigDecimal("100"));
|
||||
daym2m = (currentRegNum.getNum().subtract(preRegNum.getNum())).divide(preRegNum.getNum(), 2, RoundingMode.HALF_UP);
|
||||
//.multiply(new BigDecimal(100));
|
||||
} else {
|
||||
|
||||
}
|
||||
@ -423,8 +424,8 @@ public class AnalyticsOrderServiceImpl implements AnalyticsOrderService {
|
||||
// 计算日环比 日环比 = (当日数据 - 前一日数据) / 前一日数据 * 100%
|
||||
BigDecimal daym2m = BigDecimal.ZERO;
|
||||
if (preRegNum.getNum().compareTo(BigDecimal.ZERO) != 0) {
|
||||
daym2m = (currentRegNum.getNum().subtract(preRegNum.getNum())).divide(preRegNum.getNum(), 2, BigDecimal.ROUND_HALF_UP);
|
||||
//.multiply(new BigDecimal("100"));
|
||||
daym2m = (currentRegNum.getNum().subtract(preRegNum.getNum())).divide(preRegNum.getNum(), 2, RoundingMode.HALF_UP);
|
||||
//.multiply(new BigDecimal(100));
|
||||
} else {
|
||||
|
||||
}
|
||||
@ -483,8 +484,8 @@ public class AnalyticsOrderServiceImpl implements AnalyticsOrderService {
|
||||
// 计算日环比 日环比 = (当日数据 - 前一日数据) / 前一日数据 * 100%
|
||||
BigDecimal daym2m = BigDecimal.ZERO;
|
||||
if (preRegNum.getNum().compareTo(BigDecimal.ZERO) != 0) {
|
||||
daym2m = (currentRegNum.getNum().subtract(preRegNum.getNum())).divide(preRegNum.getNum(), 2, BigDecimal.ROUND_HALF_UP);
|
||||
//.multiply(new BigDecimal("100"));
|
||||
daym2m = (currentRegNum.getNum().subtract(preRegNum.getNum())).divide(preRegNum.getNum(), 2, RoundingMode.HALF_UP);
|
||||
//.multiply(new BigDecimal(100));
|
||||
} else {
|
||||
|
||||
}
|
||||
@ -564,8 +565,8 @@ public class AnalyticsOrderServiceImpl implements AnalyticsOrderService {
|
||||
// 计算日环比 日环比 = (当日数据 - 前一日数据) / 前一日数据 * 100%
|
||||
BigDecimal daym2m = BigDecimal.ZERO;
|
||||
if (preProductNum.getNum().compareTo(BigDecimal.ZERO) != 0) {
|
||||
daym2m = (currentProductNum.getNum().subtract(preProductNum.getNum())).divide(preProductNum.getNum(), 2, BigDecimal.ROUND_HALF_UP);
|
||||
//.multiply(new BigDecimal("100"));
|
||||
daym2m = (currentProductNum.getNum().subtract(preProductNum.getNum())).divide(preProductNum.getNum(), 2, RoundingMode.HALF_UP);
|
||||
//.multiply(new BigDecimal(100));
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
|
||||
@Service
|
||||
public class AnalyticsProductServiceImpl implements AnalyticsProductService {
|
||||
@ -51,8 +52,8 @@ public class AnalyticsProductServiceImpl implements AnalyticsProductService {
|
||||
// 计算日环比 日环比 = (当日数据 - 前一日数据) / 前一日数据 * 100%
|
||||
BigDecimal daym2m = BigDecimal.ZERO;
|
||||
if (preProductNum.getNum().compareTo(BigDecimal.ZERO) != 0) {
|
||||
daym2m = (currentProductNum.getNum().subtract(preProductNum.getNum())).divide(preProductNum.getNum(), 2, BigDecimal.ROUND_HALF_UP);
|
||||
//.multiply(new BigDecimal("100"));
|
||||
daym2m = (currentProductNum.getNum().subtract(preProductNum.getNum())).divide(preProductNum.getNum(), 2, RoundingMode.HALF_UP);
|
||||
//.multiply(new BigDecimal(100));
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
@ -24,6 +24,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
@ -91,8 +92,8 @@ public class AnalyticsReturnServiceImpl implements AnalyticsReturnService {
|
||||
// 计算日环比 日环比 = (当日数据 - 前一日数据) / 前一日数据 * 100%
|
||||
BigDecimal daym2m = BigDecimal.ZERO;
|
||||
if (preRegNum.getNum().compareTo(BigDecimal.ZERO) != 0) {
|
||||
daym2m = (currentRegNum.getNum().subtract(preRegNum.getNum())).divide(preRegNum.getNum(), 2, BigDecimal.ROUND_HALF_UP);
|
||||
//.multiply(new BigDecimal("100"));
|
||||
daym2m = (currentRegNum.getNum().subtract(preRegNum.getNum())).divide(preRegNum.getNum(), 2, RoundingMode.HALF_UP);
|
||||
//.multiply(new BigDecimal(100));
|
||||
} else {
|
||||
|
||||
}
|
||||
@ -150,8 +151,8 @@ public class AnalyticsReturnServiceImpl implements AnalyticsReturnService {
|
||||
// 计算日环比 日环比 = (当日数据 - 前一日数据) / 前一日数据 * 100%
|
||||
BigDecimal daym2m = BigDecimal.ZERO;
|
||||
if (preRegNum.getNum().compareTo(BigDecimal.ZERO) != 0) {
|
||||
daym2m = (currentRegNum.getNum().subtract(preRegNum.getNum())).divide(preRegNum.getNum(), 2, BigDecimal.ROUND_HALF_UP);
|
||||
//.multiply(new BigDecimal("100"));
|
||||
daym2m = (currentRegNum.getNum().subtract(preRegNum.getNum())).divide(preRegNum.getNum(), 2, RoundingMode.HALF_UP);
|
||||
//.multiply(new BigDecimal(100));
|
||||
} else {
|
||||
|
||||
}
|
||||
@ -205,8 +206,8 @@ public class AnalyticsReturnServiceImpl implements AnalyticsReturnService {
|
||||
// 计算日环比 日环比 = (当日数据 - 前一日数据) / 前一日数据 * 100%
|
||||
BigDecimal daym2m = BigDecimal.ZERO;
|
||||
if (preRegNum.getNum().compareTo(BigDecimal.ZERO) != 0) {
|
||||
daym2m = (currentRegNum.getNum().subtract(preRegNum.getNum())).divide(preRegNum.getNum(), 2, BigDecimal.ROUND_HALF_UP);
|
||||
//.multiply(new BigDecimal("100"));
|
||||
daym2m = (currentRegNum.getNum().subtract(preRegNum.getNum())).divide(preRegNum.getNum(), 2, RoundingMode.HALF_UP);
|
||||
//.multiply(new BigDecimal(100));
|
||||
} else {
|
||||
|
||||
}
|
||||
@ -287,8 +288,8 @@ public class AnalyticsReturnServiceImpl implements AnalyticsReturnService {
|
||||
// 计算日环比 日环比 = (当日数据 - 前一日数据) / 前一日数据 * 100%
|
||||
BigDecimal daym2m = BigDecimal.ZERO;
|
||||
if (preProductNum.getNum().compareTo(BigDecimal.ZERO) != 0) {
|
||||
daym2m = (currentProductNum.getNum().subtract(preProductNum.getNum())).divide(preProductNum.getNum(), 2, BigDecimal.ROUND_HALF_UP);
|
||||
//.multiply(new BigDecimal("100"));
|
||||
daym2m = (currentProductNum.getNum().subtract(preProductNum.getNum())).divide(preProductNum.getNum(), 2, RoundingMode.HALF_UP);
|
||||
//.multiply(new BigDecimal(100));
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
@ -17,6 +17,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@ -52,8 +53,8 @@ public class AnalyticsStoreServiceImpl implements AnalyticsStoreService {
|
||||
// 计算日环比 日环比 = (当日数据 - 前一日数据) / 前一日数据 * 100%
|
||||
BigDecimal daym2m = BigDecimal.ZERO;
|
||||
if (yestodayRegUser.getNum().compareTo(BigDecimal.ZERO) != 0) {
|
||||
daym2m = (todayRegUser.getNum().subtract(yestodayRegUser.getNum())).divide(yestodayRegUser.getNum(), 2, BigDecimal.ROUND_HALF_UP);
|
||||
//.multiply(new BigDecimal("100"));
|
||||
daym2m = (todayRegUser.getNum().subtract(yestodayRegUser.getNum())).divide(yestodayRegUser.getNum(), 2, RoundingMode.HALF_UP);
|
||||
//.multiply(new BigDecimal(100));
|
||||
} else {
|
||||
|
||||
}
|
||||
@ -113,8 +114,8 @@ public class AnalyticsStoreServiceImpl implements AnalyticsStoreService {
|
||||
// 计算日环比 日环比 = (当日数据 - 前一日数据) / 前一日数据 * 100%
|
||||
BigDecimal daym2m = BigDecimal.ZERO;
|
||||
if (preRegNum.getNum().compareTo(BigDecimal.ZERO) != 0) {
|
||||
daym2m = (currentRegNum.getNum().subtract(preRegNum.getNum())).divide(preRegNum.getNum(), 2, BigDecimal.ROUND_HALF_UP);
|
||||
//.multiply(new BigDecimal("100"));
|
||||
daym2m = (currentRegNum.getNum().subtract(preRegNum.getNum())).divide(preRegNum.getNum(), 2, RoundingMode.HALF_UP);
|
||||
//.multiply(new BigDecimal(100));
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
@ -23,6 +23,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
@ -59,8 +60,8 @@ public class AnalyticsSysServiceImpl implements AnalyticsSysService {
|
||||
// 计算日环比 日环比 = (当日数据 - 前一日数据) / 前一日数据 * 100%
|
||||
BigDecimal daym2m = BigDecimal.ZERO;
|
||||
if (yestodayVisits.getNum().compareTo(BigDecimal.ZERO) != 0) {
|
||||
daym2m = (todayVisits.getNum().subtract(yestodayVisits.getNum())).divide(yestodayVisits.getNum(), 2, BigDecimal.ROUND_HALF_UP);
|
||||
//.multiply(new BigDecimal("100"));
|
||||
daym2m = (todayVisits.getNum().subtract(yestodayVisits.getNum())).divide(yestodayVisits.getNum(), 2, RoundingMode.HALF_UP);
|
||||
//.multiply(new BigDecimal(100));
|
||||
} else {
|
||||
|
||||
}
|
||||
@ -105,8 +106,8 @@ public class AnalyticsSysServiceImpl implements AnalyticsSysService {
|
||||
// 计算日环比 日环比 = (当日数据 - 前一日数据) / 前一日数据 * 100%
|
||||
BigDecimal daym2m = BigDecimal.ZERO;
|
||||
if (preProductNum.getNum().compareTo(BigDecimal.ZERO) != 0) {
|
||||
daym2m = (currentProductNum.getNum().subtract(preProductNum.getNum())).divide(preProductNum.getNum(), 2, BigDecimal.ROUND_HALF_UP);
|
||||
//.multiply(new BigDecimal("100"));
|
||||
daym2m = (currentProductNum.getNum().subtract(preProductNum.getNum())).divide(preProductNum.getNum(), 2, RoundingMode.HALF_UP);
|
||||
//.multiply(new BigDecimal(100));
|
||||
} else {
|
||||
|
||||
}
|
||||
@ -144,8 +145,8 @@ public class AnalyticsSysServiceImpl implements AnalyticsSysService {
|
||||
// 计算日环比 日环比 = (当日数据 - 前一日数据) / 前一日数据 * 100%
|
||||
BigDecimal daym2m = BigDecimal.ZERO;
|
||||
if (preProductNum.getNum().compareTo(BigDecimal.ZERO) != 0) {
|
||||
daym2m = (currentProductNum.getNum().subtract(preProductNum.getNum())).divide(preProductNum.getNum(), 2, BigDecimal.ROUND_HALF_UP);
|
||||
//.multiply(new BigDecimal("100"));
|
||||
daym2m = (currentProductNum.getNum().subtract(preProductNum.getNum())).divide(preProductNum.getNum(), 2, RoundingMode.HALF_UP);
|
||||
//.multiply(new BigDecimal(100));
|
||||
} else {
|
||||
|
||||
}
|
||||
@ -207,8 +208,8 @@ public class AnalyticsSysServiceImpl implements AnalyticsSysService {
|
||||
// 计算日环比 日环比 = (当日数据 - 前一日数据) / 前一日数据 * 100%
|
||||
BigDecimal daym2m = BigDecimal.ZERO;
|
||||
if (preProductNum.getNum().compareTo(BigDecimal.ZERO) != 0) {
|
||||
daym2m = (currentProductNum.getNum().subtract(preProductNum.getNum())).divide(preProductNum.getNum(), 2, BigDecimal.ROUND_HALF_UP);
|
||||
//.multiply(new BigDecimal("100"));
|
||||
daym2m = (currentProductNum.getNum().subtract(preProductNum.getNum())).divide(preProductNum.getNum(), 2, RoundingMode.HALF_UP);
|
||||
//.multiply(new BigDecimal(100));
|
||||
} else {
|
||||
|
||||
}
|
||||
@ -270,8 +271,8 @@ public class AnalyticsSysServiceImpl implements AnalyticsSysService {
|
||||
// 计算日环比 日环比 = (当日数据 - 前一日数据) / 前一日数据 * 100%
|
||||
BigDecimal daym2m = BigDecimal.ZERO;
|
||||
if (preProductNum.getNum().compareTo(BigDecimal.ZERO) != 0) {
|
||||
daym2m = (currentProductNum.getNum().subtract(preProductNum.getNum())).divide(preProductNum.getNum(), 2, BigDecimal.ROUND_HALF_UP);
|
||||
//.multiply(new BigDecimal("100"));
|
||||
daym2m = (currentProductNum.getNum().subtract(preProductNum.getNum())).divide(preProductNum.getNum(), 2, RoundingMode.HALF_UP);
|
||||
//.multiply(new BigDecimal(100));
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
@ -95,7 +95,7 @@ public class ShopBaseStoreCategoryAdminController {
|
||||
return CommonResult.failed(I18nUtil._("分成比例不能小于94"));
|
||||
}
|
||||
|
||||
if (shopBaseStoreCategory.getSplit_ratio().compareTo(new BigDecimal("100")) > 0) {
|
||||
if (shopBaseStoreCategory.getSplit_ratio().compareTo(new BigDecimal(100)) > 0) {
|
||||
return CommonResult.failed(I18nUtil._("分成比例不能大于100"));
|
||||
}
|
||||
|
||||
|
||||
@ -10,8 +10,8 @@ import com.suisung.mall.core.web.service.RedisService;
|
||||
import com.suisung.mall.core.web.service.impl.BaseServiceImpl;
|
||||
import com.suisung.mall.shop.base.mapper.ShopBaseStoreCategoryMapper;
|
||||
import com.suisung.mall.shop.base.service.ShopBaseStoreCategoryService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import com.suisung.mall.shop.store.service.ShopStoreBaseService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.context.request.RequestAttributes;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
@ -66,7 +66,7 @@ public class ShopBaseStoreCategoryServiceImpl extends BaseServiceImpl<ShopBaseSt
|
||||
cache_key = cache_key + ":category_is_enable:" + category_is_enable;
|
||||
queryWrapper.eq("category_is_enable", category_is_enable);
|
||||
}
|
||||
Integer pageSize =ObjectUtil.defaultIfNull(getParameter("pageSize",Integer.class),10) ;
|
||||
Integer pageSize = ObjectUtil.defaultIfNull(getParameter("pageSize", Integer.class), 10);
|
||||
cache_key = cache_key + ":" + LANG;
|
||||
|
||||
// 设置cache todo 关闭缓存(修改分类的时候没删除缓存)
|
||||
@ -79,39 +79,39 @@ public class ShopBaseStoreCategoryServiceImpl extends BaseServiceImpl<ShopBaseSt
|
||||
category_rows = Convert.toList(Map.class, categories);
|
||||
|
||||
List<CompletableFuture<Void>> futures = new ArrayList<>();
|
||||
Map<String,Map> storeLis = new HashMap<>();
|
||||
if(openFindStore){
|
||||
Map<String, Map> storeLis = new HashMap<>();
|
||||
if (openFindStore) {
|
||||
long startTime = System.currentTimeMillis();
|
||||
for (Map category_row : category_rows) {
|
||||
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
|
||||
CompletableFuture<Void> future = CompletableFuture.supplyAsync(() -> {
|
||||
RequestContextHolder.setRequestAttributes(requestAttributes,true);
|
||||
RequestContextHolder.setRequestAttributes(requestAttributes, true);
|
||||
Integer store_category_id = (Integer) category_row.get("store_category_id");
|
||||
Map<String, Object> row = new HashMap<>();
|
||||
row.put("store_category_id", String.valueOf(store_category_id));
|
||||
row.put("findStore",true);
|
||||
row.put("store_type","1");
|
||||
Map storeListMap= shopStoreBaseService.getStoreList(1, pageSize,row);
|
||||
row.put("findStore", true);
|
||||
row.put("store_type", "1");
|
||||
Map storeListMap = shopStoreBaseService.getStoreList(1, pageSize, row);
|
||||
storeLis.put(String.valueOf(store_category_id), storeListMap);
|
||||
return null;
|
||||
});
|
||||
futures.add(future);
|
||||
}
|
||||
|
||||
CompletableFuture<Void> allOfFuture = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
|
||||
.thenRun(() -> {
|
||||
long endTime = System.currentTimeMillis();
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
log.debug("异步调用完成! 总耗时: "+(endTime - startTime) + "ms\n");
|
||||
CompletableFuture<Void> allOfFuture = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
|
||||
.thenRun(() -> {
|
||||
long endTime = System.currentTimeMillis();
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
log.debug("异步调用完成! 总耗时: " + (endTime - startTime) + "ms\n");
|
||||
});
|
||||
});
|
||||
});
|
||||
allOfFuture.join();
|
||||
}
|
||||
|
||||
for (Map category_row : category_rows) {
|
||||
Integer store_category_id = (Integer) category_row.get("store_category_id");
|
||||
List<Map> rs = getCategoryTree(store_category_id, category_is_enable);
|
||||
if(openFindStore){
|
||||
if (openFindStore) {
|
||||
category_row.put("storeList", storeLis.get(String.valueOf(store_category_id)));
|
||||
}
|
||||
category_row.put("id", category_row.get("store_category_id"));
|
||||
@ -122,7 +122,7 @@ public class ShopBaseStoreCategoryServiceImpl extends BaseServiceImpl<ShopBaseSt
|
||||
|
||||
}
|
||||
if (CollUtil.isNotEmpty(category_rows)) {
|
||||
// redisService.set(cache_key, category_rows);
|
||||
// redisService.set(cache_key, category_rows);
|
||||
}
|
||||
}
|
||||
|
||||
@ -167,7 +167,7 @@ public class ShopBaseStoreCategoryServiceImpl extends BaseServiceImpl<ShopBaseSt
|
||||
@Override
|
||||
public BigDecimal getStoreCategoryRatio(Integer storeCategoryId) {
|
||||
// 默认分账比例为100%
|
||||
BigDecimal defaultRatio = new BigDecimal("100");
|
||||
BigDecimal defaultRatio = new BigDecimal(100);
|
||||
|
||||
try {
|
||||
// 检查参数是否为空
|
||||
|
||||
@ -182,4 +182,24 @@ public class LakalaController extends BaseControllerImpl {
|
||||
|
||||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(resp);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 分账结果通知
|
||||
* 参考:https://o.lakala.com/#/home/document/detail?id=393
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
@ApiOperation(value = "分账关系绑定申请异步回调通知", notes = "分账关系绑定申请异步回调通知")
|
||||
@RequestMapping(value = "/sacs/separateNotify", method = RequestMethod.POST)
|
||||
public ResponseEntity<JSONObject> separateNotify(HttpServletRequest request) {
|
||||
JSONObject resp = lakalaPayService.sacsSeparateNotify(request);
|
||||
if (resp != null && "SUCCESS".equals(resp.get("code"))) {
|
||||
return ResponseEntity.ok(resp);
|
||||
}
|
||||
|
||||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(resp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -47,4 +47,15 @@ public interface LklOrderSeparateService extends IBaseService<LklOrderSeparate>
|
||||
* @return
|
||||
*/
|
||||
Boolean updateRemark(Long id, String remark);
|
||||
|
||||
|
||||
/**
|
||||
* 根据唯一组合键 logNo和 separateNo 修改备注
|
||||
*
|
||||
* @param logNo
|
||||
* @param separateNo
|
||||
* @param remark
|
||||
* @return
|
||||
*/
|
||||
Boolean updateRemark(String logNo, String separateNo, String remark);
|
||||
}
|
||||
|
||||
@ -1582,26 +1582,37 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
|
||||
|
||||
/**
|
||||
* 拉卡拉订单分账,用户确认收货成功之后(大约15秒后),进行分账
|
||||
* 说明:分账指令是异步处理模式,响应报文成功时,指令状态是”status”: “PROCESSING”,需要等待分账结果通知,或者主动发起查询,建议主动发起查询与分账指令动作之间间隔15秒以上。
|
||||
* 参考:https://o.lakala.com/#/home/document/detail?id=389
|
||||
* 执行拉卡拉订单分账操作
|
||||
* <p>
|
||||
* 用户确认收货成功之后(大约15秒后),进行分账操作。
|
||||
* 分账指令是异步处理模式,响应报文成功时,指令状态是"status": "PROCESSING",
|
||||
* 需要等待分账结果通知,或者主动发起查询。
|
||||
* 建议主动发起查询与分账指令动作之间间隔15秒以上。
|
||||
* </p>
|
||||
* <p>
|
||||
* 参考文档:https://o.lakala.com/#/home/document/detail?id=389
|
||||
* </p>
|
||||
*
|
||||
* @param orderId 平台订单Id
|
||||
* @return
|
||||
* @param storeId 店铺Id,可为空
|
||||
* @return Pair<Boolean, String> 处理结果对,first为是否成功,second为结果描述信息
|
||||
*/
|
||||
@Override
|
||||
public Pair<Boolean, String> innerDoOrderSeparate(String orderId, String storeId) {
|
||||
// 输入参数校验
|
||||
// 1. 输入参数校验
|
||||
if (StrUtil.isBlank(orderId)) {
|
||||
log.warn("分账操作参数校验失败:订单号为空");
|
||||
return Pair.of(false, "订单号不能为空");
|
||||
}
|
||||
|
||||
try {
|
||||
// TODO 检查可分账余额是否足够?
|
||||
|
||||
// 查询订单信息
|
||||
// 2. 查询订单信息
|
||||
log.info("开始执行订单[{}]分账操作", orderId);
|
||||
List<ShopOrderLkl> shopOrderLklList = shopOrderLklService.selectByOrderId(orderId, "", storeId);
|
||||
if (CollectionUtil.isEmpty(shopOrderLklList)) {
|
||||
log.warn("分账操作失败:订单[{}]不存在", orderId);
|
||||
return Pair.of(false, "订单不存在");
|
||||
}
|
||||
|
||||
@ -1609,57 +1620,53 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
int successCount = 0;
|
||||
StringBuilder errorMessages = new StringBuilder();
|
||||
|
||||
// 初始化拉卡拉SDK
|
||||
// 3. 初始化拉卡拉SDK
|
||||
initLKLSDK();
|
||||
|
||||
// 遍历处理每个店铺订单的分账
|
||||
// 4. 遍历处理每个店铺订单的分账
|
||||
log.info("订单[{}]包含{}个子订单,开始逐一处理", orderId, totalCount);
|
||||
for (ShopOrderLkl shopOrderLkl : shopOrderLklList) {
|
||||
log.debug("处理子订单:storeId={}, splitLogNo={}", shopOrderLkl.getStore_id(), shopOrderLkl.getLkl_split_log_no());
|
||||
|
||||
// TODO 检查已经分账的,不再去分账了
|
||||
LklOrderSeparate lklOrderSeparateExist = lklOrderSeparateService.getByOutTradeNo(shopOrderLkl.getLkl_log_no(), orderId);
|
||||
// 5. 检查分账状态,避免重复处理
|
||||
LklOrderSeparate lklOrderSeparateExist = lklOrderSeparateService.getByOutTradeNo(shopOrderLkl.getLkl_split_log_no(), orderId);
|
||||
if (lklOrderSeparateExist != null) {
|
||||
String status = lklOrderSeparateExist.getStatus();
|
||||
if ("SUCCESS".equals(status)) {
|
||||
log.warn("订单 [{}] 已完成分账,跳过处理。", orderId);
|
||||
log.info("订单[{}]子订单[{}]已完成分账,跳过处理", orderId, shopOrderLkl.getLkl_log_no());
|
||||
successCount++;
|
||||
continue;
|
||||
}
|
||||
if ("PROCESSING".equals(status) || "ACCEPTED".equals(status)) {
|
||||
log.warn("订单 [{}] 分账处理中或已受理,跳过处理。", orderId);
|
||||
log.info("订单[{}]子订单[{}]分账处理中或已受理,跳过处理", orderId, shopOrderLkl.getLkl_log_no());
|
||||
successCount++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// 6. 获取订单分账相关参数
|
||||
String merchantNo = shopOrderLkl.getLkl_merchant_no();
|
||||
// 分账金额 = 应付总金额-运费
|
||||
Integer totalAmt = shopOrderLkl.getTotal_amt();
|
||||
totalAmt = CheckUtil.isEmpty(totalAmt) ? 0 : totalAmt;
|
||||
// 分账金额 = 应付总金额-运费(支付时已计算好)
|
||||
Integer splitAmount = shopOrderLkl.getSplit_amt();
|
||||
splitAmount = CheckUtil.isEmpty(splitAmount) ? 0 : splitAmount;
|
||||
Integer shoppingFee = shopOrderLkl.getShopping_fee();
|
||||
shoppingFee = CheckUtil.isEmpty(shoppingFee) ? 0 : shoppingFee;
|
||||
// 商家分账比例
|
||||
BigDecimal splitRatioMch = shopOrderLkl.getSplit_ratio();
|
||||
|
||||
// 金额合法性校验
|
||||
// if (paymentAmount <= 0 || (shoppingFee != null && paymentAmount <= shoppingFee)) {
|
||||
// String errorMsg = String.format("店铺[%s]订单金额异常或运费过高,跳过分账", shopOrderLkl.getStore_id());
|
||||
// log.error(errorMsg);
|
||||
// errorMessages.append(errorMsg).append("; ");
|
||||
// lklOrderSeparateService.updateRemark(lklOrderSeparateExist.getId(), errorMsg);
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// 分账总金额(支付金额-运费)运费不参与分账,单位(分)
|
||||
Integer splitAmount = totalAmt - shoppingFee;
|
||||
// 7. 分账金额校验
|
||||
if (splitAmount <= 0) {
|
||||
String errorMsg = String.format("店铺[%s]订单%s分账金额异常,跳过分账", shopOrderLkl.getStore_id(), orderId);
|
||||
String errorMsg = String.format("店铺[%s]订单[%s]分账金额[%d]异常,跳过分账",
|
||||
shopOrderLkl.getStore_id(), orderId, splitAmount);
|
||||
log.error(errorMsg);
|
||||
errorMessages.append(errorMsg).append("; ");
|
||||
lklOrderSeparateService.updateRemark(lklOrderSeparateExist.getId(), errorMsg);
|
||||
if (lklOrderSeparateExist != null) {
|
||||
lklOrderSeparateService.updateRemark(lklOrderSeparateExist.getId(), errorMsg);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// 获取分账接收方信息
|
||||
// 8. 获取分账接收方信息
|
||||
LklLedgerMerReceiverBind platform = lklLedgerMerReceiverBindService.getPlatformByMerCupNo(merchantNo);
|
||||
List<LklLedgerMerReceiverBind> distributors = lklLedgerMerReceiverBindService.selectDistributorByMerCupNo(merchantNo);
|
||||
|
||||
@ -1670,48 +1677,44 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 判断是否可以分账(商家比例不超过100%)
|
||||
boolean canSplit = splitRatioMch != null && splitRatioMch.compareTo(new BigDecimal("100")) <= 0;
|
||||
// 9. 判断是否可以分账(商家比例不超过100%)
|
||||
boolean canSplit = splitRatioMch != null && splitRatioMch.compareTo(new BigDecimal(100)) <= 0;
|
||||
if (!canSplit) {
|
||||
String errorMsg = String.format("店铺[%s]分账比例异常,无法分账", shopOrderLkl.getStore_id());
|
||||
String errorMsg = String.format("店铺[%s]分账比例[%s]异常,无法分账",
|
||||
shopOrderLkl.getStore_id(), splitRatioMch);
|
||||
log.error(errorMsg);
|
||||
errorMessages.append(errorMsg).append("; ");
|
||||
continue;
|
||||
}
|
||||
|
||||
// 构建分账请求对象
|
||||
// 10. 构建分账请求对象
|
||||
V3SacsSeparateRequest request = new V3SacsSeparateRequest();
|
||||
request.setMerchantNo(merchantNo);
|
||||
request.setLogNo(shopOrderLkl.getLkl_log_no());
|
||||
request.setLogNo(shopOrderLkl.getLkl_split_log_no()); // 合单和非合单的流水号保存在此字段
|
||||
request.setLogDate(shopOrderLkl.getLkl_log_date());
|
||||
request.setOutSeparateNo(orderId);
|
||||
request.setOutSeparateNo(shopOrderLkl.getOut_separate_no());
|
||||
request.setTotalAmt(splitAmount.toString());
|
||||
request.setLklOrgNo(orgCode);
|
||||
request.setCalType("0");
|
||||
request.setNotifyUrl(projectDomain + "/api/mobile/shop/lakala/sacs/separateNotify");
|
||||
|
||||
// 构建分账接收方列表
|
||||
// 11. 构建分账接收方列表
|
||||
List<V3SacsSeparateRecvDatas> recvDatas = new ArrayList<>();
|
||||
|
||||
// 1. 先处理运费分账(如果有运费) == update 2025-08-22 运费不分账了,走合单拆分,直接打给商家
|
||||
// if (shoppingFee != null && shoppingFee > 0) {
|
||||
// V3SacsSeparateRecvDatas receiver = new V3SacsSeparateRecvDatas();
|
||||
// receiver.setRecvNo(platform.getReceiver_no());
|
||||
// receiver.setSeparateValue(shoppingFee.toString());
|
||||
// recvDatas.add(receiver);
|
||||
// }
|
||||
|
||||
Integer totalSeparateValue = 0;// 平台方和代理商总计分账金额
|
||||
// 2. 再处理剩余金额的分账(如果可以分账)
|
||||
// 12. 处理分账逻辑(如果可以分账)
|
||||
if (canSplit) {
|
||||
|
||||
// 计算实际可分账金额(扣除运费后)
|
||||
// Integer splitAmount = totalAmt - shoppingFee;
|
||||
// 计算平台+代理商的总比例
|
||||
BigDecimal splitRatioNoMch = new BigDecimal("100").subtract(splitRatioMch);
|
||||
BigDecimal splitRatioNoMch = new BigDecimal(100).subtract(splitRatioMch);
|
||||
|
||||
// 13. 根据是否有代理商决定分账模式
|
||||
if (!CollectionUtils.isEmpty(distributors) && splitRatioNoMch.compareTo(BigDecimal.ONE) > 0) {
|
||||
// 平台+代理商分账模式
|
||||
log.debug("订单[{}]采用平台+代理商分账模式", orderId);
|
||||
|
||||
if (!CollectionUtils.isEmpty(distributors) && splitRatioNoMch.compareTo(BigDecimal.ONE) > 0) { // 平台+代理商分账模式
|
||||
// 平台收取1%手续费
|
||||
BigDecimal platformValue = CommonUtil.DecimalRoundHalfDown(new BigDecimal(splitAmount).multiply(new BigDecimal("0.01")));
|
||||
BigDecimal platformValue = CommonUtil.DecimalRoundHalfDown(
|
||||
new BigDecimal(splitAmount).multiply(new BigDecimal("0.01")));
|
||||
if (platformValue.compareTo(BigDecimal.ZERO) > 0) {
|
||||
V3SacsSeparateRecvDatas receiver = new V3SacsSeparateRecvDatas();
|
||||
receiver.setRecvNo(platform.getReceiver_no());
|
||||
@ -1719,11 +1722,13 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
recvDatas.add(receiver);
|
||||
|
||||
totalSeparateValue += platformValue.intValue();
|
||||
log.debug("平台分账:金额={}分,接收方={}", platformValue, platform.getReceiver_no());
|
||||
}
|
||||
|
||||
// 代理商分账(扣除平台1%后的剩余比例)
|
||||
BigDecimal distributorRatio = splitRatioNoMch.subtract(new BigDecimal("1")).divide(new BigDecimal(100));
|
||||
BigDecimal distributorValue = CommonUtil.DecimalRoundHalfDown(new BigDecimal(splitAmount).multiply(distributorRatio));
|
||||
BigDecimal distributorValue = CommonUtil.DecimalRoundHalfDown(
|
||||
new BigDecimal(splitAmount).multiply(distributorRatio));
|
||||
if (distributorValue.compareTo(BigDecimal.ZERO) > 0 && !distributors.isEmpty()) {
|
||||
V3SacsSeparateRecvDatas receiver = new V3SacsSeparateRecvDatas();
|
||||
receiver.setRecvNo(distributors.get(0).getReceiver_no());
|
||||
@ -1731,9 +1736,12 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
recvDatas.add(receiver);
|
||||
|
||||
totalSeparateValue += distributorValue.intValue();
|
||||
log.debug("代理商分账:金额={}分,接收方={}", distributorValue, distributors.get(0).getReceiver_no());
|
||||
}
|
||||
} else {
|
||||
// 仅平台分账模式
|
||||
log.debug("订单[{}]采用仅平台分账模式", orderId);
|
||||
|
||||
BigDecimal platformRatio = splitRatioNoMch.divide(new BigDecimal(100));
|
||||
BigDecimal platformValue = new BigDecimal(splitAmount).multiply(platformRatio);
|
||||
if (platformValue.compareTo(BigDecimal.ZERO) > 0) {
|
||||
@ -1743,32 +1751,69 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
recvDatas.add(receiver);
|
||||
|
||||
totalSeparateValue += platformValue.intValue();
|
||||
log.debug("平台分账:金额={}分,接收方={}", platformValue, platform.getReceiver_no());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 设置分账接收方列表
|
||||
// 14. 设置分账接收方列表
|
||||
request.setRecvDatas(recvDatas);
|
||||
log.debug("分账请求参数: {}", JSONUtil.toJsonStr(request));
|
||||
log.info("分账请求参数: 订单={}, 商户={}, 金额={}分, 分账接收方数量={}",
|
||||
orderId, merchantNo, splitAmount, recvDatas.size());
|
||||
|
||||
// 发送分账请求
|
||||
// 记录详细的分账信息,便于部署后排查问题
|
||||
if (log.isDebugEnabled()) {
|
||||
StringBuilder detailLog = new StringBuilder();
|
||||
detailLog.append("详细分账信息:");
|
||||
detailLog.append("订单ID=").append(shopOrderLkl.getOrder_id()).append(", ");
|
||||
detailLog.append("商户号=").append(merchantNo).append(", ");
|
||||
detailLog.append("分账流水号=").append(shopOrderLkl.getLkl_split_log_no()).append(", ");
|
||||
detailLog.append("外部分账单号=").append(shopOrderLkl.getOut_separate_no()).append(", ");
|
||||
detailLog.append("分账总金额=").append(splitAmount).append("分, ");
|
||||
detailLog.append("运费=").append(shoppingFee).append("分, ");
|
||||
detailLog.append("商家分账比例=").append(splitRatioMch).append("%, ");
|
||||
detailLog.append("平台接收方=").append(platform.getReceiver_no()).append(", ");
|
||||
|
||||
if (!CollectionUtils.isEmpty(distributors)) {
|
||||
detailLog.append("代理商接收方=[");
|
||||
for (int i = 0; i < distributors.size(); i++) {
|
||||
if (i > 0) detailLog.append(",");
|
||||
detailLog.append(distributors.get(i).getReceiver_no());
|
||||
}
|
||||
detailLog.append("], ");
|
||||
}
|
||||
|
||||
detailLog.append("分账接收方数量=").append(recvDatas.size());
|
||||
log.debug(detailLog.toString());
|
||||
}
|
||||
|
||||
log.debug("分账请求详细参数: {}", JSONUtil.toJsonStr(request));
|
||||
|
||||
// 15. 发送分账请求
|
||||
log.info("向拉卡拉发送分账请求:订单={}, 商户={}, 分账流水号={}",
|
||||
orderId, merchantNo, shopOrderLkl.getLkl_split_log_no());
|
||||
String response = LKLSDK.httpPost(request);
|
||||
if (StrUtil.isBlank(response)) {
|
||||
errorMessages.append("拉卡拉无响应; ");
|
||||
String errorMsg = String.format("拉卡拉无响应,订单=%s,商户=%s,分账流水号=%s",
|
||||
orderId, merchantNo, shopOrderLkl.getLkl_split_log_no());
|
||||
log.error(errorMsg);
|
||||
errorMessages.append(errorMsg).append("; ");
|
||||
continue;
|
||||
}
|
||||
|
||||
log.debug("分账响应结果: {}", response);
|
||||
|
||||
// 解析响应结果
|
||||
// 16. 解析响应结果
|
||||
JSONObject respJson = JSONUtil.parseObj(response);
|
||||
if (respJson == null || !lklSacsSuccessCode.equals(respJson.getStr("code")) || respJson.getJSONObject("resp_data") == null) {
|
||||
errorMessages.append("拉卡拉返回格式异常; ");
|
||||
log.error("拉卡拉分账失败:{}", response);
|
||||
String errorMsg = String.format("拉卡拉返回格式异常,订单=%s,商户=%s,分账流水号=%s,响应=%s,respJson=%s",
|
||||
orderId, merchantNo, shopOrderLkl.getLkl_split_log_no(), response, respJson);
|
||||
log.error(errorMsg);
|
||||
errorMessages.append(errorMsg).append("; ");
|
||||
continue;
|
||||
}
|
||||
|
||||
// 保存分账记录
|
||||
// 17. 保存分账记录
|
||||
JSONObject respData = respJson.getJSONObject("resp_data");
|
||||
LklOrderSeparate lklOrderSeparate = new LklOrderSeparate();
|
||||
lklOrderSeparate.setSeparate_no(respData.getStr("separate_no"));
|
||||
@ -1786,67 +1831,101 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
|
||||
try {
|
||||
if (lklOrderSeparateService.addOrUpdateByReceiverNo(lklOrderSeparate)) {
|
||||
log.info("分账记录保存成功:订单={}, 分账单号={}, 状态={}, 分账流水号={}",
|
||||
orderId, lklOrderSeparate.getSeparate_no(), lklOrderSeparate.getStatus(), lklOrderSeparate.getLog_no());
|
||||
successCount++;
|
||||
} else {
|
||||
lklOrderSeparateService.updateRemark(lklOrderSeparate.getId(), errorMessages.toString());
|
||||
String errorMsg = String.format("保存分账记录失败,订单=%s,分账单号=%s,分账流水号=%s",
|
||||
orderId, lklOrderSeparate.getSeparate_no(), lklOrderSeparate.getLog_no());
|
||||
log.error(errorMsg);
|
||||
lklOrderSeparateService.updateRemark(lklOrderSeparate.getLog_no(), lklOrderSeparate.getSeparate_no(), errorMsg);
|
||||
errorMessages.append(errorMsg).append("; ");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("保存分账记录失败: {}", e.getMessage(), e);
|
||||
errorMessages.append("保存分账记录失败; ");
|
||||
String errorMsg = String.format("保存分账记录异常,订单=%s,分账单号=%s,流水号=%s,错误=%s",
|
||||
orderId,
|
||||
lklOrderSeparate.getSeparate_no(),
|
||||
lklOrderSeparate.getLog_no(),
|
||||
e.getMessage());
|
||||
log.error(errorMsg, e);
|
||||
errorMessages.append(errorMsg).append("; ");
|
||||
}
|
||||
}
|
||||
|
||||
// 返回最终处理结果
|
||||
// 18. 返回最终处理结果
|
||||
log.info("订单[{}]分账处理完成:总订单数={},成功处理数={}", orderId, totalCount, successCount);
|
||||
if (successCount == 0) {
|
||||
return Pair.of(false, "分账全部失败: " + errorMessages);
|
||||
|
||||
String result = "分账全部失败: " + errorMessages;
|
||||
log.warn("订单[{}]分账结果:{}", orderId, result);
|
||||
return Pair.of(false, result);
|
||||
} else if (successCount < totalCount) {
|
||||
return Pair.of(true, "部分分账成功,处理中: " + errorMessages);
|
||||
String result = "部分分账成功,处理中: " + errorMessages;
|
||||
log.info("订单[{}]分账结果:{}", orderId, result);
|
||||
return Pair.of(true, result);
|
||||
} else {
|
||||
return Pair.of(true, "全部订单分账已提交处理");
|
||||
String result = "全部订单分账已提交处理";
|
||||
log.info("订单[{}]分账结果:{}", orderId, result);
|
||||
return Pair.of(true, result);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("分账系统异常: {}", e.getMessage(), e);
|
||||
String errorMsg = String.format("分账系统异常,订单=%s,错误=%s", orderId, e.getMessage());
|
||||
log.error(errorMsg, e);
|
||||
return Pair.of(false, "系统异常,请稍后重试");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 分账结果通知
|
||||
* 参考:https://o.lakala.com/#/home/document/detail?id=393
|
||||
* 拉卡拉分账结果通知处理
|
||||
* <p>
|
||||
* 用于接收拉卡拉分账系统的异步通知,处理分账结果状态更新。
|
||||
* 当分账状态发生变化时,拉卡拉会主动调用此接口通知分账结果。
|
||||
* </p>
|
||||
* <p>
|
||||
* 参考文档:https://o.lakala.com/#/home/document/detail?id=393
|
||||
* </p>
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
* @param request HTTP请求对象,包含拉卡拉分账结果通知的参数
|
||||
* @return JSONObject 响应结果对象,包含处理结果状态
|
||||
* <ul>
|
||||
* <li>成功: {"code": "SUCCESS", "message": "操作成功"}</li>
|
||||
* <li>失败: {"code": "FAIL", "message": "错误信息"}</li>
|
||||
* </ul>
|
||||
*/
|
||||
@Override
|
||||
public JSONObject sacsSeparateNotify(HttpServletRequest request) {
|
||||
log.debug("分账结果通知异步回调开始");
|
||||
log.info("开始处理拉卡拉分账结果通知异步回调");
|
||||
|
||||
// 1. 验签处理
|
||||
// 1. 验签处理 - 验证通知来源的合法性
|
||||
log.debug("开始进行通知签名验证");
|
||||
Pair<Boolean, String> signCheckResult = LakalaUtil.chkLklApiNotifySign(request, lklNotifyCerPath, false);
|
||||
if (!signCheckResult.getFirst()) {
|
||||
log.warn("分账通知验签失败: {}", signCheckResult.getSecond());
|
||||
String errorMsg = "分账通知验签失败: " + signCheckResult.getSecond();
|
||||
log.warn(errorMsg);
|
||||
return JSONUtil.createObj()
|
||||
.set("code", "FAIL")
|
||||
.set("retMsg", signCheckResult.getSecond());
|
||||
}
|
||||
|
||||
// 2. 解析请求参数
|
||||
// 2. 解析请求参数 - 将验签后的参数转换为JSON对象
|
||||
log.debug("解析通知参数");
|
||||
JSONObject paramsJson = JSONUtil.parseObj(signCheckResult.getSecond());
|
||||
if (paramsJson == null) {
|
||||
log.error("分账通知参数解析失败: 请求参数为空");
|
||||
String errorMsg = "分账通知参数解析失败: 请求参数为空";
|
||||
log.error(errorMsg);
|
||||
return JSONUtil.createObj()
|
||||
.put("code", "FAIL")
|
||||
.put("message", "请求参数为空");
|
||||
}
|
||||
|
||||
// 3. 提取关键参数并校验
|
||||
String logNo = paramsJson.getStr("log_no");
|
||||
// 3. 提取关键参数并校验 - 确保必要参数完整
|
||||
log.debug("校验必要参数完整性");
|
||||
String logNo = paramsJson.getStr("log_no"); // 合单订单是子单流水号,非合单时是主单流水号
|
||||
String separateNo = paramsJson.getStr("separate_no");
|
||||
String outSeparateNo = paramsJson.getStr("out_separate_no");
|
||||
String status = paramsJson.getStr("status");
|
||||
String finalStatus = paramsJson.getStr("final_status");
|
||||
|
||||
|
||||
List<String> missingParams = new ArrayList<>();
|
||||
if (StrUtil.isBlank(outSeparateNo)) missingParams.add("outSeparateNo");
|
||||
if (StrUtil.isBlank(separateNo)) missingParams.add("separateNo");
|
||||
@ -1860,7 +1939,28 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
.put("message", errorMsg);
|
||||
}
|
||||
|
||||
// 4. 构建分账记录对象
|
||||
LklOrderSeparate lklOrderSeparateExist = lklOrderSeparateService.getByOutTradeNo(logNo, outSeparateNo);
|
||||
if (lklOrderSeparateExist == null) {
|
||||
String errorMsg = "未找到对应的分账记录";
|
||||
log.error(errorMsg + ", 外部分账单号={}, 分账单号={}, 参数详情: {}", outSeparateNo, separateNo, paramsJson);
|
||||
return JSONUtil.createObj()
|
||||
.put("code", "FAIL")
|
||||
.put("message", errorMsg);
|
||||
}
|
||||
|
||||
if ("SUCCESS".equals(lklOrderSeparateExist.getFinal_status())) {
|
||||
String errorMsg = "分账已处理成功,请不要重复通知";
|
||||
log.warn(errorMsg + ", 订单号={}, 外部分账单号={}, 参数详情: {}", logNo, outSeparateNo, paramsJson);
|
||||
return JSONUtil.createObj()
|
||||
.put("code", "SUCCESS")
|
||||
.put("message", "分账已处理成功,请不要重复通知");
|
||||
}
|
||||
|
||||
// 4. 记录关键参数信息,便于问题排查
|
||||
log.info("接收到分账通知,分账单号={}, 外部分账单号={}, 状态={}, 最终状态={}",
|
||||
separateNo, outSeparateNo, status, finalStatus);
|
||||
|
||||
// 5. 构建分账记录对象 - 准备更新数据库的分账记录
|
||||
LklOrderSeparate lklOrderSeparate = new LklOrderSeparate();
|
||||
lklOrderSeparate.setLog_no(logNo);
|
||||
lklOrderSeparate.setSeparate_no(separateNo);
|
||||
@ -1875,22 +1975,27 @@ public class LakalaApiServiceImpl implements LakalaApiService {
|
||||
JSONArray detailDatas = paramsJson.getJSONArray("detail_datas");
|
||||
lklOrderSeparate.setDetail_datas(detailDatas != null ? detailDatas.toString() : "[]");
|
||||
|
||||
// 5. 持久化处理
|
||||
// 6. 持久化处理 - 更新分账记录到数据库
|
||||
log.debug("开始更新分账记录到数据库");
|
||||
try {
|
||||
boolean updateSuccess = lklOrderSeparateService.addOrUpdateByReceiverNo(lklOrderSeparate);
|
||||
if (!updateSuccess) {
|
||||
log.error("分账记录更新失败, separateNo={}", separateNo);
|
||||
String errorMsg = String.format("分账记录更新失败, separateNo=%s", separateNo);
|
||||
log.error(errorMsg);
|
||||
return JSONUtil.createObj()
|
||||
.put("code", "FAIL")
|
||||
.put("message", "数据更新失败");
|
||||
}
|
||||
|
||||
log.debug("分账通知处理成功, separateNo={}, status={}", separateNo, status);
|
||||
// 7. 记录处理成功日志
|
||||
log.info("分账通知处理成功, separateNo={}, status={}", separateNo, status);
|
||||
return JSONUtil.createObj()
|
||||
.put("code", "SUCCESS")
|
||||
.put("message", "操作成功");
|
||||
} catch (Exception e) {
|
||||
log.error("分账通知数据处理异常, separateNo={}: {}", separateNo, e.getMessage(), e);
|
||||
// 8. 异常处理
|
||||
String errorMsg = String.format("分账通知数据处理异常, separateNo=%s: %s", separateNo, e.getMessage());
|
||||
log.error(errorMsg, e);
|
||||
return JSONUtil.createObj()
|
||||
.put("code", "FAIL")
|
||||
.put("message", "系统处理异常");
|
||||
|
||||
@ -54,30 +54,30 @@ public class LklOrderSeparateServiceImpl extends BaseServiceImpl<LklOrderSeparat
|
||||
/**
|
||||
* 根据拉卡拉对账单流水号和平台订单号查询记录
|
||||
*
|
||||
* @param logNo
|
||||
* @param splitLogNo
|
||||
* @param outSeparateNo
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public LklOrderSeparate getByOutTradeNo(String logNo, String outSeparateNo) {
|
||||
public LklOrderSeparate getByOutTradeNo(String splitLogNo, String outSeparateNo) {
|
||||
try {
|
||||
if (StrUtil.isBlank(logNo) || StrUtil.isBlank(outSeparateNo)) {
|
||||
log.warn("查询参数为空:logNo={}, outSeparateNo={}", logNo, outSeparateNo);
|
||||
if (StrUtil.isBlank(splitLogNo) || StrUtil.isBlank(outSeparateNo)) {
|
||||
log.warn("查询参数为空:logNo={}, outSeparateNo={}", splitLogNo, outSeparateNo);
|
||||
return null;
|
||||
}
|
||||
|
||||
List<LklOrderSeparate> list = list(new QueryWrapper<LklOrderSeparate>()
|
||||
.eq("log_no", logNo)
|
||||
.eq("log_no", splitLogNo)
|
||||
.eq("out_separate_no", outSeparateNo));
|
||||
|
||||
if (CollUtil.isEmpty(list)) {
|
||||
log.info("未找到记录:logNo={}, outSeparateNo={}", logNo, outSeparateNo);
|
||||
log.info("未找到记录:logNo={}, outSeparateNo={}", splitLogNo, outSeparateNo);
|
||||
return null;
|
||||
}
|
||||
|
||||
return list.get(0);
|
||||
} catch (Exception e) {
|
||||
log.error("查询记录时发生异常:logNo={}, outSeparateNo={}, 异常信息={}", logNo, outSeparateNo, e.getMessage(), e);
|
||||
log.error("查询记录时发生异常:logNo={}, outSeparateNo={}, 异常信息={}", splitLogNo, outSeparateNo, e.getMessage(), e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -130,4 +130,24 @@ public class LklOrderSeparateServiceImpl extends BaseServiceImpl<LklOrderSeparat
|
||||
lklOrderSeparate.setRemark(remark);
|
||||
return updateById(lklOrderSeparate);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据唯一组合键 logNo和 separateNo 修改备注
|
||||
*
|
||||
* @param logNo
|
||||
* @param separateNo
|
||||
* @param remark
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Boolean updateRemark(String logNo, String separateNo, String remark) {
|
||||
if (StrUtil.isEmpty(logNo) || StrUtil.isEmpty(separateNo) || StrUtil.isEmpty(remark)) {
|
||||
return false;
|
||||
}
|
||||
LklOrderSeparate lklOrderSeparate = new LklOrderSeparate();
|
||||
lklOrderSeparate.setLog_no(logNo);
|
||||
lklOrderSeparate.setSeparate_no(separateNo);
|
||||
lklOrderSeparate.setRemark(remark);
|
||||
return updateById(lklOrderSeparate);
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,10 +36,20 @@ public interface ShopOrderLklService extends IBaseService<ShopOrderLkl> {
|
||||
* 根据拉卡拉的回调数据,更新拉卡拉的订单信息
|
||||
*
|
||||
* @param lklPayNotifyDataJson 异步通知返回的body json数据:
|
||||
* // {"out_trade_no":"202203151637334864280014","trade_no":"2022031566210203291925","log_no":"66210203291925",
|
||||
* // 非合单返回的数据异步通知返回的 body json数据:{"out_trade_no":"202203151637334864280014","trade_no":"2022031566210203291925","log_no":"66210203291925",
|
||||
* // "acc_trade_no":"2022031522001483661454130929 ","trade_status":"SUCCESS","trade_state":"SUCCESS","total_amount":"1",
|
||||
* // "payer_amount":"1","acc_settle_amount":"1","trade_time":"20220315163808","user_id1":"app***@163.com",
|
||||
* // "user_id2":"2088432881453660","notify_url":"https://www.baidu.com","account_type":"ALIPAY","card_type":"99"}
|
||||
* <p>
|
||||
* // 合单返回的数据异步通知返回的 body json数据:{"out_trade_no":"DD-20250830-10","trade_no":"20250830110113130266250034160499","log_no":"66250034160499",
|
||||
* // "acc_trade_no":"4200002826202508306761393882","trade_status":"SUCCESS","trade_state":"SUCCESS","total_amount":"2","payer_amount":"2","acc_settle_amount":"2",
|
||||
* // "acc_mdiscount_amount":"0","acc_discount_amount":"0","trade_time":"20250830180435","user_id1":"oDVKR7T0qxg6O8tqIL9SgY6LXqqQ",
|
||||
* // "user_id2":"oVxsc1QRAqDRv_gAmXuLZwSVSL18","notify_url":"https://mall.gpxscs.cn/mobile/pay/index/lkl_wxPay_notify_url","account_type":"WECHAT",
|
||||
* // "bank_type":"OTHERS","card_type":"02","merchant_no":"8226330541100GU","remark":"","sub_mch_id":"803819329",
|
||||
* // "out_split_rsp_infos":[{"sub_trade_no":"20250830110113130266250034112794","sub_log_no":"66250034112794","out_sub_trade_no":"ORD_DD-20250830-10",
|
||||
* // "merchant_no":"8226330541100GU","term_no":"N5817779","amount":"1","settle_type":"0"},{"sub_trade_no":"20250830110113130266250034160498","sub_log_no":"66250034160498",
|
||||
* // "out_sub_trade_no":"DF_DD-20250830-10","merchant_no":"822584059990FYP","term_no":"N5811590","amount":"1","settle_type":"0"}],"trade_req_date":"20250830","gb_amount":"",
|
||||
* // "qb_amount":""}
|
||||
* @return
|
||||
*/
|
||||
Boolean addOrUpdateByLklPayNotifyDataJson(JSONObject lklPayNotifyDataJson);
|
||||
|
||||
@ -9112,11 +9112,11 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
|
||||
}
|
||||
|
||||
// 确保比例在合理范围 [0, 100]
|
||||
storeSplitRatio = storeSplitRatio.max(BigDecimal.ZERO).min(new BigDecimal("100"));
|
||||
storeSplitRatio = storeSplitRatio.max(BigDecimal.ZERO).min(new BigDecimal(100));
|
||||
|
||||
// 分账金额 = 支付金额 × 平台和代理商分账比例 ÷ 100 (将百分比转换为小数)
|
||||
BigDecimal result = pendingAmount.multiply(new BigDecimal("100").subtract(storeSplitRatio))
|
||||
.divide(new BigDecimal("100"), 2, RoundingMode.HALF_DOWN); // 保留两位小数
|
||||
BigDecimal result = pendingAmount.multiply(new BigDecimal(100).subtract(storeSplitRatio))
|
||||
.divide(new BigDecimal(100), 2, RoundingMode.HALF_DOWN); // 保留两位小数
|
||||
|
||||
logger.debug("计算分账金额: storeId={}, pendingAmount={}, ratio={}, result={}",
|
||||
storeId, pendingAmount, storeSplitRatio, result);
|
||||
|
||||
@ -16,6 +16,7 @@ import cn.hutool.json.JSONUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.suisung.mall.common.modules.order.ShopOrderBase;
|
||||
import com.suisung.mall.common.modules.order.ShopOrderLkl;
|
||||
import com.suisung.mall.common.utils.CheckUtil;
|
||||
import com.suisung.mall.common.utils.DateTimeUtils;
|
||||
import com.suisung.mall.common.utils.JsonUtil;
|
||||
import com.suisung.mall.core.web.service.impl.BaseServiceImpl;
|
||||
@ -158,6 +159,7 @@ public class ShopOrderLklServiceImpl extends BaseServiceImpl<ShopOrderLklMapper,
|
||||
|
||||
ShopOrderLkl record = new ShopOrderLkl();
|
||||
record.setOrder_id(orderId);
|
||||
record.setOut_separate_no(JsonUtil.getJsonValueSmart(reqDataJson, "outTradeNo"));
|
||||
|
||||
// 设置请求内容
|
||||
|
||||
@ -169,6 +171,15 @@ public class ShopOrderLklServiceImpl extends BaseServiceImpl<ShopOrderLklMapper,
|
||||
}
|
||||
record.setTotal_amt(amount); // 应支付总金额
|
||||
|
||||
// 关键数据:获取店铺ID,分账比例用到
|
||||
Integer storeId = shopOrderBase.getStore_id();
|
||||
record.setStore_id(Convert.toStr(storeId));
|
||||
|
||||
// 运费和商家分账比例
|
||||
BigDecimal shipperFee = shopOrderDataService.getOrderShippingFee(orderId); // 运费获取
|
||||
record.setShopping_fee(shipperFee.multiply(BigDecimal.valueOf(100)).intValue()); // 运费,单位:分
|
||||
record.setSplit_ratio(shopStoreBaseService.getStoreSplitRatio(storeId, false)); // 商家分账比例计算
|
||||
|
||||
record.setAccount_type(JsonUtil.getJsonValueSmart(reqDataJson, "accountType"));
|
||||
record.setTrans_type(JsonUtil.getJsonValueSmart(reqDataJson, "transType"));
|
||||
record.setNotify_url(JsonUtil.getJsonValueSmart(reqDataJson, "notifyUrl"));
|
||||
@ -177,20 +188,12 @@ public class ShopOrderLklServiceImpl extends BaseServiceImpl<ShopOrderLklMapper,
|
||||
record.setLkl_req(JSONUtil.toJsonStr(reqDataJson));
|
||||
|
||||
// 设置响应内容
|
||||
record.setLkl_log_no(JsonUtil.getJsonValueSmart(respDataJson, "log_no"));
|
||||
String logNo = JsonUtil.getJsonValueSmart(respDataJson, "log_no");
|
||||
record.setLkl_log_no(logNo);
|
||||
|
||||
record.setLkl_trade_no(JsonUtil.getJsonValueSmart(respDataJson, "trade_no"));
|
||||
record.setLkl_resp(JSONUtil.toJsonStr(respDataJson));
|
||||
|
||||
// 关键数据:获取店铺ID,分账比例用到
|
||||
Integer storeId = shopOrderBase.getStore_id();
|
||||
|
||||
record.setStore_id(Convert.toStr(storeId));
|
||||
|
||||
// 运费和商家分账比例
|
||||
BigDecimal shipperFee = shopOrderDataService.getOrderShippingFee(orderId);
|
||||
record.setShopping_fee(shipperFee.multiply(BigDecimal.valueOf(100)).intValue()); // 运费,单位:分
|
||||
record.setSplit_ratio(shopStoreBaseService.getStoreSplitRatio(storeId, false)); // 商家分账比例
|
||||
|
||||
return addOrUpdateByStoreOrder(record);
|
||||
} catch (Exception e) {
|
||||
log.error("新增拉卡拉支付记录出错", e);
|
||||
@ -232,6 +235,22 @@ public class ShopOrderLklServiceImpl extends BaseServiceImpl<ShopOrderLklMapper,
|
||||
record.setLkl_trade_no(lklPayNotifyDataJson.getStr("trade_no"));
|
||||
record.setTrade_status(lklPayNotifyDataJson.getStr("trade_status"));
|
||||
|
||||
// 新增的订单字段,lkl_split_log_no,out_separate_no,split_amt 三字段无值,就给主单的值
|
||||
record.setLkl_split_log_no(JsonUtil.getJsonValueSmart(lklPayNotifyDataJson, "split_log_no"));
|
||||
if (CheckUtil.isEmpty(record.getLkl_split_log_no())) {
|
||||
record.setLkl_split_log_no(logNo);
|
||||
}
|
||||
|
||||
record.setOut_separate_no(JsonUtil.getJsonValueSmart(lklPayNotifyDataJson, "out_separate_no"));
|
||||
if (CheckUtil.isEmpty(record.getOut_separate_no())) {
|
||||
record.setOut_separate_no(orderId);
|
||||
}
|
||||
|
||||
record.setSplit_amt(JsonUtil.getJsonValueSmart(lklPayNotifyDataJson, "split_amt", Integer.class));
|
||||
if (CheckUtil.isEmpty(record.getSplit_amt())) {
|
||||
record.setSplit_amt(record.getTotal_amt());
|
||||
}
|
||||
|
||||
// 安全地设置响应内容
|
||||
record.setLkl_notify_resp(JSONUtil.toJsonStr(lklPayNotifyDataJson));
|
||||
|
||||
|
||||
@ -870,7 +870,7 @@ public class ShopMchEntryServiceImpl extends BaseServiceImpl<ShopMchEntryMapper,
|
||||
// 自动计算商家分成比例
|
||||
BigDecimal splitRatio = shopBaseStoreCategoryService.getStoreCategoryRatio(record.getBiz_category());
|
||||
if (splitRatio == null || splitRatio.compareTo(BigDecimal.ZERO) <= 0) {
|
||||
splitRatio = new BigDecimal("100");
|
||||
splitRatio = new BigDecimal(100);
|
||||
}
|
||||
|
||||
// 如果是驳回状态,直接返回成功消息
|
||||
|
||||
@ -2033,7 +2033,7 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl<ShopStoreBaseMappe
|
||||
// 添加默认客户等级
|
||||
InvoicingCustomerLevel invoicingCustomerLevel = new InvoicingCustomerLevel();
|
||||
invoicingCustomerLevel.setCustomer_level_name(I18nUtil._("普通(系统默认,不可删除)"));
|
||||
invoicingCustomerLevel.setCustomer_level_discountrate(new BigDecimal("100"));
|
||||
invoicingCustomerLevel.setCustomer_level_discountrate(new BigDecimal(100));
|
||||
invoicingCustomerLevel.setCustomer_level_is_buildin(1);
|
||||
invoicingCustomerLevel.setCustomer_level_desc("");
|
||||
|
||||
@ -3608,7 +3608,7 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl<ShopStoreBaseMappe
|
||||
// 添加默认客户等级
|
||||
InvoicingCustomerLevel invoicingCustomerLevel = new InvoicingCustomerLevel();
|
||||
invoicingCustomerLevel.setCustomer_level_name(I18nUtil._("普通(系统默认,不可删除)"));
|
||||
invoicingCustomerLevel.setCustomer_level_discountrate(new BigDecimal("100"));
|
||||
invoicingCustomerLevel.setCustomer_level_discountrate(new BigDecimal(100));
|
||||
invoicingCustomerLevel.setCustomer_level_is_buildin(1);
|
||||
invoicingCustomerLevel.setCustomer_level_desc("");
|
||||
|
||||
@ -3684,7 +3684,7 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl<ShopStoreBaseMappe
|
||||
*/
|
||||
@Override
|
||||
public BigDecimal getStoreSplitRatio(Integer storeId, boolean reCalculate) {
|
||||
BigDecimal defaultSplitRatio = new BigDecimal("100");
|
||||
BigDecimal defaultSplitRatio = new BigDecimal(100);
|
||||
if (storeId == null || storeId <= 0) {
|
||||
return defaultSplitRatio;
|
||||
}
|
||||
|
||||
@ -6,10 +6,11 @@ import java.math.RoundingMode;
|
||||
public class ProductPriceCalculator {
|
||||
/**
|
||||
* 计算切割后的商品单价和数量
|
||||
*
|
||||
* @param unitPricePerKg 千克单价(元/千克)
|
||||
* @param totalWeightKg 总重量(千克)
|
||||
* @param pieceWeight 切割单位重量(数值)
|
||||
* @param weightUnit 重量单位("g"=克,"kg"=千克)
|
||||
* @param totalWeightKg 总重量(千克)
|
||||
* @param pieceWeight 切割单位重量(数值)
|
||||
* @param weightUnit 重量单位("g"=克,"kg"=千克)
|
||||
* @return 包含两个元素的数组:[切割后单价(元/单位), 完整单位数量]
|
||||
*/
|
||||
public static BigDecimal[] calculatePriceAndQuantity(
|
||||
@ -70,7 +71,7 @@ public class ProductPriceCalculator {
|
||||
|
||||
// 千克单位示例
|
||||
BigDecimal[] result3 = calculatePriceAndQuantity(
|
||||
new BigDecimal("100"),
|
||||
new BigDecimal(100),
|
||||
new BigDecimal("2.5"),
|
||||
new BigDecimal("0.5"),
|
||||
"kg");
|
||||
|
||||
@ -57,7 +57,7 @@ public class ShopBatchSubmitListener extends AnalysisEventListener<SxGoosModelEx
|
||||
this.syncThirdDataService = syncThirdDataService;
|
||||
this.syncStoreSpecsService = syncStoreSpecsService;
|
||||
// 创建线程池(根据CPU核心数优化)
|
||||
// int corePoolSize = Runtime.getRuntime().availableProcessors();
|
||||
// int corePoolSize = Runtime.getRuntime().availableProcessors();
|
||||
// log.info("核心线程数量{}", corePoolSize);
|
||||
this.executorService = Executors.newFixedThreadPool(6);
|
||||
this.futures = new ArrayList<>();
|
||||
@ -74,7 +74,7 @@ public class ShopBatchSubmitListener extends AnalysisEventListener<SxGoosModelEx
|
||||
sxGoosModelExcel.setProduct_barcode("1");
|
||||
sxGoosModelExcel.setProduct_name("产品1");
|
||||
sxGoosModelExcel.setShop_specs("颜色");
|
||||
sxGoosModelExcel.setRetail_price(new BigDecimal("100"));
|
||||
sxGoosModelExcel.setRetail_price(new BigDecimal(100));
|
||||
sxGoosModelExcel.setStock(new BigDecimal("10"));
|
||||
sxGoosModelExcel.setJsonSpecs("[颜色:红色][尺寸:10]");
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user