Commit 0e754a9924aff002dde438bf725ea84c3a7f5c35

Authored by puhui999
2 parents f363c598 89e847c8

Merge remote-tracking branch 'yudao/feature/mall_product' into feature/mall_product

Showing 42 changed files with 323 additions and 245 deletions
sql/mysql/pay_wallet.sql
@@ -9,7 +9,7 @@ CREATE TABLE `pay_transfer` @@ -9,7 +9,7 @@ CREATE TABLE `pay_transfer`
9 `app_id` bigint NOT NULL COMMENT '应用编号', 9 `app_id` bigint NOT NULL COMMENT '应用编号',
10 `merchant_order_id` varchar(64) NOT NULL COMMENT '商户订单编号', 10 `merchant_order_id` varchar(64) NOT NULL COMMENT '商户订单编号',
11 `price` int NOT NULL COMMENT '转账金额,单位:分', 11 `price` int NOT NULL COMMENT '转账金额,单位:分',
12 - `title` varchar(512) NOT NULL COMMENT '转账标题', 12 + `subject` varchar(512) NOT NULL COMMENT '转账标题',
13 `payee_info` varchar(512) NOT NULL COMMENT '收款人信息,不同类型和渠道不同', 13 `payee_info` varchar(512) NOT NULL COMMENT '收款人信息,不同类型和渠道不同',
14 `status` tinyint NOT NULL COMMENT '转账状态', 14 `status` tinyint NOT NULL COMMENT '转账状态',
15 `success_time` datetime NULL COMMENT '转账成功时间', 15 `success_time` datetime NULL COMMENT '转账成功时间',
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/PayClientFactoryImpl.java
@@ -50,8 +50,6 @@ public class PayClientFactoryImpl implements PayClientFactory { @@ -50,8 +50,6 @@ public class PayClientFactoryImpl implements PayClientFactory {
50 clientClass.put(ALIPAY_APP, AlipayAppPayClient.class); 50 clientClass.put(ALIPAY_APP, AlipayAppPayClient.class);
51 clientClass.put(ALIPAY_PC, AlipayPcPayClient.class); 51 clientClass.put(ALIPAY_PC, AlipayPcPayClient.class);
52 clientClass.put(ALIPAY_BAR, AlipayBarPayClient.class); 52 clientClass.put(ALIPAY_BAR, AlipayBarPayClient.class);
53 - // 支付包转账客户端  
54 - clientClass.put(ALIPAY_TRANSFER, AlipayTransferClient.class);  
55 // Mock 支付客户端 53 // Mock 支付客户端
56 clientClass.put(MOCK, MockPayClient.class); 54 clientClass.put(MOCK, MockPayClient.class);
57 } 55 }
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java
@@ -6,24 +6,28 @@ import cn.hutool.core.lang.Assert; @@ -6,24 +6,28 @@ import cn.hutool.core.lang.Assert;
6 import cn.hutool.core.map.MapUtil; 6 import cn.hutool.core.map.MapUtil;
7 import cn.hutool.core.util.StrUtil; 7 import cn.hutool.core.util.StrUtil;
8 import cn.hutool.http.HttpUtil; 8 import cn.hutool.http.HttpUtil;
  9 +import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
9 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; 10 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
10 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; 11 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
11 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO; 12 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
12 import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO; 13 import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO;
13 import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO; 14 import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO;
  15 +import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferRespDTO;
  16 +import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferUnifiedReqDTO;
14 import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient; 17 import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient;
15 import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum; 18 import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum;
  19 +import cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferTypeEnum;
16 import com.alipay.api.AlipayApiException; 20 import com.alipay.api.AlipayApiException;
17 import com.alipay.api.AlipayConfig; 21 import com.alipay.api.AlipayConfig;
18 import com.alipay.api.AlipayResponse; 22 import com.alipay.api.AlipayResponse;
19 import com.alipay.api.DefaultAlipayClient; 23 import com.alipay.api.DefaultAlipayClient;
20 -import com.alipay.api.domain.AlipayTradeFastpayRefundQueryModel;  
21 -import com.alipay.api.domain.AlipayTradeQueryModel;  
22 -import com.alipay.api.domain.AlipayTradeRefundModel; 24 +import com.alipay.api.domain.*;
23 import com.alipay.api.internal.util.AlipaySignature; 25 import com.alipay.api.internal.util.AlipaySignature;
  26 +import com.alipay.api.request.AlipayFundTransUniTransferRequest;
24 import com.alipay.api.request.AlipayTradeFastpayRefundQueryRequest; 27 import com.alipay.api.request.AlipayTradeFastpayRefundQueryRequest;
25 import com.alipay.api.request.AlipayTradeQueryRequest; 28 import com.alipay.api.request.AlipayTradeQueryRequest;
26 import com.alipay.api.request.AlipayTradeRefundRequest; 29 import com.alipay.api.request.AlipayTradeRefundRequest;
  30 +import com.alipay.api.response.AlipayFundTransUniTransferResponse;
27 import com.alipay.api.response.AlipayTradeFastpayRefundQueryResponse; 31 import com.alipay.api.response.AlipayTradeFastpayRefundQueryResponse;
28 import com.alipay.api.response.AlipayTradeQueryResponse; 32 import com.alipay.api.response.AlipayTradeQueryResponse;
29 import com.alipay.api.response.AlipayTradeRefundResponse; 33 import com.alipay.api.response.AlipayTradeRefundResponse;
@@ -39,6 +43,9 @@ import java.util.Objects; @@ -39,6 +43,9 @@ import java.util.Objects;
39 import java.util.function.Supplier; 43 import java.util.function.Supplier;
40 44
41 import static cn.hutool.core.date.DatePattern.NORM_DATETIME_FORMATTER; 45 import static cn.hutool.core.date.DatePattern.NORM_DATETIME_FORMATTER;
  46 +import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST;
  47 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception0;
  48 +import static cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig.MODE_CERTIFICATE;
