update 重构汇付会员

This commit is contained in:
Guoqs
2026-03-25 16:19:15 +08:00
parent ea3ad1c904
commit 89263bbe51
15 changed files with 621 additions and 122 deletions

View File

@@ -0,0 +1,85 @@
# 汇付会员页面重构计划
## Summary
基于 AdaPay 官方文档、SDK 能力和当前仓库现状,重构现有商户详情页里的汇付用户区域,统一提供个人用户、企业用户、结算账户三类操作入口,并补齐后端接口与页面状态流。
- 一商户仅维护一个当前有效的汇付用户关系
- 一商户仅维护一个当前有效的结算账户
- 删除汇付用户按本地解绑落地,不做远端 AdaPay 用户对象删除
## 个人用户与企业用户
- 个人用户 `Member`
- 轻量开户,无审核附件
- 核心字段:`nickname``gender``location``email`
- 支持创建、查询、更新
- 结算账户单独创建
- 企业用户 `CorpMember`
- 需要企业实名资料和附件压缩包
- 审核状态:`A/B/C/D/E`
- 支持创建、查询、更新
- 结算账户单独创建或删除
- 结算账户 `SettleAccount`
- 个人和企业都独立维护
- 支持创建、查询、删除
- 删除用户前必须先删除结算账户
## 本次实现
### 页面与交互
- 重构商户详情页“钱包汇总”中的汇付用户区域
- 页面拆成三块:
- 用户概览
- 用户操作
- 结算账户操作
- 新增用户时先选个人/企业,再进入对应表单
- 删除用户按钮仅在没有结算账户时可用
- 企业用户保留审核状态和失败原因展示
### 后端接口
- `POST /adapay/member/createAdapayMember`
- `POST /adapay/member/createCorpMember`
- `POST /adapay/member/selectAdapayMember`
- `POST /adapay/member/updateAdapayMember`
- `POST /adapay/member/deleteAdapayMember`
- `POST /adapay/member/createSettleAccount`
- `POST /adapay/member/selectSettleAccount`
- `POST /adapay/member/deleteSettleAccount`
### 后端类型
- `CreatePersonalMemberDTO`
- `CreateCorpMemberDTO`
- `UpdatePersonalMemberDTO`
- `UpdateCorpMemberDTO`
- `CreateSettleAccountDTO`
- `DeleteAdapayMemberDTO`
- `AdapayMemberAggregateVO`
### 服务规则
- 个人用户创建与结算账户创建彻底拆开
- 企业用户创建与结算账户创建彻底拆开
- 用户查询返回聚合结果,兼容旧字段并补充:
- `memberType`
- `adapayMember`
- `adapayCorpMember`
- `settleAccountList`
- `canDeleteUser`
- `deleteBlockReason`
- 删除结算账户后只清空本地 `settle_account_id`,不删除用户绑定关系
- 删除用户前校验当前商户下不存在结算账户
## 测试结论
- 后端:`mvn -pl jsowell-admin -am compile -DskipTests` 通过
- 前端:对本次改动文件执行 `eslint --no-ignore` 通过
## Assumptions
- “删除汇付用户”按本地解绑实现,不做 AdaPay 远端用户删除
- 当前实现边界仍是一商户对应一个当前有效汇付用户
- 不支持同一商户同时维护多个有效汇付用户

View File

