fix 入驻潜在空指针问题

This commit is contained in:
Jack 2025-09-24 21:57:02 +08:00
parent 52eead2229
commit a25e511404
9 changed files with 960 additions and 649 deletions

View File

@ -63,8 +63,8 @@ public class GlobalExceptionHandler {
.map(ConstraintViolation::getMessage) .map(ConstraintViolation::getMessage)
.collect(Collectors.joining("; ")); .collect(Collectors.joining("; "));
logError(req, "约束违反异常", e); logError(req, "数据库约束违反异常", e);
return CommonResult.validateFailed("系统数据异常,请联系管理员"); return CommonResult.validateFailed("记录是否已存在,请检查");
} }
/** /**

View File

@ -27,38 +27,78 @@ import java.util.regex.Pattern;
@Slf4j @Slf4j
public class CheckUtil { 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 * 校验数据 不为null和0
* *
* @param param * @param param 待校验的Integer值
* @return * @return boolean 不为null且不为0返回true否则返回false
*/ */
public static boolean isNotEmpty(Integer param) { public static boolean isNotEmpty(Integer param) {
return param != null && param != 0; return param != null && param != 0;
} }
/**
* 校验数据 不为null和0
*
* @param param 待校验的Long值
* @return boolean 不为null且不为0返回true否则返回false
*/
public static boolean isNotEmpty(Long param) { 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) { 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) { 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) { 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) { 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;
}
// 检查特殊值undefinednullnone不区分大小写
return !"undefined".equalsIgnoreCase(trimmed) &&
!"null".equalsIgnoreCase(trimmed) &&
!"none".equalsIgnoreCase(trimmed);
} }
public static boolean isEmpty(Integer param) { public static boolean isEmpty(Integer param) {

View File

@ -377,36 +377,43 @@ public class LakalaApiServiceImpl implements LakalaApiService {
/** /**
* 商家申请入网电子合同给到商家签署合同 * 商家申请入网电子合同给到商家签署合同
* *
* @param mchId * @param mchId 商户ID
* @return * @return Pair<Boolean, String> 申请结果第一个元素表示是否成功第二个元素为结果信息
*/ */
@Override @Override
public Pair<Boolean, String> applyLedgerMerEc(Long mchId) { public Pair<Boolean, String> applyLedgerMerEc(Long mchId) {
log.debug("商家开始申请入网电子合同"); log.debug("商家开始申请入网电子合同,入驻编号: {}", mchId);
if (ObjectUtil.isEmpty(mchId)) {
return Pair.of(false, I18nUtil._("缺少商家必要参数!")); // 1. 参数校验
if (CheckUtil.isEmpty(mchId)) {
log.warn("商家申请入网电子合同失败:缺少商家必要参数,入驻编号: {}", mchId);
return Pair.of(false, "缺少商家入驻编号!");
} }
// 获取商家信息 // 2. 获取商家信息
ShopMchEntry shopMchEntry = shopMchEntryService.shopMerchEntryById(mchId); ShopMchEntry shopMchEntry = shopMchEntryService.shopMerchEntryById(mchId);
if (shopMchEntry == null) { if (ObjectUtil.isEmpty(shopMchEntry)) {
return Pair.of(false, I18nUtil._("缺少商家相关信息!")); log.warn("商家申请入网电子合同失败:缺少商家相关入驻信息,入驻编号: {}", mchId);
return Pair.of(false, "缺少商家相关入驻信息!");
} }
String contractMobile = shopMchEntry.getLegal_person_mobile(); 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); LklLedgerEc lklLedgerEc = lklLedgerEcService.getByMchId(shopMchEntry.getId(), "", CommonConstant.Enable);
if (lklLedgerEc != null if (lklLedgerEc != null && "COMPLETED".equals(lklLedgerEc.getEc_status())) {
&& "COMPLETED".equals(lklLedgerEc.getEc_status())) {
// TODO 电子合同已签署完成但有一些错误的信息这种情况需要怎么处理
// 办法重新再签署合同更新拉卡拉的电子合同信息到商家入驻表中
log.info("商户:{} 电子合同已签署过,重新提交将被覆盖!", mchId); log.info("商户:{} 电子合同已签署过,重新提交将被覆盖!", mchId);
} }
// 是企业类型商家 // 4. 判断商家类型企业或个人
Boolean isQy = CommonConstant.MCH_ENTITY_TYPE_QY.equals(shopMchEntry.getEntity_type()); Boolean isQy = CommonConstant.MCH_ENTITY_TYPE_QY.equals(shopMchEntry.getEntity_type());
log.debug("商家类型:{}isQy: {}", isQy ? "企业" : "个人", isQy);
// 5. 装配请求数据
JSONObject reqData = new JSONObject(); JSONObject reqData = new JSONObject();
reqData.put("order_no", StringUtils.genLklOrderNo(8)); reqData.put("order_no", StringUtils.genLklOrderNo(8));
reqData.put("org_id", orgCode); reqData.put("org_id", orgCode);
@ -430,7 +437,7 @@ public class LakalaApiServiceImpl implements LakalaApiService {
reqData.put("acct_name", shopMchEntry.getAccount_holder_name()); reqData.put("acct_name", shopMchEntry.getAccount_holder_name());
reqData.put("remark", "申请入网电子合同"); reqData.put("remark", "申请入网电子合同");
// 正式上线的时候调整 api 地址 // 6. 构建回调地址
String domain = projectDomain; String domain = projectDomain;
if (isProdProject()) { if (isProdProject()) {
domain += "/api"; domain += "/api";
@ -440,11 +447,11 @@ public class LakalaApiServiceImpl implements LakalaApiService {
String retUrl = domain + "/mobile/shop/lakala/ec/applyNotify"; String retUrl = domain + "/mobile/shop/lakala/ec/applyNotify";
reqData.put("ret_url", retUrl); reqData.put("ret_url", retUrl);
// 7. 构建合同参数
LocalDate today = LocalDate.now(); LocalDate today = LocalDate.now();
String signDate = DateTimeUtils.formatLocalDate(today, "yyyy-MM-dd"); String signDate = DateTimeUtils.formatLocalDate(today, "yyyy-MM-dd");
String platformName = "桂平发发网络有限公司"; String platformName = "桂平发发网络有限公司";
JSONObject ecParams = new JSONObject(); JSONObject ecParams = new JSONObject();
ecParams.put("A1", isQy ? shopMchEntry.getBiz_license_company() : shopMchEntry.getAccount_holder_name()); ecParams.put("A1", isQy ? shopMchEntry.getBiz_license_company() : shopMchEntry.getAccount_holder_name());
ecParams.put("A30", wxFee); // 测试环境微信费率0.6 ecParams.put("A30", wxFee); // 测试环境微信费率0.6
@ -507,6 +514,7 @@ public class LakalaApiServiceImpl implements LakalaApiService {
// 该字段是json字符串不是json对象 // 该字段是json字符串不是json对象
reqData.put("ec_content_parameters", ecParams.toString()); reqData.put("ec_content_parameters", ecParams.toString());
// 8. 构建请求体
JSONObject reqBody = new JSONObject(); JSONObject reqBody = new JSONObject();
reqBody.put("req_time", DateTimeUtils.formatDateTime(LocalDateTime.now(), "yyyyMMddHHmmss")); reqBody.put("req_time", DateTimeUtils.formatDateTime(LocalDateTime.now(), "yyyyMMddHHmmss"));
reqBody.put("version", "3.0"); reqBody.put("version", "3.0");
@ -521,25 +529,27 @@ public class LakalaApiServiceImpl implements LakalaApiService {
log.debug("申请入网电子合同请求参数:{}", JsonUtil.toJSONString(reqBody)); log.debug("申请入网电子合同请求参数:{}", JsonUtil.toJSONString(reqBody));
// 9. 发送请求
String errMsg = ""; String errMsg = "";
JSONObject response = RestTemplateHttpUtil.sendLklPost(reqUrl, header, reqBody, JSONObject.class); JSONObject response = RestTemplateHttpUtil.sendLklPost(reqUrl, header, reqBody, JSONObject.class);
log.debug("拉卡拉申请入网电子合同响应参数:{}", JsonUtil.toJSONString(response)); log.debug("拉卡拉申请入网电子合同响应参数:{}", JsonUtil.toJSONString(response));
if (ObjectUtil.isEmpty(response) || !lklSuccessCode.equals(response.getStr("retCode"))) { if (ObjectUtil.isEmpty(response) || !lklSuccessCode.equals(response.getStr("retCode"))) {
errMsg = "拉卡拉申请入网电子合同," + response.getStr("retMsg"); errMsg = "拉卡拉申请入网电子合同," + response.getStr("retMsg");
log.warn("拉卡拉申请入网电子合同失败:{}商户ID: {}", errMsg, mchId);
shopMchEntryService.updateMerchEntryApprovalByMchId(shopMchEntry.getId(), CommonConstant.MCH_APPR_STA_LKL_NOPASS, errMsg); shopMchEntryService.updateMerchEntryApprovalByMchId(shopMchEntry.getId(), CommonConstant.MCH_APPR_STA_LKL_NOPASS, errMsg);
return Pair.of(false, errMsg); return Pair.of(false, errMsg);
} }
JSONObject respData = response.getJSONObject("respData"); JSONObject respData = response.getJSONObject("respData");
if (respData == null) { if (respData == null) {
errMsg = "拉卡拉申请入网电子合同," + response.getStr("retMsg"); errMsg = "拉卡拉申请入网电子合同,响应数据为空";
log.warn("拉卡拉申请入网电子合同失败:{},入驻编号: {}", errMsg, mchId);
shopMchEntryService.updateMerchEntryApprovalByMchId(shopMchEntry.getId(), CommonConstant.MCH_APPR_STA_LKL_NOPASS, errMsg); shopMchEntryService.updateMerchEntryApprovalByMchId(shopMchEntry.getId(), CommonConstant.MCH_APPR_STA_LKL_NOPASS, errMsg);
return Pair.of(false, errMsg); return Pair.of(false, errMsg);
} }
// 商家入网申请电子合同处理数据 // 10. 处理响应数据并保存到本地数据库
// 先写入本地数据库表中
LklLedgerEc record = new LklLedgerEc(); LklLedgerEc record = new LklLedgerEc();
record.setMch_id(mchId); record.setMch_id(mchId);
record.setMch_mobile(contractMobile); record.setMch_mobile(contractMobile);
@ -550,32 +560,31 @@ public class LakalaApiServiceImpl implements LakalaApiService {
String ecResultUrl = respData.getStr("result_url"); String ecResultUrl = respData.getStr("result_url");
record.setResult_url(ecResultUrl); record.setResult_url(ecResultUrl);
record.setResp_body(response.toString()); record.setResp_body(response.toString());
Boolean success = lklLedgerEcService.addOrUpdateByMchId(record); Boolean success = lklLedgerEcService.addOrUpdateByMchId(record);
if (!success) { if (!success) {
errMsg = "申请入网电子合同失败,数据保存失败"; 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); return Pair.of(false, errMsg);
} }
// 更新拉卡拉的电子合同信息到商家入驻表中 // 11. 更新拉卡拉的电子合同信息到商家入驻表中
shopMchEntryService.updateMerchEntryEcResultUrlByMchId(mchId, ecResultUrl); shopMchEntryService.updateMerchEntryEcResultUrlByMchId(mchId, ecResultUrl);
// 发短信给商家及时签署合同 SMS_488465246 // 12. 发送短信通知商家及时签署合同
//
//恭喜您的开店入驻申请已审核通过请尽快登录小发商家版APP平台签署电子合同签署链接24小时内有效逾期需重新提交申请如有疑问请联系客服感谢您的支持
// shopMessageTemplateService.aliyunSmsSend(contractMobile, "SMS_493160417", null);//SMS_479760276
// 恭喜您的开店入驻申请已审核通过点击链接 https://mall.gpxscs.cn/api/mobile/shop/lakala/sign/ec/${code}
// 或前往小发商家版APP完成电子合同签署链接24小时内有效逾期需重新提交申请如有疑问可联系客服感谢您的支持
shopMessageTemplateService.aliyunSmsSend(contractMobile, "SMS_494860064", null); shopMessageTemplateService.aliyunSmsSend(contractMobile, "SMS_494860064", null);
// 13. 发送推送消息通知商家签署电子合同
JSONObject payload = new JSONObject(); JSONObject payload = new JSONObject();
payload.put("category", CommonConstant.PUSH_MSG_CATE_EC); 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, "商家入网申请电子合同成功"); return Pair.of(true, "商家入网申请电子合同成功");
} }
/** /**
* 商户分账业务开通申请 * 商户分账业务开通申请
* *
@ -618,6 +627,10 @@ public class LakalaApiServiceImpl implements LakalaApiService {
if (!Boolean.TRUE.equals(forceReApply)) { if (!Boolean.TRUE.equals(forceReApply)) {
log.info("商户{}已申请过分账业务,无需重复申请", merCupNo); log.info("商户{}已申请过分账业务,无需重复申请", merCupNo);
// 检查绑定关系
return Pair.of(true, I18nUtil._("商家已经申请过了!")); return Pair.of(true, I18nUtil._("商家已经申请过了!"));
} }
} }
@ -893,118 +906,160 @@ public class LakalaApiServiceImpl implements LakalaApiService {
/** /**
* 商户入网电子合同申请回调通知 * 商户入网电子合同申请回调通知
* <p>
* 处理拉卡拉商户入网电子合同签署完成后的回调通知更新合同状态并触发后续进件流程
* 参考https://o.lakala.com/#/home/document/detail?id=289 * 参考https://o.lakala.com/#/home/document/detail?id=289
* *
* @param request * @param request HTTP请求对象包含拉卡拉回调通知的参数
* @return * @return JSONObject 响应结果对象
*/ */
@Override @Override
public JSONObject applyLedgerMerEcNotify(HttpServletRequest request) { public JSONObject applyLedgerMerEcNotify(HttpServletRequest request) {
log.debug("商户入网电子合同申请回调通知开始"); log.debug("商户入网电子合同申请回调通知开始处理");
// 验签
// 1. 验签处理
Pair<Boolean, String> checkResult = LakalaUtil.chkLklApiNotifySign(request, lklNotifyCerPath, false); Pair<Boolean, String> checkResult = LakalaUtil.chkLklApiNotifySign(request, lklNotifyCerPath, false);
if (!checkResult.getFirst()) { if (!checkResult.getFirst()) {
log.warn("商户入网电子合同申请回调验签失败: {}", checkResult.getSecond());
return JSONUtil.createObj().set("code", "FAIL").set("retMsg", checkResult.getSecond()); return JSONUtil.createObj().set("code", "FAIL").set("retMsg", checkResult.getSecond());
} }
String errMsg = "入网电子合同申请回调:"; // 2. 初始化响应对象
JSONObject respData = new JSONObject(); JSONObject respData = new JSONObject();
respData.set("code", "FAIL").set("message", "返回数据转换异常!"); respData.set("code", "FAIL").set("message", "返回数据转换异常!");
// 3. 解析回调参数
JSONObject paramsJSON = JSONUtil.parseObj(checkResult.getSecond()); JSONObject paramsJSON = JSONUtil.parseObj(checkResult.getSecond());
if (paramsJSON == null) { if (paramsJSON == null) {
log.warn("商户入网电子合同申请回调参数解析失败");
return respData; return respData;
} }
// 4. 提取关键参数
Long ecApplyId = paramsJSON.getLong("ecApplyId"); Long ecApplyId = paramsJSON.getLong("ecApplyId");
String ecNo = paramsJSON.getStr("ecNo"); String ecNo = paramsJSON.getStr("ecNo");
String ecStatus = paramsJSON.getStr("ecStatus"); // COMPLETED String ecStatus = paramsJSON.getStr("ecStatus"); // COMPLETED
// 5. 合同状态校验
if (ecStatus == null || !ecStatus.equals("COMPLETED")) { if (ecStatus == null || !ecStatus.equals("COMPLETED")) {
log.debug("入网电子合同申请未签署完成!"); log.debug("入网电子合同申请未签署完成,当前状态: {}", ecStatus);
respData.put("message", "商户入网电子合同尚未签署,请稍候!"); respData.put("message", "商户入网电子合同尚未签署,请稍候!");
return respData; return respData;
} }
// 6. 必要参数校验
if (ecApplyId == null || StrUtil.isBlank(ecNo)) { if (ecApplyId == null || StrUtil.isBlank(ecNo)) {
log.error("入网电子合同申请回调ecApplyId 为空"); log.error("入网电子合同申请回调参数缺失: ecApplyId={}, ecNo={}", ecApplyId, ecNo);
respData.put("message", "ecApplyId 返回空值!"); respData.put("message", "回调参数返回空值!");
return respData; return respData;
} }
// 7. 查询本地电子合同记录
LklLedgerEc lklLedgerEc = lklLedgerEcService.getByApplyId(ecApplyId, "", CommonConstant.Enable); LklLedgerEc lklLedgerEc = lklLedgerEcService.getByApplyId(ecApplyId, "", CommonConstant.Enable);
if (lklLedgerEc == null) { if (lklLedgerEc == null) {
log.error("入网电子合同申请回调找不到对应入网lklLedgerEc电子合同记录"); log.error("入网电子合同申请回调找不到对应记录ecApplyId: {}", ecApplyId);
respData.put("message", "找不到对应入网电子合同记录!"); respData.put("message", "找不到对应入网电子合同记录!");
return respData; return respData;
} }
// 8. 获取商户ID并校验
Long mchId = lklLedgerEc.getMch_id(); Long mchId = lklLedgerEc.getMch_id();
if (ObjectUtil.isEmpty(mchId)) { if (ObjectUtil.isEmpty(mchId)) {
log.error("入网电子合同申请回调:找不到商家关联数据"); log.error("入网电子合同申请回调商户ID为空ecApplyId: {}", ecApplyId);
respData.put("message", "找不到商家关联数据!"); respData.put("message", "找不到商家关联数据!");
return respData; return respData;
} }
// if ("COMPLETED".equals(lklLedgerEc.getEc_status())) { // 9. 查询商户入驻信息
// ShopMchEntry shopMchEntry = shopMchEntryService.shopMerchEntryById(lklLedgerEc.getMch_id()); ShopMchEntry shopMchEntry = shopMchEntryService.shopMerchEntryById(mchId);
// if (shopMchEntry != null if (shopMchEntry == null) {
// ) { log.error("入网电子合同申请回调找不到商户入驻信息mchId: {}", mchId);
// log.error("入网电子合同申请回调:找不到对应商户信息"); respData.put("message", "找不到商家入驻关联数据!");
// respData.put("message", "找不到对应商户信息!");
// return respData;
// }
//
// respData.put("code", "SUCCESS");
// respData.put("message", "操作成功!");
// log.info("商户入网电子合同申请回调:已处理成功,不需再重新处理");
// return respData;
// }
// base64 合同文件上传到 cos 服务器返回 url 地址
Pair<String, String> 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", "更新电子合同失败!");
return respData; return respData;
} }
// 更新商家入驻表的合同编号和签署地址更改状态 try {
shopMchEntryService.updateMerchantLklEContractInfo(mchId, ecNo, paramsJSON.getStr("ecName"), lklLedgerEc.getResult_url(), ecCosFileUrl, eclklFilePath); // 10. 下载并上传电子合同文件
log.debug("开始处理电子合同文件ecApplyId: {}", ecApplyId);
Pair<String, String> ecFilePair = ledgerMerEcDownload(ecApplyId);
String ecCosFileUrl = "";
String eclklFilePath = "";
// 商家电子合同签署完毕后收到异步通知触发拉卡拉商家进件重要环节 if (ecFilePair != null) {
Pair<Boolean, String> resultPair = lklTkService.registrationMerchant(mchId); ecCosFileUrl = ecFilePair.getFirst();
if (!resultPair.getFirst()) { eclklFilePath = ecFilePair.getSecond();
errMsg = resultPair.getSecond(); log.debug("电子合同文件处理完成COS地址: {}, 拉卡拉路径: {}", ecCosFileUrl, eclklFilePath);
shopMchEntryService.updateMerchEntryApprovalByMchId(mchId, CommonConstant.MCH_APPR_STA_LKL_NOPASS, errMsg); } else {
log.error(errMsg); log.warn("电子合同文件下载失败ecApplyId: {}", ecApplyId);
throw new ApiException(errMsg); }
// 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<Boolean, String> 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 服务器 * 商户入网盖章电子合同下载, 并上传到 cos 服务器
* *
@ -1444,166 +1499,190 @@ public class LakalaApiServiceImpl implements LakalaApiService {
// 1. 参数校验提前失败 // 1. 参数校验提前失败
if (paramsJSON == null) { if (paramsJSON == null) {
log.warn("商家绑定分账接收方申请失败:绑定参数为空"); log.warn("商家绑定分账接收方申请失败:绑定参数为空");
return Pair.of(false, I18nUtil._("绑定参数为空")); return Pair.of(false, "绑定参数为空");
} }
String merCupNo = paramsJSON.getStr("merCupNo"); String merCupNo = paramsJSON.getStr("merCupNo");
if (StrUtil.isBlank(merCupNo)) { if (StrUtil.isBlank(merCupNo)) {
log.warn("商家绑定分账接收方申请失败商户号merCupNo为空"); log.warn("商家绑定分账接收方申请失败商户号merCupNo为空");
return Pair.of(false, I18nUtil._("商户号merCupNo为空")); return Pair.of(false, "商户号merCupNo为空");
} }
log.debug("商家绑定分账接收方申请参数:{}", paramsJSON); log.debug("商家绑定分账接收方申请参数:{}", paramsJSON);
// 2. 基础数据查询提前失败 try {
log.debug("开始查询商户入驻信息,商户号: {}", merCupNo); // 2. 基础数据查询提前失败
ShopMchEntry shopMchEntry = shopMchEntryService.getShopMerchEntryByMerCupNo(merCupNo); log.debug("开始查询商户入驻信息,商户号: {}", merCupNo);
if (shopMchEntry == null) { ShopMchEntry shopMchEntry = shopMchEntryService.getShopMerchEntryByMerCupNo(merCupNo);
log.warn("商家绑定分账接收方申请失败:商户入驻记录不存在,商户号: {}", merCupNo); if (shopMchEntry == null) {
return Pair.of(false, I18nUtil._("商户入驻记录不存在")); log.warn("商家绑定分账接收方申请失败:商户入驻记录不存在,商户号: {}", merCupNo);
} return Pair.of(false, "商户入驻记录不存在");
// 进件记录
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<LklLedgerReceiver> 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);
// 单个接收方处理失败继续处理其他接收方
} }
}
// 10. 返回结果 // 进件记录
log.info("分账接收方绑定处理完成,成功: {},总数: {}", successCount, totalCount); log.debug("开始查询分账业务申请记录,商户号: {}", merCupNo);
if (successCount == 0) { LklLedgerMember lklLedgerMember = lklLedgerMemberService.getByMerCupNo(merCupNo);
log.error("商家绑定分账接收方全部失败"); if (lklLedgerMember == null || !CommonConstant.Enable.equals(lklLedgerMember.getAudit_status())) {
if (lklLedgerMember != null) { log.warn("商家绑定分账接收方申请失败:商家尚未申请分账业务或审核未通过,商户号: {}", merCupNo);
shopMchEntryService.updateMerchEntryApprovalByMchId( return Pair.of(false, "商家尚未申请分账业务");
lklLedgerMember.getMch_id(), CommonConstant.MCH_APPR_STA_NOPASS, "商家绑定分账接收方失败"
);
} }
return Pair.of(false, "商家绑定分账接收方失败");
} else if (successCount < totalCount) { // 检查必要字段
String message = String.format("商家绑定分账接收方,部分提交成功(%d/%d待审核通知", successCount, totalCount); if (StrUtil.isBlank(lklLedgerMember.getMer_inner_no())) {
log.info(message); log.warn("商家绑定分账接收方申请失败商户内部号mer_inner_no为空商户号: {}", merCupNo);
return Pair.of(true, message); lklLedgerMember.setMer_inner_no("");
} else { }
String message = "商家绑定分账接收方,全部提交成功,待审核通知";
log.info(message); // 分账接收方列表
return Pair.of(true, message); log.debug("开始查询分账接收方列表");
List<LklLedgerReceiver> 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; // 单个失败不影响其他接收方处理
}
Object applyId = respJson.getByPath("respData.applyId");
log.info("拉卡拉分账接收方绑定申请提交成功,订单号: {},商户号: {},接收方: {}申请ID: {}",
orderNo, merCupNo, receiverNo, applyId);
if (ObjectUtil.isEmpty(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"));
// 处理可能为null的platform_id
paramsJSON.set("platform_id", receiver.getPlatform_id() != null ? receiver.getPlatform_id().toString() : "");
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 +1704,41 @@ public class LakalaApiServiceImpl implements LakalaApiService {
Pair<Boolean, String> checkResult = LakalaUtil.chkLklApiNotifySign(request, lklNotifyCerPath, false); Pair<Boolean, String> checkResult = LakalaUtil.chkLklApiNotifySign(request, lklNotifyCerPath, false);
if (!checkResult.getFirst()) { if (!checkResult.getFirst()) {
log.warn("验签失败: {}", checkResult.getSecond()); 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. 解析回调参数 // 2. 解析回调参数
JSONObject paramsJSON = JSONUtil.parseObj(checkResult.getSecond()); JSONObject paramsJSON = JSONUtil.parseObj(checkResult.getSecond());
log.debug("##### 商家绑定接收方回调参数:{} ####", paramsJSON); log.debug("##### 商家绑定接收方回调参数:{} ####", paramsJSON);
// 检查参数是否包含必要的applyId // 3. 参数校验
if (paramsJSON == null || StrUtil.isBlank(paramsJSON.getStr("applyId"))) { if (paramsJSON == null) {
log.error("商家绑定分账接收方通知数据有误"); log.error("商家绑定分账接收方通知数据有误: 参数为空");
return JSONUtil.createObj().set("code", "FAIL").set("message", "商家绑定分账接收方通知数据有误!"); return JSONUtil.createObj().set("code", "FAIL").set("message", "商家绑定分账接收方通知数据有误!");
} }
// 3. 提取核心参数
String merCupNo = paramsJSON.getStr("merCupNo");
String applyId = paramsJSON.getStr("applyId"); String applyId = paramsJSON.getStr("applyId");
String merCupNo = paramsJSON.getStr("merCupNo");
String auditStatus = paramsJSON.getStr("auditStatus"); String auditStatus = paramsJSON.getStr("auditStatus");
if (StrUtil.isBlank(applyId)) {
log.error("商家绑定分账接收方通知数据有误: applyId为空");
return JSONUtil.createObj().set("code", "FAIL").set("message", "商家绑定分账接收方通知数据有误!");
}
// 4. 根据申请ID获取绑定记录 // 4. 根据申请ID获取绑定记录
LklLedgerMerReceiverBind lklLedgerMerReceiverBind = lklLedgerMerReceiverBindService.getMerReceiverByApplyId(applyId); LklLedgerMerReceiverBind lklLedgerMerReceiverBind = lklLedgerMerReceiverBindService.getMerReceiverByApplyId(applyId);
if (lklLedgerMerReceiverBind == null || CheckUtil.isEmpty(lklLedgerMerReceiverBind.getMch_id())) { if (lklLedgerMerReceiverBind == null) {
log.warn("无法获取到绑定记录applyId: {}", applyId); log.warn("无法获取到绑定记录applyId: {}", applyId);
return JSONUtil.createObj().set("code", "FAIL").set("message", "无法获取到绑定记录!"); 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. 参数校验防止空值 // 5. 参数校验防止空值
if (StrUtil.hasBlank(merCupNo, applyId, auditStatus)) { if (StrUtil.hasBlank(merCupNo, applyId, auditStatus)) {
String errorMsg = String.format("关键参数缺失merCupNo=%s, applyId=%s, auditStatus=%s", merCupNo, applyId, auditStatus); String errorMsg = String.format("关键参数缺失merCupNo=%s, applyId=%s, auditStatus=%s", merCupNo, applyId, auditStatus);
@ -1668,16 +1756,23 @@ public class LakalaApiServiceImpl implements LakalaApiService {
} }
// 7. 更新绑定记录的状态信息 // 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( Boolean updateSuccess = lklLedgerMerReceiverBindService.updateAuditResult(
applyId, applyId,
paramsJSON.getStr("merInnerNo"), merInnerNo,
merCupNo, merCupNo,
paramsJSON.getStr("receiverNo"), receiverNo,
paramsJSON.getStr("entrustFileName"), entrustFileName,
paramsJSON.getStr("entrustFilePath"), entrustFilePath,
auditStatus, auditStatus,
paramsJSON.getStr("auditStatusText"), auditStatusText,
paramsJSON.getStr("remark") remark
); );
if (!Boolean.TRUE.equals(updateSuccess)) { if (!Boolean.TRUE.equals(updateSuccess)) {
@ -1685,24 +1780,31 @@ public class LakalaApiServiceImpl implements LakalaApiService {
return JSONUtil.createObj().set("code", "FAIL").set("message", "更新绑定状态失败"); return JSONUtil.createObj().set("code", "FAIL").set("message", "更新绑定状态失败");
} }
Long mchId = lklLedgerMerReceiverBind.getMch_id();
// 8. 成功后更新商户绑定状态为已绑定 // 8. 成功后更新商户绑定状态为已绑定
shopMchEntryService.updateMulStatus(mchId, merCupNo, 0, 0, 0, 0, 0, 1, CommonConstant.MCH_APPR_STA_PASS); shopMchEntryService.updateMulStatus(mchId, merCupNo, 0, 0, 0, 0, 0, 1, CommonConstant.MCH_APPR_STA_PASS);
// 9. 创建店铺并初始化 try {
// 新建一个正式的已审核通过的店铺不要抛异常使用补偿机制可以独立初始化店铺 // 9. 判断是否可以创建店铺了
// 重要包含了更改 merchEntryInfo 的状态 使用法人小微个人的手机号注册商家账号作为店铺的管理员 if (shopMchEntryService.canBuildingShopStore(mchId)) {
Pair<Integer, String> retPair = shopStoreBaseService.covMerchEntryInfo2StoreInfo(mchId, false); // 创建店铺并初始化
if (retPair.getFirst() <= 0) { // 新建一个正式的已审核通过的店铺不要抛异常使用补偿机制可以独立初始化店铺
shopMchEntryService.updateMerchEntryApprovalByMchId(mchId, null, "创建初始化店铺失败:" + retPair.getSecond()); // 重要包含了更改 merchEntryInfo 的状态 使用法人小微个人的手机号注册商家账号作为店铺的管理员
log.error("进件成功,但初始化店铺失败: mchId={}, reason={}", mchId, retPair.getSecond()); Pair<Integer, String> retPair = shopStoreBaseService.covMerchEntryInfo2StoreInfo(mchId, false);
} else { if (retPair.getFirst() <= 0) {
shopMchEntryService.updateMulStatus(mchId, merCupNo, 0, 0, 1, 0, 0, 0, 0); shopMchEntryService.updateMerchEntryApprovalByMchId(mchId, null, "创建并初始化店铺失败:" + retPair.getSecond());
log.info("进件成功创建并初始化店铺成功mchId={}", mchId); log.error("进件成功,但初始化店铺失败: mchId={}, reason={}", mchId, retPair.getSecond());
} } else {
shopMchEntryService.updateMulStatus(mchId, merCupNo, 0, 0, 1, 0, 0, 0, 0);
log.info("进件成功创建并初始化店铺成功mchId={}", mchId);
}
}
// 10. 检查商户绑定状态是否完成 更改总的审核状态 // 10. 检查商户绑定状态是否完成 更改总的审核状态
shopMchEntryService.checkMerchEntryFinished(mchId); shopMchEntryService.checkMerchEntryFinished(mchId);
} catch (Exception e) {
log.error("处理商户店铺创建或状态检查时发生异常mchId: {}", mchId, e);
// 不中断主流程继续返回成功
}
// 11. 日志记录并返回成功响应 // 11. 日志记录并返回成功响应
log.info("商家绑定分账接收方异步通知处理完成mchId:{} merCupNo{}", mchId, merCupNo); log.info("商家绑定分账接收方异步通知处理完成mchId:{} merCupNo{}", mchId, merCupNo);

View File

@ -42,9 +42,10 @@ public interface PushMessageService {
* *
* @param userId * @param userId
* @param payload * @param payload
* @param isFinishNotice 是签署完成通知
* @return * @return
*/ */
CompletableFuture<Boolean> noticeMerchantSignEcContract(Integer userId, JSONObject payload); CompletableFuture<Boolean> noticeMerchantSignEcContract(Integer userId, JSONObject payload, Boolean isFinishNotice);
/** /**

View File

@ -33,7 +33,7 @@ import java.util.stream.Collectors;
public class PushMessageServiceImpl implements PushMessageService { public class PushMessageServiceImpl implements PushMessageService {
private static final String appName = "小发同城"; private static final String appName = "小发同城";
@Lazy @Lazy
@Resource @Resource
private UniCloudPushService uniCloudPushService; private UniCloudPushService uniCloudPushService;
@ -109,7 +109,7 @@ public class PushMessageServiceImpl implements PushMessageService {
@Async @Async
@Override @Override
public CompletableFuture<Boolean> noticeMerchantSignEcContract(Integer userId, JSONObject payload) { public CompletableFuture<Boolean> noticeMerchantSignEcContract(Integer userId, JSONObject payload, Boolean isFinishNotice) {
try { try {
// 获取商家的 cid 列表确保用户 ID 有效 // 获取商家的 cid 列表确保用户 ID 有效
if (userId == null || userId <= 0) { if (userId == null || userId <= 0) {
@ -137,9 +137,12 @@ public class PushMessageServiceImpl implements PushMessageService {
return CompletableFuture.completedFuture(false); // 无有效 cid 无需推送 return CompletableFuture.completedFuture(false); // 无有效 cid 无需推送
} }
String title = isFinishNotice ? "通知您合同已签署完毕" : "邀请您签署入驻合同";
String content = isFinishNotice ? "您的开店入驻合同已签署完成!" : "恭喜您!您的开店入驻申请已初步审核通过!请尽快登录小发商家 APP 平台签署电子合同签署链接24小时内有效逾期需重新提交申请。如有疑问请联系客服感谢您的支持";
Pair<Boolean, String> result = uniCloudPushService.sendPushMessageBatch(cidList, Pair<Boolean, String> result = uniCloudPushService.sendPushMessageBatch(cidList,
appName + "邀请您签署入驻合同", appName + title,
"恭喜您的开店入驻申请已审核通过!请尽快登录小发商家 APP 平台签署电子合同签署链接24小时内有效逾期需重新提交申请。如有疑问请联系客服感谢您的支持", content,
payload); payload);
if (!result.getFirst()) { if (!result.getFirst()) {

View File

@ -72,8 +72,8 @@ public class SFExpressController {
@ApiOperation(value = "查询顺丰同城订单状态流", notes = "查询顺丰同城订单状态流") @ApiOperation(value = "查询顺丰同城订单状态流", notes = "查询顺丰同城订单状态流")
@RequestMapping(value = "/list-order-feed", method = RequestMethod.POST) @RequestMapping(value = "/list-order-feed", method = RequestMethod.POST)
public ThirdApiRes listOrderFeed(@RequestParam(name = "order_id", defaultValue = "") String orderId) { public ThirdApiRes listOrderFeed(@RequestParam(name = "order_id", defaultValue = "") String orderId) {
if (StrUtil.isBlank(orderId) || orderId == "undefined" || orderId == "null") { if (StrUtil.isBlank(orderId) || "undefined".equals(orderId) || "null".equals(orderId) || "none".equals(orderId)) {
return new ThirdApiRes().fail(1003, "请求参数有误!"); return new ThirdApiRes().fail(1003, "缺少参数或参数有误!");
} }
Map<String, Object> params = new HashMap<>(); Map<String, Object> params = new HashMap<>();

View File

@ -293,6 +293,15 @@ public interface ShopMchEntryService {
*/ */
Boolean checkMerchEntryFinished(Long mchId); Boolean checkMerchEntryFinished(Long mchId);
/**
* 检查商户入驻流程当前是否可以创建店铺了
*
* @param mchId 商户入驻ID
* @return boolean 可以创建店铺返回true否则返回false
*/
Boolean canBuildingShopStore(Long mchId);
/** /**
* 检查更新商户入驻店铺初始化状态 * 检查更新商户入驻店铺初始化状态
* *

View File

@ -173,7 +173,6 @@ public class ShopMchEntryServiceImpl extends BaseServiceImpl<ShopMchEntryMapper,
return CommonResult.failed("请指定店铺或银行的省市区!"); return CommonResult.failed("请指定店铺或银行的省市区!");
} }
if (!PhoneNumberUtils.checkPhoneNumber(loginMobile)) { if (!PhoneNumberUtils.checkPhoneNumber(loginMobile)) {
log.warn("申请人手机号码格式错误,手机号: {}", loginMobile); log.warn("申请人手机号码格式错误,手机号: {}", loginMobile);
return CommonResult.failed("申请人手机号码有误!"); return CommonResult.failed("申请人手机号码有误!");
@ -1042,7 +1041,7 @@ public class ShopMchEntryServiceImpl extends BaseServiceImpl<ShopMchEntryMapper,
if (StrUtil.isBlank(contactMobile)) { if (StrUtil.isBlank(contactMobile)) {
return Pair.of(false, "联系人手机号不能为空"); return Pair.of(false, "联系人手机号不能为空");
} }
queryWrapper.eq("legal_person_mobile", contactMobile); queryWrapper.eq("legal_person_mobile", contactMobile); // 企业和个人公用该字段联系人手机号
String msg = ""; String msg = "";
// 4. 根据主体类型设置额外查询条件和提示信息 // 4. 根据主体类型设置额外查询条件和提示信息
@ -1067,7 +1066,6 @@ public class ShopMchEntryServiceImpl extends BaseServiceImpl<ShopMchEntryMapper,
return Pair.of(false, msg); return Pair.of(false, msg);
} }
log.info("可以申请入驻,准备申请入驻"); log.info("可以申请入驻,准备申请入驻");
return Pair.of(true, "可以申请入驻,准备下一个流程"); return Pair.of(true, "可以申请入驻,准备下一个流程");
@ -1738,6 +1736,7 @@ public class ShopMchEntryServiceImpl extends BaseServiceImpl<ShopMchEntryMapper,
log.error("更新商户入驻信息状态失败, mchId={}", mchId); log.error("更新商户入驻信息状态失败, mchId={}", mchId);
return false; return false;
} }
return true; // 返回 true表示入驻流程已全部完成 return true; // 返回 true表示入驻流程已全部完成
} catch (Exception e) { } catch (Exception e) {
@ -1747,6 +1746,51 @@ public class ShopMchEntryServiceImpl extends BaseServiceImpl<ShopMchEntryMapper,
} }
} }
/**
* 检查商户入驻流程当前是否可以创建店铺了
*
* @param mchId 商户入驻ID
* @return boolean 可以创建店铺返回true否则返回false
*/
@Override
public Boolean canBuildingShopStore(Long mchId) {
// 1. 参数校验
if (ObjectUtil.isEmpty(mchId)) {
log.error("检查商户是否可以创建店铺失败商户入驻ID为空");
return false;
}
try {
// 2. 根据商户ID获取商户入驻信息
ShopMchEntry merchantEntry = shopMerchEntryById(mchId);
if (merchantEntry == null) {
log.error("检查商户是否可以创建店铺失败:商户不存在, mchId={}", mchId);
return false;
}
// 3. 检查各项前置状态是否已完成
boolean isFinished = CommonConstant.Enable.equals(merchantEntry.getHas_ec_signed())
&& CommonConstant.Enable.equals(merchantEntry.getHas_apply_mer())
&& CommonConstant.Enable.equals(merchantEntry.getHas_apply_split())
&& CommonConstant.Enable.equals(merchantEntry.getHas_apply_receiver())
&& CommonConstant.Enable.equals(merchantEntry.getHas_bind_receiver());
// 4. 返回检查结果
if (isFinished) {
log.debug("商户满足创建店铺条件, mchId={}", mchId);
return true;
} else {
log.debug("商户不满足创建店铺条件, mchId={}", mchId);
return false;
}
} catch (Exception e) {
// 5. 异常处理记录异常信息避免程序中断
log.error("检查商户是否可以创建店铺时发生异常, mchId={}", mchId, e);
return false;
}
}
/** /**
* 根据商户号或商家手机号修改商户入驻信息多个状态 * 根据商户号或商家手机号修改商户入驻信息多个状态