diff --git a/mall-common/src/main/java/com/suisung/mall/common/exception/GlobalExceptionHandler.java b/mall-common/src/main/java/com/suisung/mall/common/exception/GlobalExceptionHandler.java index f36913fe..5ccd944b 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/exception/GlobalExceptionHandler.java +++ b/mall-common/src/main/java/com/suisung/mall/common/exception/GlobalExceptionHandler.java @@ -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异常 */ diff --git a/mall-common/src/main/java/com/suisung/mall/common/modules/esign/EsignPlatformInfo.java b/mall-common/src/main/java/com/suisung/mall/common/modules/esign/EsignPlatformInfo.java index 65fe2e04..85e532a1 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/modules/esign/EsignPlatformInfo.java +++ b/mall-common/src/main/java/com/suisung/mall/common/modules/esign/EsignPlatformInfo.java @@ -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 = "邀请码,后期跟收益有关") diff --git a/mall-common/src/main/java/com/suisung/mall/common/modules/lakala/LklLedgerMerReceiverBind.java b/mall-common/src/main/java/com/suisung/mall/common/modules/lakala/LklLedgerMerReceiverBind.java index 12a86ea8..19d80664 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/modules/lakala/LklLedgerMerReceiverBind.java +++ b/mall-common/src/main/java/com/suisung/mall/common/modules/lakala/LklLedgerMerReceiverBind.java @@ -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; diff --git a/mall-common/src/main/java/com/suisung/mall/common/modules/lakala/LklLedgerReceiver.java b/mall-common/src/main/java/com/suisung/mall/common/modules/lakala/LklLedgerReceiver.java index 1beb64f3..ad0bce8b 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/modules/lakala/LklLedgerReceiver.java +++ b/mall-common/src/main/java/com/suisung/mall/common/modules/lakala/LklLedgerReceiver.java @@ -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; diff --git a/mall-common/src/main/java/com/suisung/mall/common/modules/order/ShopOrderLkl.java b/mall-common/src/main/java/com/suisung/mall/common/modules/order/ShopOrderLkl.java index f1b4ce81..95b9ab22 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/modules/order/ShopOrderLkl.java +++ b/mall-common/src/main/java/com/suisung/mall/common/modules/order/ShopOrderLkl.java @@ -98,6 +98,8 @@ public class ShopOrderLkl implements Serializable { private String separate_remark; + private String separate_msg; + private Integer status; private Date created_at; diff --git a/mall-common/src/main/java/com/suisung/mall/common/modules/order/dto/MchOrderInfoDTO.java b/mall-common/src/main/java/com/suisung/mall/common/modules/order/dto/MchOrderInfoDTO.java index 23378173..05f732dc 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/modules/order/dto/MchOrderInfoDTO.java +++ b/mall-common/src/main/java/com/suisung/mall/common/modules/order/dto/MchOrderInfoDTO.java @@ -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 = "订单运费") diff --git a/mall-common/src/main/java/com/suisung/mall/common/pojo/dto/LklSeparateWithTotalAmountDTO.java b/mall-common/src/main/java/com/suisung/mall/common/pojo/dto/LklSeparateWithTotalAmountDTO.java index c99bc491..8721b4a1 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/pojo/dto/LklSeparateWithTotalAmountDTO.java +++ b/mall-common/src/main/java/com/suisung/mall/common/pojo/dto/LklSeparateWithTotalAmountDTO.java @@ -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% diff --git a/mall-common/src/main/java/com/suisung/mall/common/service/impl/UniCloudPushServiceImpl.java b/mall-common/src/main/java/com/suisung/mall/common/service/impl/UniCloudPushServiceImpl.java index 0569d890..ad3021b8 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/service/impl/UniCloudPushServiceImpl.java +++ b/mall-common/src/main/java/com/suisung/mall/common/service/impl/UniCloudPushServiceImpl.java @@ -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; } - + /** * 处理推送响应 */ diff --git a/mall-pay/src/main/java/com/suisung/mall/pay/service/impl/PayConsumeTradeServiceImpl.java b/mall-pay/src/main/java/com/suisung/mall/pay/service/impl/PayConsumeTradeServiceImpl.java index 3cc53738..6d58007c 100644 --- a/mall-pay/src/main/java/com/suisung/mall/pay/service/impl/PayConsumeTradeServiceImpl.java +++ b/mall-pay/src/main/java/com/suisung/mall/pay/service/impl/PayConsumeTradeServiceImpl.java @@ -188,7 +188,7 @@ public class PayConsumeTradeServiceImpl extends BaseServiceImpl getDistributorAndPlatformByIds(Long mchId); + List selectAgentAndPlatformByMchId(Long mchId); /** * 根据分类和营业执照号获取平台方信息 diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/esign/service/impl/EsignPlatformInfoServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/esign/service/impl/EsignPlatformInfoServiceImpl.java index 8c259542..f85c1fb4 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/esign/service/impl/EsignPlatformInfoServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/esign/service/impl/EsignPlatformInfoServiceImpl.java @@ -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 平台方和代理商信息列表 */ @Override - public List getDistributorAndPlatformByIds(Long mchId) { + public List selectAgentAndPlatformByMchId(Long mchId) { + List esignPlatformInfos = new ArrayList<>(); + + log.debug("[获取平台和代理商信息] 开始查询平台方和代理商信息,商户ID: {}", mchId); + // 获取平台方记录 QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.eq("level", 0) .eq("status", CommonConstant.Enable) - .orderByAsc("level"); + .orderByAsc("id"); - List 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 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) { diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/controller/mobile/LakalaController.java b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/controller/mobile/LakalaController.java index 5a100b20..9d0a5539 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/controller/mobile/LakalaController.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/controller/mobile/LakalaController.java @@ -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 tags = new ArrayList<>(); -//// tags.add("纯净水"); -//// tags.add("放心"); -// return libraryProductService.matchLibraryProducts(paramsJSON.getStr("barcode"), paramsJSON.getStr("productName"), tags); - - // 测试推送消息 -// List 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 = "批量发送推送消息 - 测试案例") diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/LklLedgerReceiverService.java b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/LklLedgerReceiverService.java index 61ec9d94..00666ce8 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/LklLedgerReceiverService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/LklLedgerReceiverService.java @@ -99,4 +99,20 @@ public interface LklLedgerReceiverService extends IBaseService selectAgentAndPlatformByMchId(Long mchId); + + /** + * 根据入驻编号获取商户的二级代理接收方信息 + * + * @param mchId + * @return + */ + LklLedgerReceiver getMch2ndAgent(Long mchId); } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LakalaApiServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LakalaApiServiceImpl.java index f3772397..9a34c6f8 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LakalaApiServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LakalaApiServiceImpl.java @@ -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 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 { *

参考:https://o.lakala.com/#/home/document/detail?id=386 * 为商户绑定分账接收方,包括平台方和代理商(如有)。 * - * @param paramsJSON 包含绑定参数的JSON对象 {merCupNo} + * @param paramsJSON 包含绑定参数的JSON对象 {merCupNo, merInnerNo} * @return Pair对象,第一个元素表示操作是否成功,第二个元素为操作结果信息 */ public Pair 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 receiverList = lklLedgerReceiverService.selectPlatformAnDistributorList(); + List 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 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 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 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, "系统异常,请稍后重试"); } } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LklLedgerReceiverServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LklLedgerReceiverServiceImpl.java index 2832b90a..218519fd 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LklLedgerReceiverServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LklLedgerReceiverServiceImpl.java @@ -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 esignPlatformInfoList = esignPlatformInfoService.getDistributorAndPlatformByIds(mchId); + List esignPlatformInfoList = esignPlatformInfoService.selectAgentAndPlatformByMchId(mchId); if (CollectionUtil.isEmpty(esignPlatformInfoList)) { return null; } @@ -166,6 +170,11 @@ public class LklLedgerReceiverServiceImpl extends BaseServiceImpl selectAgentAndPlatformByMchId(Long mchId) { + List list = new ArrayList<>(); + + log.debug("[获取平台和代理商信息] 开始查询平台方和代理商接收方信息,商户ID: {}", mchId); + + // 获取平台方记录 + QueryWrapper 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 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; + } + } } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LklTkServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LklTkServiceImpl.java index 474c0230..c9a6337a 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LklTkServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LklTkServiceImpl.java @@ -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("进件、申请分账业务成功已成功,等待拉卡拉审核分账业务请求,但创建分账接收方失败了,请管理员补偿流程"); diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java index 51235422..5a02f88c 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderBaseServiceImpl.java @@ -6529,10 +6529,7 @@ public class ShopOrderBaseServiceImpl extends BaseServiceImpl 100) { - firstProductName = firstProductName.substring(0, 100); - } + firstProductName = StrUtil.subPre(StrUtil.trim(firstProductName), 100); product_item_name = firstProductName + "等商品"; } } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderReturnServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderReturnServiceImpl.java index 3a396142..049413ae 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderReturnServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/order/service/impl/ShopOrderReturnServiceImpl.java @@ -1519,14 +1519,11 @@ public class ShopOrderReturnServiceImpl extends BaseServiceImpl 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 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 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 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 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 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()); } } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/user/service/impl/ShopUserCartServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/user/service/impl/ShopUserCartServiceImpl.java index 2de90dc0..5bc42de8 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/user/service/impl/ShopUserCartServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/user/service/impl/ShopUserCartServiceImpl.java @@ -2619,11 +2619,11 @@ public class ShopUserCartServiceImpl extends BaseServiceImpl items = (List) cart_data.get("items"); for (Map store_row : items) { - // 检查店铺城市和收货地址是否同一城市? - List 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 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")); diff --git a/mall-shop/src/main/resources/mapper/order/ShopOrderBaseMapper.xml b/mall-shop/src/main/resources/mapper/order/ShopOrderBaseMapper.xml index ac55d2d7..a4b55af8 100644 --- a/mall-shop/src/main/resources/mapper/order/ShopOrderBaseMapper.xml +++ b/mall-shop/src/main/resources/mapper/order/ShopOrderBaseMapper.xml @@ -586,6 +586,8 @@ + + @@ -762,7 +764,6 @@ THEN oi.order_time + #{expireSeconds}*1000 ELSE oi.order_time + 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)