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 0ef2b315..850a999c 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 @@ -63,8 +63,8 @@ public class GlobalExceptionHandler { .map(ConstraintViolation::getMessage) .collect(Collectors.joining("; ")); - logError(req, "约束违反异常", e); - return CommonResult.validateFailed("系统数据异常,请联系管理员!"); + logError(req, "数据库约束违反异常", e); + return CommonResult.validateFailed("记录是否已存在,请检查!"); } /** diff --git a/mall-common/src/main/java/com/suisung/mall/common/utils/CheckUtil.java b/mall-common/src/main/java/com/suisung/mall/common/utils/CheckUtil.java index fb4bc945..e1e66e23 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/utils/CheckUtil.java +++ b/mall-common/src/main/java/com/suisung/mall/common/utils/CheckUtil.java @@ -27,38 +27,78 @@ import java.util.regex.Pattern; @Slf4j public class CheckUtil { -// private static String[] parsePatterns = {"yyyy-MM-dd", "yyyy年MM月dd日", -// "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy/MM/dd", -// "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyyMMdd"}; - /** * 校验数据 不为null和0 * - * @param param - * @return + * @param param 待校验的Integer值 + * @return boolean 不为null且不为0返回true,否则返回false */ public static boolean isNotEmpty(Integer param) { return param != null && param != 0; } + /** + * 校验数据 不为null和0 + * + * @param param 待校验的Long值 + * @return boolean 不为null且不为0返回true,否则返回false + */ public static boolean isNotEmpty(Long param) { - return param != null && param != 0; + return param != null && param != 0L; } + /** + * 校验数据 不为null和0 + * + * @param param 待校验的BigDecimal值 + * @return boolean 不为null且不为0返回true,否则返回false + */ public static boolean isNotEmpty(BigDecimal param) { - return param != null && param.floatValue() != 0; + return param != null && param.compareTo(BigDecimal.ZERO) != 0; } + /** + * 校验数据 不为null和0 + * + * @param param 待校验的Float值 + * @return boolean 不为null且不为0返回true,否则返回false + */ public static boolean isNotEmpty(Float param) { - return param != null && param != 0; + return param != null && param != 0f && !param.isNaN(); } + /** + * 校验数据 不为null和0 + * + * @param param 待校验的Double值 + * @return boolean 不为null且不为0返回true,否则返回false + */ public static boolean isNotEmpty(Double param) { - return param != null && param != 0; + return param != null && param != 0d && !param.isNaN(); } + /** + * 校验字符串不为null、空字符串、空白字符及特殊值 + * + * @param param 待校验的字符串 + * @return boolean 不为空返回true,否则返回false + */ public static boolean isNotEmpty(String param) { - return param != null && param != ""; + // 检查null值和空字符串 + if (param == null || param.isEmpty()) { + return false; + } + + // 去除首尾空格后检查是否为空 + String trimmed = param.trim(); + if (trimmed.isEmpty()) { + return false; + } + + // 检查特殊值:undefined、null、none(不区分大小写) + return !"undefined".equalsIgnoreCase(trimmed) && + !"null".equalsIgnoreCase(trimmed) && + !"none".equalsIgnoreCase(trimmed); } public static boolean isEmpty(Integer param) { diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/components/quartz/service/impl/QuartzServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/components/quartz/service/impl/QuartzServiceImpl.java index 5327bac8..afd72519 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/components/quartz/service/impl/QuartzServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/components/quartz/service/impl/QuartzServiceImpl.java @@ -58,19 +58,15 @@ public class QuartzServiceImpl implements QuartzService { throw new ApiException(I18nUtil._("任务实现类名称不能为空!")); } - // 2. 加载任务类 - Class clazz; try { + // 2. 加载任务类 + Class clazz; + String fullClassName = PATH_PREFIX + cName; logger.debug("[Quartz] 尝试加载任务类: {}", fullClassName); clazz = (Class) Class.forName(fullClassName); logger.debug("[Quartz] 成功加载任务类: {}", fullClassName); - } catch (ClassNotFoundException e) { - logger.error("[Quartz] 定时任务脚本不存在!类名: {}{}", PATH_PREFIX, cName, e); - throw new ApiException(I18nUtil._("定时任务脚本不存在!类名: " + PATH_PREFIX + cName), e); - } - try { // 3. 构建任务详情和触发器 JobKey jobKey = new JobKey(jName, jGroup); JobDetail jobDetail = JobBuilder.newJob(clazz) @@ -86,6 +82,9 @@ public class QuartzServiceImpl implements QuartzService { logger.debug("[Quartz] 构建任务详情和触发器完成: jobKey={}, triggerKey={}", jobKey, triggerKey); + // 打印最终执行的 cron 表达式 + logger.info("[Quartz] 定时任务最终执行表达式: {}", trigger.getCronExpression()); + // 4. 检查任务是否已存在 if (scheduler.checkExists(jobKey)) { logger.info("[Quartz] 任务已存在,先删除旧任务: jobKey={}", jobKey); @@ -110,6 +109,9 @@ public class QuartzServiceImpl implements QuartzService { logger.error("[Quartz] 添加定时任务失败!任务名称={}, 任务组={}, 触发器名称={}, 触发器组={}", jName, jGroup, tName, tGroup, e); throw new ApiException(I18nUtil._("添加定时任务失败!"), e); + } catch (ClassNotFoundException e) { + logger.error("[Quartz] 定时任务脚本不存在!类名: {}{}", PATH_PREFIX, cName, e); + throw new ApiException(I18nUtil._("定时任务脚本不存在!类名: " + PATH_PREFIX + cName), e); } catch (Exception e) { logger.error("[Quartz] 添加定时任务时发生未知异常!任务名称={}, 任务组={}, 触发器名称={}, 触发器组={}", jName, jGroup, tName, tGroup, e); 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 4c11a08c..ac07da3b 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 @@ -116,7 +116,9 @@ public class LakalaController extends BaseControllerImpl { // return sfExpressApiService.createSfExpressShop(66, "能辉超市", "桂平市", "广西壮族自治区贵港市桂平市广佰汇超市(桂平店)", "谢能坤", "17777525395", "110.07165452271", "23.369069486251"); - return lakalaApiService.sacsQuery("8226330541100GU", "20250918770188017227140800").toString(); +// return lakalaApiService.sacsQuery("8226330541100GU", "20250918770188017227140800").toString(); + + return lakalaApiService.queryLedgerMer("8226330541100HA"); } @ApiOperation(value = "批量发送推送消息 - 测试案例", notes = "批量发送推送消息 - 测试案例") diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/LakalaApiService.java b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/LakalaApiService.java index 598e1be4..1b28f065 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/LakalaApiService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/LakalaApiService.java @@ -10,6 +10,7 @@ package com.suisung.mall.shop.lakala.service; import cn.hutool.json.JSONObject; import com.suisung.mall.common.api.CommonResult; +import com.suisung.mall.common.modules.store.ShopMchEntry; import org.springframework.data.util.Pair; import javax.servlet.http.HttpServletRequest; @@ -268,6 +269,18 @@ public interface LakalaApiService { */ JSONObject sacsQuery(String merchantNo, String separateNo); + + /** + * 商户分账业务信息查询 + * 参考:https://o.lakala.com/#/home/document/detail?id=381 + * + * @param merCupNo 银联商户号 + * @return 分账业务信息,查询失败时返回null + *

+ * 返回:{"merInnerNo":"4002025092404043540","merCupNo":"8226330541100HA","splitLowestRatio":20.0,"orgId":"980688","orgName":"桂平发发","splitStatus":"VALID","splitStatusText":"启用","splitRange":"ALL","sepFundSource":"TR","bindRelations":[{"merInnerNo":"4002025092404043540","merCupNo":"8226330541100HA","receiverNo":"SR2024000129789","receiverName":"桂平发发网络有限公司"}],"platformId":null,"splitLaunchMode":"MANUAL","splitRuleSource":null,"eleContractNo":"QY20250924613672961"} + */ + JSONObject queryLedgerMer(String merCupNo); + /** * 订单分账撤销 * 参考:https://o.lakala.com/#/home/document/detail?id=390 @@ -288,4 +301,13 @@ public interface LakalaApiService { */ Integer fixedUnSuccessSeparateStatusJob(); + /** + * 检测修复补全商户的商户分账业务信息及分账接收方绑定关系(分账业务申请异步通知的补偿机制) + * + * @param shopMchEntry 商户入驻信息实例 + * @return + */ + Boolean checkAndFixLedgerMerApplyAndBindRelations(ShopMchEntry shopMchEntry); + + } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/LklLedgerMemberService.java b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/LklLedgerMemberService.java index d0a6aa46..6f407c5a 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/LklLedgerMemberService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/LklLedgerMemberService.java @@ -50,8 +50,9 @@ public interface LklLedgerMemberService extends IBaseService { * @param auditStatus * @param auditStatusText * @param remark + * @param notifyResp * @return */ - Boolean updateAuditResult(String applyId, String merInnerNo, String merCupNo, String entrustFileName, String entrustFilePath, String auditStatus, String auditStatusText, String remark); + Boolean updateAuditResult(String applyId, String merInnerNo, String merCupNo, String entrustFileName, String entrustFilePath, String auditStatus, String auditStatusText, String remark, String notifyResp); } 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 bc7cf18d..c04d3518 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 @@ -377,36 +377,43 @@ public class LakalaApiServiceImpl implements LakalaApiService { /** * 商家申请入网电子合同(给到商家签署合同) * - * @param mchId - * @return + * @param mchId 商户ID + * @return Pair 申请结果,第一个元素表示是否成功,第二个元素为结果信息 */ @Override public Pair applyLedgerMerEc(Long mchId) { - log.debug("商家开始申请入网电子合同"); - if (ObjectUtil.isEmpty(mchId)) { - return Pair.of(false, I18nUtil._("缺少商家必要参数!")); + log.debug("商家开始申请入网电子合同,入驻编号: {}", mchId); + + // 1. 参数校验 + if (CheckUtil.isEmpty(mchId)) { + log.warn("商家申请入网电子合同失败:缺少商家必要参数,入驻编号: {}", mchId); + return Pair.of(false, "缺少商家入驻编号!"); } - // 获取商家信息 + // 2. 获取商家信息 ShopMchEntry shopMchEntry = shopMchEntryService.shopMerchEntryById(mchId); - if (shopMchEntry == null) { - return Pair.of(false, I18nUtil._("缺少商家相关信息!")); + if (ObjectUtil.isEmpty(shopMchEntry)) { + log.warn("商家申请入网电子合同失败:缺少商家相关入驻信息,入驻编号: {}", mchId); + return Pair.of(false, "缺少商家相关入驻信息!"); } String contractMobile = shopMchEntry.getLegal_person_mobile(); + if (StrUtil.isBlank(contractMobile)) { + log.warn("商家申请入网电子合同失败:联系人手机号为空,入驻编号: {}", mchId); + return Pair.of(false, "联系人手机号不能为空!"); + } + // 3. 检查是否已存在已完成的电子合同 LklLedgerEc lklLedgerEc = lklLedgerEcService.getByMchId(shopMchEntry.getId(), "", CommonConstant.Enable); - if (lklLedgerEc != null - && "COMPLETED".equals(lklLedgerEc.getEc_status())) { - // TODO 电子合同已签署完成(但有一些错误的信息),这种情况,需要怎么处理? - // 办法:重新再签署合同,更新拉卡拉的电子合同信息到商家入驻表中 - + if (lklLedgerEc != null && "COMPLETED".equals(lklLedgerEc.getEc_status())) { log.info("商户:{} 电子合同已签署过,重新提交将被覆盖!", mchId); } - // 是企业类型商家 + // 4. 判断商家类型(企业或个人) Boolean isQy = CommonConstant.MCH_ENTITY_TYPE_QY.equals(shopMchEntry.getEntity_type()); + log.debug("商家类型:{},isQy: {}", isQy ? "企业" : "个人", isQy); + // 5. 装配请求数据 JSONObject reqData = new JSONObject(); reqData.put("order_no", StringUtils.genLklOrderNo(8)); reqData.put("org_id", orgCode); @@ -430,7 +437,7 @@ public class LakalaApiServiceImpl implements LakalaApiService { reqData.put("acct_name", shopMchEntry.getAccount_holder_name()); reqData.put("remark", "申请入网电子合同"); - // 正式上线的时候,调整 api 地址 + // 6. 构建回调地址 String domain = projectDomain; if (isProdProject()) { domain += "/api"; @@ -440,11 +447,11 @@ public class LakalaApiServiceImpl implements LakalaApiService { String retUrl = domain + "/mobile/shop/lakala/ec/applyNotify"; reqData.put("ret_url", retUrl); - + // 7. 构建合同参数 LocalDate today = LocalDate.now(); String signDate = DateTimeUtils.formatLocalDate(today, "yyyy-MM-dd"); - String platformName = "桂平发发网络有限公司"; + JSONObject ecParams = new JSONObject(); ecParams.put("A1", isQy ? shopMchEntry.getBiz_license_company() : shopMchEntry.getAccount_holder_name()); ecParams.put("A30", wxFee); // 测试环境微信费率0.6 @@ -507,6 +514,7 @@ public class LakalaApiServiceImpl implements LakalaApiService { // 注:该字段是json字符串,不是json对象 reqData.put("ec_content_parameters", ecParams.toString()); + // 8. 构建请求体 JSONObject reqBody = new JSONObject(); reqBody.put("req_time", DateTimeUtils.formatDateTime(LocalDateTime.now(), "yyyyMMddHHmmss")); reqBody.put("version", "3.0"); @@ -521,25 +529,27 @@ public class LakalaApiServiceImpl implements LakalaApiService { log.debug("申请入网电子合同请求参数:{}", JsonUtil.toJSONString(reqBody)); + // 9. 发送请求 String errMsg = ""; JSONObject response = RestTemplateHttpUtil.sendLklPost(reqUrl, header, reqBody, JSONObject.class); log.debug("拉卡拉申请入网电子合同响应参数:{}", JsonUtil.toJSONString(response)); if (ObjectUtil.isEmpty(response) || !lklSuccessCode.equals(response.getStr("retCode"))) { errMsg = "拉卡拉申请入网电子合同," + response.getStr("retMsg"); + log.warn("拉卡拉申请入网电子合同失败:{},商户ID: {}", errMsg, mchId); shopMchEntryService.updateMerchEntryApprovalByMchId(shopMchEntry.getId(), CommonConstant.MCH_APPR_STA_LKL_NOPASS, errMsg); return Pair.of(false, errMsg); } JSONObject respData = response.getJSONObject("respData"); if (respData == null) { - errMsg = "拉卡拉申请入网电子合同," + response.getStr("retMsg"); + errMsg = "拉卡拉申请入网电子合同,响应数据为空"; + log.warn("拉卡拉申请入网电子合同失败:{},入驻编号: {}", errMsg, mchId); shopMchEntryService.updateMerchEntryApprovalByMchId(shopMchEntry.getId(), CommonConstant.MCH_APPR_STA_LKL_NOPASS, errMsg); return Pair.of(false, errMsg); } - // 商家入网申请电子合同处理数据 - // 先写入本地数据库表中 + // 10. 处理响应数据并保存到本地数据库 LklLedgerEc record = new LklLedgerEc(); record.setMch_id(mchId); record.setMch_mobile(contractMobile); @@ -550,32 +560,31 @@ public class LakalaApiServiceImpl implements LakalaApiService { String ecResultUrl = respData.getStr("result_url"); record.setResult_url(ecResultUrl); record.setResp_body(response.toString()); + Boolean success = lklLedgerEcService.addOrUpdateByMchId(record); if (!success) { errMsg = "申请入网电子合同失败,数据保存失败"; - shopMchEntryService.updateMerchEntryApprovalByMchId(shopMchEntry.getId(), CommonConstant.MCH_APPR_STA_NOPASS, errMsg); + log.error("申请入网电子合同失败:数据保存失败,商户ID: {}", mchId); + shopMchEntryService.updateMerchEntryApprovalByMchId(shopMchEntry.getId(), CommonConstant.MCH_APPR_STA_LKL_NOPASS, errMsg); return Pair.of(false, errMsg); } - // 更新拉卡拉的电子合同信息到商家入驻表中 + // 11. 更新拉卡拉的电子合同信息到商家入驻表中 shopMchEntryService.updateMerchEntryEcResultUrlByMchId(mchId, ecResultUrl); - // 发短信给商家,及时签署合同 SMS_488465246 - // - //恭喜您的开店入驻申请已审核通过!请尽快登录小发商家版APP平台签署电子合同,签署链接24小时内有效(逾期需重新提交申请)。如有疑问请联系客服,感谢您的支持! - // shopMessageTemplateService.aliyunSmsSend(contractMobile, "SMS_493160417", null);//SMS_479760276 - - // 恭喜!您的开店入驻申请已审核通过,点击链接 https://mall.gpxscs.cn/api/mobile/shop/lakala/sign/ec/${code} - // 或前往小发商家版APP完成电子合同签署,链接24小时内有效(逾期需重新提交申请)。如有疑问可联系客服,感谢您的支持! + // 12. 发送短信通知商家及时签署合同 shopMessageTemplateService.aliyunSmsSend(contractMobile, "SMS_494860064", null); + // 13. 发送推送消息通知商家签署电子合同 JSONObject payload = new JSONObject(); payload.put("category", CommonConstant.PUSH_MSG_CATE_EC); - pushMessageService.noticeMerchantSignEcContract(shopMchEntry.getCreated_by(), payload); + pushMessageService.noticeMerchantSignEcContract(shopMchEntry.getCreated_by(), payload, false); + log.info("商家入网申请电子合同成功,入驻编号: {}", mchId); return Pair.of(true, "商家入网申请电子合同成功"); } + /** * 商户分账业务开通申请 * @@ -592,7 +601,7 @@ public class LakalaApiServiceImpl implements LakalaApiService { // 参数校验 if (StringUtils.isBlank(merCupNo)) { log.warn("商户分账业务申请失败:商户号不能为空"); - return Pair.of(false, I18nUtil._("商户号不能为空!")); + return Pair.of(false, "商户号不能为空!"); } // 获取商户入驻记录 @@ -600,7 +609,7 @@ public class LakalaApiServiceImpl implements LakalaApiService { ShopMchEntry shopMchEntry = shopMchEntryService.getShopMerchEntryByMerCupNo(merCupNo); if (shopMchEntry == null) { log.warn("商户分账业务申请失败:商家入驻信息不存在,商户号: {}", merCupNo); - return Pair.of(false, I18nUtil._("商家入驻信息不存在!")); + return Pair.of(false, "商家入驻信息不存在!"); } // 商户是否已经已申请过分账业务 @@ -618,14 +627,10 @@ public class LakalaApiServiceImpl implements LakalaApiService { if (!Boolean.TRUE.equals(forceReApply)) { log.info("商户{}已申请过分账业务,无需重复申请", merCupNo); - return Pair.of(true, I18nUtil._("商家已经申请过了!")); + return Pair.of(true, "商家分账业务已申请过!"); } } - // 检查更新店铺初始化状态 -// log.debug("检查并更新店铺初始化状态,商户ID: {}", shopMchEntry.getId()); -// shopMchEntryService.checkMchEntryStoreStatus(shopMchEntry.getId(), shopMchEntry); - try { // 1. 配置初始化 log.debug("初始化拉卡拉SDK"); @@ -633,24 +638,35 @@ public class LakalaApiServiceImpl implements LakalaApiService { //2. 装配数据 log.debug("装配分账业务申请请求参数"); - String splitEntrustFilePath = shopMchEntry.getLkl_ec_file_path(); //fileUploadResp.getStr("attFileId"); + String splitEntrustFilePath = shopMchEntry.getLkl_ec_file_path(); + if (StringUtils.isBlank(splitEntrustFilePath)) { + log.warn("商户分账业务申请失败:电子合同文件路径为空,商户号: {}", merCupNo); + return Pair.of(false, "电子合同文件路径为空"); + } // 给拉卡拉通知的回调地址 String notifyUrl = projectDomain + "/api/mobile/shop/lakala/ledger/applyLedgerMerNotify"; String orderNo = StringUtils.genLklOrderNo(8); // 14位年月日时(24小时制)分秒+8位的随机数 String merCupNoValue = shopMchEntry.getLkl_mer_cup_no(); // 从进件申请返回的商户号(不要传入内部商户号,传银联商户号才有效) - String contactMobile = shopMchEntry.getLogin_mobile(); // 商户入驻注册的手机号 - String fileName = "商家分账授权委托书.pdf"; + if (StringUtils.isBlank(merCupNoValue)) { + log.warn("商户分账业务申请失败:商户cup号为空,商户号: {}", merCupNo); + return Pair.of(false, "商户cup号为空"); + } + String contactMobile = shopMchEntry.getLogin_mobile(); // 商户入驻注册的手机号 + if (StringUtils.isBlank(contactMobile)) { + log.warn("商户分账业务申请失败:联系人手机号为空,商户号: {}", merCupNo); + return Pair.of(false, "联系人手机号为空"); + } + + String fileName = "商家分账授权委托书.pdf"; JSONObject reqData = new JSONObject(); reqData.put("version", "1.0"); reqData.put("orderNo", orderNo); reqData.put("orgCode", orgCode); - -// reqData.put("merInnerNo", merCupNoValue); reqData.put("merCupNo", merCupNoValue); reqData.put("contactMobile", contactMobile); @@ -667,16 +683,13 @@ public class LakalaApiServiceImpl implements LakalaApiService { reqData.put("splitLowestRatio", splitLowestRatio); // 商家最低分账比例不低于 20% reqData.put("splitRange", "ALL"); reqData.put("settleType", "01"); //01:主动提款 03:交易自动结算 不填默认01 - // paramsJSON.put("splitLaunchMode", "MANUAL"); - // paramsJSON.put("splitRuleSource", "MER"); - // paramsJSON.put("sepFundSource", "TR"); String postUrl = ""; String operationType = ""; // 操作类型,用于日志记录和提示信息 // 确保serverUrl不为null String effectiveServerUrl = serverUrl != null ? serverUrl : ""; - if (!isLklProd) { + if (Boolean.FALSE.equals(isLklProd)) { effectiveServerUrl = effectiveServerUrl + "/sit"; } @@ -699,14 +712,14 @@ public class LakalaApiServiceImpl implements LakalaApiService { log.debug("商户分账业务{}申请请求参数: 请求地址:{}\n {}\n 响应数据:{}", operationType, postUrl, reqData, responseStr); if (StrUtil.isBlank(responseStr)) { log.error("申请拉卡拉分账业务{}无返回值,商户号: {}", operationType, merCupNo); - return Pair.of(false, I18nUtil._("申请拉卡拉分账业务无返回值!")); + return Pair.of(false, "申请拉卡拉分账业务无返回值!"); } // 成功返回示例:{'retCode':'000000','retMsg':'申请已受理,请等待审核结果','respData':{'version':'1.0','orderNo':'KFPT20230223181025407788734','orgCode':'1','applyId':681201215598657536}} JSONObject lakalaRespJSON = JSONUtil.parseObj(responseStr); if (lakalaRespJSON == null) { log.error("申请拉卡拉分账业务{}返回值异常,商户号: {}", operationType, merCupNo); - return Pair.of(false, I18nUtil._("申请拉卡拉分账业务返回值异常!")); + return Pair.of(false, "申请拉卡拉分账业务返回值异常!"); } Object applyId = lakalaRespJSON.getByPath("respData.applyId"); @@ -723,7 +736,7 @@ public class LakalaApiServiceImpl implements LakalaApiService { reqData.set("applyId", applyId); String retMsg = lakalaRespJSON.getStr("retMsg"); reqData.set("remark", retMsg); - reqData.set("auditStatusText", retMsg); // 直接使用retMsg,避免null值 + reqData.set("auditStatusText", retMsg); reqData.set("mchId", shopMchEntry.getId()); // 新增数据 @@ -732,24 +745,24 @@ public class LakalaApiServiceImpl implements LakalaApiService { String snakeCaseJson = StringUtils.convertCamelToSnake(reqData.toString()); if (StringUtils.isBlank(snakeCaseJson)) { log.error("JSON转换为下划线命名格式失败,商户号: {}", merCupNo); - return Pair.of(false, I18nUtil._("数据格式转换失败!")); + return Pair.of(false, "数据格式转换失败!"); } LklLedgerMember lklLedgerMemberNew = JSONUtil.toBean(snakeCaseJson, LklLedgerMember.class); // 根据 mchId 和 商户号更新记录 if (lklLedgerMemberNew == null || !lklLedgerMemberService.addOrUpdateByMerCupNo(lklLedgerMemberNew)) { log.error("新增或更改拉卡拉分账业务申请信息失败,订单号: {}", orderNo); - return Pair.of(false, I18nUtil._("新增或更改拉卡拉分账业务申请信息失败!")); + return Pair.of(false, "新增或更改拉卡拉分账业务申请信息失败!"); } log.info("商户分账业务{}申请提交成功,等待审核,商户号: {},申请ID: {}", operationType, merCupNo, applyId); - return Pair.of(true, I18nUtil._("商户分账业务" + operationType + "申请已提交成功,请耐心等待拉卡拉审核!")); + return Pair.of(true, "商户分账业务" + operationType + "申请已提交成功,请耐心等待拉卡拉审核!"); } catch (SDKException e) { log.error("申请拉卡拉分账业务出错,商户号: {}", merCupNo, e); - return Pair.of(false, I18nUtil._("申请拉卡拉分账业务出错!")); + return Pair.of(false, "申请拉卡拉分账业务出错!"); } catch (Exception e) { log.error("申请拉卡拉分账业务出现未预期异常,商户号: {}", merCupNo, e); - return Pair.of(false, I18nUtil._("申请拉卡拉分账业务出现未预期异常!")); + return Pair.of(false, "申请拉卡拉分账业务出现未预期异常!"); } } @@ -893,118 +906,160 @@ public class LakalaApiServiceImpl implements LakalaApiService { /** * 商户入网电子合同申请回调通知 + *

+ * 处理拉卡拉商户入网电子合同签署完成后的回调通知,更新合同状态并触发后续进件流程。 * 参考:https://o.lakala.com/#/home/document/detail?id=289 * - * @param request - * @return + * @param request HTTP请求对象,包含拉卡拉回调通知的参数 + * @return JSONObject 响应结果对象 */ @Override public JSONObject applyLedgerMerEcNotify(HttpServletRequest request) { - log.debug("商户入网电子合同申请回调通知开始"); - // 验签 + log.debug("商户入网电子合同申请回调通知开始处理"); + + // 1. 验签处理 Pair checkResult = LakalaUtil.chkLklApiNotifySign(request, lklNotifyCerPath, false); if (!checkResult.getFirst()) { - return JSONUtil.createObj().set("code", "FAIL").set("retMsg", checkResult.getSecond()); + log.warn("商户入网电子合同申请回调验签失败: {}", checkResult.getSecond()); + return JSONUtil.createObj().set("code", "FAIL").set("message", checkResult.getSecond()); } - String errMsg = "入网电子合同申请回调:"; + // 2. 初始化响应对象 JSONObject respData = new JSONObject(); respData.set("code", "FAIL").set("message", "返回数据转换异常!"); + // 3. 解析回调参数 JSONObject paramsJSON = JSONUtil.parseObj(checkResult.getSecond()); if (paramsJSON == null) { + log.warn("商户入网电子合同申请回调参数解析失败"); return respData; } + // 4. 提取关键参数 Long ecApplyId = paramsJSON.getLong("ecApplyId"); String ecNo = paramsJSON.getStr("ecNo"); String ecStatus = paramsJSON.getStr("ecStatus"); // COMPLETED + + // 5. 合同状态校验 if (ecStatus == null || !ecStatus.equals("COMPLETED")) { - log.debug("入网电子合同申请未签署完成!"); + log.debug("入网电子合同申请未签署完成,当前状态: {}", ecStatus); respData.put("message", "商户入网电子合同尚未签署,请稍候!"); return respData; } + // 6. 必要参数校验 if (ecApplyId == null || StrUtil.isBlank(ecNo)) { - log.error("入网电子合同申请回调:ecApplyId 为空"); - respData.put("message", "ecApplyId 返回空值!"); + log.error("入网电子合同申请回调参数缺失: ecApplyId={}, ecNo={}", ecApplyId, ecNo); + respData.put("message", "回调参数返回空值!"); return respData; } + // 7. 查询本地电子合同记录 LklLedgerEc lklLedgerEc = lklLedgerEcService.getByApplyId(ecApplyId, "", CommonConstant.Enable); if (lklLedgerEc == null) { - log.error("入网电子合同申请回调:找不到对应入网lklLedgerEc电子合同记录"); + log.error("入网电子合同申请回调找不到对应记录,ecApplyId: {}", ecApplyId); respData.put("message", "找不到对应入网电子合同记录!"); return respData; } + // 8. 获取商户ID并校验 Long mchId = lklLedgerEc.getMch_id(); if (ObjectUtil.isEmpty(mchId)) { - log.error("入网电子合同申请回调:找不到商家关联数据"); + log.error("入网电子合同申请回调商户ID为空,ecApplyId: {}", ecApplyId); respData.put("message", "找不到商家关联数据!"); return respData; } -// if ("COMPLETED".equals(lklLedgerEc.getEc_status())) { -// ShopMchEntry shopMchEntry = shopMchEntryService.shopMerchEntryById(lklLedgerEc.getMch_id()); -// if (shopMchEntry != null -// ) { -// log.error("入网电子合同申请回调:找不到对应商户信息"); -// respData.put("message", "找不到对应商户信息!"); -// return respData; -// } -// -// respData.put("code", "SUCCESS"); -// respData.put("message", "操作成功!"); -// log.info("商户入网电子合同申请回调:已处理成功,不需再重新处理"); -// return respData; -// } - - // 把 base64 合同文件,上传到 cos 服务器,返回 url 地址 - Pair ecFilePair = ledgerMerEcDownload(ecApplyId); - String ecCosFileUrl = ""; - String eclklFilePath = ""; - if (ecFilePair != null) { - ecCosFileUrl = ecFilePair.getFirst(); - eclklFilePath = ecFilePair.getSecond(); - } - - // 更改本地记录状态数据 - LklLedgerEc updRecord = new LklLedgerEc(); - updRecord.setEc_apply_id(ecApplyId); - updRecord.setEc_no(ecNo); - updRecord.setEc_name(paramsJSON.getStr("ecName")); - updRecord.setEc_file(ecCosFileUrl); // 合同本地文件COS URL链接 - updRecord.setLkl_file_path(eclklFilePath); - updRecord.setEc_status(paramsJSON.getStr("ecStatus")); - // 更新本地数据状态和合同编号、合同名字 - Boolean success = lklLedgerEcService.updateByApplyId(updRecord); - if (!success) { - shopMchEntryService.updateMerchEntryApprovalByMchId(mchId, CommonConstant.MCH_APPR_STA_LKL_NOPASS, "更新电子合同失败!"); - respData.set("code", "FAIL").set("message", "更新电子合同失败!"); + // 9. 查询商户入驻信息 + ShopMchEntry shopMchEntry = shopMchEntryService.shopMerchEntryById(mchId); + if (shopMchEntry == null) { + log.error("入网电子合同申请回调找不到商户入驻信息,mchId: {}", mchId); + respData.put("message", "找不到商家入驻关联数据!"); return respData; } - // 更新商家入驻表的合同编号,和签署地址,更改状态 - shopMchEntryService.updateMerchantLklEContractInfo(mchId, ecNo, paramsJSON.getStr("ecName"), lklLedgerEc.getResult_url(), ecCosFileUrl, eclklFilePath); + try { + // 10. 下载并上传电子合同文件 + log.debug("开始处理电子合同文件,ecApplyId: {}", ecApplyId); + Pair ecFilePair = ledgerMerEcDownload(ecApplyId); + String ecCosFileUrl = ""; + String eclklFilePath = ""; - // 商家电子合同签署完毕后,收到异步通知,触发拉卡拉商家进件(重要环节) - Pair resultPair = lklTkService.registrationMerchant(mchId); - if (!resultPair.getFirst()) { - errMsg = resultPair.getSecond(); - shopMchEntryService.updateMerchEntryApprovalByMchId(mchId, CommonConstant.MCH_APPR_STA_LKL_NOPASS, errMsg); - log.error(errMsg); - throw new ApiException(errMsg); + if (ecFilePair != null) { + ecCosFileUrl = ecFilePair.getFirst(); + eclklFilePath = ecFilePair.getSecond(); + log.debug("电子合同文件处理完成,COS地址: {}, 拉卡拉路径: {}", ecCosFileUrl, eclklFilePath); + } else { + log.warn("电子合同文件下载失败,ecApplyId: {}", ecApplyId); + } + + // 11. 更新本地电子合同记录状态 + LklLedgerEc updRecord = new LklLedgerEc(); + updRecord.setEc_apply_id(ecApplyId); + updRecord.setEc_no(ecNo); + updRecord.setEc_name(paramsJSON.getStr("ecName")); + updRecord.setEc_file(ecCosFileUrl); // 合同本地文件COS URL链接 + updRecord.setLkl_file_path(eclklFilePath); + updRecord.setEc_status(paramsJSON.getStr("ecStatus")); + + Boolean success = lklLedgerEcService.updateByApplyId(updRecord); + if (!success) { + String errorMsg = "更新电子合同记录失败"; + log.error("入网电子合同申请回调更新本地记录失败,mchId: {}", mchId); + shopMchEntryService.updateMerchEntryApprovalByMchId(mchId, CommonConstant.MCH_APPR_STA_LKL_NOPASS, errorMsg); + respData.set("code", "FAIL").set("message", errorMsg); + return respData; + } + + // 12. 更新商家入驻表的合同信息 + shopMchEntryService.updateMerchantLklEContractInfo( + mchId, + ecNo, + paramsJSON.getStr("ecName"), + lklLedgerEc.getResult_url(), + ecCosFileUrl, + eclklFilePath + ); + log.debug("商家入驻表电子合同信息更新完成,mchId: {}", mchId); + + // 13. 触发拉卡拉商家进件流程 + log.info("开始触发拉卡拉商家进件流程,mchId: {}", mchId); + Pair resultPair = lklTkService.registrationMerchant(mchId); + if (!resultPair.getFirst()) { + String errMsg = resultPair.getSecond(); + log.error("拉卡拉商家进件失败: {},mchId: {}", errMsg, mchId); + shopMchEntryService.updateMerchEntryApprovalByMchId(mchId, CommonConstant.MCH_APPR_STA_LKL_NOPASS, errMsg); + throw new ApiException(errMsg); + } + + // 14. 更新商户审批状态 + shopMchEntryService.updateMerchEntryApprovalByMchId( + mchId, + CommonConstant.MCH_APPR_STA_LKL_PADDING, + "已提交进件申请,请等待机构审核!" + ); + log.debug("商户审批状态更新完成,mchId: {}", mchId); + + // 15. 发送推送消息通知商家 + JSONObject payload = new JSONObject(); + payload.put("category", CommonConstant.PUSH_MSG_CATE_EC); + pushMessageService.noticeMerchantSignEcContract(shopMchEntry.getCreated_by(), payload, true); + log.debug("商家推送消息发送完成,userId: {}", shopMchEntry.getCreated_by()); + + // 16. 返回成功响应 + respData.put("code", "SUCCESS"); + respData.put("message", "操作成功!"); + log.info("商户入网电子合同申请回调处理成功,mchId: {}, ecApplyId: {}", mchId, ecApplyId); + return respData; + + } catch (Exception e) { + log.error("商户入网电子合同申请回调处理异常,mchId: {}", mchId, e); + respData.put("message", "系统处理异常: " + e.getMessage()); + return respData; } - - shopMchEntryService.updateMerchEntryApprovalByMchId(mchId, CommonConstant.MCH_APPR_STA_LKL_PADDING, "已提交进件申请,请等待机构审核!"); - - respData.put("code", "SUCCESS"); - respData.put("message", "操作成功!"); - log.info("商户入网电子合同申请回调:处理成功"); - return respData; } + /** * 商户入网盖章电子合同下载, 并上传到 cos 服务器 * @@ -1112,7 +1167,7 @@ public class LakalaApiServiceImpl implements LakalaApiService { public CommonResult applyLedgerMer(JSONObject paramsJSON) { // 检查参数 if (ObjectUtil.isEmpty(paramsJSON) || StrUtil.isBlank(paramsJSON.getStr("merCupNo"))) { - return CommonResult.failed("请填写商户号!"); + return CommonResult.failed("缺少商户号 merCupNo!"); } String merCupNo = paramsJSON.getStr("merCupNo"); @@ -1158,7 +1213,7 @@ public class LakalaApiServiceImpl implements LakalaApiService { // 验签 Pair checkResult = LakalaUtil.chkLklApiNotifySign(request, lklNotifyCerPath, false); if (!checkResult.getFirst()) { - return JSONUtil.createObj().set("code", "FAIL").set("retMsg", checkResult.getSecond()); + return JSONUtil.createObj().set("code", "FAIL").set("message", checkResult.getSecond()); } // 异步通知返回的数据 @@ -1211,7 +1266,7 @@ public class LakalaApiServiceImpl implements LakalaApiService { try { Boolean updateSuccess = lklLedgerMemberService.updateAuditResult( applyId, merInnerNo, merCupNo, entrustFileName, entrustFilePath, - auditStatus, auditStatusText, remark + auditStatus, auditStatusText, remark, checkResult.getSecond() ); if (!updateSuccess) { @@ -1444,166 +1499,189 @@ public class LakalaApiServiceImpl implements LakalaApiService { // 1. 参数校验(提前失败) if (paramsJSON == null) { log.warn("商家绑定分账接收方申请失败:绑定参数为空"); - return Pair.of(false, I18nUtil._("绑定参数为空")); + return Pair.of(false, "绑定参数为空"); } String merCupNo = paramsJSON.getStr("merCupNo"); if (StrUtil.isBlank(merCupNo)) { log.warn("商家绑定分账接收方申请失败:商户号(merCupNo)为空"); - return Pair.of(false, I18nUtil._("商户号(merCupNo)为空")); + return Pair.of(false, "商户号(merCupNo)为空"); } log.debug("商家绑定分账接收方申请参数:{}", paramsJSON); - // 2. 基础数据查询(提前失败) - log.debug("开始查询商户入驻信息,商户号: {}", merCupNo); - ShopMchEntry shopMchEntry = shopMchEntryService.getShopMerchEntryByMerCupNo(merCupNo); - if (shopMchEntry == null) { - log.warn("商家绑定分账接收方申请失败:商户入驻记录不存在,商户号: {}", merCupNo); - return Pair.of(false, I18nUtil._("商户入驻记录不存在")); - } - - // 进件记录 - log.debug("开始查询分账业务申请记录,商户号: {}", merCupNo); - LklLedgerMember lklLedgerMember = lklLedgerMemberService.getByMerCupNo(merCupNo); - if (lklLedgerMember == null || !CommonConstant.Enable.equals(lklLedgerMember.getAudit_status())) { - log.warn("商家绑定分账接收方申请失败:商家尚未申请分账业务或审核未通过,商户号: {}", merCupNo); - return Pair.of(false, I18nUtil._("商家尚未申请分账业务")); - } - - // 分账接收方列表 - log.debug("开始查询分账接收方列表"); - List receiverList = lklLedgerReceiverService.selectPlatformAnDistributorList(); - if (CollectionUtil.isEmpty(receiverList)) { - log.warn("商家绑定分账接收方申请失败:分账接收方信息为空"); - return Pair.of(false, I18nUtil._("分账接收方信息为空")); - } - - log.info("获取到 {} 个分账接收方,开始处理绑定申请", receiverList.size()); - - // 3. 公共参数准备(避免循环内重复计算) - // 正式上线的时候,调整 api 地址 - String domain = projectDomain; - if (isProdProject()) { - domain += "/api"; - } - - // 给拉卡拉通知的回调地址 - String retUrl = domain + "/mobile/shop/lakala/ledger/applyLedgerMerReceiverBindNotify"; - String entrustFileName = "小发同城合作协议书.pdf"; - String entrustFilePath = shopMchEntry.getLkl_ec_file_path(); // 拉卡拉的文件路径 - - int successCount = 0; - int totalCount = receiverList.size(); - - // 清理旧绑定数据 - // lklLedgerMerReceiverBindService.delByMchIdAndMerCupNo(shopMchEntry.getId(), merCupNo); - - // 4. 初始化SDK(建议移至类初始化或统一配置) - log.debug("初始化拉卡拉SDK"); - initLKLSDK(); - - // 5. 循环处理接收方绑定 - for (LklLedgerReceiver receiver : receiverList) { - try { - log.debug("开始处理分账接收方绑定,接收方编号: {}", receiver.getReceiver_no()); - - String receiverNo = receiver.getReceiver_no(); - - // 跳过已存在的绑定关系 - LklLedgerMerReceiverBind existingBind = lklLedgerMerReceiverBindService.getByCondition(merCupNo, receiverNo); - if (existingBind != null) { - log.info("分账绑定关系已存在,跳过处理:merCupNo={}, receiverNo={}", merCupNo, receiverNo); - successCount++; // 已存在的绑定视为成功 - continue; - } - - // 6. 构建请求参数 - String orderNo = StringUtils.genLklOrderNo(8); - log.debug("生成订单号: {}", orderNo); - - V2MmsOpenApiLedgerApplyBindRequest request = new V2MmsOpenApiLedgerApplyBindRequest(); - request.setOrderNo(orderNo); - request.setOrgCode(orgCode); - request.setVersion("1.0"); - request.setMerInnerNo(lklLedgerMember.getMer_inner_no()); - request.setMerCupNo(merCupNo); - request.setReceiverNo(receiverNo); - request.setEntrustFileName(entrustFileName); - request.setEntrustFilePath(entrustFilePath); - request.setRetUrl(retUrl); - - // 7. 记录请求参数 - log.debug("商家绑定分账接收方请求参数:{}", JSONUtil.toJsonStr(request)); - - // 8. 发送请求并处理响应 - log.info("向拉卡拉提交分账接收方绑定申请,订单号: {},商户号: {},接收方: {}", - orderNo, merCupNo, receiver.getReceiver_no()); - String responseStr = LKLSDK.httpPost(request); - JSONObject respJson = JSONUtil.parseObj(responseStr); - - if (respJson == null || !lklSuccessCode.equals(respJson.getStr("retCode"))) { - String errorMsg = respJson != null ? respJson.getStr("retMsg") : "无响应数据"; - log.error("绑定接收方拉卡拉响应失败,订单号: {},错误信息: {}", orderNo, errorMsg); - continue; // 单个失败不影响其他接收方处理 - } - - String applyId = (String) respJson.getByPath("respData.applyId"); - log.info("拉卡拉分账接收方绑定申请提交成功,订单号: {},商户号: {},接收方: {},申请ID: {}", - orderNo, merCupNo, receiverNo, applyId); - - if (StrUtil.isBlank(applyId)) { - log.error("拉卡拉分账接收方绑定申请提交失败,订单号: {},订单号: {},商户号: {},接收方: {} 申请ID为空", orderNo, merCupNo, receiverNo); - continue; - } - - // 9. 更新参数并保存记录 - paramsJSON.set("orderNo", orderNo); - paramsJSON.set("apply_id", applyId); - paramsJSON.set("org_code", orgCode); - paramsJSON.set("receiver_no", receiverNo); - paramsJSON.set("ret_url", retUrl); - paramsJSON.set("remark", respJson.getStr("retMsg")); - paramsJSON.set("platform_id", receiver.getPlatform_id()); - paramsJSON.set("mch_id", shopMchEntry.getId()); - - // 转换JSON键名格式并保存 - String snakeJson = StringUtils.convertCamelToSnake(paramsJSON.toString()); - LklLedgerMerReceiverBind bindRecord = JSONUtil.toBean(snakeJson, LklLedgerMerReceiverBind.class); - - log.debug("准备保存分账绑定记录"); - if (lklLedgerMerReceiverBindService.addOrUpdateByMerCupNoReceiverNo(bindRecord)) { - successCount++; - log.info("分账绑定记录保存成功,,订单号: {},商户号: {},接收方: {}", orderNo, merCupNo, receiverNo); - } else { - log.warn("分账绑定记录保存失败,订单号: {},商户号: {},接收方: {}", - orderNo, merCupNo, receiverNo); - } - - } catch (Exception e) { - log.error("处理分账绑定异常,商户号: {},接收方: {}", merCupNo, receiver.getReceiver_no(), e); - // 单个接收方处理失败,继续处理其他接收方 + try { + // 2. 基础数据查询(提前失败) + log.debug("开始查询商户入驻信息,商户号: {}", merCupNo); + ShopMchEntry shopMchEntry = shopMchEntryService.getShopMerchEntryByMerCupNo(merCupNo); + if (shopMchEntry == null) { + log.warn("商家绑定分账接收方申请失败:商户入驻记录不存在,商户号: {}", merCupNo); + return Pair.of(false, "商户入驻记录不存在"); } - } - // 10. 返回结果 - log.info("分账接收方绑定处理完成,成功: {},总数: {}", successCount, totalCount); - if (successCount == 0) { - log.error("商家绑定分账接收方全部失败"); - if (lklLedgerMember != null) { - shopMchEntryService.updateMerchEntryApprovalByMchId( - lklLedgerMember.getMch_id(), CommonConstant.MCH_APPR_STA_NOPASS, "商家绑定分账接收方失败" - ); + // 进件记录 + log.debug("开始查询分账业务申请记录,商户号: {}", merCupNo); + LklLedgerMember lklLedgerMember = lklLedgerMemberService.getByMerCupNo(merCupNo); + if (lklLedgerMember == null || !CommonConstant.Enable.equals(lklLedgerMember.getAudit_status())) { + log.warn("商家绑定分账接收方申请失败:商家尚未申请分账业务或审核未通过,商户号: {}", merCupNo); + return Pair.of(false, "商家尚未申请分账业务"); } - return Pair.of(false, "商家绑定分账接收方失败"); - } else if (successCount < totalCount) { - String message = String.format("商家绑定分账接收方,部分提交成功(%d/%d),待审核通知", successCount, totalCount); - log.info(message); - return Pair.of(true, message); - } else { - String message = "商家绑定分账接收方,全部提交成功,待审核通知"; - log.info(message); - return Pair.of(true, message); + + // 检查必要字段 + if (StrUtil.isBlank(lklLedgerMember.getMer_inner_no())) { + log.warn("商家绑定分账接收方申请失败:商户内部号mer_inner_no为空,商户号: {}", merCupNo); + lklLedgerMember.setMer_inner_no(""); + } + + // 分账接收方列表 + log.debug("开始查询分账接收方列表"); + List receiverList = lklLedgerReceiverService.selectPlatformAnDistributorList(); + if (CollectionUtil.isEmpty(receiverList)) { + log.warn("商家绑定分账接收方申请失败:分账接收方信息为空"); + return Pair.of(false, "分账接收方信息为空"); + } + + log.info("获取到 {} 个分账接收方,开始处理绑定申请", receiverList.size()); + + // 3. 公共参数准备(避免循环内重复计算) + // 正式上线的时候,调整 api 地址 + String domain = projectDomain; + if (isProdProject()) { + domain += "/api"; + } + + // 给拉卡拉通知的回调地址 + String retUrl = domain + "/mobile/shop/lakala/ledger/applyLedgerMerReceiverBindNotify"; + String entrustFileName = "小发同城合作协议书.pdf"; + String entrustFilePath = shopMchEntry.getLkl_ec_file_path(); // 拉卡拉的文件路径 + + // 检查文件路径 + if (StrUtil.isBlank(entrustFilePath)) { + log.warn("商家绑定分账接收方申请失败:电子合同文件路径为空,商户号: {}", merCupNo); + return Pair.of(false, "电子合同文件路径为空"); + } + + int successCount = 0; + int totalCount = receiverList.size(); + + // 清理旧绑定数据 + // lklLedgerMerReceiverBindService.delByMchIdAndMerCupNo(shopMchEntry.getId(), merCupNo); + + // 4. 初始化SDK(建议移至类初始化或统一配置) + log.debug("初始化拉卡拉SDK"); + initLKLSDK(); + + // 5. 循环处理接收方绑定 + for (LklLedgerReceiver receiver : receiverList) { + try { + // 检查接收方编号 + if (receiver == null || StrUtil.isBlank(receiver.getReceiver_no())) { + log.warn("接收方信息不完整或接收方编号为空,跳过处理,商户号: {}", merCupNo); + continue; + } + + log.debug("开始处理分账接收方绑定,接收方编号: {}", receiver.getReceiver_no()); + + String receiverNo = receiver.getReceiver_no(); + + // 跳过已存在的绑定关系 + LklLedgerMerReceiverBind existingBind = lklLedgerMerReceiverBindService.getByCondition(merCupNo, receiverNo); + if (existingBind != null) { + log.info("分账绑定关系已存在,跳过处理:merCupNo={}, receiverNo={}", merCupNo, receiverNo); + successCount++; // 已存在的绑定视为成功 + continue; + } + + // 6. 构建请求参数 + String orderNo = StringUtils.genLklOrderNo(8); + log.debug("生成订单号: {}", orderNo); + + V2MmsOpenApiLedgerApplyBindRequest request = new V2MmsOpenApiLedgerApplyBindRequest(); + request.setOrderNo(orderNo); + request.setOrgCode(orgCode); + request.setVersion("1.0"); + request.setMerInnerNo(lklLedgerMember.getMer_inner_no()); + request.setMerCupNo(merCupNo); + request.setReceiverNo(receiverNo); + request.setEntrustFileName(entrustFileName); + request.setEntrustFilePath(entrustFilePath); + request.setRetUrl(retUrl); + + // 7. 记录请求参数 + log.debug("商家绑定分账接收方请求参数:{}", JSONUtil.toJsonStr(request)); + + // 8. 发送请求并处理响应 + log.info("向拉卡拉提交分账接收方绑定申请,订单号: {},商户号: {},接收方: {}", + orderNo, merCupNo, receiver.getReceiver_no()); + String responseStr = LKLSDK.httpPost(request); + JSONObject respJson = JSONUtil.parseObj(responseStr); + + if (respJson == null || !lklSuccessCode.equals(respJson.getStr("retCode"))) { + String errorMsg = respJson != null ? respJson.getStr("retMsg", "未知错误") : "无响应数据"; + log.error("绑定接收方拉卡拉响应失败,订单号: {},错误信息: {}", orderNo, errorMsg); + continue; // 单个失败不影响其他接收方处理 + } + + String applyId = Convert.toStr(respJson.getByPath("respData.applyId")); + log.info("拉卡拉分账接收方绑定申请提交成功,订单号: {},商户号: {},接收方: {},申请ID: {}", + orderNo, merCupNo, receiverNo, applyId); + + if (StrUtil.isBlank(applyId)) { + log.error("拉卡拉分账接收方绑定申请提交失败,订单号: {},商户号: {},接收方: {} 申请ID为空", orderNo, merCupNo, receiverNo); + continue; + } + + // 9. 更新参数并保存记录 + paramsJSON.set("orderNo", orderNo); + paramsJSON.set("apply_id", applyId); + paramsJSON.set("org_code", orgCode); + paramsJSON.set("receiver_no", receiverNo); + paramsJSON.set("ret_url", retUrl); + paramsJSON.set("remark", respJson.getStr("retMsg")); + paramsJSON.set("platform_id", receiver.getPlatform_id()); + paramsJSON.set("mch_id", shopMchEntry.getId()); + + // 转换JSON键名格式并保存 + String snakeJson = StringUtils.convertCamelToSnake(paramsJSON.toString()); + LklLedgerMerReceiverBind bindRecord = JSONUtil.toBean(snakeJson, LklLedgerMerReceiverBind.class); + + log.debug("准备保存分账绑定记录"); + if (lklLedgerMerReceiverBindService.addOrUpdateByMerCupNoReceiverNo(bindRecord)) { + successCount++; + log.info("分账绑定记录保存成功,订单号: {},商户号: {},接收方: {}", orderNo, merCupNo, receiverNo); + } else { + log.warn("分账绑定记录保存失败,订单号: {},商户号: {},接收方: {}", + orderNo, merCupNo, receiverNo); + } + + } catch (Exception e) { + log.error("处理分账绑定异常,商户号: {},接收方: {}", merCupNo, receiver != null ? receiver.getReceiver_no() : "未知", e); + // 单个接收方处理失败,继续处理其他接收方 + } + } + + // 10. 返回结果 + log.info("分账接收方绑定处理完成,成功: {},总数: {}", successCount, totalCount); + if (successCount == 0) { + log.error("商家绑定分账接收方全部失败"); + if (lklLedgerMember != null) { + shopMchEntryService.updateMerchEntryApprovalByMchId( + lklLedgerMember.getMch_id(), CommonConstant.MCH_APPR_STA_NOPASS, "商家绑定分账接收方失败" + ); + } + return Pair.of(false, "商家绑定分账接收方失败"); + } else if (successCount < totalCount) { + String message = String.format("商家绑定分账接收方,部分提交成功(%d/%d),待审核通知", successCount, totalCount); + log.info(message); + return Pair.of(true, message); + } else { + String message = "商家绑定分账接收方,全部提交成功,待审核通知"; + log.info(message); + return Pair.of(true, message); + } + } catch (Exception e) { + log.error("商家绑定分账接收方申请异常,商户号: {}", merCupNo, e); + return Pair.of(false, "系统处理异常: " + e.getMessage()); } } @@ -1625,32 +1703,41 @@ public class LakalaApiServiceImpl implements LakalaApiService { Pair checkResult = LakalaUtil.chkLklApiNotifySign(request, lklNotifyCerPath, false); if (!checkResult.getFirst()) { log.warn("验签失败: {}", checkResult.getSecond()); - return JSONUtil.createObj().set("code", "FAIL").set("retMsg", checkResult.getSecond()); + return JSONUtil.createObj().set("code", "FAIL").set("message", checkResult.getSecond()); } // 2. 解析回调参数 JSONObject paramsJSON = JSONUtil.parseObj(checkResult.getSecond()); - log.debug("##### 商家绑定接收方回调参数:{} ####", paramsJSON); - // 检查参数是否包含必要的applyId - if (paramsJSON == null || StrUtil.isBlank(paramsJSON.getStr("applyId"))) { - log.error("商家绑定分账接收方通知数据有误"); + // 3. 参数校验 + if (paramsJSON == null) { + log.error("商家绑定分账接收方通知数据有误: 参数为空"); return JSONUtil.createObj().set("code", "FAIL").set("message", "商家绑定分账接收方通知数据有误!"); } - // 3. 提取核心参数 - String merCupNo = paramsJSON.getStr("merCupNo"); String applyId = paramsJSON.getStr("applyId"); + String merCupNo = paramsJSON.getStr("merCupNo"); String auditStatus = paramsJSON.getStr("auditStatus"); + if (StrUtil.isBlank(applyId)) { + log.error("商家绑定分账接收方通知数据有误: applyId为空"); + return JSONUtil.createObj().set("code", "FAIL").set("message", "商家绑定分账接收方通知数据有误!"); + } + // 4. 根据申请ID获取绑定记录 LklLedgerMerReceiverBind lklLedgerMerReceiverBind = lklLedgerMerReceiverBindService.getMerReceiverByApplyId(applyId); - if (lklLedgerMerReceiverBind == null || CheckUtil.isEmpty(lklLedgerMerReceiverBind.getMch_id())) { + if (lklLedgerMerReceiverBind == null) { log.warn("无法获取到绑定记录,applyId: {}", applyId); return JSONUtil.createObj().set("code", "FAIL").set("message", "无法获取到绑定记录!"); } + Long mchId = lklLedgerMerReceiverBind.getMch_id(); + if (CheckUtil.isEmpty(mchId)) { + log.warn("绑定记录中商户ID为空,applyId: {}", applyId); + return JSONUtil.createObj().set("code", "FAIL").set("message", "绑定记录数据异常!"); + } + // 5. 参数校验(防止空值) if (StrUtil.hasBlank(merCupNo, applyId, auditStatus)) { String errorMsg = String.format("关键参数缺失:merCupNo=%s, applyId=%s, auditStatus=%s", merCupNo, applyId, auditStatus); @@ -1668,16 +1755,23 @@ public class LakalaApiServiceImpl implements LakalaApiService { } // 7. 更新绑定记录的状态信息 + String merInnerNo = paramsJSON.getStr("merInnerNo"); + String receiverNo = paramsJSON.getStr("receiverNo"); + String entrustFileName = paramsJSON.getStr("entrustFileName"); + String entrustFilePath = paramsJSON.getStr("entrustFilePath"); + String auditStatusText = paramsJSON.getStr("auditStatusText"); + String remark = paramsJSON.getStr("remark"); + Boolean updateSuccess = lklLedgerMerReceiverBindService.updateAuditResult( applyId, - paramsJSON.getStr("merInnerNo"), + merInnerNo, merCupNo, - paramsJSON.getStr("receiverNo"), - paramsJSON.getStr("entrustFileName"), - paramsJSON.getStr("entrustFilePath"), + receiverNo, + entrustFileName, + entrustFilePath, auditStatus, - paramsJSON.getStr("auditStatusText"), - paramsJSON.getStr("remark") + auditStatusText, + remark ); if (!Boolean.TRUE.equals(updateSuccess)) { @@ -1685,20 +1779,22 @@ public class LakalaApiServiceImpl implements LakalaApiService { return JSONUtil.createObj().set("code", "FAIL").set("message", "更新绑定状态失败"); } - Long mchId = lklLedgerMerReceiverBind.getMch_id(); // 8. 成功后更新商户绑定状态为已绑定 shopMchEntryService.updateMulStatus(mchId, merCupNo, 0, 0, 0, 0, 0, 1, CommonConstant.MCH_APPR_STA_PASS); - // 9. 创建店铺,并初始化 - // 新建一个正式的已审核通过的店铺,不要抛异常,使用补偿机制,可以独立初始化店铺 - // 重要:包含了更改 merchEntryInfo 的状态, 使用法人、小微个人的手机号注册商家账号,作为店铺的管理员 - Pair retPair = shopStoreBaseService.covMerchEntryInfo2StoreInfo(mchId, false); - if (retPair.getFirst() <= 0) { - shopMchEntryService.updateMerchEntryApprovalByMchId(mchId, null, "创建初始化店铺失败:" + retPair.getSecond()); - log.error("进件成功,但初始化店铺失败: mchId={}, reason={}", mchId, retPair.getSecond()); - } else { - shopMchEntryService.updateMulStatus(mchId, merCupNo, 0, 0, 1, 0, 0, 0, 0); - log.info("进件成功,创建并初始化店铺成功!mchId={}", mchId); + // 9. 判断是否可以创建店铺了? + if (shopMchEntryService.canBuildingShopStore(mchId)) { + // 创建店铺,并初始化 + // 新建一个正式的已审核通过的店铺,不要抛异常,使用补偿机制,可以独立初始化店铺 + // 重要:包含了更改 merchEntryInfo 的状态, 使用法人、小微个人的手机号注册商家账号,作为店铺的管理员 + Pair retPair = shopStoreBaseService.covMerchEntryInfo2StoreInfo(mchId, false); + if (retPair.getFirst() <= 0) { + shopMchEntryService.updateMerchEntryApprovalByMchId(mchId, null, "创建并初始化店铺失败:" + retPair.getSecond()); + log.error("进件成功,但初始化店铺失败: mchId={}, reason={}", mchId, retPair.getSecond()); + } else { + shopMchEntryService.updateMulStatus(mchId, merCupNo, 0, 0, 1, 0, 0, 0, 0); + log.info("进件成功,创建并初始化店铺成功!mchId={}", mchId); + } } // 10. 检查商户绑定状态是否完成, 更改总的审核状态 @@ -1974,6 +2070,80 @@ public class LakalaApiServiceImpl implements LakalaApiService { } } + /** + * 商户分账业务信息查询 + * 参考:https://o.lakala.com/#/home/document/detail?id=381 + * + * @param merCupNo 银联商户号 + * @return 分账业务信息,查询失败时返回null + *

+ * 返回:{"merInnerNo":"4002025092404043540","merCupNo":"8226330541100HA","splitLowestRatio":20.0,"orgId":"980688","orgName":"桂平发发","splitStatus":"VALID","splitStatusText":"启用","splitRange":"ALL","sepFundSource":"TR","bindRelations":[{"merInnerNo":"4002025092404043540","merCupNo":"8226330541100HA","receiverNo":"SR2024000129789","receiverName":"桂平发发网络有限公司"}],"platformId":null,"splitLaunchMode":"MANUAL","splitRuleSource":null,"eleContractNo":"QY20250924613672961"} + */ + @Override + public JSONObject queryLedgerMer(String merCupNo) { + // 1. 参数校验 + if (StrUtil.isBlank(merCupNo)) { + log.warn("[分账商户查询] 参数校验失败:银联商户号为空"); + return null; + } + + // 2. 初始化拉卡拉SDK配置 + initLKLSDK(); + + try { + // 3. 构造请求参数 + String orderNo = StringUtils.genLklOrderNo(8); + V2MmsOpenApiLedgerQueryLedgerMerRequest request = new V2MmsOpenApiLedgerQueryLedgerMerRequest(); + request.setVersion("1.0"); + request.setOrderNo(orderNo); + request.setOrgCode(orgCode); + request.setMerCupNo(merCupNo); + + log.debug("[分账商户查询] 开始查询商户分账信息,商户号: {}", merCupNo); + + // 4. 发送HTTP请求到拉卡拉服务器 + String responseStr = LKLSDK.httpPost(request); + + // 5. 检查响应结果 + if (StrUtil.isBlank(responseStr)) { + log.warn("[分账商户查询] 服务器无返回值,商户号: {}", merCupNo); + return null; + } + + // 6. 解析响应JSON + JSONObject lakalaRespJSON = JSONUtil.parseObj(responseStr); + if (lakalaRespJSON == null) { + log.warn("[分账商户查询] 响应数据解析失败,商户号: {},响应内容: {}", merCupNo, responseStr); + return null; + } + + // 7. 检查业务状态码 + String code = lakalaRespJSON.getStr("retCode"); + if (!"000000".equals(code)) { + log.warn("[分账商户查询] 业务处理失败,商户号: {},错误码: {},错误信息: {}", + merCupNo, code, lakalaRespJSON.getStr("retMsg")); + return null; + } + + // 8. 检查响应数据 + JSONObject respData = lakalaRespJSON.getJSONObject("respData"); + if (respData == null) { + log.warn("[分账商户查询] 响应数据为空,商户号: {},完整响应: {}", merCupNo, responseStr); + return null; + } + + log.info("[分账商户查询] 查询成功,商户号: {}", merCupNo); + return respData; + + } catch (SDKException e) { + log.error("[分账商户查询] SDK调用异常,商户号: {}", merCupNo, e); + return null; + } catch (Exception e) { + log.error("[分账商户查询] 查询过程中发生未知异常,商户号: {}", merCupNo, e); + return null; + } + } + /** * 执行拉卡拉订单分账操作 @@ -2854,4 +3024,237 @@ public class LakalaApiServiceImpl implements LakalaApiService { return totalSuccessCount; } + /** + * 检测修复补全商户的商户分账业务信息及分账接收方绑定关系(分账业务申请异步通知的补偿机制) + * + * @param shopMchEntry 商户入驻信息实例 + * @return 是否处理成功 + */ + @Override + public Boolean checkAndFixLedgerMerApplyAndBindRelations(ShopMchEntry shopMchEntry) { + // 1. 输入参数校验 + if (shopMchEntry == null) { + log.warn("[分账业务补偿机制] 商户入驻信息为空"); + return false; + } + + if (!CommonConstant.Enable.equals(shopMchEntry.getStatus()) + || !CommonConstant.Enable.equals(shopMchEntry.getHas_ec_signed()) + || !CommonConstant.Enable.equals(shopMchEntry.getHas_apply_mer()) + ) { + log.warn("[分账业务补偿机制] 商户入驻未签署合同未进件,停止执行,mchId: {}", shopMchEntry.getId()); + return false; + } + + String merCupNo = shopMchEntry.getLkl_mer_cup_no(); + if (CheckUtil.isEmpty(merCupNo)) { + log.warn("[分账业务补偿机制] 商户未进件成功,停止执行,mchId: {}", shopMchEntry.getId()); + return false; + } + + // 2. 查询商户分账业务信息 + JSONObject ledgerMerInfo; + try { + ledgerMerInfo = queryLedgerMer(merCupNo); + } catch (Exception e) { + log.error("[分账业务补偿机制] 查询商户分账业务信息异常,merCupNo: {}", merCupNo, e); + return false; + } + + // 检查返回结果是否为空 + if (ObjectUtil.isEmpty(ledgerMerInfo)) { + log.warn("[分账业务补偿机制] 查询商户分账业务信息返回空,merCupNo: {}", merCupNo); + return false; + } + + String splitStatus = ledgerMerInfo.getStr("splitStatus"); + if (StrUtil.isBlank(splitStatus)) { + splitStatus = ""; + } + + if (!"VALID".equals(splitStatus)) { + log.warn("[分账业务补偿机制] 商户分账业务未通过或未申请,停止执行,merCupNo: {}, splitStatus: {}", merCupNo, splitStatus); + return false; + } + + log.info("[分账业务补偿机制] 开始处理商户分账信息修复,merCupNo: {}", merCupNo); + + // 3. 处理分账业务申请记录 + Long mchId = shopMchEntry.getId(); + String merInnerNo = ledgerMerInfo.getStr("merInnerNo"); + String orderNo = StringUtils.genLklOrderNo(8); + boolean memberUpdated = false; + + LklLedgerMember ledgerMember = lklLedgerMemberService.getByMerCupNo(merCupNo); + + try { + if (ObjectUtil.isEmpty(ledgerMember)) { + // 情况1: 分账业务申请记录不存在,创建新记录 + log.debug("[分账业务补偿机制] 分账业务申请记录不存在,创建新记录,merCupNo: {}", merCupNo); + + ledgerMember = new LklLedgerMember(); + ledgerMember.setOrg_code(ledgerMerInfo.getStr("orgId", orgCode)); + ledgerMember.setOrder_no(orderNo); + ledgerMember.setMer_cup_no(merCupNo); + ledgerMember.setMer_inner_no(StrUtil.blankToDefault(merInnerNo, "")); + ledgerMember.setContact_mobile(shopMchEntry.getLogin_mobile()); + ledgerMember.setSplit_lowest_ratio(ledgerMerInfo.getStr("splitLowestRatio", splitLowestRatio)); + ledgerMember.setSplit_entrust_file_name("商家分账授权委托书.pdf"); + ledgerMember.setSplit_entrust_file_path(StrUtil.blankToDefault(shopMchEntry.getLkl_ec_file_path(), "")); + ledgerMember.setSplit_range(ledgerMerInfo.getStr("splitRange", "ALL")); + ledgerMember.setEle_contract_no(ledgerMerInfo.getStr("eleContractNo", StrUtil.blankToDefault(shopMchEntry.getLkl_ec_no(), ""))); + ledgerMember.setSep_fund_source(ledgerMerInfo.getStr("sepFundSource", "TR")); + ledgerMember.setSplit_launch_mode(ledgerMerInfo.getStr("splitLaunchMode", "MANUAL")); + ledgerMember.setSettle_type("01"); + ledgerMember.setSplit_rule_source(""); + ledgerMember.setRet_url(projectDomain + "/api/mobile/shop/lakala/ledger/applyLedgerMerNotify"); + ledgerMember.setApply_id(orderNo); + ledgerMember.setAudit_status(CommonConstant.Enable); + ledgerMember.setAudit_status_text("审核通过"); + ledgerMember.setAudit_resp(ledgerMerInfo.toString()); + ledgerMember.setRemark("审核通过(补偿机制)"); + ledgerMember.setMch_id(mchId); + ledgerMember.setVersion("1.0"); + + memberUpdated = lklLedgerMemberService.addOrUpdateByMerCupNo(ledgerMember); + if (memberUpdated) { + log.info("[分账业务补偿机制] 成功创建分账业务申请记录,merCupNo: {}", merCupNo); + } else { + log.error("[分账业务补偿机制] 创建分账业务申请记录失败,merCupNo: {}", merCupNo); + return false; + } + + } else if (!CommonConstant.Enable.equals(ledgerMember.getAudit_status())) { + // 情况2: 分账业务申请记录存在但未审核通过,更新状态 + log.debug("[分账业务补偿机制] 分账业务申请记录存在但未审核通过,更新状态,merCupNo: {}", merCupNo); + + ledgerMember.setAudit_status(CommonConstant.Enable); + ledgerMember.setAudit_status_text("审核通过"); + ledgerMember.setAudit_resp(ledgerMerInfo.toString()); + ledgerMember.setRemark("审核通过(补偿机制)"); + ledgerMember.setMch_id(mchId); // 确保mch_id设置正确 + + memberUpdated = lklLedgerMemberService.addOrUpdateByMerCupNo(ledgerMember); + if (memberUpdated) { + log.info("[分账业务补偿机制] 成功更新分账业务申请记录状态,merCupNo: {}", merCupNo); + } else { + log.error("[分账业务补偿机制] 更新分账业务申请记录状态失败,merCupNo: {}", merCupNo); + return false; + } + } else { + // 情况3: 分账业务申请记录已审核通过 + log.debug("[分账业务补偿机制] 分账业务申请记录已审核通过,merCupNo: {}", merCupNo); + memberUpdated = true; + } + } catch (Exception e) { + log.error("[分账业务补偿机制] 处理分账业务申请记录异常,merCupNo: {}", merCupNo, e); + return false; + } + + // 4. 更新商户分账申请状态 + if (memberUpdated && !CommonConstant.Enable.equals(shopMchEntry.getHas_apply_split())) { + boolean updateResult = shopMchEntryService.updateMulStatus(mchId, merCupNo, 0, 0, 0, 1, 0, 0, CommonConstant.MCH_APPR_STA_LKL_PADDING); + if (updateResult) { + shopMchEntry.setHas_apply_split(CommonConstant.Enable); + log.info("[分账业务补偿机制] 成功更新商户分账申请状态,mchId: {}", mchId); + } else { + log.warn("[分账业务补偿机制] 更新商户分账申请状态失败,mchId: {}", mchId); + // 不返回false,因为这不影响主要流程 + } + } + + // 5. 处理分账接收方绑定关系 + int bindSuccessCount = 0; + JSONArray ledgerReceivers = ledgerMerInfo.getJSONArray("bindRelations"); + + if (CollUtil.isNotEmpty(ledgerReceivers)) { + log.debug("[分账业务补偿机制] 开始处理分账接收方绑定关系,绑定数量: {}", ledgerReceivers.size()); + + for (Object obj : ledgerReceivers) { + if (!(obj instanceof JSONObject)) { + continue; + } + + JSONObject ledgerReceiver = (JSONObject) obj; + if (ledgerReceiver == null) { + continue; + } + + String receiverMerCupNo = ledgerReceiver.getStr("merCupNo"); + String receiverNo = ledgerReceiver.getStr("receiverNo"); + + if (StrUtil.hasBlank(receiverMerCupNo, receiverNo)) { + log.warn("[分账业务补偿机制] 接收方信息不完整,跳过处理,receiverMerCupNo: {}, receiverNo: {}", receiverMerCupNo, receiverNo); + continue; + } + + LklLedgerMerReceiverBind ledgerMerReceiverBind = lklLedgerMerReceiverBindService.getByCondition(receiverMerCupNo, receiverNo); + boolean bindUpdated = false; + + try { + if (ObjectUtil.isEmpty(ledgerMerReceiverBind)) { + // 情况1: 绑定关系不存在,创建新记录 + log.debug("[分账业务补偿机制] 绑定关系不存在,创建新记录,merCupNo: {}, receiverNo: {}", receiverMerCupNo, receiverNo); + + ledgerMerReceiverBind = new LklLedgerMerReceiverBind(); + ledgerMerReceiverBind.setOrder_no(orderNo); + ledgerMerReceiverBind.setOrg_code(ledgerMerInfo.getStr("orgId", orgCode)); + ledgerMerReceiverBind.setMer_inner_no(ledgerReceiver.getStr("merInnerNo", "")); + ledgerMerReceiverBind.setMer_cup_no(receiverMerCupNo); + ledgerMerReceiverBind.setEntrust_file_name("小发同城合作协议书.pdf"); + ledgerMerReceiverBind.setEntrust_file_path(StrUtil.blankToDefault(shopMchEntry.getLkl_ec_file_path(), "")); + ledgerMerReceiverBind.setRet_url(projectDomain + "/api/mobile/shop/lakala/ledger/applyLedgerMerReceiverBindNotify"); + ledgerMerReceiverBind.setApply_id(orderNo); + ledgerMerReceiverBind.setPlatform_id(0L); + ledgerMerReceiverBind.setMch_id(mchId); + ledgerMerReceiverBind.setAudit_status("1"); + ledgerMerReceiverBind.setAudit_status_text("审核通过"); + ledgerMerReceiverBind.setRemark("审核通过(补偿机制)"); + ledgerMerReceiverBind.setVersion("1.0"); + + bindUpdated = lklLedgerMerReceiverBindService.addOrUpdateByMerCupNoReceiverNo(ledgerMerReceiverBind); + + } else if (!"1".equals(ledgerMerReceiverBind.getAudit_status())) { + // 情况2: 绑定关系存在但未审核通过,更新状态 + log.debug("[分账业务补偿机制] 绑定关系存在但未审核通过,更新状态,merCupNo: {}, receiverNo: {}", receiverMerCupNo, receiverNo); + + ledgerMerReceiverBind.setMch_id(mchId); + ledgerMerReceiverBind.setAudit_status("1"); + ledgerMerReceiverBind.setAudit_status_text("审核通过"); + ledgerMerReceiverBind.setRemark("审核通过(补偿机制)"); + + bindUpdated = lklLedgerMerReceiverBindService.addOrUpdateByMerCupNoReceiverNo(ledgerMerReceiverBind); + } else { + // 情况3: 绑定关系已审核通过 + log.debug("[分账业务补偿机制] 绑定关系已审核通过,merCupNo: {}, receiverNo: {}", receiverMerCupNo, receiverNo); + bindUpdated = true; + } + + if (bindUpdated) { + bindSuccessCount++; + } + } catch (Exception e) { + log.error("[分账业务补偿机制] 处理分账接收方绑定关系异常,merCupNo: {}, receiverNo: {}", receiverMerCupNo, receiverNo, e); + // 继续处理其他绑定关系 + } + } + } + + // 6. 更新商户分账接收方绑定状态 + if (bindSuccessCount > 0 && !CommonConstant.Enable.equals(shopMchEntry.getHas_bind_receiver())) { + boolean updateResult = shopMchEntryService.updateMulStatus(mchId, merCupNo, 0, 0, 0, 0, 0, 1, CommonConstant.MCH_APPR_STA_LKL_PADDING); + if (updateResult) { + shopMchEntry.setHas_bind_receiver(CommonConstant.Enable); + log.info("[分账业务补偿机制] 成功更新商户分账接收方绑定状态,mchId: {}, 成功处理数量: {}", mchId, bindSuccessCount); + } else { + log.warn("[分账业务补偿机制] 更新商户分账接收方绑定状态失败,mchId: {}", mchId); + // 不返回false,因为这不影响主要流程 + } + } + + log.info("[分账业务补偿机制] 处理完成,merCupNo: {}, memberUpdated: {}, bindSuccessCount: {}", merCupNo, memberUpdated, bindSuccessCount); + return true; + } + + } diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LklLedgerMemberServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LklLedgerMemberServiceImpl.java index 66657a65..be33de34 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LklLedgerMemberServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/service/impl/LklLedgerMemberServiceImpl.java @@ -101,10 +101,11 @@ public class LklLedgerMemberServiceImpl extends BaseServiceImpl noticeMerchantSignEcContract(Integer userId, JSONObject payload); + CompletableFuture noticeMerchantSignEcContract(Integer userId, JSONObject payload, Boolean isFinishNotice); /** diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/message/service/impl/PushMessageServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/message/service/impl/PushMessageServiceImpl.java index 1add3cd2..4d978a70 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/message/service/impl/PushMessageServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/message/service/impl/PushMessageServiceImpl.java @@ -33,7 +33,7 @@ import java.util.stream.Collectors; public class PushMessageServiceImpl implements PushMessageService { private static final String appName = "小发同城"; - + @Lazy @Resource private UniCloudPushService uniCloudPushService; @@ -109,7 +109,7 @@ public class PushMessageServiceImpl implements PushMessageService { @Async @Override - public CompletableFuture noticeMerchantSignEcContract(Integer userId, JSONObject payload) { + public CompletableFuture noticeMerchantSignEcContract(Integer userId, JSONObject payload, Boolean isFinishNotice) { try { // 获取商家的 cid 列表,确保用户 ID 有效 if (userId == null || userId <= 0) { @@ -137,9 +137,12 @@ public class PushMessageServiceImpl implements PushMessageService { return CompletableFuture.completedFuture(false); // 无有效 cid 无需推送 } + String title = isFinishNotice ? "通知您合同已签署完毕" : "邀请您签署入驻合同"; + String content = isFinishNotice ? "您的开店入驻合同已签署完成!" : "恭喜您!您的开店入驻申请已初步审核通过!请尽快登录小发商家 APP 平台签署电子合同,签署链接24小时内有效(逾期需重新提交申请)。如有疑问请联系客服,感谢您的支持!"; + Pair result = uniCloudPushService.sendPushMessageBatch(cidList, - appName + "邀请您签署入驻合同", - "恭喜您的开店入驻申请已审核通过!请尽快登录小发商家 APP 平台签署电子合同,签署链接24小时内有效(逾期需重新提交申请)。如有疑问请联系客服,感谢您的支持!", + appName + title, + content, payload); if (!result.getFirst()) { diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/sfexpress/controller/mobile/SFExpressController.java b/mall-shop/src/main/java/com/suisung/mall/shop/sfexpress/controller/mobile/SFExpressController.java index 2d1271a1..e87ffe94 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/sfexpress/controller/mobile/SFExpressController.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/sfexpress/controller/mobile/SFExpressController.java @@ -72,8 +72,8 @@ public class SFExpressController { @ApiOperation(value = "查询顺丰同城订单状态流", notes = "查询顺丰同城订单状态流") @RequestMapping(value = "/list-order-feed", method = RequestMethod.POST) public ThirdApiRes listOrderFeed(@RequestParam(name = "order_id", defaultValue = "") String orderId) { - if (StrUtil.isBlank(orderId) || orderId == "undefined" || orderId == "null") { - return new ThirdApiRes().fail(1003, "请求参数有误!"); + if (StrUtil.isBlank(orderId) || "undefined".equals(orderId) || "null".equals(orderId) || "none".equals(orderId)) { + return new ThirdApiRes().fail(1003, "缺少参数或参数有误!"); } Map params = new HashMap<>(); diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopMchEntryService.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopMchEntryService.java index ed5006b2..7ceeabc9 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopMchEntryService.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopMchEntryService.java @@ -293,6 +293,15 @@ public interface ShopMchEntryService { */ Boolean checkMerchEntryFinished(Long mchId); + + /** + * 检查商户入驻流程,当前是否可以创建店铺了? + * + * @param mchId 商户入驻ID + * @return boolean 可以创建店铺返回true,否则返回false + */ + Boolean canBuildingShopStore(Long mchId); + /** * 检查更新商户入驻店铺初始化状态 * diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopMchEntryServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopMchEntryServiceImpl.java index ad73f6f1..f47f5463 100644 --- a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopMchEntryServiceImpl.java +++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopMchEntryServiceImpl.java @@ -173,7 +173,6 @@ public class ShopMchEntryServiceImpl extends BaseServiceImpl 0; } + /** + * 重要(补偿机制),检查修复商户入驻店铺信息(商家账号关联入驻店铺Id,给商家账户创立公司员工账号和权限) + * + * @param mchId 商户入驻ID(必填) + * @return boolean 是否成功修复商户信息 + */ public Boolean checkAndFixMchStoreInfo(Long mchId) { // 1. 参数校验 if (CheckUtil.isEmpty(mchId)) { @@ -788,76 +793,86 @@ public class ShopMchEntryServiceImpl extends BaseServiceImpl result = shopStoreBaseService.covMerchEntryInfo2StoreInfo(mchId, false); if (result != null && result.getFirst() > 0) { - log.warn("商户信息修复成功,入驻ID: {}", mchId); + log.info("商户信息修复成功,入驻ID: {}", mchId); + // 修复成功后检查商户绑定状态是否完成,更改总的审核状态 + checkMerchEntryFinished(mchId); + return true; } else { log.error("商户信息修复失败,入驻ID: {}, 错误信息:{}", mchId, result != null ? result.getSecond() : "未知错误"); return false; } } + // 12. 如果信息完整,检查商户绑定状态是否完成,更改总的审核状态 + log.debug("商户信息完整,检查是否需要更新审核状态,入驻ID: {}", mchId); + checkMerchEntryFinished(mchId); + return true; } catch (Exception e) { log.error("商户信息修复异常,mchId: {}", mchId, e); @@ -1042,7 +1057,7 @@ public class ShopMchEntryServiceImpl extends BaseServiceImpl() - .eq("id", id) - .set("store_id", storeId).set("store_status", CommonConstant.Enable)); + try { + // 2. 构建更新条件 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq("id", mchId) + .set("store_id", storeId) + .set("store_status", CommonConstant.Enable) + .set("updated_at", new Date()); // 更新时间戳 + + // 3. 执行更新操作并返回结果 + boolean result = update(updateWrapper); + + if (result) { + log.info("商户店铺状态更新成功,mchId: {}, storeId: {}", mchId, storeId); + } else { + log.warn("商户店铺状态更新失败,未找到匹配记录,mchId: {}", mchId); + } + + return result; + + } catch (Exception e) { + // 4. 异常处理:记录异常信息 + log.error("更新商户店铺状态时发生异常,mchId: {}, storeId: {}", mchId, storeId, e); + return false; + } } + // /** // * 更新拉卡拉入网电子合同和签署地址 // * @@ -1738,6 +1776,7 @@ public class ShopMchEntryServiceImpl extends BaseServiceImpl 0) { + logger.warn("打包费超出范围: {}", packingFee); return CommonResult.failed("打包费请控制在0到10元范围"); } base.setPacking_fee(packingFee); + // 铃声开关 Integer ringtoneIsEnable = Convert.toInt(getParameter("ringtone_is_enable")); if (ringtoneIsEnable == null || ringtoneIsEnable <= 0) { ringtoneIsEnable = CommonConstant.Enable; } - base.setRingtone_is_enable(ringtoneIsEnable); + // 商家分账比例 + BigDecimal splitRatio = Convert.toBigDecimal(getParameter("split_ratio")); + if (CheckUtil.isNotEmpty(splitRatio)) { + if (splitRatio.compareTo(BigDecimal.valueOf(70)) >= 0 + && splitRatio.compareTo(BigDecimal.valueOf(99)) <= 0) { + base.setSplit_ratio(splitRatio); + } else { + logger.warn("分账比例超出范围: {}", splitRatio); + return CommonResult.failed("分账比例超出[70.00,99.00]范围,请修正"); + } + } // 百度坐标系BD09经纬度 转出 火星坐标系GCJ02经纬度 (因为数据库保存的经纬度统一是GCJ02经纬度,所以需要转换 ) base = bd09ToGcj02Gps(base); @@ -2397,10 +2415,20 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl 0) { + logger.warn("打包费超出范围: {}", packingFee); return CommonResult.failed("打包费请控制在0到10元范围"); } base.setPacking_fee(packingFee); @@ -2564,14 +2585,19 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl covMerchEntryInfo2StoreInfo(Long mchId, Boolean allowThrown) { - - // TODO 用法人、小微个人的手机号注册商家账号,作为店铺的管理员 - + // 参数校验 if (ObjectUtil.isEmpty(mchId)) { logger.error("生成店铺:入驻商家自增Id不能为空"); return Pair.of(0, "入驻商家自增Id不能为空"); } try { - + // 获取入驻信息 ShopMchEntry shopMchEntry = shopMchEntryService.shopMerchEntryById(mchId); if (shopMchEntry == null) { logger.error("生成店铺:入驻信息不能为空"); return Pair.of(0, "入驻信息不能为空"); } - // 如果 还没有签署入网电子合同且没有进件成功,则提示前置条件未满足 + // 前置条件检查 if (!CommonConstant.Enable.equals(shopMchEntry.getHas_ec_signed()) && !CommonConstant.Enable.equals(shopMchEntry.getHas_apply_mer())) { return Pair.of(0, "请先签署电子合同和商家进件,再创建店铺。"); } - // TODO 判断要不要给入驻的企业法人手机、小微联系人手机注册一个账号? - - // 从绑定关系中,获取入驻商家注册账号信息 - Integer userId = accountService.getUserBindConnectUserIdByCondition(shopMchEntry.getLogin_mobile(), BindCode.MOBILE, CommonConstant.USER_TYPE_MCH); + // 获取用户ID + Integer userId = accountService.getUserBindConnectUserIdByCondition( + shopMchEntry.getLogin_mobile(), BindCode.MOBILE, CommonConstant.USER_TYPE_MCH); if (userId == null) { logger.error("生成店铺:{}手机未注册商家账号", shopMchEntry.getLogin_mobile()); return Pair.of(0, "手机未注册商家账号!"); } - // 入驻时已经检查过店铺名称了,此处忽略 + // 检查店铺名称 ShopStoreBase shopStoreBase = findOneByStoreName(shopMchEntry.getStore_name()); if (shopStoreBase != null && StrUtil.isNotBlank(shopStoreBase.getLkl_merchant_no()) - && StrUtil.isNotBlank(shopStoreBase.getLkl_term_no()) - && !shopStoreBase.getStore_id().toString().equals(shopMchEntry.getStore_id())) { - // 如果店铺名称已存在,且店铺已经进件,且不等于当前入驻商家的店铺Id,提示店铺名称已存在 + && StrUtil.isNotBlank(shopMchEntry.getLkl_mer_cup_no()) + && !shopStoreBase.getLkl_merchant_no().equals(shopMchEntry.getLkl_mer_cup_no())) { logger.error("生成店铺:店铺名称已存在"); return Pair.of(0, "店铺名称已存在,请使用另一名称"); - } - // 新增 shop_store_base,shop_store_info,shop_store_company, shop_store_employee 待补充 - - // shop_store_base + // 创建或更新店铺基础信息 if (shopStoreBase == null) { shopStoreBase = new ShopStoreBase(); } - shopStoreBase.setUser_id(userId); // 店铺管理员用户Id + // 设置店铺基础信息(添加null检查) + shopStoreBase.setUser_id(userId); shopStoreBase.setStore_name(shopMchEntry.getStore_name()); - shopStoreBase.setStore_category_id(shopMchEntry.getBiz_category()); // 重要,店铺分类id,对应 shop_base_store_category 表的分类 - shopStoreBase.setStore_2nd_category_id(shopMchEntry.getBiz_second_category()); + shopStoreBase.setStore_category_id(shopMchEntry.getBiz_category()); + shopStoreBase.setStore_2nd_category_id( + shopMchEntry.getBiz_second_category() != null ? shopMchEntry.getBiz_second_category() : 0); - // 分账比例,最终提交给拉卡拉的分账比例是 20%。 - BigDecimal splitRatio = shopMchEntryService.getMchEntryRatioOrDefault(shopMchEntry.getBiz_category(), shopMchEntry.getBiz_second_category(), shopMchEntry.getSplit_ratio(), new BigDecimal(94)); + // 计算分账比例 + BigDecimal splitRatio = shopMchEntryService.getMchEntryRatioOrDefault( + shopMchEntry.getBiz_category(), + shopMchEntry.getBiz_second_category(), + shopMchEntry.getSplit_ratio(), + new BigDecimal(94)); + shopStoreBase.setSplit_ratio(splitRatio); + shopStoreBase.setPacking_fee(BigDecimal.ZERO); - shopStoreBase.setSplit_ratio(splitRatio); // 分账比例 - shopStoreBase.setPacking_fee(BigDecimal.ZERO);// 默认0元打包费 + // 处理图片信息 String storeFacadeImage = shopMchEntry.getFront_facade_image(); String storeLogoImage = shopMchEntry.getStore_logo(); if (StrUtil.isBlank(storeLogoImage)) { storeLogoImage = storeFacadeImage; } - shopStoreBase.setStore_logo(storeLogoImage); // 临时使用门面照片做logo + shopStoreBase.setStore_logo(storeLogoImage); + + // 处理地址信息(添加null检查) + String storeDistrict = shopMchEntry.getStore_district(); + if (storeDistrict != null) { + shopStoreBase.setStore_district_id(storeDistrict); + } + + String storeArea = shopMchEntry.getStore_area(); + if (storeArea != null) { + shopStoreBase.setStore_area(storeArea); + } - // 省市区记录有序列表 - shopStoreBase.setStore_district_id(shopMchEntry.getStore_district()); - shopStoreBase.setStore_area(shopMchEntry.getStore_area()); shopStoreBase.setStore_address(shopMchEntry.getStore_address()); shopStoreBase.setStore_longitude(shopMchEntry.getStore_longitude()); shopStoreBase.setStore_latitude(shopMchEntry.getStore_latitude()); - shopStoreBase.setStore_grade_id(1001); // 店铺等级,默认为普通店铺 - shopStoreBase.setStore_type(1);//店铺类型(ENUM): 1-卖家店铺; 2-供应商店铺 + shopStoreBase.setStore_grade_id(1001); + shopStoreBase.setStore_type(1); shopStoreBase.setStore_is_open(1); shopStoreBase.setStore_is_selfsupport(0); shopStoreBase.setStore_o2o_flag(0); shopStoreBase.setSubsite_id(0); - // 拉卡拉外部商户号 + // 设置拉卡拉信息 shopStoreBase.setLkl_merchant_no(shopMchEntry.getLkl_mer_cup_no()); - // 拉卡拉分配的终端号 shopStoreBase.setLkl_term_no(shopMchEntry.getLkl_term_no()); - shopStoreBase.setStore_state_id(StateCode.STORE_STATE_YES);//店铺资料信息状态(ENUM):3210-待完善资料; 3220-等待审核 ; 3230-资料审核没有通过;3240-资料审核通过,待付款 + shopStoreBase.setStore_state_id(StateCode.STORE_STATE_YES); shopStoreBase.setStore_time(DateUtil.date()); - shopStoreBase.setStore_end_time(System.currentTimeMillis() + 1000L * 60 * 60 * 24 * 365 * 5); // 5年 + shopStoreBase.setStore_end_time(System.currentTimeMillis() + 1000L * 60 * 60 * 24 * 365 * 5); + if (!save(shopStoreBase)) { logger.error("生成店铺:新增或更改店铺基本信息失败"); - if (allowThrown) { - throw new ApiException(I18nUtil._("新增或更改店铺基本信息失败")); + if (Boolean.TRUE.equals(allowThrown)) { + throw new ApiException("新增或更改店铺基本信息失败"); } return Pair.of(0, "新增或更改店铺基础信息失败"); } - // 保存后店铺Id + // 获取店铺ID Integer storeId = shopStoreBase.getStore_id(); + if (CheckUtil.isEmpty(storeId)) { + logger.error("生成店铺:店铺ID获取失败"); + return Pair.of(0, "店铺ID获取失败"); + } - // shop_store_info + // 创建店铺信息 ShopStoreInfo shopStoreInfo = new ShopStoreInfo(); shopStoreInfo.setStore_id(storeId); shopStoreInfo.setStore_start_time(DateUtil.date()); shopStoreInfo.setStore_end_time(DateUtil.offsetDay(DateUtil.date(), 365 * 5)); - shopStoreInfo.setStore_opening_hours("08:00"); - shopStoreInfo.setStore_close_hours("22:00"); - shopStoreInfo.setStore_discount(BigDecimal.valueOf(10));// 原价 + shopStoreInfo.setStore_opening_hours("07:30"); + shopStoreInfo.setStore_close_hours("23:00"); + shopStoreInfo.setStore_discount(BigDecimal.valueOf(10)); shopStoreInfo.setStore_banner(storeFacadeImage); - // 联系人手机号码 - String contact_mobile = StrUtil.isBlank(shopMchEntry.getLegal_person_mobile()) ? shopMchEntry.getLogin_mobile() : shopMchEntry.getLegal_person_mobile(); + // 处理联系人信息 + String contact_mobile = StrUtil.isNotBlank(shopMchEntry.getLegal_person_mobile()) ? + shopMchEntry.getLegal_person_mobile() : shopMchEntry.getLogin_mobile(); shopStoreInfo.setStore_tel(contact_mobile); shopStoreInfo.setContact_mobile(contact_mobile); shopStoreInfo.setContact_name(shopMchEntry.getContact_name()); - String websiteXFTC = "https://www.gpxscs.cn"; + // 构建幻灯片 JSONArray list = new JSONArray(); if (StrUtil.isNotBlank(storeFacadeImage)) { JSONObject slide = new JSONObject(); slide.put("img", storeFacadeImage); slide.put("name", "店铺门面照片"); slide.put("check", true); - slide.put("url", websiteXFTC); + slide.put("url", "https://www.gpxscs.cn"); list.put(slide); } if (StrUtil.isNotBlank(shopMchEntry.getEnvironment_image())) { @@ -3264,85 +3296,93 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl shopStoreEmployees = shopStoreEmployeeService.selectEmployeeByCondition(storeId, null, null); ShopStoreEmployee shopStoreEmployee = new ShopStoreEmployee(); shopStoreEmployee.setStore_id(storeId); shopStoreEmployee.setUser_id(userId); - shopStoreEmployee.setRights_group_id(""); // 店铺管理员,店铺 + shopStoreEmployee.setRights_group_id(""); shopStoreEmployee.setEmployee_is_kefu(CommonConstant.Enable); - if (CollUtil.isEmpty(shopStoreEmployees)) { // 添加管理员 - // shop_store_employee 店铺员工,添加管理员 + if (CollUtil.isEmpty(shopStoreEmployees)) { shopStoreEmployee.setEmployee_is_admin(CommonConstant.Enable); - } else { // 添加店员或管理员 + } else { shopStoreEmployees = shopStoreEmployeeService.selectEmployeeByCondition(storeId, userId, null); if (CollUtil.isEmpty(shopStoreEmployees)) { shopStoreEmployee.setEmployee_is_admin(CommonConstant.Disable); @@ -3353,13 +3393,13 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl resp = wxQrCodeService.genUnlimitedWxQrCode("pagesub/index/store", "store_id=" + storeId); if (StrUtil.isNotBlank(resp.getFirst())) { @@ -3367,286 +3407,347 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl 0 ? areaNames[areaNames.length - 1] : shopMchEntry.getStore_area().replace("/", ""); - sfExpressApiService.createSfExpressShop(storeId, shopMchEntry.getStore_name(), cityName, shopMchEntry.getStore_address(), shopMchEntry.getContact_name(), contact_mobile, shopMchEntry.getStore_longitude(), shopMchEntry.getStore_longitude()); + // 创建顺丰店铺(修复经纬度参数错误) + if (storeArea != null) { + String[] areaNames = storeArea.split("/"); + String cityName = areaNames.length > 0 ? areaNames[areaNames.length - 1] : storeArea.replace("/", ""); + sfExpressApiService.createSfExpressShop(storeId, shopMchEntry.getStore_name(), + cityName, shopMchEntry.getStore_address(), shopMchEntry.getContact_name(), + contact_mobile, shopMchEntry.getStore_longitude(), shopMchEntry.getStore_latitude()); + } return Pair.of(storeId, "新增成功"); } catch (Exception e) { logger.error("店铺生成失败", e); - if (allowThrown) { - throw new ApiException(I18nUtil._("店铺生成失败")); + if (Boolean.TRUE.equals(allowThrown)) { + throw new ApiException("店铺生成失败"); } return Pair.of(0, e.getMessage()); } } + /** * 初始化店长(店铺管理员)的权限组 * - * @param userId - * @param storeId + * @param userId 用户ID + * @param storeId 店铺ID + * @param allowThrown 是否允许抛出异常 */ private void initStoreExtraInfo(Integer userId, Integer storeId, Boolean allowThrown) { if (ObjectUtil.isNull(userId) || ObjectUtil.isNull(storeId)) { + log.warn("初始化店铺额外信息参数为空: userId={}, storeId={}", userId, storeId); return; } Date today = new Date(); // 当前时间 - // 初始化时添加一条店铺分析信息 - ShopStoreAnalytics storeAnalytics = shopStoreAnalyticsService.getByStoreId(storeId); - if (storeAnalytics == null) { - storeAnalytics = new ShopStoreAnalytics(); - storeAnalytics.setStore_id(storeId); - if (!shopStoreAnalyticsService.add(storeAnalytics)) { - if (allowThrown) { + try { + // 初始化时添加一条店铺分析信息 + ShopStoreAnalytics storeAnalytics = shopStoreAnalyticsService.getByStoreId(storeId); + if (storeAnalytics == null) { + storeAnalytics = new ShopStoreAnalytics(); + storeAnalytics.setStore_id(storeId); + if (!shopStoreAnalyticsService.add(storeAnalytics)) { + String errorMsg = "初始化店铺分析信息失败"; + if (Boolean.TRUE.equals(allowThrown)) { + throw new ApiException(ResultCode.FAILED); + } + log.error(errorMsg); + return; + } + } + + // 初始化店铺商品标签 + QueryWrapper tagQueryWrapper = new QueryWrapper<>(); + tagQueryWrapper.orderByAsc("product_tag_id"); + Page baseProductTagPage = shopBaseProductTagService.lists(tagQueryWrapper, 1, 5); + + if (baseProductTagPage != null && CollUtil.isNotEmpty(baseProductTagPage.getRecords())) { + List storeProductTagList = new ArrayList<>(); + for (ShopBaseProductTag tag : baseProductTagPage.getRecords()) { + if (tag != null) { + ShopStoreProductTag shopStoreProductTag = new ShopStoreProductTag(); + shopStoreProductTag.setProduct_tag_id(tag.getProduct_tag_id()); + shopStoreProductTag.setStore_id(storeId); + shopStoreProductTag.setProduct_tag_time(today); + shopStoreProductTag.setStore_product_tag_buildin(1); + storeProductTagList.add(shopStoreProductTag); + } + } + + if (CollUtil.isNotEmpty(storeProductTagList)) { + if (!shopStoreProductTagService.saveOrUpdate(storeProductTagList)) { + String errorMsg = "初始化店铺商品标签失败"; + if (Boolean.TRUE.equals(allowThrown)) { + throw new ApiException(ResultCode.FAILED); + } + log.error(errorMsg); + return; + } + } + } + + // 初始化默认店铺仓库 + InvoicingWarehouseBase invoicingWarehouseBase = new InvoicingWarehouseBase(); + invoicingWarehouseBase.setWarehouse_name("默认"); + invoicingWarehouseBase.setStore_id(storeId); + invoicingWarehouseBase.setWarehouse_address(""); + invoicingWarehouseBase.setWarehouse_number(""); + invoicingWarehouseBase.setWarehouse_contact(""); + + if (!invoicingWarehouseBaseService.saveOrUpdate(invoicingWarehouseBase)) { + String errorMsg = "初始化默认店铺仓库失败"; + if (Boolean.TRUE.equals(allowThrown)) { throw new ApiException(ResultCode.FAILED); } - log.error("初始化店铺分析信息失败"); + log.error(errorMsg); + return; } - } - // 初始化店铺商品标签 - QueryWrapper tagQueryWrapper = new QueryWrapper<>(); - tagQueryWrapper.orderByAsc("product_tag_id"); - Page base_product_tag_row = shopBaseProductTagService.lists(tagQueryWrapper, 1, 5); - List store_product_tag_row = new ArrayList<>(); - for (ShopBaseProductTag teg : base_product_tag_row.getRecords()) { - ShopStoreProductTag shopStoreProductTag = new ShopStoreProductTag(); - store_product_tag_row.add(shopStoreProductTag); - shopStoreProductTag.setProduct_tag_id(teg.getProduct_tag_id()); - shopStoreProductTag.setStore_id(storeId); - shopStoreProductTag.setProduct_tag_time(today); - shopStoreProductTag.setStore_product_tag_buildin(1); - } + // 初始化默认权限 + Page page = shopStoreEmployeeRightsBaseService.listKey(new QueryWrapper<>(), 1, ConfigConstant.MAX_LIST_NUM); + List rightsGroupRightsIds = new ArrayList<>(); - if (CollUtil.isNotEmpty(store_product_tag_row)) { - if (!shopStoreProductTagService.saveOrUpdate(store_product_tag_row)) { - if (allowThrown) { + if (page != null && CollUtil.isNotEmpty(page.getRecords())) { + rightsGroupRightsIds = Convert.toList(Integer.class, page.getRecords()); + } + + List shopStoreEmployeeRightsGroups = new ArrayList<>(); + String strRightsGroupRightsIds = CollUtil.join(rightsGroupRightsIds, ","); + + // 创建各种角色权限组 + ShopStoreEmployeeRightsGroup shopManager = new ShopStoreEmployeeRightsGroup(); + shopManager.setStore_id(storeId); + shopManager.setRights_group_rights_ids(strRightsGroupRightsIds); + shopManager.setRights_group_name("店铺管理员"); // Store Owner + shopManager.setRights_group_rights_data(""); // Store Owner + shopStoreEmployeeRightsGroups.add(shopManager); + + ShopStoreEmployeeRightsGroup operationsManager = new ShopStoreEmployeeRightsGroup(); + operationsManager.setStore_id(storeId); + operationsManager.setRights_group_rights_ids(strRightsGroupRightsIds); + operationsManager.setRights_group_name("运营经理"); // Store Owner + operationsManager.setRights_group_rights_data(""); // Store Owner + shopStoreEmployeeRightsGroups.add(operationsManager); + + ShopStoreEmployeeRightsGroup orderReviewer = new ShopStoreEmployeeRightsGroup(); + orderReviewer.setStore_id(storeId); + orderReviewer.setRights_group_rights_ids(strRightsGroupRightsIds); + orderReviewer.setRights_group_name("订单审核员"); // Store Owner + orderReviewer.setRights_group_rights_data(""); // Store Owner + shopStoreEmployeeRightsGroups.add(orderReviewer); + + ShopStoreEmployeeRightsGroup financialAuditor = new ShopStoreEmployeeRightsGroup(); + financialAuditor.setStore_id(storeId); + financialAuditor.setRights_group_rights_ids(strRightsGroupRightsIds); + financialAuditor.setRights_group_name("财务审核员"); // Store Owner + financialAuditor.setRights_group_rights_data(""); // Store Owner + shopStoreEmployeeRightsGroups.add(financialAuditor); + + ShopStoreEmployeeRightsGroup shippingAuditor = new ShopStoreEmployeeRightsGroup(); + shippingAuditor.setStore_id(storeId); + shippingAuditor.setRights_group_rights_ids(strRightsGroupRightsIds); + shippingAuditor.setRights_group_name("发货审核员"); // Store Owner + shippingAuditor.setRights_group_rights_data(""); // Store Owner + shopStoreEmployeeRightsGroups.add(shippingAuditor); + + ShopStoreEmployeeRightsGroup businessManager = new ShopStoreEmployeeRightsGroup(); + businessManager.setStore_id(storeId); + businessManager.setRights_group_rights_ids(strRightsGroupRightsIds); + businessManager.setRights_group_name("业务经理"); // Store Owner + businessManager.setRights_group_rights_data(""); // Store Owner + shopStoreEmployeeRightsGroups.add(businessManager); + + ShopStoreEmployeeRightsGroup warehouseManager = new ShopStoreEmployeeRightsGroup(); + warehouseManager.setStore_id(storeId); + warehouseManager.setRights_group_rights_ids(strRightsGroupRightsIds); + warehouseManager.setRights_group_name("仓库管理员"); // Store Owner + warehouseManager.setRights_group_rights_data(""); // Store Owner + shopStoreEmployeeRightsGroups.add(warehouseManager); + + ShopStoreEmployeeRightsGroup dataMaintainer = new ShopStoreEmployeeRightsGroup(); + dataMaintainer.setStore_id(storeId); + dataMaintainer.setRights_group_rights_ids(strRightsGroupRightsIds); + dataMaintainer.setRights_group_name("资料维护员"); // Store Owner + dataMaintainer.setRights_group_rights_data(""); // Store Owner + shopStoreEmployeeRightsGroups.add(dataMaintainer); + + ShopStoreEmployeeRightsGroup customerService = new ShopStoreEmployeeRightsGroup(); + customerService.setStore_id(storeId); + customerService.setRights_group_rights_ids(strRightsGroupRightsIds); + customerService.setRights_group_name("客服"); // Store Owner + customerService.setRights_group_rights_data(""); // Store Owner + shopStoreEmployeeRightsGroups.add(customerService); + + ShopStoreEmployeeRightsGroup extension1 = new ShopStoreEmployeeRightsGroup(); + extension1.setStore_id(storeId); + extension1.setRights_group_rights_ids(strRightsGroupRightsIds); + extension1.setRights_group_name("扩展1"); // Store Owner + extension1.setRights_group_rights_data(""); // Store Owner + shopStoreEmployeeRightsGroups.add(extension1); + + ShopStoreEmployeeRightsGroup extension2 = new ShopStoreEmployeeRightsGroup(); + extension2.setStore_id(storeId); + extension2.setRights_group_rights_ids(strRightsGroupRightsIds); + extension2.setRights_group_name("扩展2"); // Store Owner + extension2.setRights_group_rights_data(""); // Store Owner + shopStoreEmployeeRightsGroups.add(extension2); + + if (!shopStoreEmployeeRightsGroupService.saveOrUpdate(shopStoreEmployeeRightsGroups)) { + String errorMsg = "初始化店铺员工默认权限失败"; + if (Boolean.TRUE.equals(allowThrown)) { throw new ApiException(ResultCode.FAILED); } - log.error("初始化店铺商品标签失败"); + log.error(errorMsg); + return; } - } - //初始化默认店铺仓库 - InvoicingWarehouseBase invoicingWarehouseBase = new InvoicingWarehouseBase(); - invoicingWarehouseBase.setWarehouse_name(I18nUtil._("默认")); - invoicingWarehouseBase.setStore_id(storeId); - invoicingWarehouseBase.setWarehouse_address(""); - invoicingWarehouseBase.setWarehouse_number(""); - invoicingWarehouseBase.setWarehouse_contact(""); - if (!invoicingWarehouseBaseService.saveOrUpdate(invoicingWarehouseBase)) { - if (allowThrown) { - throw new ApiException(ResultCode.FAILED); - } - log.error("初始化默认店铺仓库失败"); - } + // 添加店铺到用户 + AccountUserBase accountUserBase = new AccountUserBase(); + List rightsGroupId = shopStoreEmployeeRightsGroups.stream() + .map(ShopStoreEmployeeRightsGroup::getRights_group_id) + .filter(Objects::nonNull) + .collect(Collectors.toList()); - //初始化默认权限 - Page page = shopStoreEmployeeRightsBaseService.listKey(new QueryWrapper<>(), 1, ConfigConstant.MAX_LIST_NUM); + if (CollUtil.isNotEmpty(rightsGroupId)) { + // 初始化雇员信息 + UpdateWrapper queryWrapper = new UpdateWrapper<>(); + queryWrapper.eq("user_id", userId).eq("store_id", storeId) + .set("rights_group_id", CollUtil.join(rightsGroupId, ",")) + .set("employee_is_admin", CommonConstant.Enable) + .set("employee_is_kefu", CommonConstant.Enable); - List rights_group_rights_ids = Convert.toList(Integer.class, page.getRecords()); - List shopStoreEmployeeRightsGroups = new ArrayList<>(); - String str_rights_group_rights_ids = CollUtil.join(rights_group_rights_ids, ","); - - ShopStoreEmployeeRightsGroup shopManager = new ShopStoreEmployeeRightsGroup(); - shopManager.setStore_id(storeId); - shopManager.setRights_group_rights_ids(str_rights_group_rights_ids); - shopManager.setRights_group_name(I18nUtil._("店铺管理员")); //Store Owner - shopManager.setRights_group_rights_data(""); //Store Owner - shopStoreEmployeeRightsGroups.add(shopManager); - - ShopStoreEmployeeRightsGroup operationsManager = new ShopStoreEmployeeRightsGroup(); - operationsManager.setStore_id(storeId); - operationsManager.setRights_group_rights_ids(str_rights_group_rights_ids); - operationsManager.setRights_group_name(I18nUtil._("运营经理")); //Store Owner - operationsManager.setRights_group_rights_data(""); //Store Owner - shopStoreEmployeeRightsGroups.add(operationsManager); - - ShopStoreEmployeeRightsGroup orderReviewer = new ShopStoreEmployeeRightsGroup(); - orderReviewer.setStore_id(storeId); - orderReviewer.setRights_group_rights_ids(str_rights_group_rights_ids); - orderReviewer.setRights_group_name(I18nUtil._("订单审核员")); //Store Owner - orderReviewer.setRights_group_rights_data(""); //Store Owner - shopStoreEmployeeRightsGroups.add(orderReviewer); - - ShopStoreEmployeeRightsGroup financialAuditor = new ShopStoreEmployeeRightsGroup(); - financialAuditor.setStore_id(storeId); - financialAuditor.setRights_group_rights_ids(str_rights_group_rights_ids); - financialAuditor.setRights_group_name(I18nUtil._("财务审核员")); //Store Owner - financialAuditor.setRights_group_rights_data(""); //Store Owner - shopStoreEmployeeRightsGroups.add(financialAuditor); - - ShopStoreEmployeeRightsGroup shippingAuditor = new ShopStoreEmployeeRightsGroup(); - shippingAuditor.setStore_id(storeId); - shippingAuditor.setRights_group_rights_ids(str_rights_group_rights_ids); - shippingAuditor.setRights_group_name(I18nUtil._("发货审核员")); //Store Owner - shippingAuditor.setRights_group_rights_data(""); //Store Owner - shopStoreEmployeeRightsGroups.add(shippingAuditor); - - ShopStoreEmployeeRightsGroup businessManager = new ShopStoreEmployeeRightsGroup(); - businessManager.setStore_id(storeId); - businessManager.setRights_group_rights_ids(str_rights_group_rights_ids); - businessManager.setRights_group_name(I18nUtil._("业务经理")); //Store Owner - businessManager.setRights_group_rights_data(""); //Store Owner - shopStoreEmployeeRightsGroups.add(businessManager); - - ShopStoreEmployeeRightsGroup warehouseManager = new ShopStoreEmployeeRightsGroup(); - warehouseManager.setStore_id(storeId); - warehouseManager.setRights_group_rights_ids(str_rights_group_rights_ids); - warehouseManager.setRights_group_name(I18nUtil._("仓库管理员")); //Store Owner - warehouseManager.setRights_group_rights_data(""); //Store Owner - shopStoreEmployeeRightsGroups.add(warehouseManager); - - ShopStoreEmployeeRightsGroup dataMaintainer = new ShopStoreEmployeeRightsGroup(); - dataMaintainer.setStore_id(storeId); - dataMaintainer.setRights_group_rights_ids(str_rights_group_rights_ids); - dataMaintainer.setRights_group_name(I18nUtil._("资料维护员")); //Store Owner - dataMaintainer.setRights_group_rights_data(""); //Store Owner - shopStoreEmployeeRightsGroups.add(dataMaintainer); - - ShopStoreEmployeeRightsGroup customerService = new ShopStoreEmployeeRightsGroup(); - customerService.setStore_id(storeId); - customerService.setRights_group_rights_ids(str_rights_group_rights_ids); - customerService.setRights_group_name(I18nUtil._("客服")); //Store Owner - customerService.setRights_group_rights_data(""); //Store Owner - shopStoreEmployeeRightsGroups.add(customerService); - - ShopStoreEmployeeRightsGroup extension1 = new ShopStoreEmployeeRightsGroup(); - extension1.setStore_id(storeId); - extension1.setRights_group_rights_ids(str_rights_group_rights_ids); - extension1.setRights_group_name(I18nUtil._("扩展1")); //Store Owner - extension1.setRights_group_rights_data(""); //Store Owner - shopStoreEmployeeRightsGroups.add(extension1); - - ShopStoreEmployeeRightsGroup extension2 = new ShopStoreEmployeeRightsGroup(); - extension2.setStore_id(storeId); - extension2.setRights_group_rights_ids(str_rights_group_rights_ids); - extension2.setRights_group_name(I18nUtil._("扩展2")); //Store Owner - extension2.setRights_group_rights_data(""); //Store Owner - shopStoreEmployeeRightsGroups.add(extension2); - - if (!shopStoreEmployeeRightsGroupService.saveOrUpdate(shopStoreEmployeeRightsGroups)) { - if (allowThrown) { - throw new ApiException(ResultCode.FAILED); - } - log.error("初始化店铺员工默认权限失败"); - } - - // 添加店铺到用户 - AccountUserBase accountUserBase = new AccountUserBase(); - List rights_group_id = shopStoreEmployeeRightsGroups.stream().map(s -> s.getRights_group_id()).collect(Collectors.toList()); - if (CollUtil.isNotEmpty(rights_group_id)) { - // 初始化雇员信息 - UpdateWrapper queryWrapper = new UpdateWrapper<>(); - queryWrapper.eq("user_id", userId).eq("store_id", storeId) - .set("rights_group_id", CollUtil.join(rights_group_id, ",")) - .set("employee_is_admin", CommonConstant.Enable) - .set("employee_is_kefu", CommonConstant.Enable); - if (!shopStoreEmployeeService.update(queryWrapper)) { - if (allowThrown) { - throw new ApiException(I18nUtil._("设置店铺管理员权限失败")); + if (!shopStoreEmployeeService.update(queryWrapper)) { + String errorMsg = "设置店铺管理员权限失败"; + if (Boolean.TRUE.equals(allowThrown)) { + throw new ApiException(errorMsg); + } + log.error(errorMsg); + return; } - log.error("设置店铺管理员权限失败!"); + + // 初始化商家角色(默认 店铺管理员角色) + String userRightsGroupId = Convert.toStr(rightsGroupId.get(0)); + accountUserBase.setRights_group_id(StrUtil.join(",", userRightsGroupId, "2")); } - // todo 初始化商家角色(默认 店铺管理员角色) - String user_rights_group_id = Convert.toStr(rights_group_id.get(0)); - accountUserBase.setRights_group_id(StrUtil.join(",", user_rights_group_id, 2)); - } + // 用法人、小微个人的手机号注册商家账号,作为店铺的管理员 + accountUserBase.setUser_id(userId); - // 用法人、小微个人的手机号注册商家账号,作为店铺的管理员 - accountUserBase.setUser_id(userId); - String storeIds = appendStoreIdToAccount(userId, storeId); - accountUserBase.setStore_ids(storeIds); // 重要,给用户添加上这个店铺的归属权 - if (!accountService.saveOrUpdateUserBase(accountUserBase)) { - if (allowThrown) { - throw new ApiException(I18nUtil._("店铺关联到用户失败")); + // 修复:需要实现 appendStoreIdToAccount 方法或替换为正确的逻辑 + String storeIds = appendStoreIdToAccount(userId, storeId); + accountUserBase.setStore_ids(storeIds); // 重要,给用户添加上这个店铺的归属权 + + if (!accountService.saveOrUpdateUserBase(accountUserBase)) { + String errorMsg = "店铺关联到用户失败"; + if (Boolean.TRUE.equals(allowThrown)) { + throw new ApiException(errorMsg); + } + log.error(errorMsg); + return; } - log.error("店铺关联到用户失败!"); - } - // 添加默认运输模板 - ShopStoreTransportType shopStoreTransportType = new ShopStoreTransportType(); - shopStoreTransportType.setTransport_type_name(I18nUtil._("通用全免")); // 模板名称 - shopStoreTransportType.setStore_id(storeId); // 所属店铺 - shopStoreTransportType.setTransport_type_pricing_method(1); // 计费规则(ENUM):1-按件数;2-按重量;3-按体积 - shopStoreTransportType.setTransport_type_time(today); - shopStoreTransportType.setTransport_type_freight_free(BigDecimal.ZERO); // 免运费额度 - shopStoreTransportType.setTransport_type_free(1); - if (!shopStoreTransportTypeService.saveOrUpdate(shopStoreTransportType)) { - if (allowThrown) { - throw new ApiException(I18nUtil._("添加运输模板失败")); + // 添加默认运输模板 + ShopStoreTransportType shopStoreTransportType = new ShopStoreTransportType(); + shopStoreTransportType.setTransport_type_name("通用全免"); // 模板名称 + shopStoreTransportType.setStore_id(storeId); // 所属店铺 + shopStoreTransportType.setTransport_type_pricing_method(1); // 计费规则(ENUM):1-按件数;2-按重量;3-按体积 + shopStoreTransportType.setTransport_type_time(today); + shopStoreTransportType.setTransport_type_freight_free(BigDecimal.ZERO); // 免运费额度 + shopStoreTransportType.setTransport_type_free(1); + + if (!shopStoreTransportTypeService.saveOrUpdate(shopStoreTransportType)) { + String errorMsg = "添加运输模板失败"; + if (Boolean.TRUE.equals(allowThrown)) { + throw new ApiException(errorMsg); + } + log.error(errorMsg); + return; } - log.error("添加运输模板失败!"); - } - // 店铺配置 - ShopStoreConfig shopStoreConfig = new ShopStoreConfig(); - shopStoreConfig.setStore_id(storeId); - List sc_order_process = Arrays.asList( - StateCode.ORDER_PROCESS_PAY,//支付 - StateCode.ORDER_PROCESS_OUT, //出库审核 - StateCode.ORDER_PROCESS_SHIPPED,//发货确认 - StateCode.ORDER_PROCESS_RECEIVED); + // 店铺配置 + ShopStoreConfig shopStoreConfig = new ShopStoreConfig(); + shopStoreConfig.setStore_id(storeId); + List scOrderProcess = Arrays.asList( + StateCode.ORDER_PROCESS_PAY, // 支付 + StateCode.ORDER_PROCESS_OUT, // 出库审核 + StateCode.ORDER_PROCESS_SHIPPED, // 发货确认 + StateCode.ORDER_PROCESS_RECEIVED // 收货确认 + ); - String str_sc_order_process = CollUtil.join(sc_order_process, ","); - shopStoreConfig.setSc_order_process(str_sc_order_process); + String strScOrderProcess = CollUtil.join(scOrderProcess, ","); + shopStoreConfig.setSc_order_process(strScOrderProcess); - List sc_order_return_process = Arrays.asList( - StateCode.RETURN_PROCESS_SUBMIT, - //【客户】提交退单1ReturnReturn - StateCode.RETURN_PROCESS_CHECK, - //退单审核1ReturnReturn - StateCode.RETURN_PROCESS_FINISH - //完成1ReturnReturn3130-商家拒绝退货 - ); + List scOrderReturnProcess = Arrays.asList( + StateCode.RETURN_PROCESS_SUBMIT, // 【客户】提交退单 + StateCode.RETURN_PROCESS_CHECK, // 退单审核 + StateCode.RETURN_PROCESS_FINISH // 完成 + ); - String str_sc_order_return_process = CollUtil.join(sc_order_return_process, ","); - shopStoreConfig.setSc_order_return_process(str_sc_order_return_process); // 退货流程设置(DOT) - shopStoreConfig.setSc_settle_circle(30); - shopStoreConfig.setSc_settle_last_time(System.currentTimeMillis()); - shopStoreConfig.setSc_settle_next_time(Convert.toLong(DateUtil.nextMonth())); - shopStoreConfig.setSc_start_distance(BigDecimal.ZERO); - shopStoreConfig.setSc_festival_name(""); - shopStoreConfig.setSc_festival_start(""); - shopStoreConfig.setSc_festival_end(""); - shopStoreConfig.setSc_start_amount(BigDecimal.ZERO); - shopStoreConfig.setSc_extra_amount(BigDecimal.ZERO); - shopStoreConfig.setSc_festival_amount_down(BigDecimal.ZERO); - shopStoreConfig.setSc_festival_amount_upper(BigDecimal.ZERO); - shopStoreConfig.setSc_festival_float_proportion(BigDecimal.ZERO); - if (!shopStoreConfigService.saveOrUpdate(shopStoreConfig)) { - if (allowThrown) { - throw new ApiException(I18nUtil._("添加订单流转配置失败")); + String strScOrderReturnProcess = CollUtil.join(scOrderReturnProcess, ","); + shopStoreConfig.setSc_order_return_process(strScOrderReturnProcess); // 退货流程设置(DOT) + shopStoreConfig.setSc_settle_circle(30); + shopStoreConfig.setSc_settle_last_time(System.currentTimeMillis()); + shopStoreConfig.setSc_settle_next_time(Convert.toLong(DateUtil.nextMonth())); + shopStoreConfig.setSc_start_distance(BigDecimal.ZERO); + shopStoreConfig.setSc_festival_name(""); + shopStoreConfig.setSc_festival_start(""); + shopStoreConfig.setSc_festival_end(""); + shopStoreConfig.setSc_start_amount(BigDecimal.ZERO); + shopStoreConfig.setSc_extra_amount(BigDecimal.ZERO); + shopStoreConfig.setSc_festival_amount_down(BigDecimal.ZERO); + shopStoreConfig.setSc_festival_amount_upper(BigDecimal.ZERO); + shopStoreConfig.setSc_festival_float_proportion(BigDecimal.ZERO); + + if (!shopStoreConfigService.saveOrUpdate(shopStoreConfig)) { + String errorMsg = "添加订单流转配置失败"; + if (Boolean.TRUE.equals(allowThrown)) { + throw new ApiException(errorMsg); + } + log.error(errorMsg); + return; } - log.error("添加订单流转配置失败!"); - } - // 添加默认客户等级 - InvoicingCustomerLevel invoicingCustomerLevel = new InvoicingCustomerLevel(); - invoicingCustomerLevel.setCustomer_level_name(I18nUtil._("普通(系统默认,不可删除)")); - invoicingCustomerLevel.setCustomer_level_discountrate(new BigDecimal(100)); - invoicingCustomerLevel.setCustomer_level_is_buildin(1); - invoicingCustomerLevel.setCustomer_level_desc(""); + // 添加默认客户等级 + InvoicingCustomerLevel invoicingCustomerLevel = new InvoicingCustomerLevel(); + invoicingCustomerLevel.setCustomer_level_name("普通(系统默认,不可删除)"); + invoicingCustomerLevel.setCustomer_level_discountrate(new BigDecimal(100)); + invoicingCustomerLevel.setCustomer_level_is_buildin(1); + invoicingCustomerLevel.setCustomer_level_desc(""); - if (!invoicingCustomerLevelService.saveOrUpdate(invoicingCustomerLevel)) { - if (allowThrown) { - throw new ApiException(I18nUtil._("添加默认客户等级失败")); + if (!invoicingCustomerLevelService.saveOrUpdate(invoicingCustomerLevel)) { + String errorMsg = "添加默认客户等级失败"; + if (Boolean.TRUE.equals(allowThrown)) { + throw new ApiException(errorMsg); + } + log.error(errorMsg); + return; + } + + log.info("初始化店铺额外信息成功: userId={}, storeId={}", userId, storeId); + + } catch (Exception e) { + log.error("初始化店铺额外信息异常: userId={}, storeId={}", userId, storeId, e); + if (Boolean.TRUE.equals(allowThrown)) { + if (e instanceof ApiException) { + throw e; + } else { + throw new ApiException("初始化店铺信息失败: " + e.getMessage()); + } } - log.error("添加默认客户等级失败!"); } } + /** * 根据店铺名称判断店铺是否存在 * @@ -3996,14 +4097,14 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl idList = new ArrayList<>(); String storeIds = accountUserBase.getStore_ids(); + if (StrUtil.isBlank(storeIds)) { + // 用户当前没有店铺ID,直接添加新店铺ID idList.add(storeId.toString()); } else { + // 用户已有店铺ID列表,解析并去重 idList = StrUtil.split(storeIds, ","); if (!idList.contains(storeId.toString())) { // 追加新店铺ID @@ -4028,8 +4133,14 @@ public class ShopStoreBaseServiceImpl extends BaseServiceImpl