package com.talentcard.server.business.merchant;
|
|
import com.alibaba.fastjson.JSON;
|
import com.talentcard.server.business.DatabaseRows;
|
import com.talentcard.server.business.payment.huifu.HuifuOnboardingProgressGateway;
|
import com.talentcard.server.common.BusinessException;
|
import com.talentcard.server.common.ErrorCode;
|
import java.util.ArrayList;
|
import java.util.LinkedHashMap;
|
import java.util.List;
|
import java.util.Map;
|
import java.util.UUID;
|
import org.springframework.jdbc.core.JdbcTemplate;
|
import org.springframework.stereotype.Service;
|
|
/** Six independent evidence-backed stages; provider calls never hold application row locks. */
|
@Service
|
public class MerchantOnboardingProgressService {
|
public static final String RECOVERY_HUIFU_ID = "6666000241335656";
|
private static final Map<String,String> LABELS = new LinkedHashMap<>();
|
static {
|
LABELS.put("basic", "基础审核"); LABELS.put("wechat", "微信支付");
|
LABELS.put("appId", "人才端绑定"); LABELS.put("realname", "实名与授权");
|
LABELS.put("delay", "延迟入账"); LABELS.put("settlement", "自动结算");
|
}
|
private final JdbcTemplate jdbc;
|
private final HuifuOnboardingProgressGateway gateway;
|
public MerchantOnboardingProgressService(JdbcTemplate jdbc, HuifuOnboardingProgressGateway gateway) { this.jdbc=jdbc; this.gateway=gateway; }
|
|
public boolean supports(Map<String,Object> application) { return RECOVERY_HUIFU_ID.equals(text(application.get("providerHuifuId"))); }
|
|
public Map<String,Object> refresh(Long applicationId, boolean retry) {
|
Map<String,Object> application=application(applicationId);
|
if (!supports(application)) throw new BusinessException(ErrorCode.CONFLICT,"This recovery is limited to the designated existing merchant");
|
jdbc.update("insert ignore into merchant_onboarding_progress(application_id,stages_json) values (?, '{}')", applicationId);
|
String owner=UUID.randomUUID().toString();
|
if(jdbc.update("update merchant_onboarding_progress set sync_owner=?,sync_until=date_add(now(),interval 5 minute) where application_id=? and (sync_owner is null or sync_until<now())", owner, applicationId)==0) return view(application);
|
try {
|
Map<String,Object> response=gateway.queryApplication(text(application.get("providerHuifuId")), text(application.get("providerApplyNo")));
|
if (!"00000000".equals(text(response.get("resp_code")))) {
|
String error=queryError(response);
|
jdbc.update("update merchant_onboarding_progress set sync_error=? where application_id=? and sync_owner=?",error,applicationId,owner);
|
} else {
|
Map<String,Object> stages = savedStages(applicationId);
|
String audit=text(response.get("apply_status"));
|
if ("Y".equals(audit) && "S".equals(text(response.get("reg_status")))) stages.put("basic", "confirmed");
|
else if (!"confirmed".equals(stages.get("basic"))) stages.put("basic",List.of("N","F").contains(audit) ? "failed" : "pending");
|
jdbc.update("update merchant_onboarding_progress set stages_json=?,last_synced_at=now(),sync_error='' where application_id=? and sync_owner=?",JSON.toJSONString(stages),applicationId,owner);
|
Map<String,Object> capabilities=gateway.queryCapabilities(text(application.get("providerHuifuId")));
|
if (capabilities != null && "00000000".equals(text(capabilities.get("resp_code")))) {
|
if (capabilities.containsKey("delay_flag") && capabilities.containsKey("forced_delay_flag")) {
|
stages.put("delay", "Y".equals(capabilities.get("delay_flag")) && "N".equals(capabilities.get("forced_delay_flag")) ? "confirmed" : "missing");
|
} else {
|
jdbc.update("update merchant_onboarding_progress set sync_error=? where application_id=? and sync_owner=?","汇付返回缺少延迟配置字段,已保留最后有效状态",applicationId,owner);
|
}
|
jdbc.update("update merchant_onboarding_progress set stages_json=? where application_id=? and sync_owner=?",JSON.toJSONString(stages),applicationId,owner);
|
} else {
|
jdbc.update("update merchant_onboarding_progress set sync_error=? where application_id=? and sync_owner=?",queryError(capabilities),applicationId,owner);
|
}
|
jdbc.update("update merchant_onboarding_progress set last_synced_at=now() where application_id=? and sync_owner=?",applicationId,owner);
|
}
|
} catch (RuntimeException exception) {
|
jdbc.update("update merchant_onboarding_progress set sync_error=? where application_id=? and sync_owner=?","查询结果暂未确认,已保留最后有效进度,请稍后刷新",applicationId,owner);
|
} finally {
|
jdbc.update("update merchant_onboarding_progress set sync_owner=null,sync_until=null where application_id=? and sync_owner=?",applicationId,owner);
|
}
|
return view(application(applicationId));
|
}
|
|
public Map<String,Object> view(Map<String,Object> application) {
|
Map<String,Object> result=new LinkedHashMap<>();
|
result.put("id",text(application.get("id"))); result.put("applicationNo",text(application.get("applicationNo")));
|
result.put("status","pending"); result.put("subjectType",text(application.get("subjectType")));
|
result.put("submittedAt",text(application.get("createdAt"))); result.put("retryable",false);
|
result.put("refreshable",true); result.put("lastSyncedAt",""); result.put("syncError","");
|
List<Map<String,Object>> saved=rows("select * from merchant_onboarding_progress where application_id=?",application.get("id"));
|
Map<String,Object> stages=new LinkedHashMap<>();
|
if (!saved.isEmpty()) {
|
stages=JSON.parseObject(text(saved.get(0).get("stagesJson")), Map.class);
|
result.put("lastSyncedAt",text(saved.get(0).get("lastSyncedAt")));
|
result.put("syncError",text(saved.get(0).get("syncError")));
|
}
|
List<Map<String,Object>> progress=new ArrayList<>();
|
for (var entry:LABELS.entrySet()) progress.add(Map.of("key",entry.getKey(),"label",entry.getValue(),"status",text(stages.getOrDefault(entry.getKey(),"unknown")),"reason","尚未取得通道生效证据"));
|
result.put("stages",progress); result.put("reason","请刷新进度,核实原申请与各项能力");
|
return result;
|
}
|
|
private Map<String,Object> application(Long id) {
|
List<Map<String,Object>> records=rows("select * from merchant_onboarding_application where id=? and initial_bank_card_id is not null",id);
|
if(records.isEmpty()) throw new BusinessException(ErrorCode.NOT_FOUND,"Onboarding application not found");
|
return records.get(0);
|
}
|
@SuppressWarnings("unchecked")
|
private Map<String,Object> savedStages(Long id) {
|
return JSON.parseObject(jdbc.queryForObject("select stages_json from merchant_onboarding_progress where application_id=?",String.class,id),Map.class);
|
}
|
private List<Map<String,Object>> rows(String sql,Object... args) { return DatabaseRows.normalize(jdbc.queryForList(sql,args)); }
|
private static String text(Object value) { return value==null ? "" : String.valueOf(value); }
|
private static String queryError(Map<String,Object> response) {
|
return response != null && "20002".equals(text(response.get("resp_code")))
|
? "汇付查询权限不足(20002),请联系平台运营核实接口权限"
|
: "汇付查询未成功,请稍后刷新或联系平台运营";
|
}
|
}
|