|
|
@@ -4,10 +4,17 @@ import cn.dev33.satoken.secure.BCrypt;
|
|
|
import cn.hutool.core.bean.BeanUtil;
|
|
|
import cn.hutool.core.date.DateUtil;
|
|
|
import cn.hutool.core.util.ObjectUtil;
|
|
|
+import com.alipay.api.AlipayClient;
|
|
|
+import com.alipay.api.DefaultAlipayClient;
|
|
|
+import com.alipay.api.domain.AlipayFundTransUniTransferModel;
|
|
|
+import com.alipay.api.domain.Participant;
|
|
|
+import com.alipay.api.request.AlipayFundTransUniTransferRequest;
|
|
|
+import com.alipay.api.response.AlipayFundTransUniTransferResponse;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
import com.ruoyi.agent.domain.Agent;
|
|
|
+import com.ruoyi.agent.domain.bo.AgentChangeBalanceBo;
|
|
|
import com.ruoyi.agent.service.IAgentService;
|
|
|
import com.ruoyi.base.revenue.domain.vo.RevenueSharingConfigVo;
|
|
|
import com.ruoyi.base.revenue.service.IRevenueSharingConfigService;
|
|
|
@@ -15,6 +22,7 @@ import com.ruoyi.common.core.domain.PageQuery;
|
|
|
import com.ruoyi.common.core.page.TableDataInfo;
|
|
|
import com.ruoyi.common.enums.AuditStatus;
|
|
|
import com.ruoyi.common.exception.ServiceException;
|
|
|
+import com.ruoyi.common.properties.AlipayProperties;
|
|
|
import com.ruoyi.common.utils.BeanCopyUtils;
|
|
|
import com.ruoyi.common.utils.MathUtils;
|
|
|
import com.ruoyi.common.utils.StringUtils;
|
|
|
@@ -30,12 +38,19 @@ import com.ruoyi.shop.withdrawal.service.IWithdrawalService;
|
|
|
import com.ruoyi.system.enums.SequencePrefixEnum;
|
|
|
import com.ruoyi.system.service.ISysSequenceService;
|
|
|
import com.ruoyi.user.domain.User;
|
|
|
+import com.ruoyi.user.domain.bo.UserChangeBalanceBo;
|
|
|
+import com.ruoyi.user.enums.BalanceSourceType;
|
|
|
import com.ruoyi.user.service.IUserService;
|
|
|
import lombok.RequiredArgsConstructor;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
|
import java.math.BigDecimal;
|
|
|
-import java.util.*;
|
|
|
+import java.util.Collection;
|
|
|
+import java.util.Date;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
|
|
|
/**
|
|
|
* 提现Service业务层处理
|
|
|
@@ -43,6 +58,7 @@ import java.util.*;
|
|
|
* @author ruoyi
|
|
|
* @date 2025-12-04
|
|
|
*/
|
|
|
+@Slf4j
|
|
|
@RequiredArgsConstructor
|
|
|
@Service
|
|
|
public class WithdrawalServiceImpl implements IWithdrawalService {
|
|
|
@@ -52,6 +68,7 @@ public class WithdrawalServiceImpl implements IWithdrawalService {
|
|
|
private final IAgentService agentService;
|
|
|
private final IRevenueSharingConfigService revenueSharingConfigService;
|
|
|
private final ISysSequenceService sysSequenceService;
|
|
|
+ private final AlipayProperties aliPayConfig;
|
|
|
|
|
|
/**
|
|
|
* 查询提现分页
|
|
|
@@ -266,4 +283,111 @@ public class WithdrawalServiceImpl implements IWithdrawalService {
|
|
|
return baseMapper.statistics(bo);
|
|
|
}
|
|
|
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ @Override
|
|
|
+ public Boolean audit(WithdrawalBo bo) {
|
|
|
+ Withdrawal withdrawal = loadLockById(bo.getId());
|
|
|
+ if (!AuditStatus.WAIT_AUDIT.equals(withdrawal.getAuditStatus())) {
|
|
|
+ throw new ServiceException(WithdrawalExceptionEnum.WITHDRAWAL_STATUS_NOT_WAIT_AUDIT);
|
|
|
+ }
|
|
|
+ if (WithdrawalStatus.SUCCESS.equals(withdrawal.getStatus())) {
|
|
|
+ throw new ServiceException(WithdrawalExceptionEnum.WITHDRAWAL_STATUS_SUCCESS);
|
|
|
+ }
|
|
|
+ if (AuditStatus.AUDIT_PASS.equals(bo.getAuditStatus())) {
|
|
|
+ BigDecimal amount = withdrawal.getAmount();
|
|
|
+ WithdrawalAmountVo amountVo = amount(withdrawal.getWithdrawalSourceId(), withdrawal.getWithdrawalSource());
|
|
|
+ if (amountVo.getAbleAmount().compareTo(amount) < 0) {
|
|
|
+ throw new ServiceException(WithdrawalExceptionEnum.WITHDRAWAL_AMOUNT_NOT_ENOUGH);
|
|
|
+ }
|
|
|
+ BigDecimal paymentAmount = amount.subtract(withdrawal.getFee());
|
|
|
+ //调用支付宝 转账
|
|
|
+ String thirdOrderId = alipayFundTrans(withdrawal.getWithdrawalNo(), paymentAmount, "平台提现", withdrawal.getAccountInfo());
|
|
|
+ if (StringUtils.isEmpty(thirdOrderId)) {
|
|
|
+ throw new ServiceException(WithdrawalExceptionEnum.WITHDRAWAL_THIRD_ORDER_ID_EMPTY);
|
|
|
+ }
|
|
|
+ withdrawal.setThirdOrderId(thirdOrderId);
|
|
|
+ //扣减钱包
|
|
|
+ if (WithdrawalSource.USER.equals(withdrawal.getWithdrawalSource())) {
|
|
|
+ userService.changeUserBalance(UserChangeBalanceBo.builder()
|
|
|
+ .userId(withdrawal.getWithdrawalSourceId())
|
|
|
+ .entryValue(amount)
|
|
|
+ .isAdd(false)
|
|
|
+ .sourceType(BalanceSourceType.WITHDRAWAL)
|
|
|
+ .sourceId(withdrawal.getId())
|
|
|
+ .sourceCode(withdrawal.getWithdrawalNo())
|
|
|
+ .remark("提现扣减")
|
|
|
+ .build());
|
|
|
+ } else if (WithdrawalSource.AGENT.equals(withdrawal.getWithdrawalSource())) {
|
|
|
+ agentService.changeAgentBalance(AgentChangeBalanceBo.builder()
|
|
|
+ .agentId(withdrawal.getWithdrawalSourceId())
|
|
|
+ .entryValue(amount)
|
|
|
+ .isAdd(false)
|
|
|
+ .sourceType(com.ruoyi.agent.enums.BalanceSourceType.WITHDRAW)
|
|
|
+ .sourceId(withdrawal.getId())
|
|
|
+ .sourceCode(withdrawal.getWithdrawalNo())
|
|
|
+ .remark("提现扣减")
|
|
|
+ .build());
|
|
|
+ }
|
|
|
+ withdrawal.setStatus(WithdrawalStatus.SUCCESS);
|
|
|
+ withdrawal.setPaymentAmount(paymentAmount);
|
|
|
+ withdrawal.setPaymentTime(new Date());
|
|
|
+ } else if (AuditStatus.AUDIT_NOT_PASS.equals(bo.getAuditStatus())) {
|
|
|
+ if (StringUtils.isEmpty(bo.getAuditResult())) {
|
|
|
+ throw new ServiceException(WithdrawalExceptionEnum.WITHDRAWAL_AUDIT_RESULT_NOT_EMPTY);
|
|
|
+ }
|
|
|
+ withdrawal.setStatus(WithdrawalStatus.FAIL);
|
|
|
+ } else {
|
|
|
+ throw new ServiceException(WithdrawalExceptionEnum.WITHDRAWAL_AUDIT_STATUS_NOT_SUPPORT);
|
|
|
+ }
|
|
|
+ withdrawal.setAuditStatus(bo.getAuditStatus());
|
|
|
+ withdrawal.setAuditTime(new Date());
|
|
|
+ withdrawal.setAuditUserId(bo.getAuditUserId());
|
|
|
+ withdrawal.setAuditResult(bo.getAuditResult());
|
|
|
+ return baseMapper.updateById(withdrawal) > 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ private String alipayFundTrans(String withdrawalNo, BigDecimal amount, String title, String identity) {
|
|
|
+ try {
|
|
|
+ AlipayClient alipayClient = new DefaultAlipayClient(aliPayConfig.getServerUrl(), // 支付宝网关(固定)
|
|
|
+ aliPayConfig.getAppId(), // APPID 即创建应用后生成
|
|
|
+ aliPayConfig.getAppPrivateKey(), // 开发者私钥,由开发者自己生成
|
|
|
+ aliPayConfig.getFormat(), // 参数返回格式,只支持json
|
|
|
+ aliPayConfig.getCharset(), // 编码集,支持GBK/UTF-8
|
|
|
+ aliPayConfig.getAlipayPublicKey(), // 支付宝公钥,由支付宝生成
|
|
|
+ aliPayConfig.getSignType()); // 商户生成签名字符串所使用的签名算法类型,目前支持RSA2和RSA,推荐使用RSA2
|
|
|
+ // 构造请求参数以调用接口
|
|
|
+ AlipayFundTransUniTransferRequest request = new AlipayFundTransUniTransferRequest();
|
|
|
+ AlipayFundTransUniTransferModel model = new AlipayFundTransUniTransferModel();
|
|
|
+ // 设置商家侧唯一订单号
|
|
|
+ model.setOutBizNo(withdrawalNo);
|
|
|
+ // 设置订单总金额
|
|
|
+ model.setTransAmount(amount.toString());
|
|
|
+ // 设置描述特定的业务场景
|
|
|
+ model.setBizScene("DIRECT_TRANSFER");
|
|
|
+ // 设置业务产品码
|
|
|
+ model.setProductCode("TRANS_ACCOUNT_NO_PWD");
|
|
|
+ // 设置转账业务的标题
|
|
|
+ model.setOrderTitle(title);
|
|
|
+ // 设置收款方信息
|
|
|
+ Participant payeeInfo = new Participant();
|
|
|
+ payeeInfo.setIdentity(identity);
|
|
|
+ payeeInfo.setIdentityType("ALIPAY_LOGON_ID");
|
|
|
+ model.setPayeeInfo(payeeInfo);
|
|
|
+ request.setBizModel(model);
|
|
|
+ AlipayFundTransUniTransferResponse response = alipayClient.certificateExecute(request);
|
|
|
+ if (response.isSuccess() && "SUCCESS".equals(response.getStatus())) {
|
|
|
+ return response.getOrderId();
|
|
|
+ } else {
|
|
|
+ log.info("支付宝转账失败{},{}", response.getMsg(), response.getSubMsg());
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("支付宝转账异常", e);
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ private Withdrawal loadLockById(Long id) {
|
|
|
+ return baseMapper.selectOne(new LambdaQueryWrapper<Withdrawal>().eq(Withdrawal::getId, id).last("limit 1 for update"));
|
|
|
+ }
|
|
|
+
|
|
|
}
|