diff --git a/docs/sql/adapay_member_account_v2.sql b/docs/sql/adapay_member_account_v2.sql
new file mode 100644
index 000000000..5b9a20388
--- /dev/null
+++ b/docs/sql/adapay_member_account_v2.sql
@@ -0,0 +1,7 @@
+-- 汇付开户 V2 流程:为 adapay_member_account 表新增审核状态字段
+-- 详见 docs/汇付开户V2流程计划.md 第 311-316 行
+
+ALTER TABLE adapay_member_account
+ ADD COLUMN audit_state VARCHAR(8) NULL COMMENT '汇付企业审核状态 A/B/C/D/E' AFTER del_flag,
+ ADD COLUMN audit_desc VARCHAR(512) NULL COMMENT '汇付企业审核说明' AFTER audit_state,
+ ADD COLUMN last_order_no VARCHAR(64) NULL COMMENT '最近一次企业开户/更新请求订单号' AFTER audit_desc;
diff --git a/jsowell-admin/src/main/java/com/jsowell/service/OrderService.java b/jsowell-admin/src/main/java/com/jsowell/service/OrderService.java
index 0cfffad00..15cdb3810 100644
--- a/jsowell-admin/src/main/java/com/jsowell/service/OrderService.java
+++ b/jsowell-admin/src/main/java/com/jsowell/service/OrderService.java
@@ -1402,11 +1402,22 @@ public class OrderService {
return;
}
adapayMemberAccount.setStatus(Constants.TWO);
- if (Objects.nonNull(jsonObject.getString("audit_desc"))) {
- adapayMemberAccount.setRemark(jsonObject.getString("audit_desc"));
+ String auditDesc = jsonObject.getString("audit_desc");
+ if (StringUtils.isNotBlank(auditDesc)) {
+ adapayMemberAccount.setRemark(auditDesc);
+ adapayMemberAccount.setAuditDesc(auditDesc);
}
+ // 回调上送的 audit_state 优先使用;缺省时根据失败类型兜底
+ String auditState = jsonObject.getString("audit_state");
+ if (StringUtils.isBlank(auditState)) {
+ auditState = "B";
+ }
+ adapayMemberAccount.setAuditState(auditState);
// 逻辑删除记录,并删除缓存
adapayMemberAccountService.updateAdapayMemberAccount(adapayMemberAccount);
+ if (StringUtils.isNotBlank(adapayMemberAccount.getMerchantId())) {
+ redisCache.deleteObject(CacheConstants.ADAPAY_MEMBER_ACCOUNT + adapayMemberAccount.getMerchantId());
+ }
}
/**
@@ -1424,11 +1435,26 @@ public class OrderService {
return;
}
adapayMemberAccount.setStatus(Constants.ONE);
- if (Objects.nonNull(jsonObject.getString("audit_desc"))) {
- adapayMemberAccount.setRemark(jsonObject.getString("audit_desc"));
+ String auditDesc = jsonObject.getString("audit_desc");
+ if (StringUtils.isNotBlank(auditDesc)) {
+ adapayMemberAccount.setRemark(auditDesc);
+ adapayMemberAccount.setAuditDesc(auditDesc);
+ }
+ // 优先使用回调上送的 audit_state;未上送时按是否携带结算账户区分 D/E
+ String auditState = jsonObject.getString("audit_state");
+ String settleAccountId = jsonObject.getString("settle_account_id");
+ if (StringUtils.isBlank(auditState)) {
+ auditState = StringUtils.isNotBlank(settleAccountId) ? "E" : "D";
+ }
+ adapayMemberAccount.setAuditState(auditState);
+ if (StringUtils.isNotBlank(settleAccountId)) {
+ adapayMemberAccount.setSettleAccountId(settleAccountId);
}
adapayMemberAccount.setDelFlag(DelFlagEnum.NORMAL.getValue());
adapayMemberAccountService.updateAdapayMemberAccount(adapayMemberAccount);
+ if (StringUtils.isNotBlank(adapayMemberAccount.getMerchantId())) {
+ redisCache.deleteObject(CacheConstants.ADAPAY_MEMBER_ACCOUNT + adapayMemberAccount.getMerchantId());
+ }
}
/**
diff --git a/jsowell-admin/src/main/java/com/jsowell/web/controller/pile/AdapayMemberController.java b/jsowell-admin/src/main/java/com/jsowell/web/controller/pile/AdapayMemberController.java
index 664dfefa7..3bd78bf30 100644
--- a/jsowell-admin/src/main/java/com/jsowell/web/controller/pile/AdapayMemberController.java
+++ b/jsowell-admin/src/main/java/com/jsowell/web/controller/pile/AdapayMemberController.java
@@ -320,4 +320,27 @@ public class AdapayMemberController extends BaseController {
}
return result;
}
+
+ /**
+ * V2 聚合开户详情
+ * 详见 docs/汇付开户V2流程计划.md
+ * 页面只需要这一个接口即可获得:状态、主操作、可用动作、会员资料、结算账户、提示
+ */
+ @PostMapping("/v2/detail")
+ public AjaxResult getAdapayOpenDetailV2(@RequestBody AdapayMemberInfoDTO dto) {
+ AjaxResult result;
+ try {
+ if (StringUtils.isBlank(dto.getMerchantId())) {
+ throw new BusinessException(ReturnCodeEnum.CODE_PARAM_NOT_NULL_ERROR);
+ }
+ result = AjaxResult.success(adapayService.getAdapayMemberOpenDetailV2(dto.getMerchantId()));
+ } catch (BusinessException e) {
+ logger.warn("查询汇付开户聚合详情V2 warn", e);
+ result = AjaxResult.error(e.getMessage());
+ } catch (Exception e) {
+ logger.error("查询汇付开户聚合详情V2 error", e);
+ result = AjaxResult.error("查询汇付开户聚合详情失败");
+ }
+ return result;
+ }
}
diff --git a/jsowell-common/src/main/java/com/jsowell/common/enums/adapay/AdapayOpenActionEnum.java b/jsowell-common/src/main/java/com/jsowell/common/enums/adapay/AdapayOpenActionEnum.java
new file mode 100644
index 000000000..97edd2982
--- /dev/null
+++ b/jsowell-common/src/main/java/com/jsowell/common/enums/adapay/AdapayOpenActionEnum.java
@@ -0,0 +1,35 @@
+package com.jsowell.common.enums.adapay;
+
+/**
+ * 汇付开户 V2 可用操作枚举。
+ *
+ *
由后端基于 {@link AdapayOpenStatusEnum} 计算,前端只渲染。
+ */
+public enum AdapayOpenActionEnum {
+
+ REFRESH("REFRESH", "刷新"),
+ CREATE_PERSONAL_MEMBER("CREATE_PERSONAL_MEMBER", "创建个人用户"),
+ CREATE_CORP_MEMBER("CREATE_CORP_MEMBER", "创建企业用户"),
+ UPDATE_PERSONAL_MEMBER("UPDATE_PERSONAL_MEMBER", "更新个人资料"),
+ UPDATE_CORP_MEMBER("UPDATE_CORP_MEMBER", "更新企业资料"),
+ RESUBMIT_CORP_MEMBER("RESUBMIT_CORP_MEMBER", "重新提交企业开户"),
+ CREATE_SETTLE_ACCOUNT("CREATE_SETTLE_ACCOUNT", "创建结算账户"),
+ DELETE_SETTLE_ACCOUNT("DELETE_SETTLE_ACCOUNT", "删除结算账户"),
+ DELETE_MEMBER("DELETE_MEMBER", "删除汇付用户");
+
+ private final String value;
+ private final String label;
+
+ AdapayOpenActionEnum(String value, String label) {
+ this.value = value;
+ this.label = label;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public String getLabel() {
+ return label;
+ }
+}
diff --git a/jsowell-common/src/main/java/com/jsowell/common/enums/adapay/AdapayOpenStatusEnum.java b/jsowell-common/src/main/java/com/jsowell/common/enums/adapay/AdapayOpenStatusEnum.java
new file mode 100644
index 000000000..d1241c72d
--- /dev/null
+++ b/jsowell-common/src/main/java/com/jsowell/common/enums/adapay/AdapayOpenStatusEnum.java
@@ -0,0 +1,51 @@
+package com.jsowell.common.enums.adapay;
+
+/**
+ * 汇付开户 V2 状态机
+ *
+ *
页面进入后只关心一个业务状态:当前运营商的汇付开户进度。
+ */
+public enum AdapayOpenStatusEnum {
+
+ /** 无有效 adapay_member_account */
+ NONE("NONE", "未开户"),
+ /** 个人用户已创建,未查询到结算账户 */
+ PERSONAL_OPENED_NO_SETTLE("PERSONAL_OPENED_NO_SETTLE", "个人已开户,待创建结算账户"),
+ /** 个人用户已创建,且存在结算账户 */
+ PERSONAL_COMPLETED("PERSONAL_COMPLETED", "个人开户完成"),
+ /** 企业 audit_state=A 或本地状态待审核 */
+ CORP_AUDITING("CORP_AUDITING", "企业审核中"),
+ /** 企业 audit_state=B/C 或本地状态失败 */
+ CORP_FAILED("CORP_FAILED", "企业开户失败"),
+ /** 企业 audit_state=D,或企业审核通过但无结算账户 */
+ CORP_OPENED_NO_SETTLE("CORP_OPENED_NO_SETTLE", "企业已开户,待创建结算账户"),
+ /** 企业 audit_state=E 或存在结算账户 */
+ CORP_COMPLETED("CORP_COMPLETED", "企业开户完成");
+
+ private final String value;
+ private final String label;
+
+ AdapayOpenStatusEnum(String value, String label) {
+ this.value = value;
+ this.label = label;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public String getLabel() {
+ return label;
+ }
+
+ public boolean isCorp() {
+ return this == CORP_AUDITING
+ || this == CORP_FAILED
+ || this == CORP_OPENED_NO_SETTLE
+ || this == CORP_COMPLETED;
+ }
+
+ public boolean isPersonal() {
+ return this == PERSONAL_OPENED_NO_SETTLE || this == PERSONAL_COMPLETED;
+ }
+}
diff --git a/jsowell-pile/src/main/java/com/jsowell/adapay/service/AdapayService.java b/jsowell-pile/src/main/java/com/jsowell/adapay/service/AdapayService.java
index 5ff62e405..d0ef207de 100644
--- a/jsowell-pile/src/main/java/com/jsowell/adapay/service/AdapayService.java
+++ b/jsowell-pile/src/main/java/com/jsowell/adapay/service/AdapayService.java
@@ -22,6 +22,9 @@ import com.jsowell.common.constant.CacheConstants;
import com.jsowell.common.constant.Constants;
import com.jsowell.common.core.redis.RedisCache;
import com.jsowell.common.enums.DelFlagEnum;
+import com.jsowell.common.enums.adapay.AdapayAuditStateEnum;
+import com.jsowell.common.enums.adapay.AdapayOpenActionEnum;
+import com.jsowell.common.enums.adapay.AdapayOpenStatusEnum;
import com.jsowell.common.enums.adapay.AdapayPayChannelEnum;
import com.jsowell.common.enums.adapay.AdapayStatusEnum;
import com.jsowell.common.enums.adapay.MerchantDelayModeEnum;
@@ -269,6 +272,7 @@ public class AdapayService {
* 创建个人用户
*/
public void createAdapayMember(CreatePersonalMemberDTO dto) throws BaseAdaPayException, BusinessException {
+ assertActionAllowed(dto.getMerchantId(), AdapayOpenActionEnum.CREATE_PERSONAL_MEMBER);
SettleAccountDTO request = SettleAccountDTO.builder()
.merchantId(dto.getMerchantId())
.location(dto.getLocation())
@@ -284,6 +288,7 @@ public class AdapayService {
* 创建企业用户
*/
public void createCorpMember(CreateCorpMemberDTO dto) throws BaseAdaPayException, BusinessException {
+ assertActionAllowed(dto.getMerchantId(), AdapayOpenActionEnum.CREATE_CORP_MEMBER);
SettleAccountDTO request = SettleAccountDTO.builder()
.merchantId(dto.getMerchantId())
.wechatAppId(pileMerchantInfoService.queryAppIdByMerchantId(dto.getMerchantId()))
@@ -310,6 +315,7 @@ public class AdapayService {
* 创建结算账户
*/
public void createSettleAccount(CreateSettleAccountDTO dto) throws BaseAdaPayException, BusinessException {
+ assertActionAllowed(dto.getMerchantId(), AdapayOpenActionEnum.CREATE_SETTLE_ACCOUNT);
AdapayMemberAccount adapayMemberAccount = requireCurrentMemberAccount(dto.getMerchantId());
if (CollectionUtils.isNotEmpty(selectSettleAccount(dto.getMerchantId()))) {
throw new BusinessException("", "当前商户已存在结算账户");
@@ -813,18 +819,20 @@ public class AdapayService {
// 创建企业用户参数
Map memberParams = Maps.newHashMap();
String adapayMemberId = Constants.ADAPAY_CORP_MEMBER_PREFIX + IdUtils.getMemberId();
+ String orderNo = IdUtils.get16UUID("jsdk_order");
// 先保存一条记录
AdapayMemberAccount adapayMemberAccount = new AdapayMemberAccount();
adapayMemberAccount.setMerchantId(dto.getMerchantId());
adapayMemberAccount.setAdapayMemberId(adapayMemberId);
adapayMemberAccount.setStatus(Constants.ZERO);
+ adapayMemberAccount.setAuditState(AdapayAuditStateEnum.AWAIT_AUDIT.getValue());
+ adapayMemberAccount.setLastOrderNo(orderNo);
adapayMemberAccountService.insertAdapayMemberAccount(adapayMemberAccount);
memberParams.put("member_id", adapayMemberId);
memberParams.put("app_id", config.getAdapayAppId());
- // memberParams.put("order_no", "jsdk_order" + System.currentTimeMillis());
- memberParams.put("order_no", IdUtils.get16UUID("jsdk_order"));
+ memberParams.put("order_no", orderNo);
memberParams.put("social_credit_code_expires", dto.getSocialCreditCodeExpires());
memberParams.put("business_scope", dto.getBusinessScope());
memberParams.put("name", dto.getBusinessName());
@@ -847,6 +855,8 @@ public class AdapayService {
String error_msg = (String) member.get("error_msg");
adapayMemberAccount.setStatus(Constants.TWO); // 创建失败,改状态
adapayMemberAccount.setRemark(error_msg);
+ adapayMemberAccount.setAuditState(AdapayAuditStateEnum.ACCOUNT_OPENING_FAILED.getValue());
+ adapayMemberAccount.setAuditDesc(error_msg);
adapayMemberAccountService.updateAdapayMemberAccount(adapayMemberAccount);
throw new BusinessException("", error_msg);
}
@@ -1007,11 +1017,13 @@ public class AdapayService {
String merchantId = (String) payload.get("merchantId");
AdapayMemberAccount adapayMemberAccount = requireCurrentMemberAccount(merchantId);
if (isPersonalMember(adapayMemberAccount.getAdapayMemberId())) {
+ assertActionAllowed(merchantId, AdapayOpenActionEnum.UPDATE_PERSONAL_MEMBER);
UpdatePersonalMemberDTO dto = JSON.parseObject(JSON.toJSONString(payload), UpdatePersonalMemberDTO.class);
updatePersonalMember(dto);
return;
}
+ assertActionAllowed(merchantId, AdapayOpenActionEnum.UPDATE_CORP_MEMBER);
UpdateCorpMemberDTO dto = JSON.parseObject(JSON.toJSONString(payload), UpdateCorpMemberDTO.class);
updateCorpMember(dto);
}
@@ -1074,12 +1086,13 @@ public class AdapayService {
return null;
}
+ String orderNo = IdUtils.get16UUID("jsdk_order_");
Map memberParams = Maps.newHashMap();
memberParams.put("adapay_func_code", "corp_members.update");
memberParams.put("member_id", adapayMemberAccount.getAdapayMemberId());
memberParams.put("app_id", config.getAdapayAppId());
- // memberParams.put("order_no", "jsdk_order_" + System.currentTimeMillis());
- memberParams.put("order_no", IdUtils.get16UUID("jsdk_order_"));
+ memberParams.put("order_no", orderNo);
+ memberParams.put("notify_url", ADAPAY_CALLBACK_URL);
memberParams.put("social_credit_code_expires", dto.getSocialCreditCodeExpires());
memberParams.put("business_scope", dto.getBusinessScope());
String name = dto.getBusinessName();
@@ -1103,6 +1116,13 @@ public class AdapayService {
if (AdapayStatusEnum.FAILED.getValue().equals((String) member.get("status"))) {
throw new BusinessException("", (String) member.get("error_msg"));
}
+ // 企业更新同步返回 pending,审核结果通过异步通知返回;写回审核中并记录 order_no
+ AdapayMemberAccount update = new AdapayMemberAccount();
+ update.setId(adapayMemberAccount.getId());
+ update.setStatus(Constants.ZERO);
+ update.setAuditState(AdapayAuditStateEnum.AWAIT_AUDIT.getValue());
+ update.setLastOrderNo(orderNo);
+ adapayMemberAccountService.updateAdapayMemberAccount(update);
return null;
}
@@ -1748,6 +1768,7 @@ public class AdapayService {
* @throws BaseAdaPayException
*/
public void deleteSettleAccount(AdapayMemberInfoDTO dto) throws BaseAdaPayException {
+ assertActionAllowed(dto.getMerchantId(), AdapayOpenActionEnum.DELETE_SETTLE_ACCOUNT);
AdapayMemberAccount adapayMemberAccount = requireCurrentMemberAccount(dto.getMerchantId());
String wechatAppId = pileMerchantInfoService.queryAppIdByMerchantId(dto.getMerchantId());
String adapayMemberId = StringUtils.isNotBlank(dto.getAdapayMemberId()) ? dto.getAdapayMemberId() : adapayMemberAccount.getAdapayMemberId();
@@ -1787,6 +1808,228 @@ public class AdapayService {
return adapayMemberAccount;
}
+ // ============== 汇付开户 V2 流程 ==============
+
+ /**
+ * 查询 V2 聚合开户详情,统一计算状态、主操作、可用动作。
+ * 文档:docs/汇付开户V2流程计划.md
+ */
+ public AdapayMemberOpenV2VO getAdapayMemberOpenDetailV2(String merchantId) throws BaseAdaPayException {
+ AdapayMemberAccount account = adapayMemberAccountService.selectByMerchantId(merchantId);
+ AdapayMemberOpenV2VO.AdapayMemberOpenV2VOBuilder builder = AdapayMemberOpenV2VO.builder()
+ .merchantId(merchantId)
+ .tips(Lists.newArrayList());
+
+ if (account == null) {
+ return populateV2Response(builder, AdapayOpenStatusEnum.NONE, null, null, null, null, null).build();
+ }
+
+ String adapayMemberId = account.getAdapayMemberId();
+ String wechatAppId = pileMerchantInfoService.queryAppIdByMerchantId(merchantId);
+ boolean corp = isCorpMember(adapayMemberId);
+ boolean personal = isPersonalMember(adapayMemberId);
+
+ AdapayMemberInfoVO personalVO = null;
+ AdapayCorpMemberVO corpVO = null;
+ AdapaySettleAccountVO settleVO = null;
+
+ if (personal) {
+ personalVO = queryAdapayMemberInfo(adapayMemberId, wechatAppId);
+ } else if (corp) {
+ corpVO = queryCorpAdapayMemberInfo(adapayMemberId, wechatAppId);
+ }
+
+ // 结算账户优先取本地,再尝试从企业用户响应中补齐
+ String settleAccountId = account.getSettleAccountId();
+ if (StringUtils.isBlank(settleAccountId) && corpVO != null) {
+ settleAccountId = corpVO.getSettleAccountId();
+ }
+ if (StringUtils.isNotBlank(settleAccountId)) {
+ settleVO = queryAdapaySettleAccount(adapayMemberId, settleAccountId, wechatAppId);
+ }
+
+ String auditState = resolveAuditState(account, corpVO);
+ String auditDesc = resolveAuditDesc(account, corpVO);
+ AdapayOpenStatusEnum status = computeOpenStatus(account, corp, personal, settleVO != null, auditState);
+
+ return populateV2Response(builder, status, adapayMemberId, auditState, auditDesc, personalVO, corpVO)
+ .settleAccount(settleVO)
+ .build();
+ }
+
+ /**
+ * 计算 V2 状态机。文档:docs/汇付开户V2流程计划.md 第 290-299 行
+ */
+ public AdapayOpenStatusEnum computeOpenStatus(AdapayMemberAccount account,
+ boolean corp,
+ boolean personal,
+ boolean hasSettleAccount,
+ String auditState) {
+ if (account == null) {
+ return AdapayOpenStatusEnum.NONE;
+ }
+ if (personal) {
+ return hasSettleAccount
+ ? AdapayOpenStatusEnum.PERSONAL_COMPLETED
+ : AdapayOpenStatusEnum.PERSONAL_OPENED_NO_SETTLE;
+ }
+ if (!corp) {
+ return AdapayOpenStatusEnum.NONE;
+ }
+ // 企业用户:先按汇付审核状态判断,其次按本地 status 兜底
+ if (AdapayAuditStateEnum.ACCOUNT_SUCCESSFUL.getValue().equals(auditState) || hasSettleAccount) {
+ return AdapayOpenStatusEnum.CORP_COMPLETED;
+ }
+ if (AdapayAuditStateEnum.ACCOUNT_OPENED_NO_SETTLEMENT_ACCOUNT.getValue().equals(auditState)) {
+ return AdapayOpenStatusEnum.CORP_OPENED_NO_SETTLE;
+ }
+ if (AdapayAuditStateEnum.AUDIT_FAILED.getValue().equals(auditState)
+ || AdapayAuditStateEnum.ACCOUNT_OPENING_FAILED.getValue().equals(auditState)
+ || Constants.TWO.equals(account.getStatus())) {
+ return AdapayOpenStatusEnum.CORP_FAILED;
+ }
+ if (AdapayAuditStateEnum.AWAIT_AUDIT.getValue().equals(auditState)
+ || Constants.ZERO.equals(account.getStatus())) {
+ return AdapayOpenStatusEnum.CORP_AUDITING;
+ }
+ // 审核通过但没拿到汇付细节时(status=1),按已开户但暂无结算账户处理
+ if (Constants.ONE.equals(account.getStatus())) {
+ return AdapayOpenStatusEnum.CORP_OPENED_NO_SETTLE;
+ }
+ return AdapayOpenStatusEnum.CORP_AUDITING;
+ }
+
+ /**
+ * 后端统一动作校验,避免前端绕过状态限制。
+ * 文档:docs/汇付开户V2流程计划.md 第 337-344 行
+ */
+ public void assertActionAllowed(String merchantId, AdapayOpenActionEnum action) throws BaseAdaPayException {
+ AdapayMemberOpenV2VO detail = getAdapayMemberOpenDetailV2(merchantId);
+ AdapayOpenStatusEnum status = AdapayOpenStatusEnum.valueOf(detail.getStatus());
+ if (!detail.getActions().contains(action.getValue())) {
+ throw new BusinessException("", String.format("当前状态[%s]不允许执行[%s]", status.getLabel(), action.getLabel()));
+ }
+ }
+
+ private AdapayMemberOpenV2VO.AdapayMemberOpenV2VOBuilder populateV2Response(
+ AdapayMemberOpenV2VO.AdapayMemberOpenV2VOBuilder builder,
+ AdapayOpenStatusEnum status,
+ String adapayMemberId,
+ String auditState,
+ String auditDesc,
+ AdapayMemberInfoVO personalVO,
+ AdapayCorpMemberVO corpVO) {
+ List actions = resolveActions(status);
+ String primaryAction = actions.isEmpty() ? null : actions.get(0);
+ String memberType = null;
+ if (status.isPersonal()) {
+ memberType = "PERSONAL";
+ } else if (status.isCorp()) {
+ memberType = "CORP";
+ }
+
+ List tips = buildTips(status, auditDesc);
+ boolean hasSettle = status == AdapayOpenStatusEnum.PERSONAL_COMPLETED
+ || status == AdapayOpenStatusEnum.CORP_COMPLETED;
+
+ return builder
+ .status(status.getValue())
+ .statusLabel(status.getLabel())
+ .memberType(memberType)
+ .adapayMemberId(adapayMemberId)
+ .auditState(auditState)
+ .auditDesc(auditDesc)
+ .settleAccountStatus(hasSettle ? "EXISTS" : "NONE")
+ .primaryAction(primaryAction)
+ .actions(actions)
+ .member(personalVO)
+ .corpMember(corpVO)
+ .tips(tips);
+ }
+
+ private List resolveActions(AdapayOpenStatusEnum status) {
+ List actions = Lists.newArrayList();
+ switch (status) {
+ case NONE:
+ actions.add(AdapayOpenActionEnum.CREATE_PERSONAL_MEMBER.getValue());
+ actions.add(AdapayOpenActionEnum.CREATE_CORP_MEMBER.getValue());
+ break;
+ case PERSONAL_OPENED_NO_SETTLE:
+ actions.add(AdapayOpenActionEnum.CREATE_SETTLE_ACCOUNT.getValue());
+ actions.add(AdapayOpenActionEnum.UPDATE_PERSONAL_MEMBER.getValue());
+ actions.add(AdapayOpenActionEnum.DELETE_MEMBER.getValue());
+ break;
+ case PERSONAL_COMPLETED:
+ actions.add(AdapayOpenActionEnum.UPDATE_PERSONAL_MEMBER.getValue());
+ actions.add(AdapayOpenActionEnum.DELETE_SETTLE_ACCOUNT.getValue());
+ break;
+ case CORP_AUDITING:
+ actions.add(AdapayOpenActionEnum.REFRESH.getValue());
+ break;
+ case CORP_FAILED:
+ // 失败态走 createCorpMember 接口:会先逻辑删除失败记录再重新发起开户
+ actions.add(AdapayOpenActionEnum.CREATE_CORP_MEMBER.getValue());
+ actions.add(AdapayOpenActionEnum.DELETE_MEMBER.getValue());
+ break;
+ case CORP_OPENED_NO_SETTLE:
+ actions.add(AdapayOpenActionEnum.CREATE_SETTLE_ACCOUNT.getValue());
+ actions.add(AdapayOpenActionEnum.UPDATE_CORP_MEMBER.getValue());
+ break;
+ case CORP_COMPLETED:
+ actions.add(AdapayOpenActionEnum.UPDATE_CORP_MEMBER.getValue());
+ actions.add(AdapayOpenActionEnum.DELETE_SETTLE_ACCOUNT.getValue());
+ break;
+ default:
+ break;
+ }
+ return actions;
+ }
+
+ private List buildTips(AdapayOpenStatusEnum status, String auditDesc) {
+ List tips = Lists.newArrayList();
+ switch (status) {
+ case CORP_AUDITING:
+ tips.add("企业开户已提交,请耐心等待汇付审核结果,可点击刷新查看最新状态");
+ break;
+ case CORP_FAILED:
+ if (StringUtils.isNotBlank(auditDesc)) {
+ tips.add("汇付审核失败原因:" + auditDesc);
+ }
+ tips.add("请根据失败原因修改企业资料后重新提交");
+ break;
+ case PERSONAL_OPENED_NO_SETTLE:
+ case CORP_OPENED_NO_SETTLE:
+ tips.add("22:30 后创建的结算账户,结算将延后一个结算日");
+ break;
+ case PERSONAL_COMPLETED:
+ case CORP_COMPLETED:
+ tips.add("更换银行卡需先删除结算账户,再使用原 member_id 重新创建");
+ break;
+ default:
+ break;
+ }
+ return tips;
+ }
+
+ private String resolveAuditState(AdapayMemberAccount account, AdapayCorpMemberVO corpVO) {
+ if (corpVO != null && StringUtils.isNotBlank(corpVO.getAuditState())) {
+ return corpVO.getAuditState();
+ }
+ return account == null ? null : account.getAuditState();
+ }
+
+ private String resolveAuditDesc(AdapayMemberAccount account, AdapayCorpMemberVO corpVO) {
+ if (corpVO != null && StringUtils.isNotBlank(corpVO.getAuditDesc())) {
+ return corpVO.getAuditDesc();
+ }
+ if (account == null) {
+ return null;
+ }
+ return StringUtils.isNotBlank(account.getAuditDesc()) ? account.getAuditDesc() : account.getRemark();
+ }
+
+ // ============== 汇付开户 V2 流程 end ==============
+
private boolean isPersonalMember(String adapayMemberId) {
return StringUtils.startsWith(adapayMemberId, Constants.ADAPAY_MEMBER_PREFIX);
}
diff --git a/jsowell-pile/src/main/java/com/jsowell/adapay/vo/AdapayMemberOpenV2VO.java b/jsowell-pile/src/main/java/com/jsowell/adapay/vo/AdapayMemberOpenV2VO.java
new file mode 100644
index 000000000..ec8708016
--- /dev/null
+++ b/jsowell-pile/src/main/java/com/jsowell/adapay/vo/AdapayMemberOpenV2VO.java
@@ -0,0 +1,65 @@
+package com.jsowell.adapay.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import java.util.List;
+
+/**
+ * 汇付开户 V2 聚合响应。
+ *
+ * 页面进入后只关心 {@code status} 字段,按 {@code actions} 渲染操作按钮,
+ * 不再依赖前端自行判断 memberType / auditState / settleAccountList。
+ */
+@Getter
+@Setter
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+public class AdapayMemberOpenV2VO {
+
+ /** 运营商 id */
+ private String merchantId;
+
+ /** V2 状态,取自 {@link com.jsowell.common.enums.adapay.AdapayOpenStatusEnum} */
+ private String status;
+
+ /** V2 状态对应的中文展示 */
+ private String statusLabel;
+
+ /** PERSONAL / CORP / 未开户时为 null */
+ private String memberType;
+
+ /** 当前汇付会员 id */
+ private String adapayMemberId;
+
+ /** 汇付审核状态 A/B/C/D/E(仅企业有效) */
+ private String auditState;
+
+ /** 汇付审核结果描述 */
+ private String auditDesc;
+
+ /** NONE / EXISTS */
+ private String settleAccountStatus;
+
+ /** 当前阶段的主操作,取自 {@link com.jsowell.common.enums.adapay.AdapayOpenActionEnum} */
+ private String primaryAction;
+
+ /** 所有可用动作列表 */
+ private List actions;
+
+ /** 个人会员详情,仅个人开户时非空 */
+ private AdapayMemberInfoVO member;
+
+ /** 企业会员详情,仅企业开户时非空 */
+ private AdapayCorpMemberVO corpMember;
+
+ /** 当前结算账户,没有时为空 */
+ private AdapaySettleAccountVO settleAccount;
+
+ /** 可见提示,例如审核失败原因、22:30 后创建会延后结算等 */
+ private List tips;
+}
diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/domain/AdapayMemberAccount.java b/jsowell-pile/src/main/java/com/jsowell/pile/domain/AdapayMemberAccount.java
index 62298ce8e..b5fdaf3ba 100644
--- a/jsowell-pile/src/main/java/com/jsowell/pile/domain/AdapayMemberAccount.java
+++ b/jsowell-pile/src/main/java/com/jsowell/pile/domain/AdapayMemberAccount.java
@@ -71,4 +71,19 @@ public class AdapayMemberAccount {
* 删除标识(0-正常;1-删除)
*/
private String delFlag;
+
+ /**
+ * 汇付企业审核状态 A/B/C/D/E
+ */
+ private String auditState;
+
+ /**
+ * 汇付企业审核说明
+ */
+ private String auditDesc;
+
+ /**
+ * 最近一次企业开户/更新请求订单号
+ */
+ private String lastOrderNo;
}
\ No newline at end of file
diff --git a/jsowell-pile/src/main/resources/mapper/pile/AdapayMemberAccountMapper.xml b/jsowell-pile/src/main/resources/mapper/pile/AdapayMemberAccountMapper.xml
index 5c590b5cf..3dfa7565d 100644
--- a/jsowell-pile/src/main/resources/mapper/pile/AdapayMemberAccountMapper.xml
+++ b/jsowell-pile/src/main/resources/mapper/pile/AdapayMemberAccountMapper.xml
@@ -15,11 +15,14 @@
+
+
+
id, `status`, merchant_id, adapay_member_id, settle_account_id, remark, create_time,
- create_by, update_time, update_by, del_flag
+ create_by, update_time, update_by, del_flag, audit_state, audit_desc, last_order_no