|
@@ -6,10 +6,13 @@ import lombok.extern.slf4j.Slf4j;
|
|
|
import okhttp3.*;
|
|
import okhttp3.*;
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
|
|
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
+import shop.alien.entity.store.StoreInfo;
|
|
|
import shop.alien.entity.store.WechatPartnerApplyment;
|
|
import shop.alien.entity.store.WechatPartnerApplyment;
|
|
|
import shop.alien.entity.result.R;
|
|
import shop.alien.entity.result.R;
|
|
|
|
|
+import shop.alien.mapper.StoreInfoMapper;
|
|
|
import shop.alien.mapper.WechatPartnerApplymentMapper;
|
|
import shop.alien.mapper.WechatPartnerApplymentMapper;
|
|
|
import shop.alien.store.util.WXPayUtility;
|
|
import shop.alien.store.util.WXPayUtility;
|
|
|
import shop.alien.util.system.OSUtil;
|
|
import shop.alien.util.system.OSUtil;
|
|
@@ -17,6 +20,7 @@ import shop.alien.util.system.OSUtil;
|
|
|
import javax.annotation.PostConstruct;
|
|
import javax.annotation.PostConstruct;
|
|
|
import javax.annotation.Resource;
|
|
import javax.annotation.Resource;
|
|
|
import java.io.IOException;
|
|
import java.io.IOException;
|
|
|
|
|
+import java.math.BigDecimal;
|
|
|
import java.lang.reflect.Type;
|
|
import java.lang.reflect.Type;
|
|
|
import java.security.MessageDigest;
|
|
import java.security.MessageDigest;
|
|
|
import java.security.NoSuchAlgorithmException;
|
|
import java.security.NoSuchAlgorithmException;
|
|
@@ -144,6 +148,9 @@ public class WeChatPartnerApplymentService {
|
|
|
@Resource
|
|
@Resource
|
|
|
private WechatPartnerApplymentMapper wechatPartnerApplymentMapper;
|
|
private WechatPartnerApplymentMapper wechatPartnerApplymentMapper;
|
|
|
|
|
|
|
|
|
|
+ @Resource
|
|
|
|
|
+ private StoreInfoMapper storeInfoMapper;
|
|
|
|
|
+
|
|
|
@PostConstruct
|
|
@PostConstruct
|
|
|
public void loadCertificates() {
|
|
public void loadCertificates() {
|
|
|
String privateKeyPath;
|
|
String privateKeyPath;
|
|
@@ -392,6 +399,7 @@ public class WeChatPartnerApplymentService {
|
|
|
* 则迁入 {@code id_card_info}。</li>
|
|
* 则迁入 {@code id_card_info}。</li>
|
|
|
* <li>将 {@code id_card_valid_time_begin} / {@code id_card_valid_time} 重命名为 {@code card_period_begin} / {@code card_period_end}。</li>
|
|
* <li>将 {@code id_card_valid_time_begin} / {@code id_card_valid_time} 重命名为 {@code card_period_begin} / {@code card_period_end}。</li>
|
|
|
* <li>将各 {@code *_period_end}、营业执照等 {@code period_end} 中误写的英文 {@code forever} 规范为文档用语「长期」。</li>
|
|
* <li>将各 {@code *_period_end}、营业执照等 {@code period_end} 中误写的英文 {@code forever} 规范为文档用语「长期」。</li>
|
|
|
|
|
+ * <li>{@code settlement_info.settlement_id} 微信要求 string;若前端传为 JSON 数字(如 {@code 716}、{@code 716.0}),转为字符串避免 {@code PARAM_ERROR}。</li>
|
|
|
* </ul>
|
|
* </ul>
|
|
|
*
|
|
*
|
|
|
* @param json 前端或历史模板传入的 JSON 字符串
|
|
* @param json 前端或历史模板传入的 JSON 字符串
|
|
@@ -414,6 +422,7 @@ public class WeChatPartnerApplymentService {
|
|
|
try {
|
|
try {
|
|
|
normalizeIdentityInfoIdCardNested(root);
|
|
normalizeIdentityInfoIdCardNested(root);
|
|
|
normalizeForeverToLongPeriodRecursive(root);
|
|
normalizeForeverToLongPeriodRecursive(root);
|
|
|
|
|
+ coerceSettlementInfoSettlementIdToString(root);
|
|
|
} catch (Exception e) {
|
|
} catch (Exception e) {
|
|
|
log.error("[进件] normalizeApplymentJsonForV3 处理异常,原样提交", e);
|
|
log.error("[进件] normalizeApplymentJsonForV3 处理异常,原样提交", e);
|
|
|
return json;
|
|
return json;
|
|
@@ -424,6 +433,27 @@ public class WeChatPartnerApplymentService {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
|
|
+ * 微信「入驻结算规则 ID」字段类型为 string;Gson 解析 JSON 数字会得到 {@link Number},序列化回 JSON 仍为数字,导致接口报错。
|
|
|
|
|
+ * 前置将 {@code settlement_info.settlement_id} 若为数字则转为十进制字符串(如 {@code 716.0} → {@code "716"})。
|
|
|
|
|
+ */
|
|
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
|
|
+ private void coerceSettlementInfoSettlementIdToString(Map<String, Object> root) {
|
|
|
|
|
+ Object si = root.get("settlement_info");
|
|
|
|
|
+ if (!(si instanceof Map)) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ Map<String, Object> settlementInfo = (Map<String, Object>) si;
|
|
|
|
|
+ Object sid = settlementInfo.get("settlement_id");
|
|
|
|
|
+ if (!(sid instanceof Number)) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ Number n = (Number) sid;
|
|
|
|
|
+ String asStr = new BigDecimal(n.toString()).stripTrailingZeros().toPlainString();
|
|
|
|
|
+ settlementInfo.put("settlement_id", asStr);
|
|
|
|
|
+ log.info("[进件] settlement_info.settlement_id 已由数字 {} 转为字符串 \"{}\"", n, asStr);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
* 将 {@code subject_info.identity_info} 下扁平身份证字段迁入 {@code id_card_info},并重命名有效期字段。
|
|
* 将 {@code subject_info.identity_info} 下扁平身份证字段迁入 {@code id_card_info},并重命名有效期字段。
|
|
|
*/
|
|
*/
|
|
|
@SuppressWarnings("unchecked")
|
|
@SuppressWarnings("unchecked")
|
|
@@ -533,27 +563,37 @@ public class WeChatPartnerApplymentService {
|
|
|
/**
|
|
/**
|
|
|
* 提交特约商户进件申请单,请求体为微信要求的 JSON(含 business_code、subject_info、bank_account_info 等)。
|
|
* 提交特约商户进件申请单,请求体为微信要求的 JSON(含 business_code、subject_info、bank_account_info 等)。
|
|
|
*
|
|
*
|
|
|
- * @param requestJson 与微信文档一致的 JSON 字符串(可先经 {@link #normalizeApplymentJsonForV3(String)} 规范结构)
|
|
|
|
|
|
|
+ * @param requestJson 与微信文档一致的 JSON 字符串(可先经 {@link #normalizeApplymentJsonForV3(String)} 规范结构)。
|
|
|
|
|
+ * 若传入 {@code storeId},服务端会写入必填字段 {@code business_code}(规则见 {@link #mergeBusinessCodeIntoApplymentJson(String, Integer)});
|
|
|
|
|
+ * 未传 {@code storeId} 时须在 JSON 中自行填写非空的 {@code business_code}。
|
|
|
* @param idempotencyKey 可选;传入则写入 {@code Idempotency-Key} 请求头,用于幂等重试(同一进件业务请固定同一值)
|
|
* @param idempotencyKey 可选;传入则写入 {@code Idempotency-Key} 请求头,用于幂等重试(同一进件业务请固定同一值)
|
|
|
|
|
+ * @param storeId 推荐传入;本系统门店 {@code store_info.id}。传入时后端生成 {@code business_code = 服务商商户号(sp_mchid) + "_" + storeId};审核通过后将 {@code sub_mchid} 写入该门店
|
|
|
* @return 成功时 data 为微信返回的 JSON 解析后的 Map;失败为 R.fail
|
|
* @return 成功时 data 为微信返回的 JSON 解析后的 Map;失败为 R.fail
|
|
|
*/
|
|
*/
|
|
|
- public R<Map<String, Object>> submitApplyment(String requestJson, String idempotencyKey) {
|
|
|
|
|
|
|
+ public R<Map<String, Object>> submitApplyment(String requestJson, String idempotencyKey, Integer storeId) {
|
|
|
if (StringUtils.isBlank(requestJson)) {
|
|
if (StringUtils.isBlank(requestJson)) {
|
|
|
log.warn("[进件] 请求体为空");
|
|
log.warn("[进件] 请求体为空");
|
|
|
return R.fail("请求体不能为空");
|
|
return R.fail("请求体不能为空");
|
|
|
}
|
|
}
|
|
|
final String normalizedJson = normalizeApplymentJsonForV3(requestJson);
|
|
final String normalizedJson = normalizeApplymentJsonForV3(requestJson);
|
|
|
|
|
+ final String jsonWithBusinessCode;
|
|
|
|
|
+ try {
|
|
|
|
|
+ jsonWithBusinessCode = mergeBusinessCodeIntoApplymentJson(normalizedJson, storeId);
|
|
|
|
|
+ } catch (IllegalArgumentException e) {
|
|
|
|
|
+ log.warn("[进件] business_code 处理失败: {}", e.getMessage());
|
|
|
|
|
+ return R.fail(e.getMessage());
|
|
|
|
|
+ }
|
|
|
final String payloadJson;
|
|
final String payloadJson;
|
|
|
try {
|
|
try {
|
|
|
- payloadJson = encryptSensitiveFieldsInApplymentJson(normalizedJson);
|
|
|
|
|
|
|
+ payloadJson = encryptSensitiveFieldsInApplymentJson(jsonWithBusinessCode);
|
|
|
} catch (Exception e) {
|
|
} catch (Exception e) {
|
|
|
log.error("[进件] 敏感字段加密失败", e);
|
|
log.error("[进件] 敏感字段加密失败", e);
|
|
|
return R.fail("进件请求敏感信息加密失败: " + e.getMessage());
|
|
return R.fail("进件请求敏感信息加密失败: " + e.getMessage());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 落库:提交前先写入/更新一条记录(以 sp_mchid + business_code 唯一)
|
|
// 落库:提交前先写入/更新一条记录(以 sp_mchid + business_code 唯一)
|
|
|
- String businessCode = extractBusinessCodeSafe(normalizedJson);
|
|
|
|
|
- upsertApplymentOnSubmitStart(businessCode, idempotencyKey, payloadJson);
|
|
|
|
|
|
|
+ String businessCode = extractBusinessCodeSafe(jsonWithBusinessCode);
|
|
|
|
|
+ upsertApplymentOnSubmitStart(businessCode, idempotencyKey, payloadJson, storeId);
|
|
|
|
|
|
|
|
String uri = applyment4subPath;
|
|
String uri = applyment4subPath;
|
|
|
String url = wechatPayApiHost + uri;
|
|
String url = wechatPayApiHost + uri;
|
|
@@ -618,7 +658,7 @@ public class WeChatPartnerApplymentService {
|
|
|
String template = StringUtils.isNotBlank(applymentQueryByIdPath)
|
|
String template = StringUtils.isNotBlank(applymentQueryByIdPath)
|
|
|
? applymentQueryByIdPath
|
|
? applymentQueryByIdPath
|
|
|
: "/v3/applyment4sub/applyment/applyment_id/{applyment_id}";
|
|
: "/v3/applyment4sub/applyment/applyment_id/{applyment_id}";
|
|
|
- String uri = template.replace("{applyment_id}", WXPayUtility.urlEncode(String.valueOf(applymentId)));
|
|
|
|
|
|
|
+ String uri = template.replace("{applyment_id}", String.valueOf(applymentId));
|
|
|
String url = wechatPayApiHost + uri;
|
|
String url = wechatPayApiHost + uri;
|
|
|
log.info("[进件查询] 调用微信查询申请单状态 url={}, uri={}", url, uri);
|
|
log.info("[进件查询] 调用微信查询申请单状态 url={}, uri={}", url, uri);
|
|
|
|
|
|
|
@@ -657,6 +697,86 @@ public class WeChatPartnerApplymentService {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
|
|
+ * 按门店查询最近一次特约商户进件状态(仅读本地库,不调微信接口)。
|
|
|
|
|
+ * <p>
|
|
|
|
|
+ * 从 {@code wechat_partner_applyment} 按 {@code store_id} 取最新一条(按更新时间、主键倒序)。
|
|
|
|
|
+ * 进件提交、定时任务或查询接口已把微信侧状态写入本表,此处直接返回落库数据即可。
|
|
|
|
|
+ * </p>
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param storeId 门店主键 {@link StoreInfo#getId()},须与进件提交时 query 参数 {@code storeId} 一致
|
|
|
|
|
+ * @return 成功时 data 为列表:有记录时含一条 Map,无进件记录时为空列表(不返回业务错误)
|
|
|
|
|
+ */
|
|
|
|
|
+ public R<List<WechatPartnerApplyment>> queryApplymentStateByStoreId(Integer storeId) {
|
|
|
|
|
+ if (storeId == null || storeId <= 0) {
|
|
|
|
|
+ log.warn("[进件查询] storeId 非法 storeId={}", storeId);
|
|
|
|
|
+ return R.fail("门店 storeId 不能为空且必须大于 0");
|
|
|
|
|
+ }
|
|
|
|
|
+ List<WechatPartnerApplyment> record = findLatestApplymentByStoreId(storeId);
|
|
|
|
|
+ if (record == null) {
|
|
|
|
|
+ log.info("[进件查询] 按门店无进件记录,返回空列表 storeId={}", storeId);
|
|
|
|
|
+ return R.data(Collections.emptyList());
|
|
|
|
|
+ }
|
|
|
|
|
+ log.info("[进件查询] 按门店返回本地库状态 storeId={}", storeId);
|
|
|
|
|
+ return R.data(record);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 同一门店可能存在多次进件记录时,取最新一条用于展示与查询。
|
|
|
|
|
+ */
|
|
|
|
|
+ private List<WechatPartnerApplyment> findLatestApplymentByStoreId(int storeId) {
|
|
|
|
|
+ LambdaQueryWrapper<WechatPartnerApplyment> qw = new LambdaQueryWrapper<WechatPartnerApplyment>()
|
|
|
|
|
+ .eq(WechatPartnerApplyment::getStoreId, storeId)
|
|
|
|
|
+ .orderByDesc(WechatPartnerApplyment::getUpdatedAt)
|
|
|
|
|
+ .orderByDesc(WechatPartnerApplyment::getId);
|
|
|
|
|
+ return wechatPartnerApplymentMapper.selectList(qw);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 合并 {@code business_code} 到进件根节点。
|
|
|
|
|
+ * <p>
|
|
|
|
|
+ * 微信要求 {@code business_code}(业务申请编号)必填且唯一。当请求带 {@code storeId} 时,由后端统一生成为:
|
|
|
|
|
+ * {@code 服务商商户号(sp_mchid) + "_" + storeId}(下划线分隔,与配置项 {@code payment.wechatPartnerPay.business.spMchId} 一致),
|
|
|
|
|
+ * 避免前端漏传或传空串导致 {@code PARAM_ERROR}。
|
|
|
|
|
+ * </p>
|
|
|
|
|
+ * <p>
|
|
|
|
|
+ * 未传 {@code storeId} 时,若 JSON 中 {@code business_code} 已非空则保留;否则抛出 {@link IllegalArgumentException}。
|
|
|
|
|
+ * </p>
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param normalizedJson 已规范化的进件 JSON 字符串
|
|
|
|
|
+ * @param storeId 可选,有值则覆盖/写入 {@code business_code}
|
|
|
|
|
+ * @return 合并后的 JSON 字符串
|
|
|
|
|
+ */
|
|
|
|
|
+ private String mergeBusinessCodeIntoApplymentJson(String normalizedJson, Integer storeId) {
|
|
|
|
|
+ Map<String, Object> root;
|
|
|
|
|
+ try {
|
|
|
|
|
+ root = GSON.fromJson(normalizedJson, MAP_TYPE);
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ throw new IllegalArgumentException("进件 JSON 解析失败,无法写入 business_code: " + e.getMessage());
|
|
|
|
|
+ }
|
|
|
|
|
+ if (root == null) {
|
|
|
|
|
+ root = new LinkedHashMap<>();
|
|
|
|
|
+ }
|
|
|
|
|
+ if (storeId != null) {
|
|
|
|
|
+ String sp = StringUtils.trimToEmpty(spMchId);
|
|
|
|
|
+ if (StringUtils.isBlank(sp)) {
|
|
|
|
|
+ throw new IllegalArgumentException("未配置服务商商户号 payment.wechatPartnerPay.business.spMchId,无法生成 business_code");
|
|
|
|
|
+ }
|
|
|
|
|
+ String code = sp + "_" + storeId;
|
|
|
|
|
+ root.put("business_code", code);
|
|
|
|
|
+ log.info("[进件] 已生成并写入 business_code={}(sp_mchid_storeId 格式,storeId={})", code, storeId);
|
|
|
|
|
+ return GSON.toJson(root);
|
|
|
|
|
+ }
|
|
|
|
|
+ Object v = root.get("business_code");
|
|
|
|
|
+ String existing = v == null ? "" : String.valueOf(v).trim();
|
|
|
|
|
+ if (StringUtils.isBlank(existing)) {
|
|
|
|
|
+ throw new IllegalArgumentException(
|
|
|
|
|
+ "请传入查询参数 storeId(后端将生成 business_code=服务商商户号_storeId),或在 JSON 根节点填写非空的 business_code");
|
|
|
|
|
+ }
|
|
|
|
|
+ return GSON.toJson(root);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
* 从进件 JSON 中提取 business_code(用于落库幂等主键);解析失败则返回 null。
|
|
* 从进件 JSON 中提取 business_code(用于落库幂等主键);解析失败则返回 null。
|
|
|
*/
|
|
*/
|
|
|
private static String extractBusinessCodeSafe(String requestJson) {
|
|
private static String extractBusinessCodeSafe(String requestJson) {
|
|
@@ -676,7 +796,7 @@ public class WeChatPartnerApplymentService {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private void upsertApplymentOnSubmitStart(String businessCode, String idempotencyKey, String payloadJson) {
|
|
|
|
|
|
|
+ private void upsertApplymentOnSubmitStart(String businessCode, String idempotencyKey, String payloadJson, Integer storeId) {
|
|
|
if (StringUtils.isBlank(businessCode)) {
|
|
if (StringUtils.isBlank(businessCode)) {
|
|
|
log.warn("[进件落库] business_code 为空,跳过落库(请在请求体中填写 business_code)");
|
|
log.warn("[进件落库] business_code 为空,跳过落库(请在请求体中填写 business_code)");
|
|
|
return;
|
|
return;
|
|
@@ -696,6 +816,9 @@ public class WeChatPartnerApplymentService {
|
|
|
if (StringUtils.isBlank(record.getSpMchid()) || "UNKNOWN".equalsIgnoreCase(record.getSpMchid())) {
|
|
if (StringUtils.isBlank(record.getSpMchid()) || "UNKNOWN".equalsIgnoreCase(record.getSpMchid())) {
|
|
|
record.setSpMchid(dbSpMchid);
|
|
record.setSpMchid(dbSpMchid);
|
|
|
}
|
|
}
|
|
|
|
|
+ if (storeId != null) {
|
|
|
|
|
+ record.setStoreId(storeId);
|
|
|
|
|
+ }
|
|
|
record.setIdempotencyKey(idempotencyKey);
|
|
record.setIdempotencyKey(idempotencyKey);
|
|
|
record.setLastSubmitTime(now);
|
|
record.setLastSubmitTime(now);
|
|
|
record.setRequestJson(payloadJson);
|
|
record.setRequestJson(payloadJson);
|
|
@@ -705,7 +828,7 @@ public class WeChatPartnerApplymentService {
|
|
|
} else {
|
|
} else {
|
|
|
wechatPartnerApplymentMapper.updateById(record);
|
|
wechatPartnerApplymentMapper.updateById(record);
|
|
|
}
|
|
}
|
|
|
- log.info("[进件落库] submitStart sp_mchid={}, business_code={}, id={}", record.getSpMchid(), businessCode, record.getId());
|
|
|
|
|
|
|
+ log.info("[进件落库] submitStart sp_mchid={}, business_code={}, storeId={}, id={}", record.getSpMchid(), businessCode, record.getStoreId(), record.getId());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private void upsertApplymentOnSubmitResult(String businessCode, Map<String, Object> respMap, String respBody) {
|
|
private void upsertApplymentOnSubmitResult(String businessCode, Map<String, Object> respMap, String respBody) {
|
|
@@ -742,6 +865,7 @@ public class WeChatPartnerApplymentService {
|
|
|
}
|
|
}
|
|
|
log.info("[进件落库] submitResult business_code={}, applyment_id={}, state={}",
|
|
log.info("[进件落库] submitResult business_code={}, applyment_id={}, state={}",
|
|
|
businessCode, record.getApplymentId(), record.getApplymentState());
|
|
businessCode, record.getApplymentId(), record.getApplymentState());
|
|
|
|
|
+ syncStoreInfoWechatSubMchidIfApproved(record);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private void upsertApplymentOnSubmitError(String businessCode, String errMsg, String respBody) {
|
|
private void upsertApplymentOnSubmitError(String businessCode, String errMsg, String respBody) {
|
|
@@ -806,6 +930,7 @@ public class WeChatPartnerApplymentService {
|
|
|
} else {
|
|
} else {
|
|
|
wechatPartnerApplymentMapper.updateById(record);
|
|
wechatPartnerApplymentMapper.updateById(record);
|
|
|
}
|
|
}
|
|
|
|
|
+ syncStoreInfoWechatSubMchidIfApproved(record);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private void upsertApplymentOnQueryError(long applymentId, String errMsg, String respBody) {
|
|
private void upsertApplymentOnQueryError(long applymentId, String errMsg, String respBody) {
|
|
@@ -823,6 +948,35 @@ public class WeChatPartnerApplymentService {
|
|
|
wechatPartnerApplymentMapper.updateById(record);
|
|
wechatPartnerApplymentMapper.updateById(record);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 进件状态为「已完成」且微信返回 {@code sub_mchid} 时,将特约商户号写入关联门店 {@code store_info.wechat_sub_mchid}。
|
|
|
|
|
+ */
|
|
|
|
|
+ private void syncStoreInfoWechatSubMchidIfApproved(WechatPartnerApplyment record) {
|
|
|
|
|
+ if (record == null || record.getStoreId() == null) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (record.getIsApproved() == null || record.getIsApproved() != 1) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (StringUtils.isBlank(record.getSubMchid())) {
|
|
|
|
|
+ log.warn("[进件] 状态已完成但 sub_mchid 为空,跳过写入门店 storeId={}", record.getStoreId());
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ try {
|
|
|
|
|
+ StoreInfo si = storeInfoMapper.selectById(record.getStoreId());
|
|
|
|
|
+ if (si == null) {
|
|
|
|
|
+ log.warn("[进件] 门店不存在,跳过写入 wechat_sub_mchid storeId={}", record.getStoreId());
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ storeInfoMapper.update(null, new LambdaUpdateWrapper<StoreInfo>()
|
|
|
|
|
+ .eq(StoreInfo::getId, record.getStoreId())
|
|
|
|
|
+ .set(StoreInfo::getWechatSubMchid, record.getSubMchid()));
|
|
|
|
|
+ log.info("[进件] 已写入门店 wechat_sub_mchid storeId={}, sub_mchid={}", record.getStoreId(), record.getSubMchid());
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.error("[进件] 写入 store_info.wechat_sub_mchid 失败 storeId={}", record.getStoreId(), e);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
private WechatPartnerApplyment findByBusinessCode(String businessCode) {
|
|
private WechatPartnerApplyment findByBusinessCode(String businessCode) {
|
|
|
LambdaQueryWrapper<WechatPartnerApplyment> qw = new LambdaQueryWrapper<WechatPartnerApplyment>()
|
|
LambdaQueryWrapper<WechatPartnerApplyment> qw = new LambdaQueryWrapper<WechatPartnerApplyment>()
|
|
|
.eq(WechatPartnerApplyment::getBusinessCode, businessCode)
|
|
.eq(WechatPartnerApplyment::getBusinessCode, businessCode)
|