@@ -18,6 +18,7 @@ import com.jsowell.pile.service.ClearingWithdrawInfoService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map; import java.util.Map;
@RestController @RestController
@@ -30,14 +31,55 @@ public class AdapayMemberController extends BaseController {
@Autowired @Autowired
private ClearingWithdrawInfoService clearingWithdrawInfoService; private ClearingWithdrawInfoService clearingWithdrawInfoService;
/**
* 创建个人用户
*/
@PostMapping("/createAdapayMember")
public AjaxResult createAdapayMember(@RequestBody CreatePersonalMemberDTO dto) {
AjaxResult result;
try {
if (StringUtils.isBlank(dto.getMerchantId())) {
throw new BusinessException(ReturnCodeEnum.CODE_PARAM_NOT_NULL_ERROR);
}
adapayService.createAdapayMember(dto);
result = AjaxResult.success();
} catch (BusinessException e) {
logger.warn("创建个人汇付用户接口warn", e);
result = AjaxResult.error(e.getMessage());
} catch (Exception e) {
logger.error("创建个人汇付用户接口error", e);
result = AjaxResult.error("创建个人汇付用户接口异常:" + e.getMessage());
}
return result;
}
/**
* 创建企业用户
*/
@PostMapping("/createCorpMember")
public AjaxResult createCorpMember(@RequestBody CreateCorpMemberDTO dto) {
AjaxResult result;
try {
if (StringUtils.isBlank(dto.getMerchantId())) {
throw new BusinessException(ReturnCodeEnum.CODE_PARAM_NOT_NULL_ERROR);
}
adapayService.createCorpMember(dto);
result = AjaxResult.success();
} catch (BusinessException e) {
logger.warn("创建企业汇付用户接口warn", e);
result = AjaxResult.error(e.getMessage());
} catch (Exception e) {
logger.error("创建企业汇付用户接口error", e);
result = AjaxResult.error("创建企业汇付用户接口异常:" + e.getMessage());
}
return result;
}
/** /**
* 创建结算账户 * 创建结算账户
* http://localhost:8080/adapay/member/createSettleAccount
* @param dto
* @return
*/ */
@PostMapping("/createSettleAccount") @PostMapping("/createSettleAccount")
public AjaxResult createSettleAccount(@RequestBody SettleAccountDTO dto) { public AjaxResult createSettleAccount(@RequestBody CreateSettleAccountDTO dto) {
logger.info("创建结算账户接口 param:{}", JSON.toJSONString(dto)); logger.info("创建结算账户接口 param:{}", JSON.toJSONString(dto));
AjaxResult result; AjaxResult result;
try { try {
@@ -59,7 +101,6 @@ public class AdapayMemberController extends BaseController {
/** /**
* 查询汇付会员接口 * 查询汇付会员接口
* http://localhost:8080/adapay/member/selectAdapayMember
*/ */
@PostMapping("/selectAdapayMember") @PostMapping("/selectAdapayMember")
public AjaxResult selectAdapayMember(@RequestBody AdapayMemberInfoDTO dto) { public AjaxResult selectAdapayMember(@RequestBody AdapayMemberInfoDTO dto) {
@@ -68,8 +109,7 @@ public class AdapayMemberController extends BaseController {
if (StringUtils.isBlank(dto.getMerchantId())) { if (StringUtils.isBlank(dto.getMerchantId())) {
throw new BusinessException(ReturnCodeEnum.CODE_PARAM_NOT_NULL_ERROR); throw new BusinessException(ReturnCodeEnum.CODE_PARAM_NOT_NULL_ERROR);
} }
Map<String, Object> map = adapayService.selectAdapayMember(dto.getMerchantId()); result = AjaxResult.success(adapayService.selectAdapayMember(dto.getMerchantId()));
result = AjaxResult.success(map);
} catch (BusinessException e) { } catch (BusinessException e) {
logger.warn("查询汇付会员接口异常warn", e); logger.warn("查询汇付会员接口异常warn", e);
result = AjaxResult.error(e.getMessage()); result = AjaxResult.error(e.getMessage());
@@ -81,24 +121,67 @@ public class AdapayMemberController extends BaseController {
} }
/** /**
* 更新结算账户接口 * 查询结算账户接口
* http://localhost:8080/adapay/member/updateAdapayMember
*/ */
@PostMapping("/updateAdapayMember") @PostMapping("/selectSettleAccount")
public AjaxResult updateAdapayMember(@RequestBody SettleAccountDTO dto) { public AjaxResult selectSettleAccount(@RequestBody AdapayMemberInfoDTO dto) {
AjaxResult result; AjaxResult result;
try { try {
if (StringUtils.isBlank(dto.getMerchantId())) { if (StringUtils.isBlank(dto.getMerchantId())) {
throw new BusinessException(ReturnCodeEnum.CODE_PARAM_NOT_NULL_ERROR); throw new BusinessException(ReturnCodeEnum.CODE_PARAM_NOT_NULL_ERROR);
} }
Map<String, Object> map = adapayService.updateAdapayMember(dto); List<?> list = adapayService.selectSettleAccount(dto.getMerchantId());
result = AjaxResult.success(map); result = AjaxResult.success(list);
} catch (BusinessException e) { } catch (BusinessException e) {
logger.warn("更新结算账户接口warn", e); logger.warn("查询结算账户接口warn", e);
result = AjaxResult.error(e.getMessage()); result = AjaxResult.error(e.getMessage());
} catch (Exception e) { } catch (Exception e) {
logger.error("更新结算账户接口error", e); logger.error("查询结算账户接口error", e);
result = AjaxResult.error("查询汇付会员接口异常"); result = AjaxResult.error("查询结算账户接口异常");
}
return result;
}
/**
* 更新汇付会员接口
*/
@PostMapping("/updateAdapayMember")
public AjaxResult updateAdapayMember(@RequestBody Map<String, Object> dto) {
AjaxResult result;
try {
if (StringUtils.isBlank((String) dto.get("merchantId"))) {
throw new BusinessException(ReturnCodeEnum.CODE_PARAM_NOT_NULL_ERROR);
}
adapayService.updateAdapayMember(dto);
result = AjaxResult.success();
} catch (BusinessException e) {
logger.warn("更新汇付会员接口warn", e);
result = AjaxResult.error(e.getMessage());
} catch (Exception e) {
logger.error("更新汇付会员接口error", e);
result = AjaxResult.error("更新汇付会员接口异常");
}
return result;
}
/**
* 删除汇付会员绑定关系
*/
@PostMapping("/deleteAdapayMember")
public AjaxResult deleteAdapayMember(@RequestBody DeleteAdapayMemberDTO dto) {
AjaxResult result;
try {
if (StringUtils.isBlank(dto.getMerchantId())) {
throw new BusinessException(ReturnCodeEnum.CODE_PARAM_NOT_NULL_ERROR);
}
adapayService.deleteAdapayMember(dto);
result = AjaxResult.success();
} catch (BusinessException e) {
logger.warn("删除汇付会员绑定接口warn", e);
result = AjaxResult.error(e.getMessage());
} catch (Exception e) {
logger.error("删除汇付会员绑定接口error", e);
result = AjaxResult.error("删除汇付会员绑定接口异常");
} }
return result; return result;
} }

View File

@@ -0,0 +1,29 @@
package com.jsowell.adapay.dto;
import lombok.*;
import java.util.List;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class CreateCorpMemberDTO {
private String merchantId;
private String name;
private String provCode;
private String areaCode;
private String socialCreditCode;
private String socialCreditCodeExpires;
private String businessScope;
private String legalPerson;
private String legalCertId;
private String legalCertIdExpires;
private String legalMp;
private String address;
private String zipCode;
private String telphone;
private String email;
private List<String> imgList;
}

View File

@@ -0,0 +1,16 @@
package com.jsowell.adapay.dto;
import lombok.*;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class CreatePersonalMemberDTO {
private String merchantId;
private String location;
private String email;
private String gender;
private String nickname;
}

View File

@@ -0,0 +1,23 @@
package com.jsowell.adapay.dto;
import lombok.*;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class CreateSettleAccountDTO {
private String merchantId;
private String bankAcctType;
private String cardId;
private String cardNo;
private String cardName;
private String certId;
private String certType;
private String telNo;
private String bankCode;
private String bankName;
private String provCode;
private String areaCode;
}

View File

@@ -0,0 +1,13 @@
package com.jsowell.adapay.dto;
import lombok.*;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class DeleteAdapayMemberDTO {
private String merchantId;
private String adapayMemberId;
}

View File

@@ -0,0 +1,28 @@
package com.jsowell.adapay.dto;
import lombok.*;
import java.util.List;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class UpdateCorpMemberDTO {
private String merchantId;
private String name;
private String provCode;
private String areaCode;
private String socialCreditCodeExpires;
private String businessScope;
private String legalPerson;
private String legalCertId;
private String legalCertIdExpires;
private String legalMp;
private String address;
private String zipCode;
private String telphone;
private String email;
private List<String> imgList;
}

View File

@@ -0,0 +1,16 @@
package com.jsowell.adapay.dto;
import lombok.*;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class UpdatePersonalMemberDTO {
private String merchantId;
private String location;
private String email;
private String gender;
private String nickname;
}

View File

@@ -266,33 +266,91 @@ public class AdapayService {
} }
/** /**
* 创建结算账 * 创建个人用
*
* @param dto
* @throws BaseAdaPayException
* @throws BusinessException
*/ */
public void createSettleAccount(SettleAccountDTO dto) throws BaseAdaPayException, BusinessException { public void createAdapayMember(CreatePersonalMemberDTO dto) throws BaseAdaPayException, BusinessException {
String bankAcctType = dto.getBankAcctType(); SettleAccountDTO request = SettleAccountDTO.builder()
.merchantId(dto.getMerchantId())
.location(dto.getLocation())
.email(dto.getEmail())
.gender(dto.getGender())
.nickname(dto.getNickname())
.wechatAppId(pileMerchantInfoService.queryAppIdByMerchantId(dto.getMerchantId()))
.build();
createMember(request);
}
/**
* 创建企业用户
*/
public void createCorpMember(CreateCorpMemberDTO dto) throws BaseAdaPayException, BusinessException {
SettleAccountDTO request = SettleAccountDTO.builder()
.merchantId(dto.getMerchantId())
.wechatAppId(pileMerchantInfoService.queryAppIdByMerchantId(dto.getMerchantId()))
.businessName(dto.getName())
.provCode(dto.getProvCode())
.areaCode(dto.getAreaCode())
.socialCreditCode(dto.getSocialCreditCode())
.socialCreditCodeExpires(dto.getSocialCreditCodeExpires())
.businessScope(dto.getBusinessScope())
.legalPerson(dto.getLegalPerson())
.legalCertId(dto.getLegalCertId())
.legalCertIdExpires(dto.getLegalCertIdExpires())
.legalMp(dto.getLegalMp())
.address(dto.getAddress())
.zipCode(dto.getZipCode())
.telphone(dto.getTelphone())
.email(dto.getEmail())
.imgList(dto.getImgList())
.build();
createCorpMember(request);
}
/**
* 创建结算账户
*/
public void createSettleAccount(CreateSettleAccountDTO dto) throws BaseAdaPayException, BusinessException {
AdapayMemberAccount adapayMemberAccount = requireCurrentMemberAccount(dto.getMerchantId());
if (CollectionUtils.isNotEmpty(selectSettleAccount(dto.getMerchantId()))) {
throw new BusinessException("", "当前商户已存在结算账户");
}
// 设置wechatAppId
String wechatAppId = pileMerchantInfoService.queryAppIdByMerchantId(dto.getMerchantId()); String wechatAppId = pileMerchantInfoService.queryAppIdByMerchantId(dto.getMerchantId());
dto.setWechatAppId(wechatAppId); SettleAccountDTO request = buildSettleAccountDTO(dto);
Map<String, Object> settleCount = createSettleAccountRequest(request, adapayMemberAccount.getAdapayMemberId(), wechatAppId);
String cardId = dto.getCardId(); if (settleCount == null || StringUtils.equals((String) settleCount.get("status"), "failed")) {
String cardNo = dto.getCardNo(); String errorMsg = settleCount == null ? "创建汇付结算账户失败" : (String) settleCount.get("error_msg");
if (StringUtils.isBlank(cardId) && StringUtils.isNotBlank(cardNo)) { throw new BusinessException("00500001", errorMsg);
dto.setCardId(cardNo);
}
if (StringUtils.isBlank(cardNo) && StringUtils.isNotBlank(cardId)) {
dto.setCardNo(cardId);
} }
if (StringUtils.equals(bankAcctType, Constants.ONE)) { AdapayMemberAccount updateRecord = new AdapayMemberAccount();
createCorpMember(dto); updateRecord.setAdapayMemberId(adapayMemberAccount.getAdapayMemberId());
} else if (StringUtils.equals(bankAcctType, Constants.TWO)) { updateRecord.setSettleAccountId((String) settleCount.get("id"));
createMember(dto); adapayMemberAccountService.updateAdapayMemberAccountByMemberId(updateRecord);
} }
/**
* 查询当前商户的结算账户
*/
public List<AdapaySettleAccountVO> selectSettleAccount(String merchantId) throws BaseAdaPayException {
AdapayMemberAccount adapayMemberAccount = adapayMemberAccountService.selectByMerchantId(merchantId);
if (adapayMemberAccount == null) {
return Lists.newArrayList();
}
String wechatAppId = pileMerchantInfoService.queryAppIdByMerchantId(merchantId);
String settleAccountId = adapayMemberAccount.getSettleAccountId();
if (StringUtils.isBlank(settleAccountId) && isCorpMember(adapayMemberAccount.getAdapayMemberId())) {
AdapayCorpMemberVO corpMemberVO = queryCorpAdapayMemberInfo(adapayMemberAccount.getAdapayMemberId(), wechatAppId);
if (corpMemberVO != null) {
settleAccountId = corpMemberVO.getSettleAccountId();
}
}
AdapaySettleAccountVO adapaySettleAccountVO = queryAdapaySettleAccount(adapayMemberAccount.getAdapayMemberId(), settleAccountId, wechatAppId);
if (adapaySettleAccountVO == null) {
return Lists.newArrayList();
}
adapaySettleAccountVO.setMerchantId(merchantId);
return Lists.newArrayList(adapaySettleAccountVO);
} }
/** /**
@@ -314,9 +372,8 @@ public class AdapayService {
// 查询汇付会员关系 // 查询汇付会员关系
AdapayMemberAccount adapayMemberAccount = adapayMemberAccountService.selectByMerchantId(dto.getMerchantId()); AdapayMemberAccount adapayMemberAccount = adapayMemberAccountService.selectByMerchantId(dto.getMerchantId());
if (adapayMemberAccount != null && StringUtils.equals(adapayMemberAccount.getStatus(), Constants.ONE)) { if (adapayMemberAccount != null) {
log.error("通过merchantId:{}, 查询到结算账户配置:{}", dto.getMerchantId(), JSON.toJSONString(adapayMemberAccount)); throw new BusinessException("", "当前商户已绑定汇付用户");
return;
} }
log.info("=======execute CreateMember begin======="); log.info("=======execute CreateMember begin=======");
@@ -338,19 +395,10 @@ public class AdapayService {
throw new BusinessException("00500001", errorMsg); throw new BusinessException("00500001", errorMsg);
} }
Map<String, Object> settleCount = createSettleAccountRequest(dto, adapayMemberId, dto.getWechatAppId());
if (settleCount == null || StringUtils.equals((String) settleCount.get("status"), "failed")) {
String errorMsg = settleCount == null ? "创建汇付结算账户失败" : (String) settleCount.get("error_msg");
throw new BusinessException("00500001", errorMsg);
}
String settleAccountId = (String) settleCount.get("id");
// 保存到数据库 // 保存到数据库
adapayMemberAccount = new AdapayMemberAccount(); adapayMemberAccount = new AdapayMemberAccount();
adapayMemberAccount.setMerchantId(dto.getMerchantId()); adapayMemberAccount.setMerchantId(dto.getMerchantId());
adapayMemberAccount.setAdapayMemberId(adapayMemberId); adapayMemberAccount.setAdapayMemberId(adapayMemberId);
adapayMemberAccount.setSettleAccountId(settleAccountId);
adapayMemberAccount.setStatus(Constants.ONE); adapayMemberAccount.setStatus(Constants.ONE);
adapayMemberAccountService.insertAdapayMemberAccount(adapayMemberAccount); adapayMemberAccountService.insertAdapayMemberAccount(adapayMemberAccount);
} }
@@ -361,66 +409,61 @@ public class AdapayService {
* @param merchantId * @param merchantId
* @return * @return
*/ */
public Map<String, Object> selectAdapayMember(String merchantId) throws BaseAdaPayException { public AdapayMemberAggregateVO selectAdapayMember(String merchantId) throws BaseAdaPayException {
Map<String, Object> map = Maps.newHashMap();
AdapayMemberAccount adapayMemberAccount = adapayMemberAccountService.selectByMerchantId(merchantId); AdapayMemberAccount adapayMemberAccount = adapayMemberAccountService.selectByMerchantId(merchantId);
if (adapayMemberAccount == null) { if (adapayMemberAccount == null) {
log.error("通过merchantId:{}, 没有查询到结算账户配置", merchantId); log.error("通过merchantId:{}, 没有查询到结算账户配置", merchantId);
return null; return null;
} }
String bankAcctType = null; AdapayMemberAggregateVO.AdapayMemberAggregateVOBuilder builder = AdapayMemberAggregateVO.builder()
AdapayMemberInfoVO adapayMemberInfoVO = null; .adapayMemberId(adapayMemberAccount.getAdapayMemberId());
AdapayCorpMemberVO adapayCorpMemberVO = null;
List<AdapaySettleAccountVO> list = null;
// 审核失败 // 审核失败
if (Constants.TWO.equals(adapayMemberAccount.getStatus())) { if (Constants.TWO.equals(adapayMemberAccount.getStatus())) {
bankAcctType = Constants.ONE; // 只有企业用户才会审核失败 AdapayCorpMemberVO adapayCorpMemberVO = new AdapayCorpMemberVO();
adapayCorpMemberVO = new AdapayCorpMemberVO();
MerchantInfoVO merchantInfoVO = pileMerchantInfoService.getMerchantInfoVO(adapayMemberAccount.getMerchantId()); MerchantInfoVO merchantInfoVO = pileMerchantInfoService.getMerchantInfoVO(adapayMemberAccount.getMerchantId());
if (merchantInfoVO != null) { if (merchantInfoVO != null) {
adapayCorpMemberVO.setName(merchantInfoVO.getMerchantName()); adapayCorpMemberVO.setName(merchantInfoVO.getMerchantName());
} }
adapayCorpMemberVO.setAuditState("B"); adapayCorpMemberVO.setAuditState("B");
adapayCorpMemberVO.setAuditDesc(adapayMemberAccount.getRemark()); adapayCorpMemberVO.setAuditDesc(adapayMemberAccount.getRemark());
map.put("adapayCorpMember", adapayCorpMemberVO); return builder
map.put("bankAcctType", bankAcctType); .memberType("CORP")
map.put("adapayMember", adapayMemberInfoVO); .bankAcctType(Constants.ONE)
map.put("settleAccountList", list); .adapayCorpMember(adapayCorpMemberVO)
return map; .settleAccountList(Lists.newArrayList())
.canDeleteUser(true)
.build();
} }
// 通过merchantId获取appId // 通过merchantId获取appId
String wechatAppId = pileMerchantInfoService.queryAppIdByMerchantId(merchantId); String wechatAppId = pileMerchantInfoService.queryAppIdByMerchantId(merchantId);
String adapayMemberId = adapayMemberAccount.getAdapayMemberId(); String adapayMemberId = adapayMemberAccount.getAdapayMemberId();
List<AdapaySettleAccountVO> settleAccountList = selectSettleAccount(merchantId);
boolean canDeleteUser = CollectionUtils.isEmpty(settleAccountList);
builder
.settleAccountList(settleAccountList)
.canDeleteUser(canDeleteUser)
.deleteBlockReason(canDeleteUser ? "" : "请先删除结算账户");
if (StringUtils.startsWith(adapayMemberId, Constants.ADAPAY_MEMBER_PREFIX)) { if (StringUtils.startsWith(adapayMemberId, Constants.ADAPAY_MEMBER_PREFIX)) {
bankAcctType = Constants.TWO;
// 查询个人用户 // 查询个人用户
adapayMemberInfoVO = queryAdapayMemberInfo(adapayMemberId, wechatAppId); AdapayMemberInfoVO adapayMemberInfoVO = queryAdapayMemberInfo(adapayMemberId, wechatAppId);
if (adapayMemberInfoVO != null) { return builder
adapayMemberInfoVO.setMerchantId(merchantId); .memberType("PERSONAL")
.bankAcctType(Constants.TWO)
.adapayMember(adapayMemberInfoVO)
.build();
} }
AdapaySettleAccountVO adapaySettleAccountVO = queryAdapaySettleAccount(adapayMemberId, adapayMemberAccount.getSettleAccountId(), wechatAppId);
if (adapaySettleAccountVO != null) {
adapaySettleAccountVO.setMerchantId(merchantId);
}
map.put("adapayMember", adapayMemberInfoVO);
list = Lists.newArrayList(adapaySettleAccountVO);
map.put("settleAccountList", list);
} else {
bankAcctType = Constants.ONE;
// 查询企业用户 // 查询企业用户
adapayCorpMemberVO = queryCorpAdapayMemberInfo(adapayMemberId, wechatAppId); AdapayCorpMemberVO adapayCorpMemberVO = queryCorpAdapayMemberInfo(adapayMemberId, wechatAppId);
} return builder
.memberType("CORP")
map.put("bankAcctType", bankAcctType); .bankAcctType(Constants.ONE)
map.put("adapayMember", adapayMemberInfoVO); .adapayCorpMember(adapayCorpMemberVO)
map.put("settleAccountList", list); .build();
map.put("adapayCorpMember", adapayCorpMemberVO);
return map;
} }
@@ -449,6 +492,7 @@ public class AdapayService {
QueryMemberResponse queryMemberResponse = JSON.parseObject(JSON.toJSONString(member), QueryMemberResponse.class); QueryMemberResponse queryMemberResponse = JSON.parseObject(JSON.toJSONString(member), QueryMemberResponse.class);
AdapayMemberInfoVO resultVO = AdapayMemberInfoVO.builder() AdapayMemberInfoVO resultVO = AdapayMemberInfoVO.builder()
.memberId(adapayMemberId)
.nickname(queryMemberResponse.getNickname()) .nickname(queryMemberResponse.getNickname())
.gender(queryMemberResponse.getGender()) .gender(queryMemberResponse.getGender())
.email(queryMemberResponse.getEmail()) .email(queryMemberResponse.getEmail())
@@ -761,6 +805,11 @@ public class AdapayService {
// 逻辑删除原来审核不通过的记录 // 逻辑删除原来审核不通过的记录
adapayMemberAccountService.deleteAuditFailed(dto.getMerchantId()); adapayMemberAccountService.deleteAuditFailed(dto.getMerchantId());
AdapayMemberAccount currentAccount = adapayMemberAccountService.selectByMerchantId(dto.getMerchantId());
if (currentAccount != null) {
throw new BusinessException("", "当前商户已绑定汇付用户");
}
// 创建企业用户参数 // 创建企业用户参数
Map<String, Object> memberParams = Maps.newHashMap(); Map<String, Object> memberParams = Maps.newHashMap();
String adapayMemberId = Constants.ADAPAY_CORP_MEMBER_PREFIX + IdUtils.getMemberId(); String adapayMemberId = Constants.ADAPAY_CORP_MEMBER_PREFIX + IdUtils.getMemberId();
@@ -790,10 +839,6 @@ public class AdapayService {
memberParams.put("zip_code", dto.getZipCode()); memberParams.put("zip_code", dto.getZipCode());
memberParams.put("telphone", dto.getTelphone()); memberParams.put("telphone", dto.getTelphone());
memberParams.put("email", dto.getEmail()); memberParams.put("email", dto.getEmail());
memberParams.put("bank_code", dto.getBankCode());
memberParams.put("bank_acct_type", dto.getBankAcctType());
memberParams.put("card_no", dto.getCardNo());
memberParams.put("card_name", dto.getCardName());
memberParams.put("notify_url", ADAPAY_CALLBACK_URL); memberParams.put("notify_url", ADAPAY_CALLBACK_URL);
File file = ZipUtil.createZipFileFromImages(dto.getImgList()); File file = ZipUtil.createZipFileFromImages(dto.getImgList());
Map<String, Object> member = CorpMember.create(memberParams, file, config.getWechatAppId()); Map<String, Object> member = CorpMember.create(memberParams, file, config.getWechatAppId());
@@ -958,6 +1003,63 @@ public class AdapayService {
* @return * @return
* @throws BaseAdaPayException * @throws BaseAdaPayException
*/ */
public void updateAdapayMember(Map<String, Object> payload) throws BaseAdaPayException {
String merchantId = (String) payload.get("merchantId");
AdapayMemberAccount adapayMemberAccount = requireCurrentMemberAccount(merchantId);
if (isPersonalMember(adapayMemberAccount.getAdapayMemberId())) {
UpdatePersonalMemberDTO dto = JSON.parseObject(JSON.toJSONString(payload), UpdatePersonalMemberDTO.class);
updatePersonalMember(dto);
return;
}
UpdateCorpMemberDTO dto = JSON.parseObject(JSON.toJSONString(payload), UpdateCorpMemberDTO.class);
updateCorpMember(dto);
}
public void updateCorpMember(UpdateCorpMemberDTO dto) throws BaseAdaPayException {
SettleAccountDTO request = SettleAccountDTO.builder()
.merchantId(dto.getMerchantId())
.businessName(dto.getName())
.provCode(dto.getProvCode())
.areaCode(dto.getAreaCode())
.socialCreditCodeExpires(dto.getSocialCreditCodeExpires())
.businessScope(dto.getBusinessScope())
.legalPerson(dto.getLegalPerson())
.legalCertId(dto.getLegalCertId())
.legalCertIdExpires(dto.getLegalCertIdExpires())
.legalMp(dto.getLegalMp())
.address(dto.getAddress())
.zipCode(dto.getZipCode())
.telphone(dto.getTelphone())
.email(dto.getEmail())
.imgList(dto.getImgList())
.build();
updateAdapayMember(request);
}
public void updatePersonalMember(UpdatePersonalMemberDTO dto) throws BaseAdaPayException {
String wechatAppId = pileMerchantInfoService.queryAppIdByMerchantId(dto.getMerchantId());
AbstractAdapayConfig config = AdapayConfigFactory.getConfig(wechatAppId);
if (config == null) {
throw new BusinessException(ReturnCodeEnum.CODE_ADAPAY_CONFIG_IS_NULL_ERROR);
}
AdapayMemberAccount adapayMemberAccount = requireCurrentMemberAccount(dto.getMerchantId());
Map<String, Object> memberParams = Maps.newHashMap();
memberParams.put("member_id", adapayMemberAccount.getAdapayMemberId());
memberParams.put("app_id", config.getAdapayAppId());
memberParams.put("location", dto.getLocation());
memberParams.put("email", dto.getEmail());
memberParams.put("gender", dto.getGender());
memberParams.put("nickname", dto.getNickname());
Map<String, Object> member = Member.update(memberParams, config.getWechatAppId());
log.info("更新个人账户param:{}, result:{}", JSON.toJSONString(memberParams), JSON.toJSONString(member));
if (member == null || AdapayStatusEnum.FAILED.getValue().equals((String) member.get("status"))) {
String errorMsg = member == null ? "更新汇付个人用户失败" : (String) member.get("error_msg");
throw new BusinessException("", errorMsg);
}
}
public Map<String, Object> updateAdapayMember(SettleAccountDTO dto) throws BaseAdaPayException { public Map<String, Object> updateAdapayMember(SettleAccountDTO dto) throws BaseAdaPayException {
String wechatAppId = pileMerchantInfoService.queryAppIdByMerchantId(dto.getMerchantId()); String wechatAppId = pileMerchantInfoService.queryAppIdByMerchantId(dto.getMerchantId());
// 获取汇付支付配置 // 获取汇付支付配置
@@ -1486,7 +1588,13 @@ public class AdapayService {
settleAccountDTO.setBankAcctType(dto.getBankAcctType()); settleAccountDTO.setBankAcctType(dto.getBankAcctType());
settleAccountDTO.setProvCode(dto.getProvCode()); settleAccountDTO.setProvCode(dto.getProvCode());
settleAccountDTO.setAreaCode(dto.getAreaCode()); settleAccountDTO.setAreaCode(dto.getAreaCode());
this.createSettleAccountRequest(settleAccountDTO, adapayMemberId, wechatAppId); Map<String, Object> settleAccount = this.createSettleAccountRequest(settleAccountDTO, adapayMemberId, wechatAppId);
if (settleAccount != null && !StringUtils.equals((String) settleAccount.get("status"), "failed")) {
AdapayMemberAccount updateRecord = new AdapayMemberAccount();
updateRecord.setAdapayMemberId(adapayMemberId);
updateRecord.setSettleAccountId((String) settleAccount.get("id"));
adapayMemberAccountService.updateAdapayMemberAccountByMemberId(updateRecord);
}
} }
/** /**
@@ -1551,33 +1659,21 @@ public class AdapayService {
* @throws BaseAdaPayException * @throws BaseAdaPayException
*/ */
public void createBankAccount(SettleAccountDTO dto) throws BaseAdaPayException { public void createBankAccount(SettleAccountDTO dto) throws BaseAdaPayException {
// 根据运营商id 查出现有的adapayMemberId CreateSettleAccountDTO request = CreateSettleAccountDTO.builder()
String merchantId = dto.getMerchantId(); .merchantId(dto.getMerchantId())
// 新写一个查询方法,查询最近一条的记录(因为之前已经删除过数据,使用原查询方法查不到数据) .bankAcctType(dto.getBankAcctType())
AdapayMemberAccount adapayMemberAccount = adapayMemberAccountService.selectRecentInfoByMerchantId(merchantId); .cardId(dto.getCardId())
if (adapayMemberAccount == null) { .cardNo(dto.getCardNo())
return; .cardName(dto.getCardName())
} .certId(dto.getCertId())
String adapayMemberId = adapayMemberAccount.getAdapayMemberId(); .certType(dto.getCertType())
// 查询该商户的wxAppId .telNo(dto.getTelNo())
String wxAppId = pileMerchantInfoService.queryAppIdByMerchantId(merchantId); .bankCode(dto.getBankCode())
// 创建结算账户请求 .bankName(dto.getBankName())
Map<String, Object> settleAccount = this.createSettleAccountRequest(dto, adapayMemberId, wxAppId); .provCode(dto.getProvCode())
.areaCode(dto.getAreaCode())
// 保存结果 .build();
if (settleAccount == null || StringUtils.equals((String) settleAccount.get("status"), "failed")) { createSettleAccount(request);
String errorMsg = settleAccount == null ? "创建汇付结算账户失败" : (String) settleAccount.get("error_msg");
throw new BusinessException("00500001", errorMsg);
}
String settleAccountId = (String) settleAccount.get("id");
// 保存到数据库
adapayMemberAccount = new AdapayMemberAccount();
adapayMemberAccount.setMerchantId(dto.getMerchantId());
adapayMemberAccount.setAdapayMemberId(adapayMemberId);
adapayMemberAccount.setSettleAccountId(settleAccountId);
adapayMemberAccount.setStatus(Constants.ONE);
adapayMemberAccountService.insertAdapayMemberAccount(adapayMemberAccount);
} }
/** /**
@@ -1586,14 +1682,79 @@ public class AdapayService {
* @throws BaseAdaPayException * @throws BaseAdaPayException
*/ */
public void deleteSettleAccount(AdapayMemberInfoDTO dto) throws BaseAdaPayException { public void deleteSettleAccount(AdapayMemberInfoDTO dto) throws BaseAdaPayException {
// 查询appId AdapayMemberAccount adapayMemberAccount = requireCurrentMemberAccount(dto.getMerchantId());
String wechatAppId = pileMerchantInfoService.queryAppIdByMerchantId(dto.getMerchantId()); String wechatAppId = pileMerchantInfoService.queryAppIdByMerchantId(dto.getMerchantId());
// 1、新建删除请求 2、如果成功再将数据库中的记录删除 String adapayMemberId = StringUtils.isNotBlank(dto.getAdapayMemberId()) ? dto.getAdapayMemberId() : adapayMemberAccount.getAdapayMemberId();
this.createDeleteSettleAccountRequest(dto.getAdapayMemberId(), dto.getSettleAccountId(), wechatAppId); String settleAccountId = StringUtils.isNotBlank(dto.getSettleAccountId()) ? dto.getSettleAccountId() : adapayMemberAccount.getSettleAccountId();
// 删除数据库中的记录 if (StringUtils.isBlank(settleAccountId) && isCorpMember(adapayMemberId)) {
AdapayCorpMemberVO corpMemberVO = queryCorpAdapayMemberInfo(adapayMemberId, wechatAppId);
if (corpMemberVO != null) {
settleAccountId = corpMemberVO.getSettleAccountId();
}
}
if (StringUtils.isBlank(settleAccountId)) {
throw new BusinessException("", "未查询到结算账户");
}
this.createDeleteSettleAccountRequest(adapayMemberId, settleAccountId, wechatAppId);
adapayMemberAccountService.clearSettleAccountByMerchantId(dto.getMerchantId());
}
public void deleteAdapayMember(DeleteAdapayMemberDTO dto) throws BaseAdaPayException {
AdapayMemberAccount adapayMemberAccount = requireCurrentMemberAccount(dto.getMerchantId());
if (StringUtils.isNotBlank(dto.getAdapayMemberId())
&& !StringUtils.equals(dto.getAdapayMemberId(), adapayMemberAccount.getAdapayMemberId())) {
throw new BusinessException("", "汇付用户信息不匹配");
}
if (CollectionUtils.isNotEmpty(selectSettleAccount(dto.getMerchantId()))) {
throw new BusinessException("", "请先删除结算账户");
}
adapayMemberAccountService.deleteAccountByMerchantId(dto.getMerchantId()); adapayMemberAccountService.deleteAccountByMerchantId(dto.getMerchantId());
} }
private AdapayMemberAccount requireCurrentMemberAccount(String merchantId) {
AdapayMemberAccount adapayMemberAccount = adapayMemberAccountService.selectByMerchantId(merchantId);
if (adapayMemberAccount == null) {
throw new BusinessException(ReturnCodeEnum.CODE_ADAPAY_MEMBER_IS_NULL_ERROR);
}
return adapayMemberAccount;
}
private boolean isPersonalMember(String adapayMemberId) {
return StringUtils.startsWith(adapayMemberId, Constants.ADAPAY_MEMBER_PREFIX);
}
private boolean isCorpMember(String adapayMemberId) {
return StringUtils.startsWith(adapayMemberId, Constants.ADAPAY_CORP_MEMBER_PREFIX);
}
private SettleAccountDTO buildSettleAccountDTO(CreateSettleAccountDTO dto) {
SettleAccountDTO request = SettleAccountDTO.builder()
.merchantId(dto.getMerchantId())
.bankAcctType(dto.getBankAcctType())
.cardId(dto.getCardId())
.cardNo(dto.getCardNo())
.cardName(dto.getCardName())
.certId(dto.getCertId())
.certType(dto.getCertType())
.telNo(dto.getTelNo())
.bankCode(dto.getBankCode())
.bankName(dto.getBankName())
.provCode(dto.getProvCode())
.areaCode(dto.getAreaCode())
.build();
String cardId = request.getCardId();
String cardNo = request.getCardNo();
if (StringUtils.isBlank(cardId) && StringUtils.isNotBlank(cardNo)) {
request.setCardId(cardNo);
}
if (StringUtils.isBlank(cardNo) && StringUtils.isNotBlank(cardId)) {
request.setCardNo(cardId);
}
return request;
}
/** /**
* 根据paymentIdList查询分账信息 * 根据paymentIdList查询分账信息
* @param paymentIdList * @param paymentIdList

View File

@@ -0,0 +1,21 @@
package com.jsowell.adapay.vo;
import lombok.*;
import java.util.List;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class AdapayMemberAggregateVO {
private String memberType;
private String bankAcctType;
private String adapayMemberId;
private Boolean canDeleteUser;
private String deleteBlockReason;
private AdapayMemberInfoVO adapayMember;
private AdapayCorpMemberVO adapayCorpMember;
private List<AdapaySettleAccountVO> settleAccountList;
}

View File

@@ -8,6 +8,8 @@ import lombok.*;
@AllArgsConstructor @AllArgsConstructor
@Builder @Builder
public class AdapayMemberInfoVO { public class AdapayMemberInfoVO {
// 汇付会员id
private String memberId;
// 运营商id // 运营商id
private String merchantId; private String merchantId;
// 地址 // 地址

View File

@@ -126,6 +126,8 @@ public interface AdapayMemberAccountMapper {
*/ */
void deleteAccountByMerchantId(String merchantId); void deleteAccountByMerchantId(String merchantId);
void clearSettleAccountByMerchantId(String merchantId);
/** /**
* 根据运营商id查询最近一条的信息 * 根据运营商id查询最近一条的信息
* @param merchantId * @param merchantId

View File

@@ -116,6 +116,8 @@ public interface AdapayMemberAccountService {
*/ */
void deleteAccountByMerchantId(String merchantId); void deleteAccountByMerchantId(String merchantId);
void clearSettleAccountByMerchantId(String merchantId);
/** /**
* 根据运营商Id查询最近一条的信息 * 根据运营商Id查询最近一条的信息
* @param merchantId * @param merchantId

View File

@@ -262,6 +262,13 @@ public class AdapayMemberAccountServiceImpl implements AdapayMemberAccountServic
@Override @Override
public void deleteAccountByMerchantId(String merchantId) { public void deleteAccountByMerchantId(String merchantId) {
adapayMemberAccountMapper.deleteAccountByMerchantId(merchantId); adapayMemberAccountMapper.deleteAccountByMerchantId(merchantId);
redisCache.deleteObject(CacheConstants.ADAPAY_MEMBER_ACCOUNT + merchantId);
}
@Override
public void clearSettleAccountByMerchantId(String merchantId) {
adapayMemberAccountMapper.clearSettleAccountByMerchantId(merchantId);
redisCache.deleteObject(CacheConstants.ADAPAY_MEMBER_ACCOUNT + merchantId);
} }
/** /**
@@ -282,4 +289,3 @@ public class AdapayMemberAccountServiceImpl implements AdapayMemberAccountServic
return adapayMemberAccountMapper.selectUsedAdapayMemberIdByMerchantId(merchantId); return adapayMemberAccountMapper.selectUsedAdapayMemberIdByMerchantId(merchantId);
} }
} }

View File

@@ -515,6 +515,8 @@
from adapay_member_account from adapay_member_account
where del_flag = '0' where del_flag = '0'
and merchant_id = #{merchantId,jdbcType=VARCHAR} and merchant_id = #{merchantId,jdbcType=VARCHAR}
order by create_time desc, id desc
limit 1
</select> </select>
<delete id="deleteByMemberId"> <delete id="deleteByMemberId">
@@ -532,8 +534,18 @@
<update id="deleteAccountByMerchantId"> <update id="deleteAccountByMerchantId">
update update
adapay_member_account adapay_member_account
set del_flag = '0' set del_flag = '1'
where merchant_id = #{merchantId,jdbcType=VARCHAR} where merchant_id = #{merchantId,jdbcType=VARCHAR}
and del_flag = '0'
</update>
<update id="clearSettleAccountByMerchantId">
update
adapay_member_account
set settle_account_id = null,
update_time = now()
where merchant_id = #{merchantId,jdbcType=VARCHAR}
and del_flag = '0'
</update> </update>
<select id="selectRecentInfoByMerchantId" resultMap="BaseResultMap"> <select id="selectRecentInfoByMerchantId" resultMap="BaseResultMap">