42 49
43 /** 50 /**
44 * 支付宝抽象类,实现支付宝统一的接口、以及部分实现(退款) 51 * 支付宝抽象类,实现支付宝统一的接口、以及部分实现(退款)
@@ -105,16 +112,20 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient<AlipayPa @@ -105,16 +112,20 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient<AlipayPa
105 // 1.2 构建 AlipayTradeQueryRequest 请求 112 // 1.2 构建 AlipayTradeQueryRequest 请求
106 AlipayTradeQueryRequest request = new AlipayTradeQueryRequest(); 113 AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
107 request.setBizModel(model); 114 request.setBizModel(model);
108 -  
109 - // 2.1 执行请求  
110 - AlipayTradeQueryResponse response = client.execute(request); 115 + AlipayTradeQueryResponse response;
  116 + if (Objects.equals(config.getMode(), MODE_CERTIFICATE)) {
  117 + // 证书模式
  118 + response = client.certificateExecute(request);
  119 + } else {
  120 + response = client.execute(request);
  121 + }
111 if (!response.isSuccess()) { // 不成功,例如说订单不存在 122 if (!response.isSuccess()) { // 不成功,例如说订单不存在
112 return PayOrderRespDTO.closedOf(response.getSubCode(), response.getSubMsg(), 123 return PayOrderRespDTO.closedOf(response.getSubCode(), response.getSubMsg(),
113 outTradeNo, response); 124 outTradeNo, response);
114 } 125 }
115 // 2.2 解析订单的状态 126 // 2.2 解析订单的状态
116 Integer status = parseStatus(response.getTradeStatus()); 127 Integer status = parseStatus(response.getTradeStatus());
117 - Assert.notNull(status, (Supplier<Throwable>) () -> { 128 + Assert.notNull(status, () -> {
118 throw new IllegalArgumentException(StrUtil.format("body({}) 的 trade_status 不正确", response.getBody())); 129 throw new IllegalArgumentException(StrUtil.format("body({}) 的 trade_status 不正确", response.getBody()));
119 }); 130 });
120 return PayOrderRespDTO.of(status, response.getTradeNo(), response.getBuyerUserId(), LocalDateTimeUtil.of(response.getSendPayDate()), 131 return PayOrderRespDTO.of(status, response.getTradeNo(), response.getBuyerUserId(), LocalDateTimeUtil.of(response.getSendPayDate()),
@@ -148,7 +159,13 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient&lt;AlipayPa @@ -148,7 +159,13 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient&lt;AlipayPa
148 request.setBizModel(model); 159 request.setBizModel(model);
149 160
150 // 2.1 执行请求 161 // 2.1 执行请求
151 - AlipayTradeRefundResponse response = client.execute(request); 162 + AlipayTradeRefundResponse response;
  163 + if (Objects.equals(config.getMode(), MODE_CERTIFICATE)) {
  164 + // 证书模式
  165 + response = client.certificateExecute(request);
  166 + } else {
  167 + response = client.execute(request);
  168 + }
152 if (!response.isSuccess()) { 169 if (!response.isSuccess()) {
153 // 当出现 ACQ.SYSTEM_ERROR, 退款可能成功也可能失败。 返回 WAIT 状态. 后续 job 会轮询 170 // 当出现 ACQ.SYSTEM_ERROR, 退款可能成功也可能失败。 返回 WAIT 状态. 后续 job 会轮询
154 if (ObjectUtils.equalsAny(response.getSubCode(), "ACQ.SYSTEM_ERROR", "SYSTEM_ERROR")) { 171 if (ObjectUtils.equalsAny(response.getSubCode(), "ACQ.SYSTEM_ERROR", "SYSTEM_ERROR")) {
@@ -185,7 +202,13 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient&lt;AlipayPa @@ -185,7 +202,13 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient&lt;AlipayPa
185 request.setBizModel(model); 202 request.setBizModel(model);
186 203
187 // 2.1 执行请求 204 // 2.1 执行请求
188 - AlipayTradeFastpayRefundQueryResponse response = client.execute(request); 205 + AlipayTradeFastpayRefundQueryResponse response;
  206 + if (Objects.equals(config.getMode(), MODE_CERTIFICATE)) {
  207 + // 证书模式
  208 + response = client.certificateExecute(request);
  209 + } else {
  210 + response = client.execute(request);
  211 + }
189 if (!response.isSuccess()) { 212 if (!response.isSuccess()) {
190 // 明确不存在的情况,应该就是失败,可进行关闭 213 // 明确不存在的情况,应该就是失败,可进行关闭
191 if (ObjectUtils.equalsAny(response.getSubCode(), "TRADE_NOT_EXIST", "ACQ.TRADE_NOT_EXIST")) { 214 if (ObjectUtils.equalsAny(response.getSubCode(), "TRADE_NOT_EXIST", "ACQ.TRADE_NOT_EXIST")) {
@@ -202,7 +225,69 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient&lt;AlipayPa @@ -202,7 +225,69 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient&lt;AlipayPa
202 return PayRefundRespDTO.waitingOf(null, outRefundNo, response); 225 return PayRefundRespDTO.waitingOf(null, outRefundNo, response);
203 } 226 }
204 227
  228 + @Override
  229 + protected PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) throws AlipayApiException {
  230 + // 1.1 校验公钥类型 必须使用公钥证书模式
  231 + if (!Objects.equals(config.getMode(), MODE_CERTIFICATE)) {
  232 + throw new IllegalStateException("支付宝单笔转账必须使用公钥证书模式");
  233 + }
205 234
  235 + // 1.2 构建 AlipayFundTransUniTransferModel
  236 + AlipayFundTransUniTransferModel model = new AlipayFundTransUniTransferModel();
  237 + // ① 通用的参数
  238 + model.setTransAmount(formatAmount(reqDTO.getPrice())); // 转账金额
  239 + model.setOrderTitle(reqDTO.getTitle()); // 转账业务的标题,用于在支付宝用户的账单里显示。
  240 + model.setOutBizNo(reqDTO.getOutTransferNo());
  241 + model.setProductCode("TRANS_ACCOUNT_NO_PWD"); // 销售产品码。单笔无密转账固定为 TRANS_ACCOUNT_NO_PWD
  242 + model.setBizScene("DIRECT_TRANSFER"); // 业务场景 单笔无密转账固定为 DIRECT_TRANSFER
  243 + model.setBusinessParams(JsonUtils.toJsonString(reqDTO.getChannelExtras()));
  244 + PayTransferTypeEnum transferType = PayTransferTypeEnum.typeOf(reqDTO.getType());
  245 + switch (transferType) {
  246 + // TODO @jason:是不是不用传递 transferType 参数哈?因为应该已经明确是支付宝啦?
  247 + // @芋艿。 是不是还要考虑转账到银行卡。所以传 transferType 但是转账到银行卡不知道要如何测试??
  248 + case ALIPAY_BALANCE: {
  249 + // ② 个性化的参数
  250 + Participant payeeInfo = new Participant();
  251 + payeeInfo.setIdentityType("ALIPAY_LOGON_ID");
  252 + String logonId = MapUtil.getStr(reqDTO.getPayeeInfo(), "ALIPAY_LOGON_ID");
  253 + if (StrUtil.isEmpty(logonId)) {
  254 + throw exception0(BAD_REQUEST.getCode(), "支付包登录 ID 不能为空");
  255 + }
  256 + String accountName = MapUtil.getStr(reqDTO.getPayeeInfo(), "ALIPAY_ACCOUNT_NAME");
  257 + if (StrUtil.isEmpty(accountName)) {
  258 + throw exception0(BAD_REQUEST.getCode(), "支付包账户名称不能为空");
  259 + }
  260 + payeeInfo.setIdentity(logonId); // 支付宝登录号
  261 + payeeInfo.setName(accountName); // 支付宝账号姓名
  262 + model.setPayeeInfo(payeeInfo);
  263 + // 1.3 构建 AlipayFundTransUniTransferRequest
  264 + AlipayFundTransUniTransferRequest request = new AlipayFundTransUniTransferRequest();
  265 + request.setBizModel(model);
  266 + // 执行请求
  267 + AlipayFundTransUniTransferResponse response = client.certificateExecute(request);
  268 + // 处理结果
  269 + if (!response.isSuccess()) {
  270 + // 当出现 SYSTEM_ERROR, 转账可能成功也可能失败。 返回 WAIT 状态. 后续 job 会轮询
  271 + if (ObjectUtils.equalsAny(response.getSubCode(), "SYSTEM_ERROR", "ACQ.SYSTEM_ERROR")) {
  272 + return PayTransferRespDTO.waitingOf(null, reqDTO.getOutTransferNo(), response);
  273 + }
  274 + return PayTransferRespDTO.closedOf(response.getSubCode(), response.getSubMsg(),
  275 + reqDTO.getOutTransferNo(), response);
  276 + }
  277 + return PayTransferRespDTO.successOf(response.getOrderId(), parseTime(response.getTransDate()),
  278 + response.getOutBizNo(), response);
  279 + }
  280 + case BANK_CARD: {
  281 + Participant payeeInfo = new Participant();
  282 + payeeInfo.setIdentityType("BANKCARD_ACCOUNT");
  283 + // TODO 待实现
  284 + throw new UnsupportedOperationException("待实现");
  285 + }
  286 + default: {
  287 + throw new IllegalStateException("不正确的转账类型: " + transferType);
  288 + }
  289 + }
  290 + }
206 291
207 // ========== 各种工具方法 ========== 292 // ========== 各种工具方法 ==========
208 293
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayAppPayClient.java
@@ -2,8 +2,6 @@ package cn.iocoder.yudao.framework.pay.core.client.impl.alipay; @@ -2,8 +2,6 @@ package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
2 2
3 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; 3 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
4 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO; 4 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
5 -import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferRespDTO;  
6 -import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferUnifiedReqDTO;  
7 import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum; 5 import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
8 import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum; 6 import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
9 import com.alipay.api.AlipayApiException; 7 import com.alipay.api.AlipayApiException;
@@ -58,9 +56,4 @@ public class AlipayAppPayClient extends AbstractAlipayPayClient { @@ -58,9 +56,4 @@ public class AlipayAppPayClient extends AbstractAlipayPayClient {
58 return PayOrderRespDTO.waitingOf(displayMode, response.getBody(), 56 return PayOrderRespDTO.waitingOf(displayMode, response.getBody(),
59 reqDTO.getOutTradeNo(), response); 57 reqDTO.getOutTradeNo(), response);
60 } 58 }
61 -  
62 - @Override  
63 - protected PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) {  
64 - throw new UnsupportedOperationException("支付宝【App 支付】不支持转账操作");  
65 - }  
66 } 59 }
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayBarPayClient.java
@@ -5,8 +5,6 @@ import cn.hutool.core.map.MapUtil; @@ -5,8 +5,6 @@ import cn.hutool.core.map.MapUtil;
5 import cn.hutool.core.util.StrUtil; 5 import cn.hutool.core.util.StrUtil;
6 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; 6 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
7 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO; 7 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
8 -import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferRespDTO;  
9 -import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferUnifiedReqDTO;  
10 import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum; 8 import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
11 import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum; 9 import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
12 import com.alipay.api.AlipayApiException; 10 import com.alipay.api.AlipayApiException;
@@ -16,9 +14,11 @@ import com.alipay.api.response.AlipayTradePayResponse; @@ -16,9 +14,11 @@ import com.alipay.api.response.AlipayTradePayResponse;
16 import lombok.extern.slf4j.Slf4j; 14 import lombok.extern.slf4j.Slf4j;
17 15
18 import java.time.LocalDateTime; 16 import java.time.LocalDateTime;
  17 +import java.util.Objects;
19 18
20 import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST; 19 import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST;
21 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception0; 20 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception0;
  21 +import static cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig.MODE_CERTIFICATE;
22 22
23 /** 23 /**
24 * 支付宝【条码支付】的 PayClient 实现类 24 * 支付宝【条码支付】的 PayClient 实现类
@@ -61,7 +61,13 @@ public class AlipayBarPayClient extends AbstractAlipayPayClient { @@ -61,7 +61,13 @@ public class AlipayBarPayClient extends AbstractAlipayPayClient {
61 request.setReturnUrl(reqDTO.getReturnUrl()); 61 request.setReturnUrl(reqDTO.getReturnUrl());
62 62
63 // 2.1 执行请求 63 // 2.1 执行请求
64 - AlipayTradePayResponse response = client.execute(request); 64 + AlipayTradePayResponse response;
  65 + if (Objects.equals(config.getMode(), MODE_CERTIFICATE)) {
  66 + // 证书模式
  67 + response = client.certificateExecute(request);
  68 + } else {
  69 + response = client.execute(request);
  70 + }
65 // 2.2 处理结果 71 // 2.2 处理结果
66 if (!response.isSuccess()) { 72 if (!response.isSuccess()) {
67 return buildClosedPayOrderRespDTO(reqDTO, response); 73 return buildClosedPayOrderRespDTO(reqDTO, response);
@@ -76,9 +82,4 @@ public class AlipayBarPayClient extends AbstractAlipayPayClient { @@ -76,9 +82,4 @@ public class AlipayBarPayClient extends AbstractAlipayPayClient {
76 return PayOrderRespDTO.waitingOf(displayMode, "", 82 return PayOrderRespDTO.waitingOf(displayMode, "",
77 reqDTO.getOutTradeNo(), response); 83 reqDTO.getOutTradeNo(), response);
78 } 84 }
79 -  
80 - @Override  
81 - protected PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) {  
82 - throw new UnsupportedOperationException("支付宝【条码支付】不支持转账操作");  
83 - }  
84 } 85 }
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayPcPayClient.java
@@ -4,8 +4,6 @@ import cn.hutool.core.util.ObjectUtil; @@ -4,8 +4,6 @@ import cn.hutool.core.util.ObjectUtil;
4 import cn.hutool.http.Method; 4 import cn.hutool.http.Method;
5 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; 5 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
6 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO; 6 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
7 -import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferRespDTO;  
8 -import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferUnifiedReqDTO;  
9 import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum; 7 import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
10 import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum; 8 import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
11 import com.alipay.api.AlipayApiException; 9 import com.alipay.api.AlipayApiException;
@@ -68,9 +66,4 @@ public class AlipayPcPayClient extends AbstractAlipayPayClient { @@ -68,9 +66,4 @@ public class AlipayPcPayClient extends AbstractAlipayPayClient {
68 return PayOrderRespDTO.waitingOf(displayMode, response.getBody(), 66 return PayOrderRespDTO.waitingOf(displayMode, response.getBody(),
69 reqDTO.getOutTradeNo(), response); 67 reqDTO.getOutTradeNo(), response);
70 } 68 }
71 -  
72 - @Override  
73 - protected PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) {  
74 - throw new UnsupportedOperationException("支付宝【PC 网站】不支持转账操作");  
75 - }  
76 } 69 }
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayQrPayClient.java
@@ -2,8 +2,6 @@ package cn.iocoder.yudao.framework.pay.core.client.impl.alipay; @@ -2,8 +2,6 @@ package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
2 2
3 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; 3 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
4 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO; 4 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
5 -import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferRespDTO;  
6 -import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferUnifiedReqDTO;  
7 import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum; 5 import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
8 import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum; 6 import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
9 import com.alipay.api.AlipayApiException; 7 import com.alipay.api.AlipayApiException;
@@ -12,6 +10,10 @@ import com.alipay.api.request.AlipayTradePrecreateRequest; @@ -12,6 +10,10 @@ import com.alipay.api.request.AlipayTradePrecreateRequest;
12 import com.alipay.api.response.AlipayTradePrecreateResponse; 10 import com.alipay.api.response.AlipayTradePrecreateResponse;
13 import lombok.extern.slf4j.Slf4j; 11 import lombok.extern.slf4j.Slf4j;
14 12
  13 +import java.util.Objects;
  14 +
  15 +import static cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig.MODE_CERTIFICATE;
  16 +
15 /** 17 /**
16 * 支付宝【扫码支付】的 PayClient 实现类 18 * 支付宝【扫码支付】的 PayClient 实现类
17 * 19 *
@@ -47,7 +49,13 @@ public class AlipayQrPayClient extends AbstractAlipayPayClient { @@ -47,7 +49,13 @@ public class AlipayQrPayClient extends AbstractAlipayPayClient {
47 request.setReturnUrl(reqDTO.getReturnUrl()); 49 request.setReturnUrl(reqDTO.getReturnUrl());
48 50
49 // 2.1 执行请求 51 // 2.1 执行请求
50 - AlipayTradePrecreateResponse response = client.execute(request); 52 + AlipayTradePrecreateResponse response;
  53 + if (Objects.equals(config.getMode(), MODE_CERTIFICATE)) {
  54 + // 证书模式
  55 + response = client.certificateExecute(request);
  56 + } else {
  57 + response = client.execute(request);
  58 + }
51 // 2.2 处理结果 59 // 2.2 处理结果
52 if (!response.isSuccess()) { 60 if (!response.isSuccess()) {
53 return buildClosedPayOrderRespDTO(reqDTO, response); 61 return buildClosedPayOrderRespDTO(reqDTO, response);
@@ -55,9 +63,4 @@ public class AlipayQrPayClient extends AbstractAlipayPayClient { @@ -55,9 +63,4 @@ public class AlipayQrPayClient extends AbstractAlipayPayClient {
55 return PayOrderRespDTO.waitingOf(displayMode, response.getQrCode(), 63 return PayOrderRespDTO.waitingOf(displayMode, response.getQrCode(),
56 reqDTO.getOutTradeNo(), response); 64 reqDTO.getOutTradeNo(), response);
57 } 65 }
58 -  
59 - @Override  
60 - protected PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) {  
61 - throw new UnsupportedOperationException("支付宝【扫码支付】不支持转账操作");  
62 - }  
63 } 66 }
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayTransferClient.java deleted
1 -package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;  
2 -  
3 -import cn.hutool.core.map.MapUtil;  
4 -import cn.hutool.core.util.StrUtil;  
5 -import cn.iocoder.yudao.framework.common.util.json.JsonUtils;  
6 -import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;  
7 -import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;  
8 -import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;  
9 -import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO;  
10 -import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO;  
11 -import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferRespDTO;  
12 -import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferUnifiedReqDTO;  
13 -import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;  
14 -import cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferTypeEnum;  
15 -import com.alipay.api.AlipayApiException;  
16 -import com.alipay.api.domain.AlipayFundTransUniTransferModel;  
17 -import com.alipay.api.domain.Participant;  
18 -import com.alipay.api.request.AlipayFundTransUniTransferRequest;  
19 -import com.alipay.api.response.AlipayFundTransUniTransferResponse;  
20 -import lombok.extern.slf4j.Slf4j;  
21 -  
22 -import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST;  
23 -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception0;  
24 -  
25 -// TODO @jason:看看能不能融合到 AbstractAlipayPayClient 中。  
26 -/**  
27 - * 支付宝转账的 PayClient 实现类  
28 - *  
29 - * @author jason  
30 - */  
31 -@Slf4j  
32 -public class AlipayTransferClient extends AbstractAlipayPayClient {  
33 - // TODO @jason:方法之间,要有空格噢  
34 - public AlipayTransferClient(Long channelId, AlipayPayClientConfig config) {  
35 - super(channelId, PayChannelEnum.ALIPAY_TRANSFER.getCode(), config);  
36 - }  
37 - @Override  
38 - protected PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) {  
39 - throw new UnsupportedOperationException("支付宝转账不支持统一下单请求");  
40 - }  
41 - @Override  
42 - protected PayRefundRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) {  
43 - throw new UnsupportedOperationException("支付宝转账不支持统一退款请求");  
44 - }  
45 - @Override  
46 - protected PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) throws AlipayApiException {  
47 - // 1.1 构建 AlipayFundTransUniTransferModel  
48 - AlipayFundTransUniTransferModel model = new AlipayFundTransUniTransferModel();  
49 - // ① 通用的参数  
50 - model.setTransAmount(formatAmount(reqDTO.getPrice())); // 转账金额  
51 - model.setOrderTitle(reqDTO.getTitle()); // 转账业务的标题,用于在支付宝用户的账单里显示。  
52 - model.setOutBizNo(reqDTO.getOutTransferNo());  
53 - model.setProductCode("TRANS_ACCOUNT_NO_PWD"); // 销售产品码。单笔无密转账固定为 TRANS_ACCOUNT_NO_PWD  
54 - model.setBizScene("DIRECT_TRANSFER"); // 业务场景 单笔无密转账固定为 DIRECT_TRANSFER  
55 - model.setBusinessParams(JsonUtils.toJsonString(reqDTO.getChannelExtras()));  
56 - PayTransferTypeEnum transferType = PayTransferTypeEnum.ofType(reqDTO.getType());  
57 - switch(transferType) {  
58 - case WX_BALANCE:  
59 - case WALLET_BALANCE: {  
60 - log.error("[doUnifiedTransfer],支付宝转账不支持的转账类型{}", transferType);  
61 - throw new UnsupportedOperationException(String.format("支付宝转账不支持转账类型: %s",transferType.getName()));  
62 - }  
63 - // TODO @jason:是不是不用传递 transferType 参数哈?因为应该已经明确是支付宝啦?  
64 - case ALIPAY_BALANCE: {  
65 - // ② 个性化的参数  
66 - Participant payeeInfo = new Participant();  
67 - payeeInfo.setIdentityType("ALIPAY_LOGON_ID");  
68 - String logonId = MapUtil.getStr(reqDTO.getPayeeInfo(), "ALIPAY_LOGON_ID");  
69 - if (StrUtil.isEmpty(logonId)) {  
70 - throw exception0(BAD_REQUEST.getCode(), "支付包登录 ID 不能为空");  
71 - }  
72 - String accountName = MapUtil.getStr(reqDTO.getPayeeInfo(), "ALIPAY_ACCOUNT_NAME");  
73 - if (StrUtil.isEmpty(accountName)) {  
74 - throw exception0(BAD_REQUEST.getCode(), "支付包账户名称不能为空");  
75 - }  
76 - payeeInfo.setIdentity(logonId); // 支付宝登录号  
77 - payeeInfo.setName(accountName); // 支付宝账号姓名  
78 - model.setPayeeInfo(payeeInfo);  
79 - // 1.2 构建 AlipayFundTransUniTransferRequest  
80 - AlipayFundTransUniTransferRequest request = new AlipayFundTransUniTransferRequest();  
81 - request.setBizModel(model);  
82 - // 执行请求  
83 - AlipayFundTransUniTransferResponse response = client.certificateExecute(request);  
84 - // 处理结果  
85 - if (!response.isSuccess()) {  
86 - // 当出现 SYSTEM_ERROR, 转账可能成功也可能失败。 返回 WAIT 状态. 后续 job 会轮询  
87 - if (ObjectUtils.equalsAny(response.getSubCode(), "SYSTEM_ERROR", "ACQ.SYSTEM_ERROR")) {  
88 - return PayTransferRespDTO.waitingOf(null, reqDTO.getOutTransferNo(), response);  
89 - }  
90 - return PayTransferRespDTO.closedOf(response.getSubCode(), response.getSubMsg(),  
91 - reqDTO.getOutTransferNo(), response);  
92 - }  
93 - return PayTransferRespDTO.successOf(response.getOrderId(), parseTime(response.getTransDate()),  
94 - response.getOutBizNo(), response);  
95 - }  
96 - case BANK_CARD: {  
97 - Participant payeeInfo = new Participant();  
98 - payeeInfo.setIdentityType("BANKCARD_ACCOUNT");  
99 - throw new UnsupportedOperationException("待实现");  
100 - }  
101 - default: {  
102 - throw new IllegalStateException("不正确的转账类型: " + transferType);  
103 - }  
104 - }  
105 - }  
106 -  
107 -}  
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayWapPayClient.java
@@ -3,8 +3,6 @@ package cn.iocoder.yudao.framework.pay.core.client.impl.alipay; @@ -3,8 +3,6 @@ package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
3 import cn.hutool.http.Method; 3 import cn.hutool.http.Method;
4 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; 4 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
5 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO; 5 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
6 -import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferRespDTO;  
7 -import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferUnifiedReqDTO;  
8 import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum; 6 import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
9 import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum; 7 import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
10 import com.alipay.api.AlipayApiException; 8 import com.alipay.api.AlipayApiException;
@@ -57,9 +55,4 @@ public class AlipayWapPayClient extends AbstractAlipayPayClient { @@ -57,9 +55,4 @@ public class AlipayWapPayClient extends AbstractAlipayPayClient {
57 return PayOrderRespDTO.waitingOf(displayMode, response.getBody(), 55 return PayOrderRespDTO.waitingOf(displayMode, response.getBody(),
58 reqDTO.getOutTradeNo(), response); 56 reqDTO.getOutTradeNo(), response);
59 } 57 }
60 -  
61 - @Override  
62 - public PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) {  
63 - throw new UnsupportedOperationException("支付宝【Wap 网站】不支持转账操作");  
64 - }  
65 } 58 }
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/channel/PayChannelEnum.java
@@ -28,9 +28,6 @@ public enum PayChannelEnum { @@ -28,9 +28,6 @@ public enum PayChannelEnum {
28 ALIPAY_APP("alipay_app", "支付宝App 支付", AlipayPayClientConfig.class), 28 ALIPAY_APP("alipay_app", "支付宝App 支付", AlipayPayClientConfig.class),
29 ALIPAY_QR("alipay_qr", "支付宝扫码支付", AlipayPayClientConfig.class), 29 ALIPAY_QR("alipay_qr", "支付宝扫码支付", AlipayPayClientConfig.class),
30 ALIPAY_BAR("alipay_bar", "支付宝条码支付", AlipayPayClientConfig.class), 30 ALIPAY_BAR("alipay_bar", "支付宝条码支付", AlipayPayClientConfig.class),
31 - // TODO @jason:是不是按照微信聊的,合并回 ALIPAY_PC;因为支付宝、微信都是多种支付方式,选择其中的一种即可;  
32 - ALIPAY_TRANSFER("alipay_transfer", "支付宝转账", AlipayPayClientConfig.class),  
33 -  
34 MOCK("mock", "模拟支付", NonePayClientConfig.class), 31 MOCK("mock", "模拟支付", NonePayClientConfig.class),
35 32
36 WALLET("wallet", "钱包支付", NonePayClientConfig.class); 33 WALLET("wallet", "钱包支付", NonePayClientConfig.class);
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/transfer/PayTransferTypeEnum.java
@@ -34,8 +34,7 @@ public enum PayTransferTypeEnum implements IntArrayValuable { @@ -34,8 +34,7 @@ public enum PayTransferTypeEnum implements IntArrayValuable {
34 return ARRAYS; 34 return ARRAYS;
35 } 35 }
36 36
37 - // TODO @jason:是不是 typeOf 更符合预期哈?  
38 - public static PayTransferTypeEnum ofType(Integer type) { 37 + public static PayTransferTypeEnum typeOf(Integer type) {
39 return ArrayUtil.firstMatch(item -> item.getType().equals(type), values()); 38 return ArrayUtil.firstMatch(item -> item.getType().equals(type), values());
40 } 39 }
41 40
yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferCreateReqDTO.java
1 package cn.iocoder.yudao.module.pay.api.transfer.dto; 1 package cn.iocoder.yudao.module.pay.api.transfer.dto;
2 2
  3 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  4 +import cn.iocoder.yudao.module.pay.enums.transfer.PayTransferTypeEnum;
3 import lombok.Data; 5 import lombok.Data;
4 6
5 import javax.validation.constraints.Min; 7 import javax.validation.constraints.Min;
@@ -23,7 +25,7 @@ public class PayTransferCreateReqDTO { @@ -23,7 +25,7 @@ public class PayTransferCreateReqDTO {
23 * 类型 25 * 类型
24 */ 26 */
25 @NotNull(message = "转账类型不能为空") 27 @NotNull(message = "转账类型不能为空")
26 - // TODO @jason:枚举的校验 28 + @InEnum(PayTransferTypeEnum.class)
27 private Integer type; 29 private Integer type;
28 30
29 /** 31 /**
@@ -35,14 +37,14 @@ public class PayTransferCreateReqDTO { @@ -35,14 +37,14 @@ public class PayTransferCreateReqDTO {
35 /** 37 /**
36 * 转账金额,单位:分 38 * 转账金额,单位:分
37 */ 39 */
38 - // TODO @jason:这个金额是不是非空哈  
39 @Min(value = 1, message = "转账金额必须大于零") 40 @Min(value = 1, message = "转账金额必须大于零")
  41 + @NotNull(message = "转账金额不能为空")
40 private Integer price; 42 private Integer price;
41 43
42 - // TODO @jason:这个标题,是不是不允许空呀  
43 /** 44 /**
44 * 转账标题 45 * 转账标题
45 */ 46 */
  47 + @NotEmpty(message = "转账标题不能为空")
46 private String title; 48 private String title;
47 49
48 @NotEmpty(message = "收款方信息不能为空") 50 @NotEmpty(message = "收款方信息不能为空")
yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java
@@ -62,6 +62,7 @@ public interface ErrorCodeConstants { @@ -62,6 +62,7 @@ public interface ErrorCodeConstants {
62 ErrorCode WALLET_RECHARGE_PACKAGE_AND_PRICE_IS_EMPTY = new ErrorCode(1_007_008_011, "充值金额和充钱套餐不能同时为空"); 62 ErrorCode WALLET_RECHARGE_PACKAGE_AND_PRICE_IS_EMPTY = new ErrorCode(1_007_008_011, "充值金额和充钱套餐不能同时为空");
63 ErrorCode WALLET_RECHARGE_PACKAGE_NOT_FOUND = new ErrorCode(1_007_008_012, "钱包充值套餐不存在"); 63 ErrorCode WALLET_RECHARGE_PACKAGE_NOT_FOUND = new ErrorCode(1_007_008_012, "钱包充值套餐不存在");
64 ErrorCode WALLET_RECHARGE_PACKAGE_IS_DISABLE = new ErrorCode(1_007_008_013, "钱包充值套餐已禁用"); 64 ErrorCode WALLET_RECHARGE_PACKAGE_IS_DISABLE = new ErrorCode(1_007_008_013, "钱包充值套餐已禁用");
  65 + ErrorCode WALLET_RECHARGE_PACKAGE_NAME_EXISTS = new ErrorCode(1_007_008_014, "钱包充值套餐名称已存在");
65 66
66 // ========== 转账模块 1-007-009-000 ========== 67 // ========== 转账模块 1-007-009-000 ==========
67 ErrorCode PAY_TRANSFER_SUBMIT_CHANNEL_ERROR = new ErrorCode(1_007_009_000, "发起转账报错,错误码:{},错误提示:{}"); 68 ErrorCode PAY_TRANSFER_SUBMIT_CHANNEL_ERROR = new ErrorCode(1_007_009_000, "发起转账报错,错误码:{},错误提示:{}");
yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/member/PayWalletBizTypeEnum.java
1 package cn.iocoder.yudao.module.pay.enums.member; 1 package cn.iocoder.yudao.module.pay.enums.member;
2 2
  3 +import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
3 import lombok.AllArgsConstructor; 4 import lombok.AllArgsConstructor;
4 import lombok.Getter; 5 import lombok.Getter;
5 6
  7 +import java.util.Arrays;
  8 +
6 /** 9 /**
7 * 钱包交易业务分类 10 * 钱包交易业务分类
8 * 11 *
@@ -10,7 +13,7 @@ import lombok.Getter; @@ -10,7 +13,7 @@ import lombok.Getter;
10 */ 13 */
11 @AllArgsConstructor 14 @AllArgsConstructor
12 @Getter 15 @Getter
13 -public enum PayWalletBizTypeEnum { 16 +public enum PayWalletBizTypeEnum implements IntArrayValuable {
14 17
15 RECHARGE(1, "充值"), 18 RECHARGE(1, "充值"),
16 RECHARGE_REFUND(2, "充值退款"), 19 RECHARGE_REFUND(2, "充值退款"),
@@ -28,4 +31,10 @@ public enum PayWalletBizTypeEnum { @@ -28,4 +31,10 @@ public enum PayWalletBizTypeEnum {
28 */ 31 */
29 private final String description; 32 private final String description;
30 33
  34 + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PayWalletBizTypeEnum::getType).toArray();
  35 +
  36 + @Override
  37 + public int[] array() {
  38 + return ARRAYS;
  39 + }
31 } 40 }
yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/transfer/PayTransferTypeEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.pay.enums.transfer;
  2 +
  3 +import cn.hutool.core.util.ArrayUtil;
  4 +import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
  5 +import lombok.AllArgsConstructor;
  6 +import lombok.Getter;
  7 +
  8 +import java.util.Arrays;
  9 +
  10 +/**
  11 + * 转账类型枚举
  12 + *
  13 + * @author jason
  14 + */
  15 +@AllArgsConstructor
  16 +@Getter
  17 +public enum PayTransferTypeEnum implements IntArrayValuable {
  18 +
  19 + ALIPAY_BALANCE(1, "支付宝余额"),
  20 + WX_BALANCE(2, "微信余额"),
  21 + BANK_CARD(3, "银行卡"),
  22 + WALLET_BALANCE(4, "钱包余额");
  23 +
  24 + public static final String ALIPAY_LOGON_ID = "ALIPAY_LOGON_ID";
  25 + public static final String ALIPAY_ACCOUNT_NAME = "ALIPAY_ACCOUNT_NAME";
  26 +
  27 + private final Integer type;
  28 + private final String name;
  29 +
  30 + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PayTransferTypeEnum::getType).toArray();
  31 +
  32 + @Override
  33 + public int[] array() {
  34 + return ARRAYS;
  35 + }
  36 +
  37 + public static PayTransferTypeEnum typeOf(Integer type) {
  38 + return ArrayUtil.firstMatch(item -> item.getType().equals(type), values());
  39 + }
  40 +
  41 +}
yudao-module-pay/yudao-module-pay-biz/pom.xml
@@ -24,6 +24,11 @@ @@ -24,6 +24,11 @@
24 <version>${revision}</version> 24 <version>${revision}</version>
25 </dependency> 25 </dependency>
26 26
  27 + <dependency>
  28 + <groupId>cn.iocoder.boot</groupId>
  29 + <artifactId>yudao-module-member-api</artifactId>
  30 + <version>${revision}</version>
  31 + </dependency>
27 <!-- 业务组件 --> 32 <!-- 业务组件 -->
28 <dependency> 33 <dependency>
29 <groupId>cn.iocoder.boot</groupId> 34 <groupId>cn.iocoder.boot</groupId>
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/PayTransferApiImpl.java
1 package cn.iocoder.yudao.module.pay.api.transfer; 1 package cn.iocoder.yudao.module.pay.api.transfer;
2 2
3 import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferCreateReqDTO; 3 import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferCreateReqDTO;
  4 +import cn.iocoder.yudao.module.pay.service.transfer.PayTransferService;
4 import org.springframework.stereotype.Service; 5 import org.springframework.stereotype.Service;
5 import org.springframework.validation.annotation.Validated; 6 import org.springframework.validation.annotation.Validated;
6 7
  8 +import javax.annotation.Resource;
  9 +
7 /** 10 /**
8 * 转账单 API 实现类 11 * 转账单 API 实现类
9 * 12 *
@@ -12,11 +15,11 @@ import org.springframework.validation.annotation.Validated; @@ -12,11 +15,11 @@ import org.springframework.validation.annotation.Validated;
12 @Service 15 @Service
13 @Validated 16 @Validated
14 public class PayTransferApiImpl implements PayTransferApi { 17 public class PayTransferApiImpl implements PayTransferApi {
  18 + @Resource
  19 + private PayTransferService payTransferService;
15 20
16 @Override 21 @Override
17 public Long createTransfer(PayTransferCreateReqDTO reqDTO) { 22 public Long createTransfer(PayTransferCreateReqDTO reqDTO) {
18 - // TODO @jason:貌似没实现噢  
19 - return null; 23 + return payTransferService.createTransfer(reqDTO);
20 } 24 }
21 -  
22 } 25 }
23 \ No newline at end of file 26 \ No newline at end of file
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/transfer/PayDemoTransferCreateReqVO.java
@@ -17,11 +17,10 @@ import java.util.Map; @@ -17,11 +17,10 @@ import java.util.Map;
17 @Data 17 @Data
18 public class PayDemoTransferCreateReqVO { 18 public class PayDemoTransferCreateReqVO {
19 19
20 - // TODO @jason:这个字段,是不是叫 type 就好了。  
21 @Schema(description = "转账类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") 20 @Schema(description = "转账类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
22 @NotNull(message = "转账类型不能为空") 21 @NotNull(message = "转账类型不能为空")
23 @InEnum(PayTransferTypeEnum.class) 22 @InEnum(PayTransferTypeEnum.class)
24 - private Integer transferType; 23 + private Integer type;
25 24
26 @NotNull(message = "转账金额不能为空") 25 @NotNull(message = "转账金额不能为空")
27 @Min(value = 1, message = "转账金额必须大于零") 26 @Min(value = 1, message = "转账金额必须大于零")
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/PayTransferController.java
@@ -29,7 +29,7 @@ public class PayTransferController { @@ -29,7 +29,7 @@ public class PayTransferController {
29 29
30 @PostMapping("/submit") 30 @PostMapping("/submit")
31 @Operation(summary = "提交转账订单") 31 @Operation(summary = "提交转账订单")
32 - // TODO @jason:权限的设置 32 + // TODO @jason:权限的设置, 管理后台页面加的时候加一下
33 public CommonResult<PayTransferSubmitRespVO> submitPayTransfer(@Valid @RequestBody PayTransferSubmitReqVO reqVO) { 33 public CommonResult<PayTransferSubmitRespVO> submitPayTransfer(@Valid @RequestBody PayTransferSubmitReqVO reqVO) {
34 PayTransferSubmitRespVO respVO = payTransferService.submitTransfer(reqVO, getClientIP()); 34 PayTransferSubmitRespVO respVO = payTransferService.submitTransfer(reqVO, getClientIP());
35 return success(respVO); 35 return success(respVO);
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/PayWalletController.java
1 package cn.iocoder.yudao.module.pay.controller.admin.wallet; 1 package cn.iocoder.yudao.module.pay.controller.admin.wallet;
2 2
  3 +import cn.hutool.core.collection.CollectionUtil;
  4 +import cn.hutool.core.util.StrUtil;
3 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 5 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 import cn.iocoder.yudao.framework.common.pojo.PageResult; 6 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  7 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  8 +import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
  9 +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
5 import cn.iocoder.yudao.module.pay.controller.admin.wallet.vo.wallet.PayWalletPageReqVO; 10 import cn.iocoder.yudao.module.pay.controller.admin.wallet.vo.wallet.PayWalletPageReqVO;
6 import cn.iocoder.yudao.module.pay.controller.admin.wallet.vo.wallet.PayWalletRespVO; 11 import cn.iocoder.yudao.module.pay.controller.admin.wallet.vo.wallet.PayWalletRespVO;
7 import cn.iocoder.yudao.module.pay.controller.admin.wallet.vo.wallet.PayWalletUserReqVO; 12 import cn.iocoder.yudao.module.pay.controller.admin.wallet.vo.wallet.PayWalletUserReqVO;
@@ -19,8 +24,14 @@ import org.springframework.web.bind.annotation.RestController; @@ -19,8 +24,14 @@ import org.springframework.web.bind.annotation.RestController;
19 24
20 import javax.annotation.Resource; 25 import javax.annotation.Resource;
21 import javax.validation.Valid; 26 import javax.validation.Valid;
  27 +import java.util.List;
  28 +import java.util.Map;
  29 +import java.util.Set;
22 30
  31 +import static cn.iocoder.yudao.framework.common.enums.UserTypeEnum.MEMBER;
23 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 32 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  33 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
  34 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
24 35
25 @Tag(name = "管理后台 - 用户钱包") 36 @Tag(name = "管理后台 - 用户钱包")
26 @RestController 37 @RestController
@@ -31,21 +42,37 @@ public class PayWalletController { @@ -31,21 +42,37 @@ public class PayWalletController {
31 42
32 @Resource 43 @Resource
33 private PayWalletService payWalletService; 44 private PayWalletService payWalletService;
  45 + @Resource
  46 + private MemberUserApi memberUserApi;
34 47
35 @GetMapping("/get") 48 @GetMapping("/get")
36 @PreAuthorize("@ss.hasPermission('pay:wallet:query')") 49 @PreAuthorize("@ss.hasPermission('pay:wallet:query')")
37 @Operation(summary = "获得用户钱包明细") 50 @Operation(summary = "获得用户钱包明细")
38 public CommonResult<PayWalletRespVO> getWallet(PayWalletUserReqVO reqVO) { 51 public CommonResult<PayWalletRespVO> getWallet(PayWalletUserReqVO reqVO) {
39 - PayWalletDO wallet = payWalletService.getOrCreateWallet(reqVO.getUserId(), reqVO.getUserType());  
40 - return success(PayWalletConvert.INSTANCE.convert02(wallet)); 52 + PayWalletDO wallet = payWalletService.getOrCreateWallet(reqVO.getUserId(), MEMBER.getValue());
  53 + MemberUserRespDTO memberUser = memberUserApi.getUser(reqVO.getUserId());
  54 + String nickname = memberUser == null ? "" : memberUser.getNickname();
  55 + String avatar = memberUser == null ? "" : memberUser.getAvatar();
  56 + return success(PayWalletConvert.INSTANCE.convert02(nickname, avatar, wallet));
41 } 57 }
42 58
43 @GetMapping("/page") 59 @GetMapping("/page")
44 @Operation(summary = "获得会员钱包分页") 60 @Operation(summary = "获得会员钱包分页")
45 @PreAuthorize("@ss.hasPermission('pay:wallet:query')") 61 @PreAuthorize("@ss.hasPermission('pay:wallet:query')")
46 public CommonResult<PageResult<PayWalletRespVO>> getWalletPage(@Valid PayWalletPageReqVO pageVO) { 62 public CommonResult<PageResult<PayWalletRespVO>> getWalletPage(@Valid PayWalletPageReqVO pageVO) {
47 - PageResult<PayWalletDO> pageResult = payWalletService.getWalletPage(pageVO);  
48 - return success(PayWalletConvert.INSTANCE.convertPage(pageResult)); 63 + if (StrUtil.isNotEmpty(pageVO.getNickname())) {
  64 + Set<Long> userIds = CollectionUtils.convertSet(memberUserApi.getUserListByNickname(pageVO.getNickname()),
  65 + MemberUserRespDTO::getId);
  66 + pageVO.setUserIds(userIds);
  67 + }
  68 + // 暂时支持查询 userType 会员类型。管理员类型还不知道使用场景
  69 + PageResult<PayWalletDO> pageResult = payWalletService.getWalletPage(MEMBER.getValue(),pageVO);
  70 + if (CollectionUtil.isEmpty(pageResult.getList())) {
  71 + return success(new PageResult<>(pageResult.getTotal()));
  72 + }
  73 + List<Long> userIds = convertList(pageResult.getList(), PayWalletDO::getUserId);
  74 + Map<Long, MemberUserRespDTO> userMap = convertMap(memberUserApi.getUserList(userIds),MemberUserRespDTO::getId);
  75 + return success(PayWalletConvert.INSTANCE.convertPage(pageResult, userMap));
49 } 76 }
50 77
51 } 78 }
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/PayWalletTransactionController.java
@@ -10,6 +10,7 @@ import cn.iocoder.yudao.module.pay.service.wallet.PayWalletTransactionService; @@ -10,6 +10,7 @@ import cn.iocoder.yudao.module.pay.service.wallet.PayWalletTransactionService;
10 import io.swagger.v3.oas.annotations.Operation; 10 import io.swagger.v3.oas.annotations.Operation;
11 import io.swagger.v3.oas.annotations.tags.Tag; 11 import io.swagger.v3.oas.annotations.tags.Tag;
12 import lombok.extern.slf4j.Slf4j; 12 import lombok.extern.slf4j.Slf4j;
  13 +import org.springframework.security.access.prepost.PreAuthorize;
13 import org.springframework.validation.annotation.Validated; 14 import org.springframework.validation.annotation.Validated;
14 import org.springframework.web.bind.annotation.GetMapping; 15 import org.springframework.web.bind.annotation.GetMapping;
15 import org.springframework.web.bind.annotation.RequestMapping; 16 import org.springframework.web.bind.annotation.RequestMapping;
@@ -32,7 +33,7 @@ public class PayWalletTransactionController { @@ -32,7 +33,7 @@ public class PayWalletTransactionController {
32 33
33 @GetMapping("/page") 34 @GetMapping("/page")
34 @Operation(summary = "获得钱包流水分页") 35 @Operation(summary = "获得钱包流水分页")
35 - // TODO @jason:权限校验,缺一个 36 + @PreAuthorize("@ss.hasPermission('pay:wallet:query')")
36 public CommonResult<PageResult<PayWalletTransactionRespVO>> getWalletTransactionPage( 37 public CommonResult<PageResult<PayWalletTransactionRespVO>> getWalletTransactionPage(
37 @Valid PayWalletTransactionPageReqVO pageReqVO) { 38 @Valid PayWalletTransactionPageReqVO pageReqVO) {
38 PageResult<PayWalletTransactionDO> result = payWalletTransactionService.getWalletTransactionPage(pageReqVO); 39 PageResult<PayWalletTransactionDO> result = payWalletTransactionService.getWalletTransactionPage(pageReqVO);
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/rechargepackage/WalletRechargePackagePageReqVO.java
@@ -20,14 +20,6 @@ public class WalletRechargePackagePageReqVO extends PageParam { @@ -20,14 +20,6 @@ public class WalletRechargePackagePageReqVO extends PageParam {
20 @Schema(description = "套餐名", example = "李四") 20 @Schema(description = "套餐名", example = "李四")
21 private String name; 21 private String name;
22 22
23 - // TODO @jason:payPrice 和 bonusPrice 可以去掉。。。一般太少检索啦;  
24 -  
25 - @Schema(description = "支付金额", example = "16454")  
26 - private Integer payPrice;  
27 -  
28 - @Schema(description = "赠送金额", example = "20887")  
29 - private Integer bonusPrice;  
30 -  
31 @Schema(description = "状态", example = "2") 23 @Schema(description = "状态", example = "2")
32 private Integer status; 24 private Integer status;
33 25
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/wallet/PayWalletPageReqVO.java
1 package cn.iocoder.yudao.module.pay.controller.admin.wallet.vo.wallet; 1 package cn.iocoder.yudao.module.pay.controller.admin.wallet.vo.wallet;
2 2
3 -import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;  
4 -import cn.iocoder.yudao.framework.common.validation.InEnum;  
5 -import lombok.*;  
6 -import io.swagger.v3.oas.annotations.media.Schema;  
7 import cn.iocoder.yudao.framework.common.pojo.PageParam; 3 import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
8 import org.springframework.format.annotation.DateTimeFormat; 8 import org.springframework.format.annotation.DateTimeFormat;
  9 +
9 import java.time.LocalDateTime; 10 import java.time.LocalDateTime;
  11 +import java.util.Collection;
10 12
11 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; 13 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
12 14
@@ -16,12 +18,11 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ @@ -16,12 +18,11 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
16 @ToString(callSuper = true) 18 @ToString(callSuper = true)
17 public class PayWalletPageReqVO extends PageParam { 19 public class PayWalletPageReqVO extends PageParam {
18 20
19 - @Schema(description = "用户编号", example = "14138")  
20 - private Long userId; 21 + @Schema(description = "用户昵称", example = "李四")
  22 + private String nickname;
21 23
22 - @Schema(description = "用户类型", example = "1")  
23 - @InEnum(UserTypeEnum.class)  
24 - private Integer userType; 24 + @Schema(description = "用户编号", example = "[1,2]")
  25 + private Collection<Long> userIds;
25 26
26 @Schema(description = "创建时间") 27 @Schema(description = "创建时间")
27 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) 28 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/wallet/PayWalletRespVO.java
@@ -19,6 +19,10 @@ public class PayWalletRespVO extends PayWalletBaseVO { @@ -19,6 +19,10 @@ public class PayWalletRespVO extends PayWalletBaseVO {
19 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) 19 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
20 private LocalDateTime createTime; 20 private LocalDateTime createTime;
21 21
22 - // TODO @jason:要不把用户昵称 + avatar 也读取下? 22 + @Schema(description = "用户昵称")
  23 + private String nickname;
  24 +
  25 + @Schema(description = "用户头像")
  26 + private String avatar;
23 27
24 } 28 }
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/wallet/PayWalletUserReqVO.java
1 package cn.iocoder.yudao.module.pay.controller.admin.wallet.vo.wallet; 1 package cn.iocoder.yudao.module.pay.controller.admin.wallet.vo.wallet;
2 2
3 -import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;  
4 -import cn.iocoder.yudao.framework.common.validation.InEnum;  
5 import io.swagger.v3.oas.annotations.media.Schema; 3 import io.swagger.v3.oas.annotations.media.Schema;
6 import lombok.Data; 4 import lombok.Data;
7 5
@@ -14,10 +12,4 @@ public class PayWalletUserReqVO { @@ -14,10 +12,4 @@ public class PayWalletUserReqVO {
14 @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") 12 @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
15 @NotNull(message = "用户编号不能为空") 13 @NotNull(message = "用户编号不能为空")
16 private Long userId; 14 private Long userId;
17 -  
18 - @Schema(description = "用户类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")  
19 - @NotNull(message = "用户类型不能为空")  
20 - @InEnum(value = UserTypeEnum.class, message = "用户类型必须是 {value}")  
21 - private Integer userType;  
22 -  
23 } 15 }
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/AppPayWalletRechargeController.java
@@ -19,6 +19,7 @@ import javax.annotation.Resource; @@ -19,6 +19,7 @@ import javax.annotation.Resource;
19 import javax.validation.Valid; 19 import javax.validation.Valid;
20 20
21 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 21 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  22 +import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP;
22 import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId; 23 import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId;
23 import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserType; 24 import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserType;
24 25
@@ -35,9 +36,9 @@ public class AppPayWalletRechargeController { @@ -35,9 +36,9 @@ public class AppPayWalletRechargeController {
35 @PostMapping("/create") 36 @PostMapping("/create")
36 @Operation(summary = "创建钱包充值记录(发起充值)") 37 @Operation(summary = "创建钱包充值记录(发起充值)")
37 public CommonResult<AppPayWalletRechargeCreateRespVO> createWalletRecharge( 38 public CommonResult<AppPayWalletRechargeCreateRespVO> createWalletRecharge(
38 - @Valid @RequestBody AppPayWalletRechargeCreateReqVO reqVO) { 39 + @Valid @RequestBody AppPayWalletRechargeCreateReqVO reqVO) {
39 PayWalletRechargeDO walletRecharge = walletRechargeService.createWalletRecharge( 40 PayWalletRechargeDO walletRecharge = walletRechargeService.createWalletRecharge(
40 - getLoginUserId(), getLoginUserType(), reqVO); 41 + getLoginUserId(), getLoginUserType(), getClientIP(), reqVO);
41 return success(PayWalletRechargeConvert.INSTANCE.convert(walletRecharge)); 42 return success(PayWalletRechargeConvert.INSTANCE.convert(walletRecharge));
42 } 43 }
43 44
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/recharge/AppPayWalletRechargeCreateReqVO.java
@@ -3,7 +3,9 @@ package cn.iocoder.yudao.module.pay.controller.app.wallet.vo.recharge; @@ -3,7 +3,9 @@ package cn.iocoder.yudao.module.pay.controller.app.wallet.vo.recharge;
3 import io.swagger.v3.oas.annotations.media.Schema; 3 import io.swagger.v3.oas.annotations.media.Schema;
4 import lombok.Data; 4 import lombok.Data;
5 5
  6 +import javax.validation.constraints.AssertTrue;
6 import javax.validation.constraints.Min; 7 import javax.validation.constraints.Min;
  8 +import java.util.Objects;
7 9
8 @Schema(description = "用户 APP - 创建钱包充值 Request VO") 10 @Schema(description = "用户 APP - 创建钱包充值 Request VO")
9 @Data 11 @Data
@@ -16,6 +18,8 @@ public class AppPayWalletRechargeCreateReqVO { @@ -16,6 +18,8 @@ public class AppPayWalletRechargeCreateReqVO {
16 @Schema(description = "充值套餐编号", example = "1024") 18 @Schema(description = "充值套餐编号", example = "1024")
17 private Long packageId; 19 private Long packageId;
18 20
19 - // TODO @jaosn:写个 AssertTrue 的校验方法,payPrice 和 packageId 必须二选一  
20 - 21 + @AssertTrue(message = "充值金额和充钱套餐不能同时为空")
  22 + public boolean validatePayPriceAndPackageId() {
  23 + return Objects.nonNull(payPrice) || Objects.nonNull(packageId);
  24 + }
21 } 25 }
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/transfer/PayTransferConvert.java
@@ -11,9 +11,9 @@ import org.mapstruct.factory.Mappers; @@ -11,9 +11,9 @@ import org.mapstruct.factory.Mappers;
11 public interface PayTransferConvert { 11 public interface PayTransferConvert {
12 12
13 PayTransferConvert INSTANCE = Mappers.getMapper(PayTransferConvert.class); 13 PayTransferConvert INSTANCE = Mappers.getMapper(PayTransferConvert.class);
14 - 14 + @Mapping(source = "title", target = "subject")
15 PayTransferDO convert(PayTransferCreateReqDTO dto); 15 PayTransferDO convert(PayTransferCreateReqDTO dto);
16 - @Mapping(source = "transferType", target = "type") 16 +
17 PayTransferCreateReqDTO convert(PayDemoTransferCreateReqVO vo); 17 PayTransferCreateReqDTO convert(PayDemoTransferCreateReqVO vo);
18 18
19 } 19 }
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/wallet/PayWalletConvert.java
1 package cn.iocoder.yudao.module.pay.convert.wallet; 1 package cn.iocoder.yudao.module.pay.convert.wallet;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
  5 +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
4 import cn.iocoder.yudao.module.pay.controller.admin.wallet.vo.wallet.PayWalletRespVO; 6 import cn.iocoder.yudao.module.pay.controller.admin.wallet.vo.wallet.PayWalletRespVO;
5 import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.wallet.AppPayWalletRespVO; 7 import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.wallet.AppPayWalletRespVO;
6 import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; 8 import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO;
7 import org.mapstruct.Mapper; 9 import org.mapstruct.Mapper;
8 import org.mapstruct.factory.Mappers; 10 import org.mapstruct.factory.Mappers;
9 11
  12 +import java.util.Map;
  13 +
10 @Mapper 14 @Mapper
11 public interface PayWalletConvert { 15 public interface PayWalletConvert {
12 16
@@ -14,8 +18,18 @@ public interface PayWalletConvert { @@ -14,8 +18,18 @@ public interface PayWalletConvert {
14 18
15 AppPayWalletRespVO convert(PayWalletDO bean); 19 AppPayWalletRespVO convert(PayWalletDO bean);
16 20
17 - PayWalletRespVO convert02(PayWalletDO bean); 21 + PayWalletRespVO convert02(String nickname,String avatar, PayWalletDO bean);
18 22
19 PageResult<PayWalletRespVO> convertPage(PageResult<PayWalletDO> page); 23 PageResult<PayWalletRespVO> convertPage(PageResult<PayWalletDO> page);
20 24
  25 + default PageResult<PayWalletRespVO> convertPage(PageResult<PayWalletDO> page, Map<Long, MemberUserRespDTO> userMap){
  26 + PageResult<PayWalletRespVO> pageResult = convertPage(page);
  27 + pageResult.getList().forEach( wallet -> MapUtils.findAndThen(userMap, wallet.getUserId(),
  28 + user -> {
  29 + wallet.setNickname(user.getNickname());
  30 + wallet.setAvatar(user.getAvatar());
  31 + }));
  32 + return pageResult;
  33 + }
  34 +
21 } 35 }
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/transfer/PayTransferDO.java
@@ -64,11 +64,11 @@ public class PayTransferDO extends BaseDO { @@ -64,11 +64,11 @@ public class PayTransferDO extends BaseDO {
64 * 例如说,内部系统 A 的订单号,需要保证每个 PayAppDO 唯一 64 * 例如说,内部系统 A 的订单号,需要保证每个 PayAppDO 唯一
65 */ 65 */
66 private String merchantOrderId; 66 private String merchantOrderId;
67 - // TODO @jason:这个字段,要不要改成 subject。。。和 payorderdo 保持一致;哈哈哈,我也忘记为啥当时选了这个名字了。。。 67 +
68 /** 68 /**
69 * 转账标题 69 * 转账标题
70 */ 70 */
71 - private String title; 71 + private String subject;
72 72
73 // ========== 转账相关字段 ========== 73 // ========== 转账相关字段 ==========
74 /** 74 /**
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/transfer/PayTransferExtensionDO.java
@@ -11,6 +11,7 @@ import lombok.Data; @@ -11,6 +11,7 @@ import lombok.Data;
11 import java.util.Map; 11 import java.util.Map;
12 12
13 // TODO @jason:转账是不是类似 refund,不用拓展单呀?支付做拓展单的原因,是因为它存在不确定性,可以切换多种;转账和退款,都是明确方式的; 13 // TODO @jason:转账是不是类似 refund,不用拓展单呀?支付做拓展单的原因,是因为它存在不确定性,可以切换多种;转账和退款,都是明确方式的;
  14 +// @芋艿 转账是不是也存在多种方式。 例如转账到银行卡。 可以使用微信,也可以使用支付宝。 支付宝账号余额不够,可以切换到微信
14 /** 15 /**
15 * 转账拓展单 DO 16 * 转账拓展单 DO
16 * 17 *
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/wallet/PayWalletMapper.java
@@ -17,10 +17,10 @@ public interface PayWalletMapper extends BaseMapperX&lt;PayWalletDO&gt; { @@ -17,10 +17,10 @@ public interface PayWalletMapper extends BaseMapperX&lt;PayWalletDO&gt; {
17 PayWalletDO::getUserType, userType); 17 PayWalletDO::getUserType, userType);
18 } 18 }
19 19
20 - default PageResult<PayWalletDO> selectPage(PayWalletPageReqVO reqVO) { 20 + default PageResult<PayWalletDO> selectPage(Integer userType, PayWalletPageReqVO reqVO) {
21 return selectPage(reqVO, new LambdaQueryWrapperX<PayWalletDO>() 21 return selectPage(reqVO, new LambdaQueryWrapperX<PayWalletDO>()
22 - .eqIfPresent(PayWalletDO::getUserId, reqVO.getUserId())  
23 - .eqIfPresent(PayWalletDO::getUserType, reqVO.getUserType()) 22 + .inIfPresent(PayWalletDO::getUserId, reqVO.getUserIds())
  23 + .eqIfPresent(PayWalletDO::getUserType, userType)
24 .betweenIfPresent(PayWalletDO::getCreateTime, reqVO.getCreateTime()) 24 .betweenIfPresent(PayWalletDO::getCreateTime, reqVO.getCreateTime())
25 .orderByDesc(PayWalletDO::getId)); 25 .orderByDesc(PayWalletDO::getId));
26 } 26 }
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/wallet/PayWalletRechargePackageMapper.java
@@ -12,14 +12,14 @@ import org.apache.ibatis.annotations.Mapper; @@ -12,14 +12,14 @@ import org.apache.ibatis.annotations.Mapper;
12 public interface PayWalletRechargePackageMapper extends BaseMapperX<PayWalletRechargePackageDO> { 12 public interface PayWalletRechargePackageMapper extends BaseMapperX<PayWalletRechargePackageDO> {
13 13
14 default PageResult<PayWalletRechargePackageDO> selectPage(WalletRechargePackagePageReqVO reqVO) { 14 default PageResult<PayWalletRechargePackageDO> selectPage(WalletRechargePackagePageReqVO reqVO) {
15 - // TODO @jason:排序按照充值金额  
16 return selectPage(reqVO, new LambdaQueryWrapperX<PayWalletRechargePackageDO>() 15 return selectPage(reqVO, new LambdaQueryWrapperX<PayWalletRechargePackageDO>()
17 .likeIfPresent(PayWalletRechargePackageDO::getName, reqVO.getName()) 16 .likeIfPresent(PayWalletRechargePackageDO::getName, reqVO.getName())
18 - .eqIfPresent(PayWalletRechargePackageDO::getPayPrice, reqVO.getPayPrice())  
19 - .eqIfPresent(PayWalletRechargePackageDO::getBonusPrice, reqVO.getBonusPrice())  
20 .eqIfPresent(PayWalletRechargePackageDO::getStatus, reqVO.getStatus()) 17 .eqIfPresent(PayWalletRechargePackageDO::getStatus, reqVO.getStatus())
21 .betweenIfPresent(PayWalletRechargePackageDO::getCreateTime, reqVO.getCreateTime()) 18 .betweenIfPresent(PayWalletRechargePackageDO::getCreateTime, reqVO.getCreateTime())
22 - .orderByDesc(PayWalletRechargePackageDO::getId)); 19 + .orderByDesc(PayWalletRechargePackageDO::getPayPrice));
23 } 20 }
24 21
  22 + default PayWalletRechargePackageDO selectByName(String name){
  23 + return selectOne(PayWalletRechargePackageDO::getName, name);
  24 + }
25 } 25 }
26 \ No newline at end of file 26 \ No newline at end of file
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferServiceImpl.java
@@ -46,10 +46,10 @@ public class PayDemoTransferServiceImpl implements PayDemoTransferService { @@ -46,10 +46,10 @@ public class PayDemoTransferServiceImpl implements PayDemoTransferService {
46 @Transactional(rollbackFor = Exception.class) 46 @Transactional(rollbackFor = Exception.class)
47 public Long createDemoTransfer(Long userId, @Valid PayDemoTransferCreateReqVO vo) { 47 public Long createDemoTransfer(Long userId, @Valid PayDemoTransferCreateReqVO vo) {
48 // 1 校验收款账号 48 // 1 校验收款账号
49 - validatePayeeInfo(vo.getTransferType(), vo.getPayeeInfo()); 49 + validatePayeeInfo(vo.getType(), vo.getPayeeInfo());
50 50
51 // 2 保存示例转账业务表 51 // 2 保存示例转账业务表
52 - PayDemoTransferDO demoTransfer = new PayDemoTransferDO().setUserId(userId).setType(vo.getTransferType()) 52 + PayDemoTransferDO demoTransfer = new PayDemoTransferDO().setUserId(userId).setType(vo.getType())
53 .setPrice(vo.getPrice()).setPayeeInfo(vo.getPayeeInfo()) 53 .setPrice(vo.getPrice()).setPayeeInfo(vo.getPayeeInfo())
54 .setTransferStatus(WAITING.getStatus()); 54 .setTransferStatus(WAITING.getStatus());
55 demoTransferMapper.insert(demoTransfer); 55 demoTransferMapper.insert(demoTransfer);
@@ -65,8 +65,9 @@ public class PayDemoTransferServiceImpl implements PayDemoTransferService { @@ -65,8 +65,9 @@ public class PayDemoTransferServiceImpl implements PayDemoTransferService {
65 } 65 }
66 66
67 // TODO @jason:可以参考 AppBrokerageWithdrawCreateReqVO 搞下字段哈,进行校验 67 // TODO @jason:可以参考 AppBrokerageWithdrawCreateReqVO 搞下字段哈,进行校验
  68 + // @jason payeeinfo 字段确定改一下
68 private void validatePayeeInfo(Integer transferType, Map<String, String> payeeInfo) { 69 private void validatePayeeInfo(Integer transferType, Map<String, String> payeeInfo) {
69 - PayTransferTypeEnum transferTypeEnum = ofType(transferType); 70 + PayTransferTypeEnum transferTypeEnum = typeOf(transferType);
70 switch (transferTypeEnum) { 71 switch (transferTypeEnum) {
71 case ALIPAY_BALANCE: { 72 case ALIPAY_BALANCE: {
72 if (StrUtil.isEmpty(MapUtil.getStr(payeeInfo, ALIPAY_LOGON_ID))) { 73 if (StrUtil.isEmpty(MapUtil.getStr(payeeInfo, ALIPAY_LOGON_ID))) {
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java
@@ -79,7 +79,7 @@ public class PayTransferServiceImpl implements PayTransferService { @@ -79,7 +79,7 @@ public class PayTransferServiceImpl implements PayTransferService {
79 // 3. 调用三方渠道发起转账 79 // 3. 调用三方渠道发起转账
80 PayTransferUnifiedReqDTO transferUnifiedReq = new PayTransferUnifiedReqDTO() 80 PayTransferUnifiedReqDTO transferUnifiedReq = new PayTransferUnifiedReqDTO()
81 .setOutTransferNo(transferExtension.getNo()).setPrice(transfer.getPrice()) 81 .setOutTransferNo(transferExtension.getNo()).setPrice(transfer.getPrice())
82 - .setType(transfer.getType()).setTitle(transfer.getTitle()) 82 + .setType(transfer.getType()).setTitle(transfer.getSubject())
83 .setPayeeInfo(transfer.getPayeeInfo()).setUserIp(userIp) 83 .setPayeeInfo(transfer.getPayeeInfo()).setUserIp(userIp)
84 .setChannelExtras(reqVO.getChannelExtras()); 84 .setChannelExtras(reqVO.getChannelExtras());
85 PayTransferRespDTO unifiedTransferResp = client.unifiedTransfer(transferUnifiedReq); 85 PayTransferRespDTO unifiedTransferResp = client.unifiedTransfer(transferUnifiedReq);
@@ -214,11 +214,11 @@ public class PayTransferServiceImpl implements PayTransferService { @@ -214,11 +214,11 @@ public class PayTransferServiceImpl implements PayTransferService {
214 } 214 }
215 215
216 private void validateChannelCodeAndTypeMatch(String channelCode, Integer type) { 216 private void validateChannelCodeAndTypeMatch(String channelCode, Integer type) {
217 - PayTransferTypeEnum transferType = PayTransferTypeEnum.ofType(type); 217 + PayTransferTypeEnum transferType = PayTransferTypeEnum.typeOf(type);
218 PayChannelEnum payChannel = PayChannelEnum.getByCode(channelCode); 218 PayChannelEnum payChannel = PayChannelEnum.getByCode(channelCode);
219 switch (transferType) { 219 switch (transferType) {
220 case ALIPAY_BALANCE: { 220 case ALIPAY_BALANCE: {
221 - if (payChannel != PayChannelEnum.ALIPAY_TRANSFER) { 221 + if (!payChannel.getCode().startsWith("alipay")) {
222 throw exception(PAY_TRANSFER_TYPE_AND_CHANNEL_NOT_MATCH); 222 throw exception(PAY_TRANSFER_TYPE_AND_CHANNEL_NOT_MATCH);
223 } 223 }
224 break; 224 break;
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargePackageServiceImpl.java
1 package cn.iocoder.yudao.module.pay.service.wallet; 1 package cn.iocoder.yudao.module.pay.service.wallet;
2 2
3 -import cn.hutool.core.collection.CollUtil;  
4 -import cn.hutool.core.collection.ListUtil; 3 +import cn.hutool.core.util.StrUtil;
5 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; 4 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
6 import cn.iocoder.yudao.framework.common.pojo.PageResult; 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
7 import cn.iocoder.yudao.module.pay.controller.admin.wallet.vo.rechargepackage.WalletRechargePackageCreateReqVO; 6 import cn.iocoder.yudao.module.pay.controller.admin.wallet.vo.rechargepackage.WalletRechargePackageCreateReqVO;
@@ -14,9 +13,6 @@ import org.springframework.stereotype.Service; @@ -14,9 +13,6 @@ import org.springframework.stereotype.Service;
14 13
15 import javax.annotation.Resource; 14 import javax.annotation.Resource;
16 15
17 -import java.util.Collection;  
18 -import java.util.List;  
19 -  
20 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 16 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
21 import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*; 17 import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*;
22 18
@@ -50,6 +46,8 @@ public class PayWalletRechargePackageServiceImpl implements PayWalletRechargePac @@ -50,6 +46,8 @@ public class PayWalletRechargePackageServiceImpl implements PayWalletRechargePac
50 46
51 @Override 47 @Override
52 public Long createWalletRechargePackage(WalletRechargePackageCreateReqVO createReqVO) { 48 public Long createWalletRechargePackage(WalletRechargePackageCreateReqVO createReqVO) {
  49 + // 校验套餐名是否唯一
  50 + validateRechargePackageNameUnique(null, createReqVO.getName());
53 // 插入 51 // 插入
54 PayWalletRechargePackageDO walletRechargePackage = WalletRechargePackageConvert.INSTANCE.convert(createReqVO); 52 PayWalletRechargePackageDO walletRechargePackage = WalletRechargePackageConvert.INSTANCE.convert(createReqVO);
55 walletRechargePackageMapper.insert(walletRechargePackage); 53 walletRechargePackageMapper.insert(walletRechargePackage);
@@ -57,16 +55,33 @@ public class PayWalletRechargePackageServiceImpl implements PayWalletRechargePac @@ -57,16 +55,33 @@ public class PayWalletRechargePackageServiceImpl implements PayWalletRechargePac
57 return walletRechargePackage.getId(); 55 return walletRechargePackage.getId();
58 } 56 }
59 57
60 - // TODO @jason:校验下,套餐名唯一  
61 @Override 58 @Override
62 public void updateWalletRechargePackage(WalletRechargePackageUpdateReqVO updateReqVO) { 59 public void updateWalletRechargePackage(WalletRechargePackageUpdateReqVO updateReqVO) {
63 // 校验存在 60 // 校验存在
64 validateWalletRechargePackageExists(updateReqVO.getId()); 61 validateWalletRechargePackageExists(updateReqVO.getId());
  62 + // 校验套餐名是否唯一
  63 + validateRechargePackageNameUnique(updateReqVO.getId(), updateReqVO.getName());
65 // 更新 64 // 更新
66 PayWalletRechargePackageDO updateObj = WalletRechargePackageConvert.INSTANCE.convert(updateReqVO); 65 PayWalletRechargePackageDO updateObj = WalletRechargePackageConvert.INSTANCE.convert(updateReqVO);
67 walletRechargePackageMapper.updateById(updateObj); 66 walletRechargePackageMapper.updateById(updateObj);
68 } 67 }
69 68
  69 + private void validateRechargePackageNameUnique(Long id, String name) {
  70 + if (StrUtil.isBlank(name)) {
  71 + return;
  72 + }
  73 + PayWalletRechargePackageDO rechargePackage = walletRechargePackageMapper.selectByName(name);
  74 + if (rechargePackage == null) {
  75 + return ;
  76 + }
  77 + if (id == null) {
  78 + throw exception(WALLET_RECHARGE_PACKAGE_NAME_EXISTS);
  79 + }
  80 + if (!id.equals(rechargePackage.getId())) {
  81 + throw exception(WALLET_RECHARGE_PACKAGE_NAME_EXISTS);
  82 + }
  83 + }
  84 +
70 @Override 85 @Override
71 public void deleteWalletRechargePackage(Long id) { 86 public void deleteWalletRechargePackage(Long id) {
72 // 校验存在 87 // 校验存在
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeService.java
@@ -16,9 +16,10 @@ public interface PayWalletRechargeService { @@ -16,9 +16,10 @@ public interface PayWalletRechargeService {
16 * @param userId 用户 id 16 * @param userId 用户 id
17 * @param userType 用户类型 17 * @param userType 用户类型
18 * @param createReqVO 钱包充值请求 VO 18 * @param createReqVO 钱包充值请求 VO
  19 + * @param userIp 用户Ip
19 * @return 钱包充值记录 20 * @return 钱包充值记录
20 */ 21 */
21 - PayWalletRechargeDO createWalletRecharge(Long userId, Integer userType, 22 + PayWalletRechargeDO createWalletRecharge(Long userId, Integer userType, String userIp,
22 AppPayWalletRechargeCreateReqVO createReqVO); 23 AppPayWalletRechargeCreateReqVO createReqVO);
23 24
24 /** 25 /**
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeServiceImpl.java
@@ -29,7 +29,6 @@ import static cn.hutool.core.util.ObjectUtil.notEqual; @@ -29,7 +29,6 @@ import static cn.hutool.core.util.ObjectUtil.notEqual;
29 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 29 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
30 import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.addTime; 30 import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.addTime;
31 import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; 31 import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
32 -import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP;  
33 import static cn.iocoder.yudao.module.pay.convert.wallet.PayWalletRechargeConvert.INSTANCE; 32 import static cn.iocoder.yudao.module.pay.convert.wallet.PayWalletRechargeConvert.INSTANCE;
34 import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*; 33 import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*;
35 import static cn.iocoder.yudao.module.pay.enums.refund.PayRefundStatusEnum.*; 34 import static cn.iocoder.yudao.module.pay.enums.refund.PayRefundStatusEnum.*;
@@ -63,13 +62,13 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { @@ -63,13 +62,13 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService {
63 62
64 @Override 63 @Override
65 @Transactional(rollbackFor = Exception.class) 64 @Transactional(rollbackFor = Exception.class)
66 - public PayWalletRechargeDO createWalletRecharge(Long userId, Integer userType, 65 + public PayWalletRechargeDO createWalletRecharge(Long userId, Integer userType, String userIp,
67 AppPayWalletRechargeCreateReqVO reqVO) { 66 AppPayWalletRechargeCreateReqVO reqVO) {
68 - // 1.1 校验参数 TODO @jason:AppPayWalletRechargeCreateReqVO 看下校验; 67 +
69 if (Objects.isNull(reqVO.getPayPrice()) && Objects.isNull(reqVO.getPackageId())) { 68 if (Objects.isNull(reqVO.getPayPrice()) && Objects.isNull(reqVO.getPackageId())) {
  69 + // TODO @jason @AssertTrue 貌似没有效果。需要查下原因
70 throw exception(WALLET_RECHARGE_PACKAGE_AND_PRICE_IS_EMPTY); 70 throw exception(WALLET_RECHARGE_PACKAGE_AND_PRICE_IS_EMPTY);
71 } 71 }
72 -  
73 // 1.1 计算充值金额 72 // 1.1 计算充值金额
74 int payPrice; 73 int payPrice;
75 int bonusPrice = 0; 74 int bonusPrice = 0;
@@ -87,7 +86,7 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { @@ -87,7 +86,7 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService {
87 86
88 // 2.1 创建支付单 87 // 2.1 创建支付单
89 Long payOrderId = payOrderService.createOrder(new PayOrderCreateReqDTO() 88 Long payOrderId = payOrderService.createOrder(new PayOrderCreateReqDTO()
90 - .setAppId(WALLET_PAY_APP_ID).setUserIp(getClientIP()) // TODO @jason:clientIp 从 controller 传递进来噢 89 + .setAppId(WALLET_PAY_APP_ID).setUserIp(userIp)
91 .setMerchantOrderId(recharge.getId().toString()) // 业务的订单编号 90 .setMerchantOrderId(recharge.getId().toString()) // 业务的订单编号
92 .setSubject(WALLET_RECHARGE_ORDER_SUBJECT).setBody("") 91 .setSubject(WALLET_RECHARGE_ORDER_SUBJECT).setBody("")
93 .setPrice(recharge.getPayPrice()) 92 .setPrice(recharge.getPayPrice())
@@ -181,7 +180,7 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { @@ -181,7 +180,7 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService {
181 // 退款失败 180 // 退款失败
182 if (PayRefundStatusRespEnum.isFailure(payRefund.getStatus())) { 181 if (PayRefundStatusRespEnum.isFailure(payRefund.getStatus())) {
183 // 2.2 解冻余额 182 // 2.2 解冻余额
184 - payWalletService.unFreezePrice(walletRecharge.getWalletId(), walletRecharge.getTotalPrice()); 183 + payWalletService.unfreezePrice(walletRecharge.getWalletId(), walletRecharge.getTotalPrice());
185 184
186 updateObj.setRefundStatus(FAILURE.getStatus()); 185 updateObj.setRefundStatus(FAILURE.getStatus());
187 } 186 }
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletService.java
@@ -37,7 +37,7 @@ public interface PayWalletService { @@ -37,7 +37,7 @@ public interface PayWalletService {
37 * @param pageReqVO 分页查询 37 * @param pageReqVO 分页查询
38 * @return 会员钱包分页 38 * @return 会员钱包分页
39 */ 39 */
40 - PageResult<PayWalletDO> getWalletPage(PayWalletPageReqVO pageReqVO); 40 + PageResult<PayWalletDO> getWalletPage(Integer userType, PayWalletPageReqVO pageReqVO);
41 41
42 /** 42 /**
43 * 钱包订单支付 43 * 钱包订单支付
@@ -90,13 +90,12 @@ public interface PayWalletService { @@ -90,13 +90,12 @@ public interface PayWalletService {
90 */ 90 */
91 void freezePrice(Long id, Integer price); 91 void freezePrice(Long id, Integer price);
92 92
93 - // TODO @jason:unfreeze 是单词哈,f 不用大写  
94 /** 93 /**
95 * 解冻钱包余额 94 * 解冻钱包余额
96 * 95 *
97 * @param id 钱包编号 96 * @param id 钱包编号
98 * @param price 解冻金额 97 * @param price 解冻金额
99 */ 98 */
100 - void unFreezePrice(Long id, Integer price); 99 + void unfreezePrice(Long id, Integer price);
101 100
102 } 101 }
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletServiceImpl.java
@@ -63,8 +63,8 @@ public class PayWalletServiceImpl implements PayWalletService { @@ -63,8 +63,8 @@ public class PayWalletServiceImpl implements PayWalletService {
63 } 63 }
64 64
65 @Override 65 @Override
66 - public PageResult<PayWalletDO> getWalletPage(PayWalletPageReqVO pageReqVO) {  
67 - return walletMapper.selectPage(pageReqVO); 66 + public PageResult<PayWalletDO> getWalletPage(Integer userType,PayWalletPageReqVO pageReqVO) {
  67 + return walletMapper.selectPage(userType, pageReqVO);
68 } 68 }
69 69
70 @Override 70 @Override
@@ -196,7 +196,7 @@ public class PayWalletServiceImpl implements PayWalletService { @@ -196,7 +196,7 @@ public class PayWalletServiceImpl implements PayWalletService {
196 } 196 }
197 197
198 @Override 198 @Override
199 - public void unFreezePrice(Long id, Integer price) { 199 + public void unfreezePrice(Long id, Integer price) {
200 int updateCounts = walletMapper.unFreezePrice(id, price); 200 int updateCounts = walletMapper.unFreezePrice(id, price);
201 if (updateCounts == 0) { 201 if (updateCounts == 0) {
202 throw exception(WALLET_FREEZE_PRICE_NOT_ENOUGH); 202 throw exception(WALLET_FREEZE_PRICE_NOT_ENOUGH);
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionServiceImpl.java
@@ -12,6 +12,7 @@ import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum; @@ -12,6 +12,7 @@ import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum;
12 import cn.iocoder.yudao.module.pay.service.wallet.bo.WalletTransactionCreateReqBO; 12 import cn.iocoder.yudao.module.pay.service.wallet.bo.WalletTransactionCreateReqBO;
13 import lombok.extern.slf4j.Slf4j; 13 import lombok.extern.slf4j.Slf4j;
14 import org.springframework.stereotype.Service; 14 import org.springframework.stereotype.Service;
  15 +import org.springframework.validation.annotation.Validated;
15 16
16 import javax.annotation.Resource; 17 import javax.annotation.Resource;
17 18
@@ -22,6 +23,7 @@ import javax.annotation.Resource; @@ -22,6 +23,7 @@ import javax.annotation.Resource;
22 */ 23 */
23 @Service 24 @Service
24 @Slf4j 25 @Slf4j
  26 +@Validated
25 public class PayWalletTransactionServiceImpl implements PayWalletTransactionService { 27 public class PayWalletTransactionServiceImpl implements PayWalletTransactionService {
26 28
27 /** 29 /**
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/bo/WalletTransactionCreateReqBO.java
1 package cn.iocoder.yudao.module.pay.service.wallet.bo; 1 package cn.iocoder.yudao.module.pay.service.wallet.bo;
2 2
  3 +import cn.iocoder.yudao.framework.common.validation.InEnum;
3 import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum; 4 import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum;
4 import lombok.Data; 5 import lombok.Data;
5 6
  7 +import javax.validation.constraints.NotEmpty;
  8 +import javax.validation.constraints.NotNull;
  9 +
6 /** 10 /**
7 * 创建钱包流水 BO 11 * 创建钱包流水 BO
8 * 12 *
@@ -11,12 +15,11 @@ import lombok.Data; @@ -11,12 +15,11 @@ import lombok.Data;
11 @Data 15 @Data
12 public class WalletTransactionCreateReqBO { 16 public class WalletTransactionCreateReqBO {
13 17
14 - // TODO @jason:bo 的话,最好加个参数校验哈;  
15 -  
16 /** 18 /**
17 * 钱包编号 19 * 钱包编号
18 * 20 *
19 */ 21 */
  22 + @NotNull(message = "钱包编号不能为空")
20 private Long walletId; 23 private Long walletId;
21 24
22 /** 25 /**
@@ -24,11 +27,13 @@ public class WalletTransactionCreateReqBO { @@ -24,11 +27,13 @@ public class WalletTransactionCreateReqBO {
24 * 27 *
25 * 正值表示余额增加,负值表示余额减少 28 * 正值表示余额增加,负值表示余额减少
26 */ 29 */
  30 + @NotNull(message = "交易金额不能为空")
27 private Integer price; 31 private Integer price;
28 32
29 /** 33 /**
30 * 交易后余额,单位分 34 * 交易后余额,单位分
31 */ 35 */
  36 + @NotNull(message = "交易后余额不能为空")
32 private Integer balance; 37 private Integer balance;
33 38
34 /** 39 /**
@@ -36,15 +41,19 @@ public class WalletTransactionCreateReqBO { @@ -36,15 +41,19 @@ public class WalletTransactionCreateReqBO {
36 * 41 *
37 * 枚举 {@link PayWalletBizTypeEnum#getType()} 42 * 枚举 {@link PayWalletBizTypeEnum#getType()}
38 */ 43 */
  44 + @NotNull(message = "关联业务分类不能为空")
  45 + @InEnum(PayWalletBizTypeEnum.class)
39 private Integer bizType; 46 private Integer bizType;
40 47
41 /** 48 /**
42 * 关联业务编号 49 * 关联业务编号
43 */ 50 */
  51 + @NotEmpty(message = "关联业务编号不能为空")
44 private String bizId; 52 private String bizId;
45 53
46 /** 54 /**
47 * 流水说明 55 * 流水说明
48 */ 56 */
  57 + @NotEmpty(message = "流水说明不能为空")
49 private String title; 58 private String title;
50 } 59 }