优化入驻流程

This commit is contained in:
Jack 2025-08-20 00:17:15 +08:00
parent 195a1d6735
commit 7b369442ff
7 changed files with 123 additions and 54 deletions

View File

@ -1,6 +1,7 @@
package com.suisung.mall.common.utils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.util.Pair;
import java.text.ParseException;
import java.text.SimpleDateFormat;
@ -51,6 +52,12 @@ public class DateTimeUtils {
* 特殊值空值"长期""永久" 转9999-12-31
*/
public static String convertLklDate(String dateStr) {
// 先验证是否符合格式符合直接返回不符合进行处理返回符合的格式
Pair<Boolean, String> isValid = isValidDateFormat(dateStr);
if (isValid.getFirst()) {
return isValid.getSecond();
}
String DEFAULT_FUTURE_DATE = "9999-12-31";
if (dateStr == null || dateStr.trim().isEmpty()) {
return DEFAULT_FUTURE_DATE;
@ -153,6 +160,37 @@ public class DateTimeUtils {
}
}
/**
* 判断字符串是否符合 yyyy-MM-dd 格式"长期""永久""9999-12-31"列入白名单
*
* @param dateStr 日期字符串
* @return true: 符合格式或在白名单中, false: 不符合格式
*/
public static Pair<Boolean, String> isValidDateFormat(String dateStr) {
// 空值检查
if (dateStr == null || dateStr.trim().isEmpty()) {
return Pair.of(false, "");
}
// 白名单检查
if ("长期".equals(dateStr) || "永久".equals(dateStr) || "9999-12-31".equals(dateStr)) {
return Pair.of(true, "9999-12-31");
}
// 格式检查 (yyyy-MM-dd) 长度为10第5位和第8位为'-'
if (dateStr.length() != 10 || dateStr.charAt(4) != '-' || dateStr.charAt(7) != '-') {
return Pair.of(false, dateStr);
}
try {
// 使用 LocalDate.parse 验证日期有效性
LocalDate.parse(dateStr, DateTimeFormatter.ISO_LOCAL_DATE);
return Pair.of(true, dateStr);
} catch (DateTimeException e) {
return Pair.of(false, dateStr);
}
}
/**
* 计算字符串中某个字符的出现次数
*/
@ -179,6 +217,7 @@ public class DateTimeUtils {
System.out.println(convertLklDate("25.1.2")); // 2025-01-02
System.out.println(convertLklDate("25.01.02")); // 2025-01-02
System.out.println(convertLklDate("长期")); // 9999-12-31
System.out.println(convertLklDate("永久")); // 9999-12-31
System.out.println(convertLklDate(null)); // 9999-12-31
System.out.println(convertLklDate("2025.2.30")); // 9999-12-31无效日期
}

View File

@ -8,8 +8,11 @@
package com.suisung.mall.common.utils;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.*;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
@ -19,6 +22,7 @@ import java.util.Map;
public class RestTemplateHttpUtil {
private static final RestTemplate restTemplate = new RestTemplate();
private static final Logger log = LoggerFactory.getLogger(RestTemplateHttpUtil.class);
/**
* 发送 GET 请求
@ -200,33 +204,34 @@ public class RestTemplateHttpUtil {
// 处理成功的响应
if (response.getStatusCode() == HttpStatus.OK) {
JSONObject result = new JSONObject();
result.set("retCode", "000000");
result.set("retMsg", "请求成功");
// 如果响应体是JSONObject类型解析其中的retCode和retMsg
if (response.getBody() instanceof JSONObject) {
JSONObject responseBody = (JSONObject) response.getBody();
// 尝试获取返回码和消息
String[] codeFields = {"retCode", "ret_code", "code", "code"};
String[] msgFields = {"retMsg", "ret_msg", "msg", "message"};
// 统一处理响应体
Object body = response.getBody();
JSONObject responseBody = (body instanceof JSONObject) ? (JSONObject) body : JSONUtil.parseObj(body);
String retCode = findFirstNonNullValue(responseBody, codeFields);
String retMsg = findFirstNonNullValue(responseBody, msgFields);
if (retCode != null) result.set("retCode", retCode);
if (retMsg != null) result.set("retMsg", retMsg);
log.info("####拉卡拉接口响应结果: {}", responseBody);
result.set("respData", responseBody);
} else if (response.getBody() != null) {
result.set("respData", response.getBody().toString());
}
// 尝试获取返回码消息和数据
String[] codeFields = {"retCode", "ret_code", "code"};
String[] msgFields = {"retMsg", "ret_msg", "msg", "message"};
String[] dataFields = {"respData", "resp_data", "data"};
String retCode = findFirstNonNullValue(responseBody, codeFields);
String retMsg = findFirstNonNullValue(responseBody, msgFields);
String respData = findFirstNonNullValue(responseBody, dataFields);
result.set("retCode", StrUtil.isBlank(retCode) ? "000000" : retCode);
result.set("retMsg", StrUtil.isBlank(retMsg) ? "" : retMsg);
result.set("respData", StrUtil.isBlank(respData) ? null : JSONUtil.parseObj(respData));
result.set("rawData", responseBody);
return result;
} else {
// 处理其他HTTP状态码
JSONObject result = new JSONObject();
result.set("retCode", String.valueOf(response.getStatusCode().value()));
result.set("retMsg", "HTTP状态码: " + response.getStatusCode().getReasonPhrase());
result.set("rawData", response.getBody());
return result;
}
} catch (org.springframework.web.client.HttpClientErrorException e) {
@ -240,6 +245,7 @@ public class RestTemplateHttpUtil {
JSONObject result = new JSONObject();
result.set("retCode", "500");
result.set("retMsg", "请求异常: " + e.getMessage());
result.set("rawData", "");
return result;
}
}
@ -296,14 +302,16 @@ public class RestTemplateHttpUtil {
result.set("retMsg", cn.hutool.core.util.StrUtil.isNotBlank(retMsg) ? retMsg : "请求失败: " + e.getStatusText());
// 保留原始错误信息
result.set("rawError", errorResponse);
result.set("rawData", errorResponse);
} else {
result.set("retCode", statusCode);
result.set("retMsg", "请求失败: " + e.getStatusText());
result.set("rawData", "");
}
} catch (Exception parseException) {
result.set("retCode", statusCode);
result.set("retMsg", "请求失败,无法解析错误响应: " + e.getMessage());
result.set("rawData", "");
}
return result;

View File

@ -493,7 +493,6 @@ public class LakalaApiServiceImpl implements LakalaApiService {
reqBody.put("req_data", reqData);
String reqUrl = serverUrl + "/api/v3/mms/open_api/ec/apply";
//"/api/v3/mms/open_api/ec/apply"; "/api/v2/mms/openApi/ec/apply";
String privateKey = LakalaUtil.getResourceFile(priKeyPath, false, true);
String authorization = LakalaUtil.genAuthorization(privateKey, appId, serialNo, reqBody.toString());
@ -523,7 +522,7 @@ public class LakalaApiServiceImpl implements LakalaApiService {
// 商家入网申请电子合同处理数据
// 先写入本地数据库表中
LklLedgerEc record = new LklLedgerEc();
record.setMch_id(shopMchEntry.getId());
record.setMch_id(mchId);
record.setMch_mobile(contractMobile);
record.setReq_params(reqBody.toString());
record.setNotify_url(retUrl);
@ -540,7 +539,7 @@ public class LakalaApiServiceImpl implements LakalaApiService {
}
// 更新拉卡拉的电子合同信息到商家入驻表中
shopMchEntryService.updateMerchEntryEcResultUrlByMchId(shopMchEntry.getId(), ecResultUrl);
shopMchEntryService.updateMerchEntryEcResultUrlByMchId(mchId, ecResultUrl);
// 发短信给商家及时签署合同 SMS_488465246
// 小发同城商家恭喜您的开店入驻申请已审核通过请尽快登录APP平台签署电子合同签署链接24小时内有效逾期需重新提交申请如有疑问请联系客服感谢您的支持
@ -1035,6 +1034,7 @@ public class LakalaApiServiceImpl implements LakalaApiService {
// 更新商家分账申请状态为已申请hasApplySplit=1
shopMchEntryService.updateMulStatus(lklLedgerMember.getMch_id(), "", merCupNo, 0, 0, 0, 1, 0, 0, CommonConstant.MCH_APPR_STA_LKL_PADDING);
shopMchEntryService.updateMerchEntryApprovalByMchId(lklLedgerMember.getMch_id(), null, "分账业务开通成功");
log.debug("商户分账业务申请回调处理成功applyId={}", applyId);
return JSONUtil.createObj().put("code", "SUCCESS").put("message", "操作成功!");
}

View File

@ -19,6 +19,8 @@ import com.suisung.mall.shop.lakala.mapper.LklLedgerEcMapper;
import com.suisung.mall.shop.lakala.service.LklLedgerEcService;
import org.springframework.stereotype.Service;
import java.util.Date;
@Service
public class LklLedgerEcServiceImpl extends BaseServiceImpl<LklLedgerEcMapper, LklLedgerEc> implements LklLedgerEcService {
@ -35,12 +37,14 @@ public class LklLedgerEcServiceImpl extends BaseServiceImpl<LklLedgerEcMapper, L
}
QueryWrapper<LklLedgerEc> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("mch_id", record.getMch_id()).eq("status", CommonConstant.Enable);
queryWrapper.eq("mch_id", record.getMch_id())
.eq("status", CommonConstant.Enable);
queryWrapper.orderByDesc("id");
LklLedgerEc existsRecord = findOne(queryWrapper);
if (existsRecord != null && existsRecord.getId() > 0) {
// 更新记录
record.setUpdated_at(new Date());
record.setId(existsRecord.getId());
return updateById(record);
}

View File

@ -402,8 +402,8 @@ public class LklTkServiceImpl {
reqJsonBody.put("accountIdCard", shopMchEntry.getLegal_person_id_number());//结算证件号码(身份证)
Integer SettlementMethod = shopMchEntry.getSettlement_method();
if (SettlementMethod == null || SettlementMethod < 0 || SettlementMethod > 10) {
SettlementMethod = 0;
if (SettlementMethod == null || SettlementMethod < 0 || SettlementMethod > 1) {
SettlementMethod = 0; // 结算类型 0-秒到1-次日结算
}
String settleType = String.format("D%d", SettlementMethod);
reqJsonBody.put("settleType", settleType); //结算类型D0秒到D1次日结算
@ -523,23 +523,27 @@ public class LklTkServiceImpl {
JSONObject response = RestTemplateHttpUtil.sendLklPost(buildLklTkUrl(urlPath), header, reqJsonBody, JSONObject.class);
logger.debug("拉卡拉进件响应参数:{}", response);
JSONObject respData = response.getJSONObject("respData");
if (ObjectUtil.isEmpty(response) || respData == null) {
String errMsg = response.getStr("retMsg") == null ? "拉卡拉进件出现未知错误" : response.getStr("retMsg");
if (ObjectUtil.isEmpty(response)
|| response.get("retCode") == null
|| !"000000".equals(response.getStr("retCode"))) {
String errMsg = response.getStr("retMsg") == null ? "拉卡拉发生未知错误" : response.getStr("retMsg");
shopMchEntryService.updateMerchEntryApprovalByMchId(shopMchEntry.getId(), CommonConstant.MCH_APPR_STA_LKL_NOPASS, "进件失败:" + errMsg);
return Pair.of(false, "提交进件失败:" + errMsg);
}
String lklMerInnerNo = respData.getStr("merchantNo"); //拉卡拉内部商户号
// {"merchantNo": "100132349","status": "WAIT_AUDI","state": "1"}
JSONObject rawData = response.getJSONObject("rawData"); // 进件这个接口比较特殊不安装常规返回数据
String lklMerInnerNo = rawData.getStr("merchantNo"); //拉卡拉内部商户号
// 表中的内部外部商户号暂时都传同一个内部商户号以便异步通知更改记录
Boolean success = shopMchEntryService.updateMerchEntryLklMerCupNo(mchId, CommonConstant.Disable2, lklMerInnerNo, lklMerInnerNo, reqJsonBody.toString(), respData.toString());
Boolean success = shopMchEntryService.updateMerchEntryLklMerCupNo(mchId, CommonConstant.Disable2, lklMerInnerNo, lklMerInnerNo, reqJsonBody.toString(), rawData.toString());
if (!success) {
shopMchEntryService.updateMerchEntryApprovalByMchId(shopMchEntry.getId(), CommonConstant.MCH_APPR_STA_LKL_NOPASS, "进件成功,但更新商户号失败!");
return Pair.of(false, "提交进件成功,但更新商户号失败!");
}
} catch (Exception e) {
@ -550,7 +554,7 @@ public class LklTkServiceImpl {
}
shopMchEntryService.updateMerchEntryApprovalByMchId(shopMchEntry.getId(), CommonConstant.MCH_APPR_STA_LKL_NOPASS, "商户进件:提交进件成功,请等待审核!");
shopMchEntryService.updateMerchEntryApprovalByMchId(shopMchEntry.getId(), CommonConstant.MCH_APPR_STA_LKL_PADDING, "商户进件:提交进件成功,请等待审核!");
return Pair.of(true, "提交进件成功,请等待审核!");
}
@ -606,7 +610,13 @@ public class LklTkServiceImpl {
return new JSONObject().set("code", "500").set("message", "参数解析出错");
}
// 给商家入驻表增加拉卡拉的商户号和拉卡拉返回的数据
ShopMchEntry shopMchEntry = shopMchEntryService.getShopMerchEntryByMerInnerNo(merInnerNo);
if (shopMchEntry == null) {
logger.error("拉卡拉进件异步通知:{}内部商户号入驻信息不存在!", merInnerNo);
return new JSONObject().put("code", "500").put("message", merInnerNo + "内部商户号入驻信息不存在");
}
// 校验审核状态
if (!"SUCCESS".equals(auditStatus) && !"REVIEW_PASS".equals(auditStatus)) {
@ -617,17 +627,11 @@ public class LklTkServiceImpl {
// RMK 拉卡拉进价提交成功,边处理周边的数据边等待审核异步通知
// 给商家入驻表增加拉卡拉的商户号和拉卡拉返回的数据
if (shopMchEntry == null) {
logger.error("拉卡拉进件异步通知:{}内部商户号入驻信息不存在!", merInnerNo);
return new JSONObject().put("code", "500").put("message", merInnerNo + "内部商户号入驻信息不存在");
}
Boolean success = shopMchEntryService.updateMerchEntryLklAuditStatusByLklMerCupNo(
merInnerNo, merCupNo, termNos, CommonConstant.Enable, null, data);
if (!success) {
shopMchEntryService.updateMerchEntryApprovalByMchId(shopMchEntry.getId(), CommonConstant.MCH_APPR_STA_LKL_NOPASS, "进件时更新商户号失败");
return new JSONObject().set("code", "500").set("message", "更新商户号失败");
}
@ -649,25 +653,19 @@ public class LklTkServiceImpl {
if (success && StrUtil.isNotBlank(shopMchEntry.getContract_download_url())) {
// TODO 新建一个正式的已审核通过的店铺 新建之前判断是否已经新建过了
// 新建一个正式的已审核通过的店铺不要抛异常使用补偿机制可以独立初始化店铺
ShopMchEntry shopEntry = shopMchEntryService.getShopMerchEntryByMerCupNo(merCupNo);
if (shopEntry != null && !CommonConstant.Enable.equals(shopEntry.getStore_status())) {
Long mchId = shopEntry.getId();
// 新建一个正式的已审核通过的店铺不要抛异常使用补偿机制可以独立初始化店铺
// 重要包含了更改 merchEntryInfo 的状态 TODO 用法人小微个人的手机号注册商家账号作为店铺的管理员
Pair<Integer, String> retPair = shopStoreBaseService.covMerchEntryInfo2StoreInfo(mchId, false);
if (retPair.getFirst() <= 0) {
shopMchEntryService.updateMerchEntryApprovalByMchId(shopMchEntry.getId(), null, "进件时初始化店铺失败");
logger.error("初始化店铺失败: mchId={}, reason={}", mchId, retPair.getSecond());
}
logger.info("初始化店铺成功mchId={}", mchId);
// boolean updateSuccess = shopMchEntryService.updateMulStatus(mchMobile, "", 0, 0, 1, 0, 0, 0, CommonConstant.MCH_APPR_STA_LKL_PADDING);
// if (!updateSuccess) {
// logger.warn("更新店铺状态失败: mchMobile={}", mchMobile);
// } else {
// logger.info("商家进件初始化店铺成功mchMobile={}", mchMobile);
// }
}
// 1电子合同给商家申请分账功能使用务必检查是否申请过申请过忽略
@ -678,21 +676,25 @@ public class LklTkServiceImpl {
// 统一处理分账申请结果
if (retPair.getFirst() && genSuccess) {
shopMchEntryService.updateMerchEntryApprovalByMchId(shopMchEntry.getId(), CommonConstant.MCH_APPR_STA_LKL_PADDING, "成功申请分账功能");
return new JSONObject().put("code", "200").put("message", "处理成功");
}
if (!retPair.getFirst()) {
String message = "商家申请分账功能失败:" + retPair.getSecond();
logger.error(message);
shopMchEntryService.updateMerchEntryApprovalByMchId(shopMchEntry.getId(), null, message);
return new JSONObject().set("code", "500").set("message", message);
}
if (!genSuccess) {
logger.error("申请分账接收方失败");
shopMchEntryService.updateMerchEntryApprovalByMchId(shopMchEntry.getId(), null, "申请分账接收方失败");
return new JSONObject().set("code", "500").set("message", "申请分账接收方失败");
}
}
shopMchEntryService.updateMerchEntryApprovalByMchId(shopMchEntry.getId(), CommonConstant.MCH_APPR_STA_LKL_NOPASS, "进件回调处理失败");
return new JSONObject().set("code", "500").set("message", "进件回调处理失败");
}

View File

@ -53,7 +53,7 @@ public class ShopMchEntryController extends BaseControllerImpl {
return shopMchEntryService.storeBusinessCategoryList();
}
@ApiOperation(value = "商家申请入驻城平台", notes = "商家申请入驻城平台")
@ApiOperation(value = "商家申请入驻小发同城平台", notes = "商家申请入驻小发同城平台")
@RequestMapping(value = "/apply", method = RequestMethod.POST)
public CommonResult shopMerchEntryApply(@RequestBody JSONObject shopMerchEntryJSON) {
return shopMchEntryService.shopMerchEntryApply(shopMerchEntryJSON);

View File

@ -262,7 +262,6 @@ public class ShopMchEntryServiceImpl extends BaseServiceImpl<ShopMchEntryMapper,
}
}
// 检查银行账号
if (StrUtil.isBlank(record.getBank_name()) || StrUtil.isBlank(record.getAccount_number()) || StrUtil.isBlank(record.getAccount_holder_name())) {
return CommonResult.failed("缺少银行账号信息!");
@ -475,24 +474,41 @@ public class ShopMchEntryServiceImpl extends BaseServiceImpl<ShopMchEntryMapper,
*/
private ShopMchEntry convLklDateFormat(ShopMchEntry record) {
if (record == null) {
return null;
return record;
}
// 企业
if (CommonConstant.MCH_ENTITY_TYPE_QY.equals(record.getEntity_type())) {
// 企业
// 营业执照有效期
if (StrUtil.isNotBlank(record.getBiz_license_period_begin())) {
record.setBiz_license_period_begin(DateTimeUtils.convertLklDate(record.getBiz_license_period_begin()));
}
record.setBiz_license_period_end(DateTimeUtils.convertLklDate(record.getBiz_license_period_end()));
if (StrUtil.isNotBlank(record.getBiz_license_period_end())) {
record.setBiz_license_period_end(DateTimeUtils.convertLklDate(record.getBiz_license_period_end()));
}
// 身份证有效期
if (StrUtil.isNotBlank(record.getLegal_person_id_period_begin())) {
record.setLegal_person_id_period_begin(DateTimeUtils.convertLklDate(record.getLegal_person_id_period_begin()));
}
record.setLegal_person_id_period_end(DateTimeUtils.convertLklDate(record.getLegal_person_id_period_end()));
if (StrUtil.isNotBlank(record.getLegal_person_id_period_end())) {
record.setLegal_person_id_period_end(DateTimeUtils.convertLklDate(record.getLegal_person_id_period_end()));
}
} else {
// 小微个人
// 身份证有效期
if (StrUtil.isNotBlank(record.getIndividual_id_period_begin())) {
record.setIndividual_id_period_begin(DateTimeUtils.convertLklDate(record.getIndividual_id_period_begin()));
}
record.setIndividual_id_period_end(DateTimeUtils.convertLklDate(record.getIndividual_id_period_end()));
if (StrUtil.isNotBlank(record.getIndividual_id_period_end())) {
record.setIndividual_id_period_end(DateTimeUtils.convertLklDate(record.getIndividual_id_period_end()));
}
}
return record;
@ -752,9 +768,8 @@ public class ShopMchEntryServiceImpl extends BaseServiceImpl<ShopMchEntryMapper,
return CommonResult.failed(resultPair.getSecond());
}
record.setApproval_remark("入网申请已成功提交!");
// 执行更新操作
if (!updateById(record)) {
if (!updateMerchEntryApprovalByMchId(record.getId(), null, "入网申请已成功提交!")) {
log.error("系统处理审批出错请联系管理员当前记录ID: {}", id);
return CommonResult.failed("系统处理审批出错,请联系管理员!");
}
@ -1417,7 +1432,7 @@ public class ShopMchEntryServiceImpl extends BaseServiceImpl<ShopMchEntryMapper,
public Boolean updateMerchEntryEcResultUrlByMchId(Long mchId, String lklEcResultUrl) {
try {
// 检查参数是否有效
if (mchId == null || mchId <= 0 || StrUtil.isBlank(lklEcResultUrl)) {
if (CheckUtil.isEmpty(mchId) || StrUtil.isBlank(lklEcResultUrl)) {
log.error("参数无效: mchId={}, lklEcResultUrl={}", mchId, lklEcResultUrl);
return false;
}
@ -1425,7 +1440,8 @@ public class ShopMchEntryServiceImpl extends BaseServiceImpl<ShopMchEntryMapper,
// 构建更新条件
UpdateWrapper<ShopMchEntry> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("id", mchId) // 根据商家入驻申请 ID 进行匹配
.set("lkl_ec_result_url", lklEcResultUrl); // 设置拉卡拉电子合同结果 URL
.set("lkl_ec_result_url", lklEcResultUrl) // 设置拉卡拉电子合同结果 URL
.set("approval_remark", "请引导商家签署电子合同!");
// 执行更新操作
return update(updateWrapper);