From 6f659783b5772569b1d84e17ebedfebf98ed2349 Mon Sep 17 00:00:00 2001 From: jsowell <123@jsowell.com> Date: Fri, 29 May 2026 08:43:45 +0800 Subject: [PATCH] =?UTF-8?q?update=20=E4=BC=98=E5=8C=96=E6=B1=87=E4=BB=98?= =?UTF-8?q?=E5=BC=80=E6=88=B7=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/sql/adapay_member_account_v2.sql | 7 + .../com/jsowell/service/OrderService.java | 34 ++- .../pile/AdapayMemberController.java | 23 ++ .../enums/adapay/AdapayOpenActionEnum.java | 35 +++ .../enums/adapay/AdapayOpenStatusEnum.java | 51 ++++ .../jsowell/adapay/service/AdapayService.java | 251 +++++++++++++++++- .../adapay/vo/AdapayMemberOpenV2VO.java | 65 +++++ .../pile/domain/AdapayMemberAccount.java | 15 ++ .../mapper/pile/AdapayMemberAccountMapper.xml | 40 ++- .../AdapayUnsplitRecordHandleServiceImpl.java | 4 + 10 files changed, 516 insertions(+), 9 deletions(-) create mode 100644 docs/sql/adapay_member_account_v2.sql create mode 100644 jsowell-common/src/main/java/com/jsowell/common/enums/adapay/AdapayOpenActionEnum.java create mode 100644 jsowell-common/src/main/java/com/jsowell/common/enums/adapay/AdapayOpenStatusEnum.java create mode 100644 jsowell-pile/src/main/java/com/jsowell/adapay/vo/AdapayMemberOpenV2VO.java 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