Merge branch 'main' into dev

This commit is contained in:
liyj 2025-10-17 17:01:30 +08:00
commit dffed92a76
22 changed files with 472 additions and 297 deletions

View File

@ -3,7 +3,6 @@ package com.suisung.mall.common.exception;
import cn.hutool.core.util.StrUtil;
import com.suisung.mall.common.api.CommonResult;
import com.suisung.mall.common.api.ResultCode;
import io.seata.rm.datasource.exec.LockWaitTimeoutException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataAccessException;
@ -91,8 +90,9 @@ public class GlobalExceptionHandler {
/**
* 处理系统级异常(数据库异常/通用异常)
* LockWaitTimeoutException.class
*/
@ExceptionHandler({SQLException.class, DataAccessException.class, LockWaitTimeoutException.class, Exception.class})
@ExceptionHandler({SQLException.class, DataAccessException.class})
public CommonResult handleSystemException(HttpServletRequest req, Exception e) {
logError(req, e.getMessage(), e);
@ -103,6 +103,15 @@ public class GlobalExceptionHandler {
return CommonResult.failed("系统内部异常,请联系管理员!");
}
/**
* 处理通用异常
*/
@ExceptionHandler(Exception.class)
public CommonResult handleGeneralException(HttpServletRequest req, Exception e) {
logError(req, e.getMessage(), e);
return CommonResult.failed("系统内部异常,请联系管理员!");
}
/**
* 处理业务API异常
*/

View File

@ -29,7 +29,7 @@ import java.util.Date;
public class EsignPlatformInfo implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.INPUT)
@TableId(value = "id", type = IdType.AUTO)
@ApiModelProperty(value = "自增ID")
private Long id;
@ -108,7 +108,7 @@ public class EsignPlatformInfo implements Serializable {
@ApiModelProperty(value = "平台方公司维度")
private String latitude;
@ApiModelProperty(value = "代理商等级:0-平台方(只能一条记录)1-一级代理2-二级代理;3-三级代理4-四级代理;")
@ApiModelProperty(value = "代理商等级:0-平台方(只能一条记录)1-一级代理2-二级代理;")
private Integer level;
@ApiModelProperty(value = "邀请码,后期跟收益有关")

View File

@ -29,7 +29,7 @@ import java.util.Date;
public class LklLedgerMerReceiverBind implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.INPUT)
@TableId(value = "id", type = IdType.AUTO)
@ApiModelProperty(value = "自增ID")
private Long id;
private String order_no;

View File

@ -29,7 +29,7 @@ import java.util.Date;
public class LklLedgerReceiver implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.INPUT)
@TableId(value = "id", type = IdType.AUTO)
@ApiModelProperty(value = "自增ID")
private Long id;
private String order_no;
@ -41,6 +41,7 @@ public class LklLedgerReceiver implements Serializable {
private String contact_mobile;
private String license_no;
private String license_name;
private String license_district_id;
private String legal_person_name;
private String legal_person_certificate_type;
private String legal_person_certificate_no;
@ -55,6 +56,8 @@ public class LklLedgerReceiver implements Serializable {
private String attach_list;
private String settle_type;
private Long platform_id;
private Long parent_id;
private String supplier_id;
private Integer level;
private BigDecimal split_ratio;
private Integer shipping_fee;

View File

@ -98,6 +98,8 @@ public class ShopOrderLkl implements Serializable {
private String separate_remark;
private String separate_msg;
private Integer status;
private Date created_at;

View File

@ -68,6 +68,10 @@ public class MchOrderInfoDTO implements Serializable {
private Integer currency_id;
@ApiModelProperty(value = "订单状态(LIST):2011-待订单审核;2013-待财务审核;2020-待配货/待出库审核;2030-待发货;2040-已发货/待收货确认;2060-已完成/已签收;2070-已取消/已作废;")
private Integer order_state_id;
@ApiModelProperty(value = "确认收货状态")
private Integer order_is_received;
@ApiModelProperty(value = "订单种类(ENUM): 1201-实物 ; 1202-虚拟 ; 1203-电子卡券 ; 1204-外卖订单")
private Integer kind_id;
@ApiModelProperty(value = "配送方式: 1-快递配送(运费 10 元5-自提10-普通快递16-顺丰同城;")
private Integer delivery_type_id;
@ApiModelProperty(value = "订单运费")

View File

@ -62,12 +62,12 @@ public class LklSeparateWithTotalAmountDTO {
// 测试用例1: 所有参与方都参与分账符合比例要求
System.out.println("=== 测试用例1: 所有参与方都参与分账 ===");
LklSeparateWithTotalAmountDTO dto1 = new LklSeparateWithTotalAmountDTO();
dto1.setTotalSeparateAmount(1500); // 总金额100元(10000分)
dto1.setShippingFee(600);
dto1.setTotalSeparateAmount(5500); // 总金额100元(10000分)
dto1.setShippingFee(500);
// dto1.setRefCanSeparateAmount(1496);
dto1.setLklRatio(new BigDecimal("0.0025")); // 拉卡拉分账比例0.25%
dto1.setMchRatio(new BigDecimal("0.95")); // 商家分账比例94.75%
dto1.setPlatRatio(new BigDecimal("0.01")); // 平台分账比例1%
dto1.setMchRatio(new BigDecimal("0.96")); // 商家分账比例94.75%
dto1.setPlatRatio(new BigDecimal("0.04")); // 平台分账比例1%
// dto1.setAgent2ndRatio(new BigDecimal("0.04")); // 二级代理商分账比例4%
// dto1.setAgent1stRatio(new BigDecimal("0.01")); // 一级代理商分账比例1%

View File

@ -146,10 +146,10 @@ public class UniCloudPushServiceImpl implements UniCloudPushService {
request.put("push_clientid", distinctClientIds)
.put("title", title)
.put("content", content)
.put("message_id", messageId); // 添加唯一消息ID
.put("content", content); // 添加唯一消息ID
if (payload != null) {
payload.set("message_id", messageId);
request.put("payload", payload);
}
@ -157,7 +157,7 @@ public class UniCloudPushServiceImpl implements UniCloudPushService {
log.debug("[推送服务] 请求参数: {}", request);
return request;
}
/**
* 处理推送响应
*/

File diff suppressed because one or more lines are too long

View File

@ -44,7 +44,7 @@ public class EsignController extends BaseControllerImpl {
@RequestMapping(value = "/testcase", method = RequestMethod.POST)
public Object testCase() {
//return esignContractFillingFileService.fillDocTemplate("13128997057", "91450881MADEQ92533");
return esignPlatformInfoService.getDistributorAndPlatformByIds(1L);
return esignPlatformInfoService.selectAgentAndPlatformByMchId(1L);
}
@ApiOperation(value = "管理员发起签署电子合同流程", notes = "基于文件发起签署电子合同")

View File

@ -32,7 +32,7 @@ public interface EsignPlatformInfoService {
* @param mchId
* @return
*/
List<EsignPlatformInfo> getDistributorAndPlatformByIds(Long mchId);
List<EsignPlatformInfo> selectAgentAndPlatformByMchId(Long mchId);
/**
* 根据分类和营业执照号获取平台方信息

View File

@ -27,6 +27,8 @@ import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@Slf4j
@ -70,41 +72,58 @@ public class EsignPlatformInfoServiceImpl extends BaseServiceImpl<EsignPlatformI
* @return List<EsignPlatformInfo> 平台方和代理商信息列表
*/
@Override
public List<EsignPlatformInfo> getDistributorAndPlatformByIds(Long mchId) {
public List<EsignPlatformInfo> selectAgentAndPlatformByMchId(Long mchId) {
List<EsignPlatformInfo> esignPlatformInfos = new ArrayList<>();
log.debug("[获取平台和代理商信息] 开始查询平台方和代理商信息商户ID: {}", mchId);
// 获取平台方记录
QueryWrapper<EsignPlatformInfo> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("level", 0)
.eq("status", CommonConstant.Enable)
.orderByAsc("level");
.orderByAsc("id");
List<EsignPlatformInfo> esignPlatformInfos = list(queryWrapper);
if (CollectionUtil.isEmpty(esignPlatformInfos)) {
log.error("[获取平台和代理商信息] 未找到平台方记录");
return null;
EsignPlatformInfo esignPlatformInfo = findOne(queryWrapper);
if (esignPlatformInfo == null || esignPlatformInfo.getId() == null || esignPlatformInfo.getId() <= 0) {
log.error("[获取平台和代理商信息] 未找到有效的平台方记录");
return Collections.emptyList();
}
esignPlatformInfos.add(esignPlatformInfo);
log.debug("[获取平台和代理商信息] 成功获取平台方信息ID: {}", esignPlatformInfo.getId());
// 获取商户的二级代理
EsignPlatformInfo agent2nd = getMch2ndAgent(mchId);
if (agent2nd == null) {
log.debug("[获取平台和代理商信息] 未找到二级代理,仅返回平台方信息");
return esignPlatformInfos;
}
esignPlatformInfos.add(agent2nd);
log.debug("[获取平台和代理商信息] 成功获取二级代理信息ID: {}", agent2nd.getId());
// 获取一级代理如果存在
if (CheckUtil.isEmpty(agent2nd.getParent_id())) {
if (agent2nd.getParent_id() == null || agent2nd.getParent_id() <= 0) {
log.debug("[获取平台和代理商信息] 二级代理无有效父级ID返回平台方和二级代理信息");
return esignPlatformInfos;
}
try {
EsignPlatformInfo agent1st = get(agent2nd.getParent_id());
if (agent1st != null) {
esignPlatformInfos.add(agent1st);
}
} catch (Exception e) {
log.error("[获取平台和代理商信息] 获取一级代理商时发生异常parent_id: {}", agent2nd.getParent_id(), e);
}
// 获取县级代理商的省级代理商
queryWrapper.clear();
queryWrapper.eq("id", agent2nd.getParent_id())
.eq("level", CommonConstant.Agent_Level_1st)
.gt("split_ratio", 0)
.eq("status", CommonConstant.Enable);
EsignPlatformInfo agent1st = findOne(queryWrapper);
if (agent1st != null) {
esignPlatformInfos.add(agent1st);
log.debug("[获取平台和代理商信息] 成功获取一级代理信息ID: {}", agent1st.getId());
} else {
log.debug("[获取平台和代理商信息] 未找到一级代理parent_id: {}", agent2nd.getParent_id());
}
log.debug("[获取平台和代理商信息] 查询完成,共获取 {} 条记录", esignPlatformInfos.size());
return esignPlatformInfos;
}
@ -188,12 +207,14 @@ public class EsignPlatformInfoServiceImpl extends BaseServiceImpl<EsignPlatformI
@Override
public EsignPlatformInfo getMch2ndAgent(Long mchId) {
// 参数校验
if (CheckUtil.isEmpty(mchId)) {
log.warn("[获取二级代理] 参数校验失败:商户入驻编号为空");
if (mchId == null || mchId <= 0) {
log.warn("[获取二级代理] 参数校验失败:商户入驻编号为空或无效mchId={}", mchId);
return null;
}
try {
log.debug("[获取二级代理] 开始查询二级代理信息mchId={}", mchId);
// 获取商户入驻信息
ShopMchEntry shopMchEntry = shopMchEntryService.shopMerchEntryById(mchId);
if (shopMchEntry == null) {
@ -202,7 +223,8 @@ public class EsignPlatformInfoServiceImpl extends BaseServiceImpl<EsignPlatformI
}
// 检查是否有指定的分销商ID或区域信息
if (CheckUtil.isEmpty(shopMchEntry.getDistributor_id()) && StrUtil.isBlank(shopMchEntry.getStore_district())) {
if ((shopMchEntry.getDistributor_id() == null || shopMchEntry.getDistributor_id() <= 0)
&& StrUtil.isBlank(shopMchEntry.getStore_district())) {
log.debug("[获取二级代理] 商户未指定分销商且无区域信息mchId={}", mchId);
return null;
}
@ -213,26 +235,26 @@ public class EsignPlatformInfoServiceImpl extends BaseServiceImpl<EsignPlatformI
.eq("status", CommonConstant.Enable)
.orderByAsc("id");
EsignPlatformInfo result = null;
// 优先使用指定的分销商ID查询否则使用区域信息查询
if (CheckUtil.isNotEmpty(shopMchEntry.getDistributor_id())) {
if (shopMchEntry.getDistributor_id() != null && shopMchEntry.getDistributor_id() > 0) {
queryWrapper.eq("id", shopMchEntry.getDistributor_id());
result = findOne(queryWrapper);
log.debug("[获取二级代理] 使用指定分销商ID查询distributorId={}", shopMchEntry.getDistributor_id());
}
EsignPlatformInfo result = findOne(queryWrapper);
if (result == null) {
if (StrUtil.isNotBlank(shopMchEntry.getStore_district())) {
// 运费代理商
queryWrapper.clear();
queryWrapper.eq("level", CommonConstant.Agent_Level_2nd)
.eq("status", CommonConstant.Enable)
.eq("license_district_id", shopMchEntry.getStore_district())
.gt("shipping_fee", 0).ne("supplier_id", "")
.orderByAsc("id");
log.debug("[获取二级代理] 使用区域信息查询districtId={}", shopMchEntry.getStore_district());
if (result == null && StrUtil.isNotBlank(shopMchEntry.getStore_district())) {
// 和商户同地区并且二级代理商有配送相关资质
queryWrapper.eq("license_district_id", shopMchEntry.getStore_district())
.gt("shipping_fee", 0).ne("supplier_id", "")
.orderByAsc("id");
result = findOne(queryWrapper);
log.debug("[获取二级代理] 使用区域信息查询districtId={}", shopMchEntry.getStore_district());
result = findOne(queryWrapper);
}
}
if (result == null) {

View File

@ -12,9 +12,9 @@ import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.suisung.mall.common.api.CommonResult;
import com.suisung.mall.common.service.impl.BaseControllerImpl;
import com.suisung.mall.shop.base.service.ShopBaseDistrictService;
import com.suisung.mall.shop.lakala.service.LakalaApiService;
import com.suisung.mall.shop.lakala.service.LklLedgerEcService;
import com.suisung.mall.shop.lakala.service.LklLedgerReceiverService;
import com.suisung.mall.shop.library.service.LibraryProductService;
import com.suisung.mall.shop.message.service.MqMessageService;
import com.suisung.mall.shop.message.service.PushMessageService;
@ -84,50 +84,13 @@ public class LakalaController extends BaseControllerImpl {
private LklLedgerEcService lklLedgerEcService;
@Resource
private ShopBaseDistrictService shopBaseDistrictService;
private LklLedgerReceiverService lklLedgerReceiverService;
@ApiOperation(value = "测试案例", notes = "测试案例")
@RequestMapping(value = "/testcase", method = RequestMethod.POST)
public Object testcase(@RequestBody JSONObject paramsJSON) {
// return shopOrderReturnService.sfExpressExpiredForceRefund(paramsJSON.getStr("orderId"));
// return lakalaPayService.applyLedgerMerEc(paramsJSON.getStr("mchMobile"));
// return lakalaPayService.LedgerMerEcDownload(975790666910121984L);
// return storeSameCityTransportBaseService.initDefaultSameCityTransport(58);
// return geTuiPushService.pushMessageToSingleByCid("f9da7081a7951cff6d7f1d4e2d2f270b", "", "从 shop 发消息", "none", "");
// return "";
//
// List<String> tags = new ArrayList<>();
//// tags.add("纯净水");
//// tags.add("放心");
// return libraryProductService.matchLibraryProducts(paramsJSON.getStr("barcode"), paramsJSON.getStr("productName"), tags);
// 测试推送消息
// List<String> clientIds = JSONUtil.toList(paramsJSON.getJSONArray("clientIds"), String.class);
// return pushMessageService.sendMessage(clientIds, paramsJSON.getStr("title"), paramsJSON.getStr("content"), paramsJSON.getJSONObject("payload"));
// JSONObject jsonObject = new JSONObject();
// String orderId = "DD-20250725-1";
// jsonObject.put("category", 1);
// jsonObject.put("orderId", "DD-20250725-1");
// jsonObject.put("storeId", 12);
// jsonObject.put("title", "有一笔已超时的订单!");
// jsonObject.put("message", "您有一笔已超时的订单[" + orderId + "],请及时处理。");
// mqMessageService.sendDelayMessage(jsonObject.toString(), 10000);
// return jsonObject;
// return shopOrderBaseService.sameCityOrderExpireSeconds(10000L);
// return sfExpressApiService.createSfExpressShop(66, "能辉超市", "桂平市", "广西壮族自治区贵港市桂平市广佰汇超市(桂平店)", "谢能坤", "17777525395", "110.07165452271", "23.369069486251");
// return lakalaApiService.sacsQuery("8226330541100GU", "20250918770188017227140800").toString();
String[] result = shopBaseDistrictService.convertDistrictPath(paramsJSON.getStr("id"), paramsJSON.getStr("name"));
log.info("result: " + result[0] + " " + result[1]);
return ""; //lakalaApiService.queryLedgerMer("8226330541100HA");
return lklLedgerReceiverService.selectAgentAndPlatformByMchId(36L);
}
@ApiOperation(value = "批量发送推送消息 - 测试案例", notes = "批量发送推送消息 - 测试案例")

View File

@ -99,4 +99,20 @@ public interface LklLedgerReceiverService extends IBaseService<LklLedgerReceiver
* @return
*/
Long countByCondition(String LicenseNo, String ContactMobile, Long platformId);
/**
* 根据入驻编号获取平台和代理商接收方信息
*
* @param mchId
* @return
*/
List<LklLedgerReceiver> selectAgentAndPlatformByMchId(Long mchId);
/**
* 根据入驻编号获取商户的二级代理接收方信息
*
* @param mchId
* @return
*/
LklLedgerReceiver getMch2ndAgent(Long mchId);
}

View File

@ -855,7 +855,12 @@ public class LakalaApiServiceImpl implements LakalaApiService {
log.warn("[确认收货通知] 未能获取到商品子单信息,使用原始参数进行处理");
}
} else {
log.debug("[确认收货通知] 非合单订单,使用原始参数进行处理");
// 非合单订单确认收货响应数据{"trade_no":"20251015110110000066202154232129","log_no":"66202154232129","trade_state":"SUCCESS",
// "total_amount":"2950","trade_time":"20251015165538",
// "complete_notify_url":"https://mall.gpxscs.cn/api/mobile/shop/lakala/trans/receive/completeNotify",
// "merchant_no":"8226330541100H4","sub_mch_id":"812310610","origin_trade_no":"20251015110113130266250075936522",
// "origin_log_no":"66250075936522","origin_out_trade_no":"DD_20251015_2"}
log.debug("[确认收货通知] 从订单信息中获取原始交易号: originTradeNo={} originLogNo={}", originTradeNo, originLogNo);
}
@ -892,11 +897,19 @@ public class LakalaApiServiceImpl implements LakalaApiService {
}
log.info("[确认收货通知] 订单信息更新成功: orderId={}", shopOrderLkl.getOrder_id());
// 准备发起分账指令
// 重要准备发起分账指令
log.info("[确认收货通知] 开始发起分账指令: merchantNo={}, receiveTradeNo={}, logNo={}",
merchantNo, shopOrderLkl.getLkl_receive_trade_no(), logNo);
Pair<Boolean, String> separateResult = innerDoOrderSeparateByMerchantAndLogNo(merchantNo, shopOrderLkl.getLkl_receive_trade_no(), shopOrderLkl.getLkl_receive_log_no());
if (!separateResult.getFirst()) {
shopOrderLkl.setSeparate_msg(separateResult.getSecond());
updateResult = shopOrderLklService.addOrUpdateByStoreOrder(shopOrderLkl);
if (Boolean.FALSE.equals(updateResult)) {
log.error("[确认收货通知] 更新订单信息失败: orderId={}", shopOrderLkl.getOrder_id());
return JSONUtil.createObj().set("code", "FAIL").set("message", "更新订单信息失败!");
}
log.error("[确认收货通知] 发起分账指令失败: orderId={}, reason={}", shopOrderLkl.getOrder_id(), separateResult.getSecond());
return JSONUtil.createObj().set("code", "FAIL").set("message", "发起分账指令失败:" + separateResult.getSecond());
}
@ -1503,7 +1516,7 @@ public class LakalaApiServiceImpl implements LakalaApiService {
* <p>参考https://o.lakala.com/#/home/document/detail?id=386
* 为商户绑定分账接收方包括平台方和代理商如有
*
* @param paramsJSON 包含绑定参数的JSON对象 {merCupNo}
* @param paramsJSON 包含绑定参数的JSON对象 {merCupNo, merInnerNo}
* @return Pair对象第一个元素表示操作是否成功第二个元素为操作结果信息
*/
public Pair<Boolean, String> innerApplyLedgerMerReceiverBind(JSONObject paramsJSON) {
@ -1532,6 +1545,8 @@ public class LakalaApiServiceImpl implements LakalaApiService {
return Pair.of(false, "商户入驻记录不存在");
}
Long mchId = shopMchEntry.getId();
// 进件记录
log.debug("开始查询分账业务申请记录,商户号: {}", merCupNo);
LklLedgerMember lklLedgerMember = lklLedgerMemberService.getByMerCupNo(merCupNo);
@ -1546,9 +1561,9 @@ public class LakalaApiServiceImpl implements LakalaApiService {
lklLedgerMember.setMer_inner_no("");
}
// 分账接收方列表
// 获取商家的平台和代理商分账接收方列表平台至少有一个默认是桂平发发
log.debug("开始查询分账接收方列表");
List<LklLedgerReceiver> receiverList = lklLedgerReceiverService.selectPlatformAnDistributorList();
List<LklLedgerReceiver> receiverList = lklLedgerReceiverService.selectAgentAndPlatformByMchId(mchId);
if (CollectionUtil.isEmpty(receiverList)) {
log.warn("商家绑定分账接收方申请失败:分账接收方信息为空");
return Pair.of(false, "分账接收方信息为空");
@ -1652,7 +1667,10 @@ public class LakalaApiServiceImpl implements LakalaApiService {
paramsJSON.set("ret_url", retUrl);
paramsJSON.set("remark", respJson.getStr("retMsg"));
paramsJSON.set("platform_id", receiver.getPlatform_id());
paramsJSON.set("mch_id", shopMchEntry.getId());
paramsJSON.set("mch_id", mchId);
paramsJSON.set("level", receiver.getLevel());
paramsJSON.set("split_ratio", receiver.getSplit_ratio());
paramsJSON.set("shipping_fee", receiver.getShipping_fee());
// 转换JSON键名格式并保存
String snakeJson = StringUtils.convertCamelToSnake(paramsJSON.toString());
@ -2445,21 +2463,24 @@ public class LakalaApiServiceImpl implements LakalaApiService {
return Pair.of(false, "缺少必要参数");
}
ShopOrderLkl shopOrderLkl = null;
try {
// 2. 查询订单信息
ShopOrderLkl shopOrderLkl = shopOrderLklService.getByLklMchNoAndReceiveTradeNoAndReceiveLogNo(lklMerchantNo, receiveTradeNo, receiveLogNo);
shopOrderLkl = shopOrderLklService.getByLklMchNoAndReceiveTradeNoAndReceiveLogNo(lklMerchantNo, receiveTradeNo, receiveLogNo);
if (shopOrderLkl == null) {
log.warn("[分账操作] lklMerchantNo={}, receiveTradeNo={}, receiveLogNo={} 查询订单不存在", lklMerchantNo, receiveTradeNo, receiveLogNo);
log.warn("[分账操作] 未找到对应订单记录, lklMerchantNo={}, receiveTradeNo={}, receiveLogNo={}",
lklMerchantNo, receiveTradeNo, receiveLogNo);
return Pair.of(false, "订单不存在");
}
String orderId = shopOrderLkl.getOrder_id();
log.info("[分账操作] 开始处理分账请求, lklMerchantNo={}, receiveTradeNo={}, receiveLogNo={}orderId={}",
lklMerchantNo, receiveTradeNo, receiveLogNo, orderId);
log.info("[分账操作] 开始处理分账请求, orderId={}, merchantNo={}, receiveTradeNo={}, receiveLogNo={}",
orderId, lklMerchantNo, receiveTradeNo, receiveLogNo);
// 3. 检查订单状态
if (!CommonConstant.Enable.equals(shopOrderLkl.getReceive_status())) {
log.warn("[分账操作] 订单{}交易流水号{}未被确认收货,跳过处理", orderId, receiveTradeNo);
log.warn("[分账操作] 订单未确认收货,无法分账, orderId={}, receiveTradeNo={}", orderId, receiveTradeNo);
return Pair.of(false, "订单未确认收货,暂无法分账");
}
@ -2471,7 +2492,8 @@ public class LakalaApiServiceImpl implements LakalaApiService {
&& "SUCCESS".equals(existingSeparateRecord.getStatus())
&& "SUCCESS".equals(existingSeparateRecord.getFinal_status())
&& CommonConstant.Enable.equals(shopOrderLkl.getSeparate_status())) {
log.info("[分账操作] 订单[{}]交易对账流水号[{}]已完成分账,跳过处理", orderId, shopOrderLkl.getLkl_receive_log_no());
log.info("[分账操作] 订单分账已完成,无需重复处理, orderId={}, receiveLogNo={}",
orderId, shopOrderLkl.getLkl_receive_log_no());
return Pair.of(true, "订单已分账,请勿重复操作");
}
@ -2479,14 +2501,14 @@ public class LakalaApiServiceImpl implements LakalaApiService {
Integer refCanSeparateAmt = null;
Pair<String, String> mchCanSplitAmt = queryMchCanSplitAmt(lklMerchantNo, receiveLogNo, shopOrderLkl.getLkl_log_date());
if (mchCanSplitAmt != null) {
log.info("[分账操作] 查询拉卡拉可分账余额接口:lklMerchantNo={} logDate={} receiveLogNo={} 结果:{}",
log.debug("[分账操作] 查询拉卡拉可分账余额, merchantNo={}, logDate={}, receiveLogNo={}, result={}",
lklMerchantNo, shopOrderLkl.getLkl_log_date(), receiveLogNo, mchCanSplitAmt);
// 拉卡拉返回的实际可分账金额
refCanSeparateAmt = Convert.toInt(mchCanSplitAmt.getSecond());
if (CheckUtil.isEmpty(refCanSeparateAmt)) {
log.warn("[分账操作] lklMerchantNo={} receiveTradeNo={} receiveLogNo={} 拉卡拉可分账金额无值或0系统将自动计算可分账金额",
lklMerchantNo, receiveTradeNo, receiveLogNo);
log.warn("[分账操作] 拉卡拉可分账金额为空或为0将使用系统计算金额, orderId={}, merchantNo={}",
orderId, lklMerchantNo);
}
}
@ -2498,40 +2520,56 @@ public class LakalaApiServiceImpl implements LakalaApiService {
if (mchSplitRatioRaw == null ||
mchSplitRatioRaw.compareTo(BigDecimal.ZERO) <= 0 ||
mchSplitRatioRaw.compareTo(new BigDecimal(100)) >= 0) {
log.error("[分账操作] 店铺[{}]商家分账比例[{}]不在(0-100]范围内,无法分账",
shopOrderLkl.getStore_id(), mchSplitRatioRaw);
log.error("[分账操作] 商家分账比例不在有效范围内(0-100], orderId={}, merchantNo={}, splitRatio={}",
orderId, merchantNo, mchSplitRatioRaw);
return Pair.of(false, "商家分账比例有误");
}
// 计算商家分账比例转换为小数
BigDecimal mchSplitRatio = mchSplitRatioRaw.divide(new BigDecimal(100));
log.info("[分账操作] 开始执行分账计算, orderId={}, merchantNo={}", orderId, merchantNo);
// 获取分账平台接收方信息
LklLedgerMerReceiverBind platformReceiver = lklLedgerMerReceiverBindService.getPlatformByMerCupNo(merchantNo);
if (platformReceiver == null) {
log.error("[分账操作] 商户号{} 未绑定平台方接收账户,跳过分账", merchantNo);
log.error("[分账操作] 未绑定平台方接收账户,无法分账, orderId={}, merchantNo={}", orderId, merchantNo);
return Pair.of(false, "平台方未绑定账户");
}
// 获取代理商分账信息
// 获取平台分账百分比值
BigDecimal platformSplitRatio = CheckUtil.isEmpty(platformReceiver.getSplit_ratio()) ? BigDecimal.valueOf(0.01) : platformReceiver.getSplit_ratio(); // 默认平台比例 1%
// 获取省级代理商接收方
LklLedgerMerReceiverBind agent1stReceiver = lklLedgerMerReceiverBindService.getAgent1stByMerCupNo(merchantNo);
// 获取县级代理商接收方
LklLedgerMerReceiverBind agent2ndReceiver = lklLedgerMerReceiverBindService.getAgent2ndByMerCupNo(merchantNo);
// 内部配送费单位
Integer shoppingFeeInner = CheckUtil.isEmpty(shopOrderLkl.getShopping_fee_inner()) ? 0 : shopOrderLkl.getShopping_fee_inner();
BigDecimal agent1stSplitRatio = null;
BigDecimal agent2ndSplitRatio = null;
if (agent1stReceiver != null) {
agent1stSplitRatio = CheckUtil.isEmpty(agent1stReceiver.getSplit_ratio()) ? BigDecimal.ZERO : agent1stReceiver.getSplit_ratio(); // 默认省级比例
log.warn("[分账操作] 获取到省级代理商的分账比例值, agent1stSplitRatio={}, merchantNo={}, 1streceiver={}", agent1stSplitRatio, merchantNo, agent1stReceiver.getReceiver_no());
}
if (agent2ndReceiver != null) {
agent2ndSplitRatio = CheckUtil.isEmpty(agent2ndReceiver.getSplit_ratio()) ? BigDecimal.ZERO : agent2ndReceiver.getSplit_ratio(); // 默认市级比例
log.warn("[分账操作] 获取到县级代理商的分账比例值, agent2stSplitRatio={}, merchantNo={}, 2ndreceiver={}", agent2ndSplitRatio, merchantNo, agent2ndReceiver.getReceiver_no());
// 如果县级代理商运费未配置金额使用平台的最低配送费如果平台配送费未配置金额则免运费
if (CheckUtil.isNotEmpty(agent2ndReceiver.getShipping_fee())) {
shoppingFeeInner = agent2ndReceiver.getShipping_fee();
log.warn("[分账操作] 获取到县级代理商的配送费金额(分), shoppingFeeInner={}, merchantNo={}, 2ndreceiver={}", shoppingFeeInner, merchantNo, agent2ndReceiver.getReceiver_no());
}
}
// 内部配送费单位
Integer shoppingFeeInner = CheckUtil.isEmpty(shopOrderLkl.getShopping_fee_inner()) ? 0 : shopOrderLkl.getShopping_fee_inner();
// 如果商家没有代理商且平台分账比例低于等于0.01的则平台分账比例调整到 1-商家分账比例值但不能超过0.06.
if (agent1stReceiver == null && agent2ndReceiver == null && BigDecimal.valueOf(0.01).compareTo(platformSplitRatio) >= 0) {
// 平台比例: 1-商家比例百分值但不能超过0.06.
platformSplitRatio = BigDecimal.ONE.subtract(mchSplitRatio).min(BigDecimal.valueOf(0.06));
}
// 计算拉卡拉手续费商家分账金额平台和代理商的分账金额
Pair<Boolean, LklSeparateWithTotalAmountDTO> calcResult = calculateAndEvaluateSharingParams(
@ -2542,30 +2580,39 @@ public class LakalaApiServiceImpl implements LakalaApiService {
agent1stSplitRatio, agent2ndSplitRatio, refCanSeparateAmt);
if (calcResult == null || !calcResult.getFirst() || calcResult.getSecond() == null) {
log.error("[分账操作] 分账参数评估,结果无法分账");
log.error("[分账操作] 分账参数评估失败,无法分账, orderId={}, merchantNo={}", orderId, merchantNo);
// 更新分账出错信息
shopOrderLkl.setSeparate_msg("分账数据评估,结果无法分账");
shopOrderLklService.safeUpdate(shopOrderLkl);
return Pair.of(false, "分账数据评估,结果无法分账");
}
LklSeparateWithTotalAmountDTO lklSeparateDTO = calcResult.getSecond();
log.debug("[分账操作] 分账参数计算结果:{}", lklSeparateDTO);
log.info("[分账操作] 分账计算完成, orderId={}, merchantNo={}, 分账总金额={}",
orderId, merchantNo, lklSeparateDTO.getCanSeparateAmount());
// 更新分账计算结果
shopOrderLkl.setSeparate_remark(lklSeparateDTO.toString()); // 写入分账具体情况
if (CheckUtil.isEmpty(refCanSeparateAmt)) {
shopOrderLkl.setSplit_amt(lklSeparateDTO.getCanSeparateAmount());
refCanSeparateAmt = lklSeparateDTO.getCanSeparateAmount();
} else {
shopOrderLkl.setSplit_amt_ref(refCanSeparateAmt);
}
shopOrderLkl.setSplit_amt_ref(refCanSeparateAmt);
// 可分账金额校验
if (CheckUtil.isEmpty(refCanSeparateAmt)) {
String errorMsg = String.format("[分账操作] 店铺[%s]订单[%s]可分账金额[%d]低于1分钱跳过分账",
shopOrderLkl.getStore_id(), orderId, refCanSeparateAmt);
if (CheckUtil.isEmpty(refCanSeparateAmt) || refCanSeparateAmt <= 0) {
String errorMsg = String.format("[分账操作] 可分账金额低于1分钱跳过分账, orderId=%s, merchantNo=%s, amount=%d",
orderId, merchantNo, refCanSeparateAmt);
log.error(errorMsg);
if (existingSeparateRecord != null) {
lklOrderSeparateService.updateRemark(existingSeparateRecord.getId(), errorMsg);
}
// 更新分账出错信息
shopOrderLkl.setSeparate_msg("订单可分账金额低于1分钱无法分账");
shopOrderLklService.safeUpdate(shopOrderLkl);
return Pair.of(false, "订单可分账金额低于1分钱");
}
@ -2574,67 +2621,73 @@ public class LakalaApiServiceImpl implements LakalaApiService {
Integer agent1stAmount = lklSeparateDTO.getAgent1stAmount();
Integer agent2ndAmount = lklSeparateDTO.getAgent2ndAmount();
log.info("[分账操作] 金额计算结果:订单={}, 商户={}, 总金额={}分, 可分金额={}分, 商家比例={}, 商家分得={}分, 平台比例={}, 平台分得={}分, 省级代理商比例={}, 省级代理商分得={}分, 县级代理商比例={}, 县级代理商分得={}分",
orderId, merchantNo, shopOrderLkl.getTotal_amt(), refCanSeparateAmt, mchSplitRatio, merchantAmount,
platformSplitRatio, platformAmount, agent1stSplitRatio, agent1stAmount, agent2ndSplitRatio, agent2ndAmount);
String logMsg = String.format("[分账操作] 分账金额计算完成, orderId=%s, merchantNo=%s, 总金额=%d分, 可分金额=%d分, 配送费=%d分",
orderId, merchantNo, shopOrderLkl.getTotal_amt(), refCanSeparateAmt, shoppingFeeInner);
log.info(logMsg);
// 更新分账计算结果
shopOrderLkl.setSeparate_msg(logMsg);
shopOrderLklService.safeUpdate(shopOrderLkl);
// 构建分账接收方分账列表参数
List<V3SacsSeparateRecvDatas> recvDatas = new ArrayList<>();
// 商家分账参数
if (CheckUtil.isNotEmpty(merchantAmount)) {
if (CheckUtil.isNotEmpty(merchantAmount) && merchantAmount > 0) {
V3SacsSeparateRecvDatas receiver = new V3SacsSeparateRecvDatas();
receiver.setRecvMerchantNo(merchantNo);
receiver.setSeparateValue(Convert.toStr(merchantAmount));
recvDatas.add(receiver);
log.debug("[分账操作] 添加商家接收方: merchantNo={}, amount={}", merchantNo, merchantAmount);
}
// 是否有二级代理商
boolean has2ndAgent = CheckUtil.isNotEmpty(agent2ndSplitRatio) && agent2ndReceiver != null &&
StrUtil.isNotBlank(agent2ndReceiver.getReceiver_no()) &&
CheckUtil.isNotEmpty(agent2ndAmount) && agent2ndAmount > 0;
// 平台分账参数
if (CheckUtil.isNotEmpty(platformAmount)) {
V3SacsSeparateRecvDatas receiver = new V3SacsSeparateRecvDatas();
receiver.setRecvNo(platformReceiver.getReceiver_no());
receiver.setSeparateValue(Convert.toStr(platformAmount));
recvDatas.add(receiver);
if (CheckUtil.isNotEmpty(platformAmount) && platformAmount > 0) {
if (!has2ndAgent && CheckUtil.isNotEmpty(shoppingFeeInner)) {
// 没有县级代理商的时候配送费暂由平台代收 add 2025-10-11
V3SacsSeparateRecvDatas receiver = new V3SacsSeparateRecvDatas();
receiver.setRecvNo(platformReceiver.getReceiver_no());
receiver.setSeparateValue(Convert.toStr(platformAmount + shoppingFeeInner));
recvDatas.add(receiver);
} else {
V3SacsSeparateRecvDatas receiver = new V3SacsSeparateRecvDatas();
receiver.setRecvNo(platformReceiver.getReceiver_no());
receiver.setSeparateValue(Convert.toStr(platformAmount));
recvDatas.add(receiver);
}
}
log.debug("[分账操作] 添加平台接收方: receiverNo={}, amount={}", platformReceiver.getReceiver_no(), platformAmount);
// 县级代理商分账参数
if (has2ndAgent) {
if (CheckUtil.isNotEmpty(shoppingFeeInner)) {
// 有县级代理商的时候配送费暂由它代收 add 2025-10-11
V3SacsSeparateRecvDatas shippingFeeReceiver = new V3SacsSeparateRecvDatas();
shippingFeeReceiver.setRecvNo(agent2ndReceiver.getReceiver_no());
shippingFeeReceiver.setSeparateValue(Convert.toStr(agent2ndAmount + shoppingFeeInner));
recvDatas.add(shippingFeeReceiver);
} else {
V3SacsSeparateRecvDatas receiver = new V3SacsSeparateRecvDatas();
receiver.setRecvNo(agent2ndReceiver.getReceiver_no());
receiver.setSeparateValue(Convert.toStr(agent2ndAmount));
recvDatas.add(receiver);
}
}
// 省级代理商分账参数
if (agent1stReceiver != null && StrUtil.isNotBlank(agent1stReceiver.getReceiver_no()) && CheckUtil.isNotEmpty(agent1stAmount)) {
if (CheckUtil.isNotEmpty(agent1stSplitRatio) && agent1stReceiver != null &&
StrUtil.isNotBlank(agent1stReceiver.getReceiver_no()) &&
CheckUtil.isNotEmpty(agent1stAmount) && agent1stAmount > 0) {
V3SacsSeparateRecvDatas receiver = new V3SacsSeparateRecvDatas();
receiver.setRecvNo(agent1stReceiver.getReceiver_no());
receiver.setSeparateValue(Convert.toStr(agent1stAmount));
recvDatas.add(receiver);
log.debug("[分账操作] 添加省级代理商接收方: receiverNo={}, amount={}", agent1stReceiver.getReceiver_no(), agent1stAmount);
}
// 县级代理商分账参数
if (agent2ndReceiver != null && StrUtil.isNotBlank(agent2ndReceiver.getReceiver_no()) && CheckUtil.isNotEmpty(agent2ndAmount)) {
V3SacsSeparateRecvDatas receiver = new V3SacsSeparateRecvDatas();
receiver.setRecvNo(agent2ndReceiver.getReceiver_no());
receiver.setSeparateValue(Convert.toStr(agent2ndAmount));
recvDatas.add(receiver);
log.debug("[分账操作] 添加县级代理商接收方: receiverNo={}, amount={}", agent2ndReceiver.getReceiver_no(), agent2ndAmount);
// 有县级代理商的时候配送费暂由它代收 add 2025-10-11
V3SacsSeparateRecvDatas shippingFeeReceiver = new V3SacsSeparateRecvDatas();
shippingFeeReceiver.setRecvNo(agent2ndReceiver.getReceiver_no());
shippingFeeReceiver.setSeparateValue(Convert.toStr(shoppingFeeInner));
recvDatas.add(shippingFeeReceiver);
} else {
// 没有县级代理商的时候配送费暂由平台代收 add 2025-10-11
V3SacsSeparateRecvDatas shippingFeeReceiver = new V3SacsSeparateRecvDatas();
shippingFeeReceiver.setRecvNo(platformReceiver.getReceiver_no());
shippingFeeReceiver.setSeparateValue(Convert.toStr(shoppingFeeInner));
recvDatas.add(shippingFeeReceiver);
}
// 初始化拉卡拉SDK
log.debug("[分账操作] 初始化拉卡拉SDK");
initLKLSDK();
// 构建分账请求对象
@ -2649,35 +2702,34 @@ public class LakalaApiServiceImpl implements LakalaApiService {
separateRequest.setNotifyUrl(projectDomain + "/api/mobile/shop/lakala/sacs/separateNotify");
separateRequest.setRecvDatas(recvDatas);
log.debug("[分账操作] 分账接收方数量={},请求详细参数: {}", recvDatas.size(), JSONUtil.toJsonStr(separateRequest));
log.info("[分账操作] 准备发送分账请求, orderId={}, merchantNo={}, receiveLogNo={}, 分账接收方数量={}",
orderId, merchantNo, shopOrderLkl.getLkl_receive_log_no(), recvDatas.size());
// 发送分账请求
log.info("[分账操作] 向拉卡拉发送分账请求:订单={}, 商户={}, 分账流水号={}",
orderId, merchantNo, shopOrderLkl.getLkl_receive_log_no());
String response = LKLSDK.httpPost(separateRequest);
if (StrUtil.isBlank(response)) {
String errorMsg = String.format("[分账操作] 拉卡拉无响应,订单=%s商户=%s分账流水号=%s",
String errorMsg = String.format("[分账操作] 拉卡拉无响应, orderId=%s, merchantNo=%s, receiveLogNo=%s",
orderId, merchantNo, shopOrderLkl.getLkl_receive_log_no());
shopOrderLklService.updateSeparateStatusByReceiveLogNo(shopOrderLkl.getLkl_receive_log_no(), CommonConstant.Sta_Separate_Fail, "");
shopOrderLklService.updateSeparateStatusByReceiveLogNo(shopOrderLkl.getLkl_receive_log_no(), CommonConstant.Sta_Separate_Fail, errorMsg);
log.error(errorMsg);
return Pair.of(false, "拉卡拉无响应");
}
log.debug("[分账操作] 响应结果: {}", response);
log.debug("[分账操作] 拉卡拉分账响应结果: {}", response);
// 解析响应结果
JSONObject respJson = JSONUtil.parseObj(response);
if (respJson == null || !lklSacsSuccessCode.equals(respJson.getStr("code")) || respJson.getJSONObject("resp_data") == null) {
String errorMsg = String.format("[分账操作] 拉卡拉返回格式异常,订单=%s商户=%s分账流水号=%s响应=%s",
String errorMsg = String.format("[分账操作] 拉卡拉返回格式异常, orderId=%s, merchantNo=%s, receiveLogNo=%s, response=%s",
orderId, merchantNo, shopOrderLkl.getLkl_receive_log_no(), response);
shopOrderLklService.updateSeparateStatusByReceiveLogNo(shopOrderLkl.getLkl_receive_log_no(), CommonConstant.Sta_Separate_Fail, "");
shopOrderLklService.updateSeparateStatusByReceiveLogNo(shopOrderLkl.getLkl_receive_log_no(), CommonConstant.Sta_Separate_Fail, errorMsg);
log.error(errorMsg);
return Pair.of(false, "拉卡拉分账异常:[" + (respJson != null ? respJson.getStr("code") : "未知错误码") + "]" +
(respJson != null ? respJson.getStr("msg") : "未知错误"));
}
// 只有在分账请求成功发送后更新分账备注
// 分账请求成功发送后更新分账备注
shopOrderLklService.safeUpdate(shopOrderLkl);
// 保存分账记录
@ -2699,12 +2751,11 @@ public class LakalaApiServiceImpl implements LakalaApiService {
separateRecord.setTotal_fee_amt(Convert.toStr(lklSeparateDTO.getLklAmount()));
if (lklOrderSeparateService.addOrUpdateByReceiverNo(separateRecord)) {
log.info("[分账操作] 记录保存成功:订单={}, 分账单号={}, 状态={}, 分账流水号={}",
log.info("[分账操作] 分账记录保存成功, orderId={}, separateNo={}, status={}, logNo={}",
orderId, separateRecord.getSeparate_no(), separateRecord.getStatus(), separateRecord.getLog_no());
log.info("[分账操作] 结果:订单[{}] 订单分账已提交处理", orderId);
return Pair.of(true, "订单分账已提交处理");
} else {
String errorMsg = String.format("[分账操作] 保存分账记录失败,订单=%s分账单号=%s分账流水号=%s",
String errorMsg = String.format("[分账操作] 保存分账记录失败, orderId=%s, separateNo=%s, logNo=%s",
orderId, separateRecord.getSeparate_no(), separateRecord.getLog_no());
log.error(errorMsg);
lklOrderSeparateService.updateRemark(separateRecord.getLog_no(), separateRecord.getSeparate_no(), errorMsg);
@ -2712,8 +2763,15 @@ public class LakalaApiServiceImpl implements LakalaApiService {
}
} catch (Exception e) {
String errorMsg = String.format("[分账操作] 系统异常,分账对账流水号=%s错误=%s", receiveLogNo, e.getMessage());
String errorMsg = String.format("[分账操作] 系统异常, receiveLogNo=%s, 错误=%s", receiveLogNo, e.getMessage());
log.error(errorMsg, e);
if (shopOrderLkl != null) {
shopOrderLkl.setSeparate_msg(errorMsg);
shopOrderLkl.setSeparate_status(CommonConstant.Sta_Separate_Fail);
shopOrderLklService.safeUpdate(shopOrderLkl);
}
return Pair.of(false, "系统异常,请稍后重试");
}
}

View File

@ -19,6 +19,8 @@ import com.suisung.mall.common.api.ResultCode;
import com.suisung.mall.common.constant.CommonConstant;
import com.suisung.mall.common.modules.esign.EsignPlatformInfo;
import com.suisung.mall.common.modules.lakala.LklLedgerReceiver;
import com.suisung.mall.common.modules.store.ShopMchEntry;
import com.suisung.mall.common.utils.CheckUtil;
import com.suisung.mall.core.web.service.impl.BaseServiceImpl;
import com.suisung.mall.shop.esign.service.EsignPlatformInfoService;
import com.suisung.mall.shop.lakala.mapper.LklLedgerReceiverMapper;
@ -32,6 +34,8 @@ import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@Slf4j
@ -143,7 +147,7 @@ public class LklLedgerReceiverServiceImpl extends BaseServiceImpl<LklLedgerRecei
public JSONArray buildApplyLedgerReceiverReqParams(Long mchId) {
// 获取平台记录和代理商记录
List<EsignPlatformInfo> esignPlatformInfoList = esignPlatformInfoService.getDistributorAndPlatformByIds(mchId);
List<EsignPlatformInfo> esignPlatformInfoList = esignPlatformInfoService.selectAgentAndPlatformByMchId(mchId);
if (CollectionUtil.isEmpty(esignPlatformInfoList)) {
return null;
}
@ -166,6 +170,11 @@ public class LklLedgerReceiverServiceImpl extends BaseServiceImpl<LklLedgerRecei
reqParam.put("legalPersonCertificateType", "17");
reqParam.put("legalPersonCertificateNo", esignPlatformInfo.getLegal_person_id_card());
reqParam.put("level", esignPlatformInfo.getLevel());
reqParam.put("splitRatio", esignPlatformInfo.getSplit_ratio());
reqParam.put("shippingFee", esignPlatformInfo.getShipping_fee());
reqParam.put("parentId", CheckUtil.isEmpty(esignPlatformInfo.getParent_id()) ? 0L : esignPlatformInfo.getParent_id());
reqParam.put("acctNo", esignPlatformInfo.getRec_acc_card_no());
reqParam.put("acctName", esignPlatformInfo.getRec_acc_bank_name());
reqParam.put("acctTypeCode", "57");
@ -218,18 +227,20 @@ public class LklLedgerReceiverServiceImpl extends BaseServiceImpl<LklLedgerRecei
*/
@Override
public Boolean innerApplyLedgerReceiver(Long mchId, String merCupNo) {
// 接收方至少有一个平台方
JSONArray buildApplyLedgerReceiverReqParams = buildApplyLedgerReceiverReqParams(mchId);
// 商户的分账接收方平台+代理商
JSONArray platformAndAgentReceiver = buildApplyLedgerReceiverReqParams(mchId);
if (buildApplyLedgerReceiverReqParams == null || buildApplyLedgerReceiverReqParams.isEmpty()) {
if (platformAndAgentReceiver == null || platformAndAgentReceiver.isEmpty()) {
log.error("先新增平台或代理商信息");
return false;
}
int successCnt = 0;
for (JSONObject reqParam : buildApplyLedgerReceiverReqParams.jsonIter()) {
log.debug("申请分账接收方参数:{}", reqParam.toString());
reqParam.put("mchId", mchId); // 附加入驻商户自增ID
for (JSONObject reqParam : platformAndAgentReceiver.jsonIter()) {
log.debug("申请分账接收方参数:{}", reqParam);
reqParam.put("mchId", mchId); // 附加入驻商户编号
// 向拉卡拉申请分账接收方
CommonResult result = lakalaApiService.applyLedgerReceiver(reqParam);
if (result == null || result.getStatus() != ResultCode.SUCCESS.getStatus()) {
log.error("申请分账接收方失败:{}", result.getMsg());
@ -355,4 +366,133 @@ public class LklLedgerReceiverServiceImpl extends BaseServiceImpl<LklLedgerRecei
return count(queryWrapper);
}
/**
* 根据入驻编号获取平台和代理商接收方信息
*
* @param mchId
* @return
*/
@Override
public List<LklLedgerReceiver> selectAgentAndPlatformByMchId(Long mchId) {
List<LklLedgerReceiver> list = new ArrayList<>();
log.debug("[获取平台和代理商信息] 开始查询平台方和代理商接收方信息商户ID: {}", mchId);
// 获取平台方记录
QueryWrapper<LklLedgerReceiver> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("level", 0)
.eq("status", CommonConstant.Enable).orderByAsc("id");
LklLedgerReceiver platformInfo = findOne(queryWrapper);
if (platformInfo == null || platformInfo.getId() == null || platformInfo.getId() <= 0) {
log.error("[获取平台和代理商信息] 未找到有效的平台方记录, mchId={}", mchId);
return Collections.emptyList();
}
list.add(platformInfo);
log.debug("[获取平台和代理商信息] 成功获取平台方信息ID: {}", platformInfo.getId());
// 获取商户的二级代理
LklLedgerReceiver agent2nd = getMch2ndAgent(mchId);
if (agent2nd == null) {
log.debug("[获取平台和代理商信息] 未找到二级代理商或无需二级代理商, mchId={}", mchId);
return list;
}
list.add(agent2nd);
log.debug("[获取平台和代理商信息] 成功获取二级代理信息ID: {}", agent2nd.getId());
// 获取一级代理如果存在
if (agent2nd.getParent_id() == null || agent2nd.getParent_id() <= 0) {
log.debug("[获取平台和代理商信息] 二级代理商无有效上级代理, mchId={}", mchId);
return list;
}
// 获取县级代理商的省级代理商
queryWrapper.clear();
queryWrapper.eq("platform_id", agent2nd.getParent_id())
.eq("level", CommonConstant.Agent_Level_1st)
.gt("split_ratio", 0)
.eq("status", CommonConstant.Enable)
.orderByAsc("id");
LklLedgerReceiver agent1st = findOne(queryWrapper);
if (agent1st != null) {
list.add(agent1st);
log.debug("[获取平台和代理商信息] 成功获取一级代理信息ID: {}", agent1st.getId());
} else {
log.warn("[获取平台和代理商信息] 未找到一级代理商, parent_id: {}, mchId: {}", agent2nd.getParent_id(), mchId);
}
log.debug("[获取平台和代理商信息] 查询完成,共获取 {} 条记录", list.size());
return list;
}
/**
* 根据入驻编号获取商户的二级代理接收方信息
*
* @param mchId
* @return
*/
@Override
public LklLedgerReceiver getMch2ndAgent(Long mchId) {
// 参数校验
if (mchId == null || mchId <= 0) {
log.warn("[获取二级代理] 参数校验失败商户入驻编号为空或无效mchId={}", mchId);
return null;
}
try {
log.debug("[获取二级代理] 开始查询二级代理接收方信息mchId={}", mchId);
// 获取商户入驻信息
ShopMchEntry shopMchEntry = shopMchEntryService.shopMerchEntryById(mchId);
if (shopMchEntry == null) {
log.warn("[获取二级代理] 未找到商户入驻信息mchId={}", mchId);
return null;
}
// 检查是否有指定的分销商ID或区域信息
if ((shopMchEntry.getDistributor_id() == null || shopMchEntry.getDistributor_id() <= 0)
&& StrUtil.isBlank(shopMchEntry.getStore_district())) {
log.debug("[获取二级代理] 商户未指定分销商且无区域信息mchId={}", mchId);
return null;
}
// 构建查询条件
QueryWrapper<LklLedgerReceiver> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("level", CommonConstant.Agent_Level_2nd)
.eq("status", CommonConstant.Enable)
.orderByAsc("id");
LklLedgerReceiver result = null;
// 优先使用指定的分销商ID查询否则使用区域信息查询
if (shopMchEntry.getDistributor_id() != null && shopMchEntry.getDistributor_id() > 0) {
queryWrapper.eq("platform_id", shopMchEntry.getDistributor_id());
result = findOne(queryWrapper);
log.debug("[获取二级代理] 使用指定分销商ID查询distributorId={}", shopMchEntry.getDistributor_id());
}
if (result == null && StrUtil.isNotBlank(shopMchEntry.getStore_district())) {
// 运费代理商
queryWrapper.eq("license_district_id", shopMchEntry.getStore_district())
.gt("shipping_fee", 0).ne("supplier_id", "")
.orderByAsc("id");
result = findOne(queryWrapper);
log.debug("[获取二级代理] 使用区域信息查询districtId={}", shopMchEntry.getStore_district());
}
if (result == null) {
log.info("[获取二级代理] 未找到匹配的二级代理信息mchId={}", mchId);
} else {
log.debug("[获取二级代理] 成功获取二级代理信息receiverNo={}, id={}", result.getReceiver_no(), result.getId());
}
return result;
} catch (Exception e) {
log.error("[获取二级代理] 查询过程中发生异常mchId={}", mchId, e);
return null;
}
}
}

View File

@ -365,7 +365,7 @@ public class LklTkServiceImpl {
&& !StrUtil.hasBlank(shopMchEntry.getLkl_mer_cup_no(), shopMchEntry.getLkl_term_no())) {
// 已经进件过了执行下一步操作
logger.info("商户已进件执行后续操作商户ID: {}", mchId);
registrationMerchantAfterHook(mchId, shopMchEntry.getLkl_mer_cup_no(), shopMchEntry.getDistributor_id());
registrationMerchantAfterHook(mchId, shopMchEntry.getLkl_mer_cup_no());
return Pair.of(true, "请勿重复提交,拉卡拉已进件成功了,准备提交分账业务申请!");
}
@ -709,7 +709,7 @@ public class LklTkServiceImpl {
//密集操作进件审核通过之后要下一步流程操作申请分账业务创建分账接收方
logger.info("开始执行进件后续操作商户ID: {},拉卡拉商户号: {}", mchId, merCupNo);
registrationMerchantAfterHook(mchId, merCupNo, shopMchEntry.getDistributor_id());
registrationMerchantAfterHook(mchId, merCupNo);
logger.info("拉卡拉进件异步通知处理完成商户ID: {}", mchId);
return new JSONObject().set("code", "200").set("message", "处理成功");
@ -725,9 +725,8 @@ public class LklTkServiceImpl {
*
* @param mchId
* @param merCupNo
* @param distributorId
*/
private void registrationMerchantAfterHook(Long mchId, String merCupNo, Long distributorId) {
private void registrationMerchantAfterHook(Long mchId, String merCupNo) {
logger.info("商家进件已成功,下一步申请拉卡拉分账业务,再创建分账接收方!");
// 重要给商家申请分账业务务必检查是否申请过申请过忽略
@ -740,7 +739,7 @@ public class LklTkServiceImpl {
logger.info("申请分账业务已成功,等待拉卡拉审核,准备创建分账接收方!");
}
// 2新增一个接收方记录起码要一个平台方代理商根据入驻信息新增
// 2新增一个接收方记录起码要一个平台方代理商根据入驻商家由哪个代理商邀请而确定是否新增
Boolean genSuccess = lklLedgerReceiverService.innerApplyLedgerReceiver(mchId, merCupNo);
if (!genSuccess) {
logger.error("进件、申请分账业务成功已成功,等待拉卡拉审核分账业务请求,但创建分账接收方失败了,请管理员补偿流程");

View File

@ -6529,10 +6529,7 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl<ShopOrderBaseMappe
if (CollUtil.isNotEmpty(item_items)) {
String firstProductName = Convert.toStr(item_items.get(0).get("product_item_name"));
if (StrUtil.isNotBlank(firstProductName)) {
// 限制长度防止超出字段限制
if (firstProductName.length() > 100) {
firstProductName = firstProductName.substring(0, 100);
}
firstProductName = StrUtil.subPre(StrUtil.trim(firstProductName), 100);
product_item_name = firstProductName + "等商品";
}
}

View File

@ -1519,14 +1519,11 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
//修改退货订单及其相关商品为下一个待处理状态
editShopOrderReturnAndItemNextState(return_ids, return_state_id, shopOrderReturn);
// 运费退款
ShopOrderReturn return_order_shipping_fee_row = null;
// return_state_id 是当前状态旧状态
if (ObjectUtil.equal(return_state_id, StateCode.RETURN_PROCESS_CHECK)) {
// 同意退款退货判断是否全部都退款退货修改订单状态
UserDto user = getCurrentUser();
// UserDto user = getCurrentUser();
for (ShopOrderReturn return_row : return_rows) {
String order_id = return_row.getOrder_id();
@ -1600,99 +1597,53 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
StateCode.ORDER_STATE_RECEIVED,
StateCode.ORDER_STATE_FINISH);
if (order_state_id != null && !forbiddenStates.contains(order_state_id)) {
// 取消订单,更改订单的状态为已取消
// shopOrderBaseService.cancel(order_id, info_row, false);
logger.info("处理运费和打包费事宜:{}", order_id);
ShopOrderData order_data_row = shopOrderDataService.get(order_id);
// 如果有打包费最后的退款订单的退款金额加上 打包费
if (order_data_row != null &&
order_data_row.getPacking_fee() != null &&
order_data_row.getPacking_fee().compareTo(BigDecimal.ZERO) > 0) {
// 退款金额+打包费
BigDecimal orderRefundAmountAddFee = NumberUtil.add(
order_data_row.getOrder_refund_amount(),
order_data_row.getPacking_fee());
// 最后一个退款订单如果有打包费加上打包费
return_row.setReturn_refund_amount(orderRefundAmountAddFee);
logger.debug("最后一个商品已添加打包费到退款金额订单ID: {}", order_id);
}
if (order_data_row != null) {
BigDecimal additionalFees = BigDecimal.ZERO;
List<String> feeTypes = new ArrayList<>();
// 有运费的重新生成一个运费退单
// if (order_data_row != null &&
// order_data_row.getOrder_shipping_fee_inner() != null &&
// order_data_row.getOrder_shipping_fee_inner().compareTo(BigDecimal.ZERO) > 0) {
// 注意商家配置的配送费
if (order_data_row != null &&
order_data_row.getOrder_shipping_fee() != null &&
order_data_row.getOrder_shipping_fee().compareTo(BigDecimal.ZERO) > 0) {
// 运费大于0的 执行退运费操作, 有两种方案1生成退运费售后服务单 2直接执行退款
// 1生成独立退运费售后服务单需注意运费是退给运费代理商的需要获取代理商的交易单号
return_order_shipping_fee_row = new ShopOrderReturn();
Integer buyer_user_id = info_row.getBuyer_user_id();
Integer storeId = info_row.getStore_id();
// // 平台内部订单配送费
// BigDecimal orderShippingFeeInner = order_data_row.getOrder_shipping_fee_inner();
// if (orderShippingFeeInner == null || orderShippingFeeInner.compareTo(BigDecimal.ZERO) <= 0) {
// orderShippingFeeInner = shopOrderLklService.getOrderShippingFeeInnerToDecimal(storeId, order_id);
// }
// 商家设置的配送费
BigDecimal orderShippingFee = order_data_row.getOrder_shipping_fee();
return_order_shipping_fee_row.setReturn_refund_amount(orderShippingFee); // 平台内部配送费退款金额
BigDecimal order_points_fee = ObjectUtil.defaultIfNull(order_data_row.getOrder_points_fee(), BigDecimal.ZERO);
BigDecimal order_refund_agree_points = ObjectUtil.defaultIfNull(order_data_row.getOrder_refund_agree_points(), BigDecimal.ZERO);
BigDecimal return_refund_point = NumberUtil.round(NumberUtil.sub(order_points_fee, order_refund_agree_points), 2);
return_order_shipping_fee_row.setOrder_id(order_id); // 订单编号
return_order_shipping_fee_row.setBuyer_user_id(buyer_user_id);
return_order_shipping_fee_row.setReturn_is_shipping_fee(1); //退货类型(BOOL): 0-退款单;1-退运费单
return_order_shipping_fee_row.setReturn_reason_id(0);
return_order_shipping_fee_row.setReturn_buyer_message(I18nUtil._("订单(配送费)退款"));
return_order_shipping_fee_row.setStore_id(storeId);
return_order_shipping_fee_row.setReturn_refund_point(NumberUtil.min(return_refund_point, orderShippingFee));
return_order_shipping_fee_row.setReturn_add_time(now); // 添加时间
return_order_shipping_fee_row.setReturn_tel("");
// 店铺审核操作员
Integer storeUserId = user != null ? user.getId() : 0;
return_order_shipping_fee_row.setReturn_store_user_id(storeUserId);
return_order_shipping_fee_row.setReturn_telephone("");
return_order_shipping_fee_row.setSubsite_id(info_row.getSubsite_id());
// update 2025-07-24
return_order_shipping_fee_row.setReturn_flag(0); // 退货标识(BOOL): 0-正常退货;1-退货换货
return_order_shipping_fee_row.setReturn_store_message(I18nUtil._("订单(配送费)退款"));
return_order_shipping_fee_row.setReturn_finish_time(now);
return_order_shipping_fee_row.setReturn_state_id(StateCode.RETURN_PROCESS_FINISH);
return_order_shipping_fee_row.setReturn_is_paid(1);// 退款完成
return_order_shipping_fee_row.setReturn_channel_code("lakala");
return_order_shipping_fee_row.setPayment_channel_id(1416);
return_order_shipping_fee_row.setReturn_year(DateUtil.year(now)); // 退单年份-索引查询
return_order_shipping_fee_row.setReturn_month(DateUtil.month(now) + 1); // 退单月份-索引查询
return_order_shipping_fee_row.setReturn_day(DateUtil.dayOfMonth(now)); // 退单日-索引查询
// 生成退货单
String type_code = stateCodeService.getCode(StateCode.ORDER_TYPE_FX, "state_code_code");
String return_id = shopNumberSeqService.createNextSeq(type_code);
return_order_shipping_fee_row.setReturn_id(return_id);
// 运费独立加一条退单记录
if (!add(return_order_shipping_fee_row)) {
logger.error("配送费退款订单生成失败订单ID: {}", order_id);
// 1生成退运费售后服务单
throw new ApiException(I18nUtil._("配送费退款订单生成失败!"));
// 处理打包费
if (order_data_row.getPacking_fee() != null &&
order_data_row.getPacking_fee().compareTo(BigDecimal.ZERO) > 0) {
additionalFees = additionalFees.add(order_data_row.getPacking_fee());
feeTypes.add("打包费");
logger.debug("添加打包费: {}订单ID: {}", order_data_row.getPacking_fee(), order_id);
}
logger.info("配送费退款订单生成成功,退单号: {}", return_id);
// 处理配送费
if (order_data_row.getOrder_shipping_fee() != null &&
order_data_row.getOrder_shipping_fee().compareTo(BigDecimal.ZERO) > 0) {
additionalFees = additionalFees.add(order_data_row.getOrder_shipping_fee());
feeTypes.add("配送费");
logger.debug("添加配送费: {}订单ID: {}", order_data_row.getOrder_shipping_fee(), order_id);
}
// 更新退款金额和说明
if (additionalFees.compareTo(BigDecimal.ZERO) > 0) {
BigDecimal newRefundAmount = return_row.getReturn_refund_amount().add(additionalFees);
return_row.setReturn_refund_amount(newRefundAmount);
return_row.setReturn_state_id(StateCode.RETURN_PROCESS_FINISH);
// 构建费用说明
String feeDescription = String.join("+", feeTypes);
String returnStoreMessage = return_row.getReturn_store_message();
if (StrUtil.isBlank(returnStoreMessage)) {
returnStoreMessage = "商品退款";
}
return_row.setReturn_store_message(returnStoreMessage + "+" + feeDescription);
// 保存更新
if (StrUtil.isNotBlank(return_row.getReturn_id()) && !edit(return_row)) {
logger.error("更新退货单退款金额失败退货单ID: {}", return_row.getReturn_id());
throw new ApiException(ResultCode.FAILED);
}
logger.debug("成功更新退款金额,新增费用: {},总退款金额: {}订单ID: {}",
additionalFees, newRefundAmount, order_id);
}
} else {
logger.warn("未找到订单数据无法处理费用订单ID: {}", order_id);
}
}
@ -1711,7 +1662,7 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
// 修改订单同步状态 可重新同步
ShopOrderInfo orderInfo = new ShopOrderInfo();
orderInfo.setOrder_id(order_id);
orderInfo.setOrder_is_sync(0); // 订单同步状态
orderInfo.setOrder_is_sync(0); // 是否ERP同步(BOOL):0-未同步; 1-已同步
if (!shopOrderInfoService.edit(orderInfo)) {
logger.error("修改订单同步状态失败订单ID: {}", order_id);
throw new ApiException(I18nUtil._("修改订单同步状态失败!"));
@ -1726,20 +1677,18 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
// 卖家账户扣款买家账户增加
// 佣金问题
shopOrderReturn.setReturn_is_paid(1); // 0-退货未完成1-退货完成
shopOrderReturn.setReturn_finish_time(now);
List<ShopOrderReturn> returnOrder = new ArrayList<>();
if (return_rows != null) {
returnOrder.addAll(return_rows);
}
if (return_order_shipping_fee_row != null) {
returnOrder.add(return_order_shipping_fee_row);
}
// List<ShopOrderReturn> returnOrder = new ArrayList<>();
// if (return_rows != null) {
// returnOrder.addAll(return_rows);
// }
// if (return_order_shipping_fee_row != null) {
// returnOrder.add(return_order_shipping_fee_row);
// }
// 重要执行退款操作
try {
if (!payService.doRefund(returnOrder)) {
if (!payService.doRefund(return_rows)) {
logger.error("执行退款操作失败!退单列表: {}", return_ids);
throw new ApiException("余额不足,请稍后重试");
}
@ -1752,6 +1701,9 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl<ShopOrderReturnM
logger.info("退款操作执行成功,退单列表: {}", return_ids);
// 更新退货单的退款完成状态和完成时间
// shopOrderReturn.setReturn_is_paid(CommonConstant.Enable); // 0-退货未完成1-退货完成
// shopOrderReturn.setReturn_finish_time(now);
//
ShopOrderReturn updateRefundStatus = new ShopOrderReturn();
updateRefundStatus.setReturn_is_paid(1); // 0-退货未完成1-退货完成
updateRefundStatus.setReturn_finish_time(now);

View File

@ -132,7 +132,10 @@ public class ShopStorePrinterServiceImpl extends BaseServiceImpl<ShopStorePrinte
}
// 从厂家删除其他店使用该打印机的记录
feieUtil.delPrinter(record.getPrinter_sn());
Pair<Boolean, String> pair = feieUtil.delPrinter(record.getPrinter_sn());
if (pair.getFirst()) {
logger.info("已从厂家删除打印机:{}, 详细信息:{}", record.getPrinter_sn(), pair.getSecond());
}
if (add(record)) {
return CommonResult.success(null, "添加成功");
@ -271,7 +274,10 @@ public class ShopStorePrinterServiceImpl extends BaseServiceImpl<ShopStorePrinte
// 向厂家解绑打印机
Pair<Boolean, String> retPair = feieUtil.delPrinter(record.getPrinter_sn());
if (!retPair.getFirst()) {
logger.error("从厂家删除打印机失败SN: {}, 错误信息: {}", record.getPrinter_sn(), retPair.getSecond());
return CommonResult.failed(retPair.getSecond());
} else {
logger.info("已从厂家删除打印机:{}, 详细信息:{}", record.getPrinter_sn(), retPair.getSecond());
}
}

View File

@ -2619,11 +2619,11 @@ public class ShopUserCartServiceImpl extends BaseServiceImpl<ShopUserCartMapper,
List<Map> items = (List<Map>) cart_data.get("items");
for (Map store_row : items) {
// 检查店铺城市和收货地址是否同一城市
List<Integer> storeDistrictId = Convert.toList(Integer.class, store_row.get("store_district_id"));
if (canThrow && uAddress != null && storeDistrictId != null && storeDistrictId.size() > 0 && !CollUtil.contains(storeDistrictId, uAddress.getUd_city_id())) {
throw new ApiException(I18nUtil._("订单不在同一城市,请检查您下单所在店铺的具体位置!"));
}
// // 检查店铺城市和收货地址是否同一城市
// List<Integer> storeDistrictId = Convert.toList(Integer.class, store_row.get("store_district_id"));
// if (canThrow && uAddress != null && storeDistrictId != null && storeDistrictId.size() > 0 && !CollUtil.contains(storeDistrictId, uAddress.getUd_city_id())) {
// throw new ApiException(I18nUtil._("订单不在同一城市,请检查您下单所在店铺的具体位置!"));
// }
// 一个店铺的订单
Long storeId = Convert.toLong(store_row.get("store_id"));

View File

@ -586,6 +586,8 @@
<result property="order_picked_time" column="order_picked_time"/>
<result property="currency_id" column="currency_id"/>
<result property="order_state_id" column="order_state_id"/>
<result property="order_is_received" column="order_is_received"/>
<result property="kind_id" column="kind_id"/>
<result property="delivery_type_id" column="delivery_type_id"/>
<result property="distance" column="distance"/>
@ -762,7 +764,6 @@
THEN oi.order_time + #{expireSeconds}*1000
ELSE oi.order_time + 864000000 <!-- 10天 = 10*24*60*60*1000 = 864000000毫秒 -->
END as arrival_time,
ob.order_product_amount,
ob.order_payment_amount,
ob.currency_id,
@ -776,6 +777,8 @@
oi.delivery_type_id,
oi.buyer_user_id,
oi.order_picked_time,
oi.order_is_received,
oi.kind_id,
IF((SELECT count(*) FROM shop_order_base WHERE buyer_user_id = oi.buyer_user_id AND order_state_id IN
(2011,2012,
2013, 2014, 2020, 2030, 2040))>1,2,1)