Commit 00e18a480ff4bca6e6be6c7e6119cc684bd32aba
1 parent
5842a361
code review:钱包、充值、转账的实现
Showing
49 changed files
with
178 additions
and
112 deletions
sql/mysql/pay_wallet.sql
| ... | ... | @@ -77,7 +77,7 @@ ALTER TABLE `pay_channel` |
| 77 | 77 | MODIFY COLUMN `config` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '支付渠道配置' AFTER `app_id`; |
| 78 | 78 | |
| 79 | 79 | -- ---------------------------- |
| 80 | --- 套餐充值表 | |
| 80 | +-- 充值套餐表 | |
| 81 | 81 | -- ---------------------------- |
| 82 | 82 | DROP TABLE IF EXISTS `pay_wallet_recharge_package`; |
| 83 | 83 | CREATE TABLE `pay_wallet_recharge_package` |
| ... | ... | @@ -94,7 +94,7 @@ CREATE TABLE `pay_wallet_recharge_package` |
| 94 | 94 | `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', |
| 95 | 95 | `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', |
| 96 | 96 | PRIMARY KEY (`id`) USING BTREE |
| 97 | -) ENGINE=InnoDB COMMENT='套餐充值表'; | |
| 97 | +) ENGINE=InnoDB COMMENT='充值套餐表'; | |
| 98 | 98 | |
| 99 | 99 | -- ---------------------------- |
| 100 | 100 | -- Table structure for pay_wallet_recharge | ... | ... |
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/PayTransferUnifiedReqDTO.java
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayTransferClient.java
| ... | ... | @@ -22,6 +22,7 @@ import lombok.extern.slf4j.Slf4j; |
| 22 | 22 | import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST; |
| 23 | 23 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception0; |
| 24 | 24 | |
| 25 | +// TODO @jason:看看能不能融合到 AbstractAlipayPayClient 中。 | |
| 25 | 26 | /** |
| 26 | 27 | * 支付宝转账的 PayClient 实现类 |
| 27 | 28 | * |
| ... | ... | @@ -29,6 +30,7 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU |
| 29 | 30 | */ |
| 30 | 31 | @Slf4j |
| 31 | 32 | public class AlipayTransferClient extends AbstractAlipayPayClient { |
| 33 | + // TODO @jason:方法之间,要有空格噢 | |
| 32 | 34 | public AlipayTransferClient(Long channelId, AlipayPayClientConfig config) { |
| 33 | 35 | super(channelId, PayChannelEnum.ALIPAY_TRANSFER.getCode(), config); |
| 34 | 36 | } |
| ... | ... | @@ -49,16 +51,17 @@ public class AlipayTransferClient extends AbstractAlipayPayClient { |
| 49 | 51 | model.setOrderTitle(reqDTO.getTitle()); // 转账业务的标题,用于在支付宝用户的账单里显示。 |
| 50 | 52 | model.setOutBizNo(reqDTO.getOutTransferNo()); |
| 51 | 53 | model.setProductCode("TRANS_ACCOUNT_NO_PWD"); // 销售产品码。单笔无密转账固定为 TRANS_ACCOUNT_NO_PWD |
| 52 | - model.setBizScene("DIRECT_TRANSFER"); // 业务场景 单笔无密转账固定为 DIRECT_TRANSFER。 | |
| 54 | + model.setBizScene("DIRECT_TRANSFER"); // 业务场景 单笔无密转账固定为 DIRECT_TRANSFER | |
| 53 | 55 | model.setBusinessParams(JsonUtils.toJsonString(reqDTO.getChannelExtras())); |
| 54 | 56 | PayTransferTypeEnum transferType = PayTransferTypeEnum.ofType(reqDTO.getType()); |
| 55 | - switch(transferType){ | |
| 56 | - case WX_BALANCE : | |
| 57 | - case WALLET_BALANCE : { | |
| 57 | + switch(transferType) { | |
| 58 | + case WX_BALANCE: | |
| 59 | + case WALLET_BALANCE: { | |
| 58 | 60 | log.error("[doUnifiedTransfer],支付宝转账不支持的转账类型{}", transferType); |
| 59 | 61 | throw new UnsupportedOperationException(String.format("支付宝转账不支持转账类型: %s",transferType.getName())); |
| 60 | 62 | } |
| 61 | - case ALIPAY_BALANCE : { | |
| 63 | + // TODO @jason:是不是不用传递 transferType 参数哈?因为应该已经明确是支付宝啦? | |
| 64 | + case ALIPAY_BALANCE: { | |
| 62 | 65 | // ② 个性化的参数 |
| 63 | 66 | Participant payeeInfo = new Participant(); |
| 64 | 67 | payeeInfo.setIdentityType("ALIPAY_LOGON_ID"); |
| ... | ... | @@ -90,7 +93,7 @@ public class AlipayTransferClient extends AbstractAlipayPayClient { |
| 90 | 93 | return PayTransferRespDTO.successOf(response.getOrderId(), parseTime(response.getTransDate()), |
| 91 | 94 | response.getOutBizNo(), response); |
| 92 | 95 | } |
| 93 | - case BANK_CARD : { | |
| 96 | + case BANK_CARD: { | |
| 94 | 97 | Participant payeeInfo = new Participant(); |
| 95 | 98 | payeeInfo.setIdentityType("BANKCARD_ACCOUNT"); |
| 96 | 99 | throw new UnsupportedOperationException("待实现"); |
| ... | ... | @@ -100,4 +103,5 @@ public class AlipayTransferClient extends AbstractAlipayPayClient { |
| 100 | 103 | } |
| 101 | 104 | } |
| 102 | 105 | } |
| 106 | + | |
| 103 | 107 | } | ... | ... |
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/mock/MockPayClient.java
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/channel/PayChannelEnum.java
| ... | ... | @@ -28,6 +28,7 @@ public enum PayChannelEnum { |
| 28 | 28 | ALIPAY_APP("alipay_app", "支付宝App 支付", AlipayPayClientConfig.class), |
| 29 | 29 | ALIPAY_QR("alipay_qr", "支付宝扫码支付", AlipayPayClientConfig.class), |
| 30 | 30 | ALIPAY_BAR("alipay_bar", "支付宝条码支付", AlipayPayClientConfig.class), |
| 31 | + // TODO @jason:是不是按照微信聊的,合并回 ALIPAY_PC;因为支付宝、微信都是多种支付方式,选择其中的一种即可; | |
| 31 | 32 | ALIPAY_TRANSFER("alipay_transfer", "支付宝转账", AlipayPayClientConfig.class), |
| 32 | 33 | |
| 33 | 34 | MOCK("mock", "模拟支付", NonePayClientConfig.class), | ... | ... |
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/transfer/PayTransferStatusRespEnum.java
| ... | ... | @@ -18,10 +18,10 @@ public enum PayTransferStatusRespEnum { |
| 18 | 18 | |
| 19 | 19 | /** |
| 20 | 20 | * TODO 转账到银行卡. 会有T+0 T+1 到账的请情况。 还未实现 |
| 21 | + * TODO @jason:可以看看其它开源项目,针对这个场景,处理策略是怎么样的?例如说,每天主动轮询?这个状态的单子? | |
| 21 | 22 | */ |
| 22 | 23 | IN_PROGRESS(10, "转账进行中"), |
| 23 | 24 | |
| 24 | - | |
| 25 | 25 | SUCCESS(20, "转账成功"), |
| 26 | 26 | /** |
| 27 | 27 | * 转账关闭 (失败,或者其它情况) | ... | ... |
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/transfer/PayTransferTypeEnum.java
| ... | ... | @@ -15,6 +15,7 @@ import java.util.Arrays; |
| 15 | 15 | @AllArgsConstructor |
| 16 | 16 | @Getter |
| 17 | 17 | public enum PayTransferTypeEnum implements IntArrayValuable { |
| 18 | + | |
| 18 | 19 | ALIPAY_BALANCE(1, "支付宝余额"), |
| 19 | 20 | WX_BALANCE(2, "微信余额"), |
| 20 | 21 | BANK_CARD(3, "银行卡"), |
| ... | ... | @@ -33,7 +34,9 @@ public enum PayTransferTypeEnum implements IntArrayValuable { |
| 33 | 34 | return ARRAYS; |
| 34 | 35 | } |
| 35 | 36 | |
| 37 | + // TODO @jason:是不是 typeOf 更符合预期哈? | |
| 36 | 38 | public static PayTransferTypeEnum ofType(Integer type) { |
| 37 | 39 | return ArrayUtil.firstMatch(item -> item.getType().equals(type), values()); |
| 38 | 40 | } |
| 41 | + | |
| 39 | 42 | } | ... | ... |
yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/PayTransferApi.java
yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferCreateReqDTO.java
| ... | ... | @@ -23,6 +23,7 @@ public class PayTransferCreateReqDTO { |
| 23 | 23 | * 类型 |
| 24 | 24 | */ |
| 25 | 25 | @NotNull(message = "转账类型不能为空") |
| 26 | + // TODO @jason:枚举的校验 | |
| 26 | 27 | private Integer type; |
| 27 | 28 | |
| 28 | 29 | /** |
| ... | ... | @@ -34,9 +35,11 @@ public class PayTransferCreateReqDTO { |
| 34 | 35 | /** |
| 35 | 36 | * 转账金额,单位:分 |
| 36 | 37 | */ |
| 38 | + // TODO @jason:这个金额是不是非空哈 | |
| 37 | 39 | @Min(value = 1, message = "转账金额必须大于零") |
| 38 | 40 | private Integer price; |
| 39 | 41 | |
| 42 | + // TODO @jason:这个标题,是不是不允许空呀 | |
| 40 | 43 | /** |
| 41 | 44 | * 转账标题 |
| 42 | 45 | */ |
| ... | ... | @@ -44,4 +47,5 @@ public class PayTransferCreateReqDTO { |
| 44 | 47 | |
| 45 | 48 | @NotEmpty(message = "收款方信息不能为空") |
| 46 | 49 | private Map<String, String> payeeInfo; |
| 50 | + | |
| 47 | 51 | } | ... | ... |
yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java
| ... | ... | @@ -27,8 +27,6 @@ public interface ErrorCodeConstants { |
| 27 | 27 | ErrorCode PAY_ORDER_IS_EXPIRED = new ErrorCode(1_007_002_003, "支付订单已经过期"); |
| 28 | 28 | ErrorCode PAY_ORDER_SUBMIT_CHANNEL_ERROR = new ErrorCode(1_007_002_004, "发起支付报错,错误码:{},错误提示:{}"); |
| 29 | 29 | ErrorCode PAY_ORDER_REFUND_FAIL_STATUS_ERROR = new ErrorCode(1_007_002_005, "支付订单退款失败,原因:状态不是已支付或已退款"); |
| 30 | - ErrorCode ORDER_UPDATE_PRICE_FAIL_PAID = new ErrorCode(1_007_002_006, "支付订单调价失败,原因:支付订单已付款,不能调价"); | |
| 31 | - ErrorCode ORDER_UPDATE_PRICE_FAIL_EQUAL = new ErrorCode(1_007_002_007, "支付订单调价失败,原因:价格没有变化"); | |
| 32 | 30 | |
| 33 | 31 | // ========== ORDER 模块(拓展单) 1-007-003-000 ========== |
| 34 | 32 | ErrorCode PAY_ORDER_EXTENSION_NOT_FOUND = new ErrorCode(1_007_003_000, "支付交易拓展单不存在"); |
| ... | ... | @@ -64,6 +62,7 @@ public interface ErrorCodeConstants { |
| 64 | 62 | ErrorCode WALLET_RECHARGE_PACKAGE_AND_PRICE_IS_EMPTY = new ErrorCode(1_007_008_011, "充值金额和充钱套餐不能同时为空"); |
| 65 | 63 | ErrorCode WALLET_RECHARGE_PACKAGE_NOT_FOUND = new ErrorCode(1_007_008_012, "钱包充值套餐不存在"); |
| 66 | 64 | ErrorCode WALLET_RECHARGE_PACKAGE_IS_DISABLE = new ErrorCode(1_007_008_013, "钱包充值套餐已禁用"); |
| 65 | + | |
| 67 | 66 | // ========== 转账模块 1-007-009-000 ========== |
| 68 | 67 | ErrorCode PAY_TRANSFER_SUBMIT_CHANNEL_ERROR = new ErrorCode(1_007_009_000, "发起转账报错,错误码:{},错误提示:{}"); |
| 69 | 68 | ErrorCode PAY_TRANSFER_ALIPAY_LOGIN_ID_IS_EMPTY = new ErrorCode(1_007_009_001, "支付宝登录 ID 不能为空"); | ... | ... |
yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/transfer/PayTransferStatusEnum.java
| ... | ... | @@ -24,7 +24,13 @@ public enum PayTransferStatusEnum { |
| 24 | 24 | */ |
| 25 | 25 | CLOSED(30, "转账关闭"); |
| 26 | 26 | |
| 27 | + /** | |
| 28 | + * 状态 | |
| 29 | + */ | |
| 27 | 30 | private final Integer status; |
| 31 | + /** | |
| 32 | + * 状态名 | |
| 33 | + */ | |
| 28 | 34 | private final String name; |
| 29 | 35 | |
| 30 | 36 | public static boolean isSuccess(Integer status) { |
| ... | ... | @@ -45,4 +51,5 @@ public enum PayTransferStatusEnum { |
| 45 | 51 | public static boolean isPendingStatus(Integer status) { |
| 46 | 52 | return Objects.equals(status, WAITING.getStatus()) || Objects.equals(status, IN_PROGRESS.status); |
| 47 | 53 | } |
| 54 | + | |
| 48 | 55 | } | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/PayTransferApiImpl.java
| ... | ... | @@ -5,14 +5,18 @@ import org.springframework.stereotype.Service; |
| 5 | 5 | import org.springframework.validation.annotation.Validated; |
| 6 | 6 | |
| 7 | 7 | /** |
| 8 | + * 转账单 API 实现类 | |
| 9 | + * | |
| 8 | 10 | * @author jason |
| 9 | 11 | */ |
| 10 | 12 | @Service |
| 11 | 13 | @Validated |
| 12 | 14 | public class PayTransferApiImpl implements PayTransferApi { |
| 15 | + | |
| 13 | 16 | @Override |
| 14 | 17 | public Long createTransfer(PayTransferCreateReqDTO reqDTO) { |
| 15 | - | |
| 18 | + // TODO @jason:貌似没实现噢 | |
| 16 | 19 | return null; |
| 17 | 20 | } |
| 18 | -} | |
| 21 | + | |
| 22 | +} | |
| 19 | 23 | \ 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,6 +17,7 @@ import java.util.Map; |
| 17 | 17 | @Data |
| 18 | 18 | public class PayDemoTransferCreateReqVO { |
| 19 | 19 | |
| 20 | + // TODO @jason:这个字段,是不是叫 type 就好了。 | |
| 20 | 21 | @Schema(description = "转账类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| 21 | 22 | @NotNull(message = "转账类型不能为空") |
| 22 | 23 | @InEnum(PayTransferTypeEnum.class) |
| ... | ... | @@ -26,7 +27,9 @@ public class PayDemoTransferCreateReqVO { |
| 26 | 27 | @Min(value = 1, message = "转账金额必须大于零") |
| 27 | 28 | private Integer price; |
| 28 | 29 | |
| 30 | + // TODO @jason:感觉这个动态字段,晚点改;可能要讨论下怎么搞好; | |
| 29 | 31 | @Schema(description = "收款方信息", requiredMode = Schema.RequiredMode.REQUIRED, example = "{'ALIPAY_LOGON_ID':'xxxx'}") |
| 30 | 32 | @NotEmpty(message = "收款方信息不能为空") |
| 31 | 33 | private Map<String, String> payeeInfo; |
| 34 | + | |
| 32 | 35 | } | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/PayTransferController.java
| ... | ... | @@ -29,8 +29,10 @@ public class PayTransferController { |
| 29 | 29 | |
| 30 | 30 | @PostMapping("/submit") |
| 31 | 31 | @Operation(summary = "提交转账订单") |
| 32 | + // TODO @jason:权限的设置 | |
| 32 | 33 | public CommonResult<PayTransferSubmitRespVO> submitPayTransfer(@Valid @RequestBody PayTransferSubmitReqVO reqVO) { |
| 33 | 34 | PayTransferSubmitRespVO respVO = payTransferService.submitTransfer(reqVO, getClientIP()); |
| 34 | 35 | return success(respVO); |
| 35 | 36 | } |
| 37 | + | |
| 36 | 38 | } | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/vo/PayTransferSubmitReqVO.java
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/vo/PayTransferSubmitRespVO.java
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/PayWalletRechargeController.java
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/PayWalletTransactionController.java
| ... | ... | @@ -32,9 +32,11 @@ public class PayWalletTransactionController { |
| 32 | 32 | |
| 33 | 33 | @GetMapping("/page") |
| 34 | 34 | @Operation(summary = "获得钱包流水分页") |
| 35 | + // TODO @jason:权限校验,缺一个 | |
| 35 | 36 | public CommonResult<PageResult<PayWalletTransactionRespVO>> getWalletTransactionPage( |
| 36 | 37 | @Valid PayWalletTransactionPageReqVO pageReqVO) { |
| 37 | 38 | PageResult<PayWalletTransactionDO> result = payWalletTransactionService.getWalletTransactionPage(pageReqVO); |
| 38 | 39 | return success(PayWalletTransactionConvert.INSTANCE.convertPage2(result)); |
| 39 | 40 | } |
| 41 | + | |
| 40 | 42 | } | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/rechargepackage/WalletRechargePackageBaseVO.java
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/rechargepackage/WalletRechargePackageCreateReqVO.java
| ... | ... | @@ -5,7 +5,7 @@ import lombok.Data; |
| 5 | 5 | import lombok.EqualsAndHashCode; |
| 6 | 6 | import lombok.ToString; |
| 7 | 7 | |
| 8 | -@Schema(description = "管理后台 - 套餐充值创建 Request VO") | |
| 8 | +@Schema(description = "管理后台 - 充值套餐创建 Request VO") | |
| 9 | 9 | @Data |
| 10 | 10 | @EqualsAndHashCode(callSuper = true) |
| 11 | 11 | @ToString(callSuper = true) | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/rechargepackage/WalletRechargePackagePageReqVO.java
| ... | ... | @@ -11,7 +11,7 @@ import java.time.LocalDateTime; |
| 11 | 11 | |
| 12 | 12 | import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; |
| 13 | 13 | |
| 14 | -@Schema(description = "管理后台 - 套餐充值分页 Request VO") | |
| 14 | +@Schema(description = "管理后台 - 充值套餐分页 Request VO") | |
| 15 | 15 | @Data |
| 16 | 16 | @EqualsAndHashCode(callSuper = true) |
| 17 | 17 | @ToString(callSuper = true) |
| ... | ... | @@ -20,6 +20,8 @@ public class WalletRechargePackagePageReqVO extends PageParam { |
| 20 | 20 | @Schema(description = "套餐名", example = "李四") |
| 21 | 21 | private String name; |
| 22 | 22 | |
| 23 | + // TODO @jason:payPrice 和 bonusPrice 可以去掉。。。一般太少检索啦; | |
| 24 | + | |
| 23 | 25 | @Schema(description = "支付金额", example = "16454") |
| 24 | 26 | private Integer payPrice; |
| 25 | 27 | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/rechargepackage/WalletRechargePackageRespVO.java
| ... | ... | @@ -4,7 +4,7 @@ import io.swagger.v3.oas.annotations.media.Schema; |
| 4 | 4 | import lombok.*; |
| 5 | 5 | import java.time.LocalDateTime; |
| 6 | 6 | |
| 7 | -@Schema(description = "管理后台 - 套餐充值 Response VO") | |
| 7 | +@Schema(description = "管理后台 - 充值套餐 Response VO") | |
| 8 | 8 | @Data |
| 9 | 9 | @EqualsAndHashCode(callSuper = true) |
| 10 | 10 | @ToString(callSuper = true) | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/rechargepackage/WalletRechargePackageUpdateReqVO.java
| ... | ... | @@ -7,7 +7,7 @@ import lombok.ToString; |
| 7 | 7 | |
| 8 | 8 | import javax.validation.constraints.NotNull; |
| 9 | 9 | |
| 10 | -@Schema(description = "管理后台 - 套餐充值更新 Request VO") | |
| 10 | +@Schema(description = "管理后台 - 充值套餐更新 Request VO") | |
| 11 | 11 | @Data |
| 12 | 12 | @EqualsAndHashCode(callSuper = true) |
| 13 | 13 | @ToString(callSuper = true) | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/transaction/PayWalletTransactionPageReqVO.java
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/transaction/PayWalletTransactionRespVO.java
| ... | ... | @@ -29,4 +29,7 @@ public class PayWalletTransactionRespVO { |
| 29 | 29 | |
| 30 | 30 | @Schema(description = "交易时间", requiredMode = Schema.RequiredMode.REQUIRED) |
| 31 | 31 | private LocalDateTime createTime; |
| 32 | + | |
| 33 | + // TODO @jason:merchantOrderId 字段,需要在 PayWalletTransaction 存储下;然后,前端也返回下这个字段,界面也展示下商户名 | |
| 34 | + | |
| 32 | 35 | } | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/wallet/PayWalletPageReqVO.java
| 1 | 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; | |
| 3 | 5 | import lombok.*; |
| 4 | 6 | import io.swagger.v3.oas.annotations.media.Schema; |
| 5 | 7 | import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| ... | ... | @@ -18,6 +20,7 @@ public class PayWalletPageReqVO extends PageParam { |
| 18 | 20 | private Long userId; |
| 19 | 21 | |
| 20 | 22 | @Schema(description = "用户类型", example = "1") |
| 23 | + @InEnum(UserTypeEnum.class) | |
| 21 | 24 | private Integer userType; |
| 22 | 25 | |
| 23 | 26 | @Schema(description = "创建时间") | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/wallet/PayWalletRespVO.java
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/recharge/AppPayWalletRechargeCreateReqVO.java
| ... | ... | @@ -13,7 +13,9 @@ public class AppPayWalletRechargeCreateReqVO { |
| 13 | 13 | @Min(value = 1, message = "支付金额必须大于零") |
| 14 | 14 | private Integer payPrice; |
| 15 | 15 | |
| 16 | - | |
| 17 | 16 | @Schema(description = "充值套餐编号", example = "1024") |
| 18 | 17 | private Long packageId; |
| 18 | + | |
| 19 | + // TODO @jaosn:写个 AssertTrue 的校验方法,payPrice 和 packageId 必须二选一 | |
| 20 | + | |
| 19 | 21 | } | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/wallet/PayWalletConvert.java
| ... | ... | @@ -14,7 +14,8 @@ public interface PayWalletConvert { |
| 14 | 14 | |
| 15 | 15 | AppPayWalletRespVO convert(PayWalletDO bean); |
| 16 | 16 | |
| 17 | - PayWalletRespVO convert02(PayWalletDO wallet); | |
| 17 | + PayWalletRespVO convert02(PayWalletDO bean); | |
| 18 | 18 | |
| 19 | 19 | PageResult<PayWalletRespVO> convertPage(PageResult<PayWalletDO> page); |
| 20 | + | |
| 20 | 21 | } | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/demo/PayDemoTransferDO.java
| ... | ... | @@ -20,6 +20,7 @@ import java.util.Map; |
| 20 | 20 | @KeySequence("pay_demo_transfer_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 |
| 21 | 21 | @Data |
| 22 | 22 | public class PayDemoTransferDO extends BaseDO { |
| 23 | + | |
| 23 | 24 | /** |
| 24 | 25 | * 订单编号 |
| 25 | 26 | */ |
| ... | ... | @@ -41,6 +42,7 @@ public class PayDemoTransferDO extends BaseDO { |
| 41 | 42 | */ |
| 42 | 43 | private Integer type; |
| 43 | 44 | |
| 45 | + // TODO @jason:要不字段还是弄成正确的平铺开? | |
| 44 | 46 | /** |
| 45 | 47 | * 收款人信息,不同类型和渠道不同 |
| 46 | 48 | */ |
| ... | ... | @@ -66,4 +68,5 @@ public class PayDemoTransferDO extends BaseDO { |
| 66 | 68 | * 转账支付时间 |
| 67 | 69 | */ |
| 68 | 70 | private LocalDateTime transferTime; |
| 71 | + | |
| 69 | 72 | } |
| 70 | 73 | \ No newline at end of file | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/transfer/PayTransferDO.java
| 1 | 1 | package cn.iocoder.yudao.module.pay.dal.dataobject.transfer; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| 4 | +import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum; | |
| 5 | +import cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferStatusRespEnum; | |
| 6 | +import cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferTypeEnum; | |
| 7 | +import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO; | |
| 8 | +import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO; | |
| 4 | 9 | import com.baomidou.mybatisplus.annotation.KeySequence; |
| 5 | 10 | import com.baomidou.mybatisplus.annotation.TableField; |
| 6 | 11 | import com.baomidou.mybatisplus.annotation.TableId; |
| ... | ... | @@ -26,70 +31,76 @@ public class PayTransferDO extends BaseDO { |
| 26 | 31 | */ |
| 27 | 32 | @TableId |
| 28 | 33 | private Long id; |
| 29 | - | |
| 34 | + /** | |
| 35 | + * 应用编号 | |
| 36 | + * | |
| 37 | + * 关联 {@link PayAppDO#getId()} | |
| 38 | + */ | |
| 39 | + private Long appId; | |
| 40 | + /** | |
| 41 | + * 转账渠道编号 | |
| 42 | + * | |
| 43 | + * 关联 {@link PayChannelDO#getId()} | |
| 44 | + */ | |
| 45 | + private Long channelId; | |
| 46 | + /** | |
| 47 | + * 转账渠道编码 | |
| 48 | + * | |
| 49 | + * 枚举 {@link PayChannelEnum} | |
| 50 | + */ | |
| 51 | + private String channelCode; | |
| 30 | 52 | /** |
| 31 | 53 | * 类型 |
| 54 | + * | |
| 55 | + * 枚举 {@link PayTransferTypeEnum} | |
| 32 | 56 | */ |
| 33 | 57 | private Integer type; |
| 34 | 58 | |
| 35 | - /** | |
| 36 | - * 应用编号 | |
| 37 | - */ | |
| 38 | - private Long appId; | |
| 59 | + // ========== 商户相关字段 ========== | |
| 39 | 60 | |
| 40 | 61 | /** |
| 41 | 62 | * 商户订单编号 |
| 63 | + * | |
| 64 | + * 例如说,内部系统 A 的订单号,需要保证每个 PayAppDO 唯一 | |
| 42 | 65 | */ |
| 43 | 66 | private String merchantOrderId; |
| 44 | - | |
| 45 | - /** | |
| 46 | - * 转账金额,单位:分 | |
| 47 | - */ | |
| 48 | - private Integer price; | |
| 49 | - | |
| 67 | + // TODO @jason:这个字段,要不要改成 subject。。。和 payorderdo 保持一致;哈哈哈,我也忘记为啥当时选了这个名字了。。。 | |
| 50 | 68 | /** |
| 51 | 69 | * 转账标题 |
| 52 | 70 | */ |
| 53 | 71 | private String title; |
| 54 | 72 | |
| 73 | + // ========== 转账相关字段 ========== | |
| 55 | 74 | /** |
| 56 | - * 收款人信息,不同类型和渠道不同 | |
| 75 | + * 转账金额,单位:分 | |
| 57 | 76 | */ |
| 58 | - @TableField(typeHandler = JacksonTypeHandler.class) | |
| 59 | - private Map<String, String> payeeInfo; | |
| 60 | - | |
| 77 | + private Integer price; | |
| 61 | 78 | /** |
| 62 | 79 | * 转账状态 |
| 80 | + * | |
| 81 | + * 枚举 {@link PayTransferStatusRespEnum} | |
| 63 | 82 | */ |
| 64 | 83 | private Integer status; |
| 65 | - | |
| 66 | 84 | /** |
| 67 | 85 | * 订单转账成功时间 |
| 68 | - * | |
| 69 | 86 | */ |
| 70 | 87 | private LocalDateTime successTime; |
| 71 | - | |
| 72 | 88 | /** |
| 73 | 89 | * 转账成功的转账拓展单编号 |
| 74 | 90 | * |
| 75 | 91 | * 关联 {@link PayTransferExtensionDO#getId()} |
| 76 | 92 | */ |
| 77 | 93 | private Long extensionId; |
| 78 | - | |
| 79 | 94 | /** |
| 80 | 95 | * 转账成功的转账拓展单号 |
| 81 | 96 | * |
| 82 | 97 | * 关联 {@link PayTransferExtensionDO#getNo()} |
| 83 | 98 | */ |
| 84 | 99 | private String no; |
| 85 | - | |
| 86 | 100 | /** |
| 87 | - * 转账渠道编号 | |
| 101 | + * 收款人信息,不同类型和渠道不同 | |
| 88 | 102 | */ |
| 89 | - private Long channelId; | |
| 103 | + @TableField(typeHandler = JacksonTypeHandler.class) | |
| 104 | + private Map<String, String> payeeInfo; | |
| 90 | 105 | |
| 91 | - /** | |
| 92 | - * 转账渠道编码 | |
| 93 | - */ | |
| 94 | - private String channelCode; | |
| 95 | 106 | } |
| 96 | 107 | \ No newline at end of file | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/transfer/PayTransferExtensionDO.java
| ... | ... | @@ -10,6 +10,7 @@ import lombok.Data; |
| 10 | 10 | |
| 11 | 11 | import java.util.Map; |
| 12 | 12 | |
| 13 | +// TODO @jason:转账是不是类似 refund,不用拓展单呀?支付做拓展单的原因,是因为它存在不确定性,可以切换多种;转账和退款,都是明确方式的; | |
| 13 | 14 | /** |
| 14 | 15 | * 转账拓展单 DO |
| 15 | 16 | * |
| ... | ... | @@ -61,4 +62,5 @@ public class PayTransferExtensionDO extends BaseDO { |
| 61 | 62 | * 支付渠道异步通知的内容 |
| 62 | 63 | */ |
| 63 | 64 | private String channelNotifyData; |
| 65 | + | |
| 64 | 66 | } |
| 65 | 67 | \ No newline at end of file | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/wallet/PayWalletRechargeDO.java
| ... | ... | @@ -42,7 +42,6 @@ public class PayWalletRechargeDO extends BaseDO { |
| 42 | 42 | * 实际支付金额 |
| 43 | 43 | */ |
| 44 | 44 | private Integer payPrice; |
| 45 | - | |
| 46 | 45 | /** |
| 47 | 46 | * 钱包赠送金额 |
| 48 | 47 | */ |
| ... | ... | @@ -50,8 +49,10 @@ public class PayWalletRechargeDO extends BaseDO { |
| 50 | 49 | |
| 51 | 50 | /** |
| 52 | 51 | * 充值套餐编号 |
| 52 | + * | |
| 53 | + * 关联 {@link PayWalletRechargeDO#getPackageId()} 字段 | |
| 53 | 54 | */ |
| 54 | - private Long packageId; | |
| 55 | + private Long packageId; | |
| 55 | 56 | |
| 56 | 57 | /** |
| 57 | 58 | * 是否已支付 | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/wallet/PayWalletRechargePackageDO.java
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/demo/PayDemoTransferMapper.java
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/transfer/PayTransferExtensionMapper.java
| ... | ... | @@ -14,10 +14,11 @@ public interface PayTransferExtensionMapper extends BaseMapperX<PayTransferExten |
| 14 | 14 | return selectOne(PayTransferExtensionDO::getNo, no); |
| 15 | 15 | } |
| 16 | 16 | |
| 17 | - default int updateByIdAndStatus(Long id, List<Integer> status, PayTransferExtensionDO updateObj){ | |
| 17 | + default int updateByIdAndStatus(Long id, List<Integer> whereStatuses, PayTransferExtensionDO updateObj) { | |
| 18 | 18 | return update(updateObj, new LambdaQueryWrapper<PayTransferExtensionDO>() |
| 19 | - .eq(PayTransferExtensionDO::getId, id).in(PayTransferExtensionDO::getStatus, status)); | |
| 19 | + .eq(PayTransferExtensionDO::getId, id).in(PayTransferExtensionDO::getStatus, whereStatuses)); | |
| 20 | 20 | } |
| 21 | + | |
| 21 | 22 | } |
| 22 | 23 | |
| 23 | 24 | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/transfer/PayTransferMapper.java
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/wallet/PayWalletMapper.java
| ... | ... | @@ -70,6 +70,7 @@ public interface PayWalletMapper extends BaseMapperX<PayWalletDO> { |
| 70 | 70 | |
| 71 | 71 | /** |
| 72 | 72 | * 冻结钱包部分余额 |
| 73 | + * | |
| 73 | 74 | * @param id 钱包 id |
| 74 | 75 | * @param price 冻结金额 |
| 75 | 76 | */ |
| ... | ... | @@ -84,6 +85,7 @@ public interface PayWalletMapper extends BaseMapperX<PayWalletDO> { |
| 84 | 85 | |
| 85 | 86 | /** |
| 86 | 87 | * 解冻钱包余额 |
| 88 | + * | |
| 87 | 89 | * @param id 钱包 id |
| 88 | 90 | * @param price 解冻金额 |
| 89 | 91 | */ |
| ... | ... | @@ -98,6 +100,7 @@ public interface PayWalletMapper extends BaseMapperX<PayWalletDO> { |
| 98 | 100 | |
| 99 | 101 | /** |
| 100 | 102 | * 当充值退款时, 更新钱包 |
| 103 | + * | |
| 101 | 104 | * @param id 钱包 id |
| 102 | 105 | * @param price 退款金额 |
| 103 | 106 | */ | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/wallet/PayWalletRechargeMapper.java
| ... | ... | @@ -18,8 +18,4 @@ public interface PayWalletRechargeMapper extends BaseMapperX<PayWalletRechargeDO |
| 18 | 18 | .eq(PayWalletRechargeDO::getId, id).eq(PayWalletRechargeDO::getRefundStatus, whereRefundStatus)); |
| 19 | 19 | } |
| 20 | 20 | |
| 21 | -} | |
| 22 | - | |
| 23 | - | |
| 24 | - | |
| 25 | - | |
| 21 | +} | |
| 26 | 22 | \ No newline at end of file | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/wallet/PayWalletRechargePackageMapper.java
| ... | ... | @@ -12,6 +12,7 @@ import org.apache.ibatis.annotations.Mapper; |
| 12 | 12 | public interface PayWalletRechargePackageMapper extends BaseMapperX<PayWalletRechargePackageDO> { |
| 13 | 13 | |
| 14 | 14 | default PageResult<PayWalletRechargePackageDO> selectPage(WalletRechargePackagePageReqVO reqVO) { |
| 15 | + // TODO @jason:排序按照充值金额 | |
| 15 | 16 | return selectPage(reqVO, new LambdaQueryWrapperX<PayWalletRechargePackageDO>() |
| 16 | 17 | .likeIfPresent(PayWalletRechargePackageDO::getName, reqVO.getName()) |
| 17 | 18 | .eqIfPresent(PayWalletRechargePackageDO::getPayPrice, reqVO.getPayPrice()) |
| ... | ... | @@ -20,8 +21,5 @@ public interface PayWalletRechargePackageMapper extends BaseMapperX<PayWalletRec |
| 20 | 21 | .betweenIfPresent(PayWalletRechargePackageDO::getCreateTime, reqVO.getCreateTime()) |
| 21 | 22 | .orderByDesc(PayWalletRechargePackageDO::getId)); |
| 22 | 23 | } |
| 23 | -} | |
| 24 | - | |
| 25 | - | |
| 26 | - | |
| 27 | 24 | |
| 25 | +} | |
| 28 | 26 | \ No newline at end of file | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/core/WalletPayClient.java
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferServiceImpl.java
| ... | ... | @@ -64,6 +64,7 @@ public class PayDemoTransferServiceImpl implements PayDemoTransferService { |
| 64 | 64 | return demoTransfer.getId(); |
| 65 | 65 | } |
| 66 | 66 | |
| 67 | + // TODO @jason:可以参考 AppBrokerageWithdrawCreateReqVO 搞下字段哈,进行校验 | |
| 67 | 68 | private void validatePayeeInfo(Integer transferType, Map<String, String> payeeInfo) { |
| 68 | 69 | PayTransferTypeEnum transferTypeEnum = ofType(transferType); |
| 69 | 70 | switch (transferTypeEnum) { |
| ... | ... | @@ -83,4 +84,5 @@ public class PayDemoTransferServiceImpl implements PayDemoTransferService { |
| 83 | 84 | } |
| 84 | 85 | } |
| 85 | 86 | } |
| 87 | + | |
| 86 | 88 | } | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferService.java
| ... | ... | @@ -7,6 +7,8 @@ import cn.iocoder.yudao.module.pay.controller.admin.transfer.vo.PayTransferSubmi |
| 7 | 7 | import javax.validation.Valid; |
| 8 | 8 | |
| 9 | 9 | /** |
| 10 | + * 转账 Service 接口 | |
| 11 | + * | |
| 10 | 12 | * @author jason |
| 11 | 13 | */ |
| 12 | 14 | public interface PayTransferService { |
| ... | ... | @@ -29,4 +31,5 @@ public interface PayTransferService { |
| 29 | 31 | * @return 转账单编号 |
| 30 | 32 | */ |
| 31 | 33 | Long createTransfer(@Valid PayTransferCreateReqDTO reqDTO); |
| 34 | + | |
| 32 | 35 | } | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java
| ... | ... | @@ -34,7 +34,10 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU |
| 34 | 34 | import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*; |
| 35 | 35 | import static cn.iocoder.yudao.module.pay.enums.transfer.PayTransferStatusEnum.*; |
| 36 | 36 | |
| 37 | +// TODO @jason:等彻底实现完,单测写写; | |
| 37 | 38 | /** |
| 39 | + * 转账 Service 实现类 | |
| 40 | + * | |
| 38 | 41 | * @author jason |
| 39 | 42 | */ |
| 40 | 43 | @Service |
| ... | ... | @@ -47,10 +50,12 @@ public class PayTransferServiceImpl implements PayTransferService { |
| 47 | 50 | private PayTransferMapper transferMapper; |
| 48 | 51 | @Resource |
| 49 | 52 | private PayTransferExtensionMapper transferExtensionMapper; |
| 53 | + | |
| 50 | 54 | @Resource |
| 51 | 55 | private PayAppService appService; |
| 52 | 56 | @Resource |
| 53 | 57 | private PayChannelService channelService; |
| 58 | + | |
| 54 | 59 | @Resource |
| 55 | 60 | private PayNoRedisDAO noRedisDAO; |
| 56 | 61 | |
| ... | ... | @@ -64,7 +69,7 @@ public class PayTransferServiceImpl implements PayTransferService { |
| 64 | 69 | PayChannelDO channel = validateChannelCanSubmit(transfer.getAppId(), reqVO.getChannelCode()); |
| 65 | 70 | PayClient client = channelService.getPayClient(channel.getId()); |
| 66 | 71 | |
| 67 | - // 2 新增转账拓展单 | |
| 72 | + // 2. 新增转账拓展单 | |
| 68 | 73 | String no = noRedisDAO.generate(TRANSFER_NO_PREFIX); |
| 69 | 74 | PayTransferExtensionDO transferExtension = new PayTransferExtensionDO().setNo(no) |
| 70 | 75 | .setTransferId(transfer.getId()).setChannelId(channel.getId()) |
| ... | ... | @@ -112,8 +117,9 @@ public class PayTransferServiceImpl implements PayTransferService { |
| 112 | 117 | notifyTransferClosed(channel, notify); |
| 113 | 118 | } |
| 114 | 119 | // WAITING 状态无需处理 |
| 115 | - // TODO IN_PROGRESS 待处理 | |
| 120 | + // TODO IN_PROGRESS 待处理 | |
| 116 | 121 | } |
| 122 | + | |
| 117 | 123 | private void notifyTransferSuccess(PayChannelDO channel, PayTransferRespDTO notify) { |
| 118 | 124 | // 1. 更新 PayTransferExtensionDO 转账成功 |
| 119 | 125 | PayTransferExtensionDO transferExtension = updateTransferExtensionSuccess(notify); |
| ... | ... | @@ -121,7 +127,7 @@ public class PayTransferServiceImpl implements PayTransferService { |
| 121 | 127 | // 2. 更新 PayTransferDO 转账成功 |
| 122 | 128 | Boolean transferred = updateTransferSuccess(channel,transferExtension, notify); |
| 123 | 129 | if (transferred) { |
| 124 | - return ; | |
| 130 | + return; | |
| 125 | 131 | } |
| 126 | 132 | // 3. TODO 插入转账通知记录 |
| 127 | 133 | } | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargePackageService.java
| ... | ... | @@ -31,7 +31,7 @@ public interface PayWalletRechargePackageService { |
| 31 | 31 | PayWalletRechargePackageDO validWalletRechargePackage(Long packageId); |
| 32 | 32 | |
| 33 | 33 | /** |
| 34 | - * 创建套餐充值 | |
| 34 | + * 创建充值套餐 | |
| 35 | 35 | * |
| 36 | 36 | * @param createReqVO 创建信息 |
| 37 | 37 | * @return 编号 |
| ... | ... | @@ -39,33 +39,25 @@ public interface PayWalletRechargePackageService { |
| 39 | 39 | Long createWalletRechargePackage(@Valid WalletRechargePackageCreateReqVO createReqVO); |
| 40 | 40 | |
| 41 | 41 | /** |
| 42 | - * 更新套餐充值 | |
| 42 | + * 更新充值套餐 | |
| 43 | 43 | * |
| 44 | 44 | * @param updateReqVO 更新信息 |
| 45 | 45 | */ |
| 46 | 46 | void updateWalletRechargePackage(@Valid WalletRechargePackageUpdateReqVO updateReqVO); |
| 47 | 47 | |
| 48 | - | |
| 49 | 48 | /** |
| 50 | - * 删除套餐充值 | |
| 49 | + * 删除充值套餐 | |
| 51 | 50 | * |
| 52 | 51 | * @param id 编号 |
| 53 | 52 | */ |
| 54 | 53 | void deleteWalletRechargePackage(Long id); |
| 55 | 54 | |
| 56 | 55 | /** |
| 57 | - * 获得套餐充值列表 | |
| 58 | - * | |
| 59 | - * @param ids 编号 | |
| 60 | - * @return 套餐充值列表 | |
| 61 | - */ | |
| 62 | - List<PayWalletRechargePackageDO> getWalletRechargePackageList(Collection<Long> ids); | |
| 63 | - | |
| 64 | - /** | |
| 65 | - * 获得套餐充值分页 | |
| 56 | + * 获得充值套餐分页 | |
| 66 | 57 | * |
| 67 | 58 | * @param pageReqVO 分页查询 |
| 68 | - * @return 套餐充值分页 | |
| 59 | + * @return 充值套餐分页 | |
| 69 | 60 | */ |
| 70 | 61 | PageResult<PayWalletRechargePackageDO> getWalletRechargePackagePage(WalletRechargePackagePageReqVO pageReqVO); |
| 62 | + | |
| 71 | 63 | } | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargePackageServiceImpl.java
| ... | ... | @@ -57,6 +57,7 @@ public class PayWalletRechargePackageServiceImpl implements PayWalletRechargePac |
| 57 | 57 | return walletRechargePackage.getId(); |
| 58 | 58 | } |
| 59 | 59 | |
| 60 | + // TODO @jason:校验下,套餐名唯一 | |
| 60 | 61 | @Override |
| 61 | 62 | public void updateWalletRechargePackage(WalletRechargePackageUpdateReqVO updateReqVO) { |
| 62 | 63 | // 校验存在 |
| ... | ... | @@ -81,14 +82,6 @@ public class PayWalletRechargePackageServiceImpl implements PayWalletRechargePac |
| 81 | 82 | } |
| 82 | 83 | |
| 83 | 84 | @Override |
| 84 | - public List<PayWalletRechargePackageDO> getWalletRechargePackageList(Collection<Long> ids) { | |
| 85 | - if (CollUtil.isEmpty(ids)) { | |
| 86 | - return ListUtil.empty(); | |
| 87 | - } | |
| 88 | - return walletRechargePackageMapper.selectBatchIds(ids); | |
| 89 | - } | |
| 90 | - | |
| 91 | - @Override | |
| 92 | 85 | public PageResult<PayWalletRechargePackageDO> getWalletRechargePackagePage(WalletRechargePackagePageReqVO pageReqVO) { |
| 93 | 86 | return walletRechargePackageMapper.selectPage(pageReqVO); |
| 94 | 87 | } | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeServiceImpl.java
| ... | ... | @@ -44,7 +44,7 @@ import static cn.iocoder.yudao.module.pay.enums.refund.PayRefundStatusEnum.*; |
| 44 | 44 | public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { |
| 45 | 45 | |
| 46 | 46 | /** |
| 47 | - * TODO 放到 配置文件中 | |
| 47 | + * TODO 芋艿:放到 payconfig | |
| 48 | 48 | */ |
| 49 | 49 | private static final Long WALLET_PAY_APP_ID = 8L; |
| 50 | 50 | |
| ... | ... | @@ -65,13 +65,14 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { |
| 65 | 65 | @Transactional(rollbackFor = Exception.class) |
| 66 | 66 | public PayWalletRechargeDO createWalletRecharge(Long userId, Integer userType, |
| 67 | 67 | AppPayWalletRechargeCreateReqVO reqVO) { |
| 68 | - // 1.1 校验参数 | |
| 68 | + // 1.1 校验参数 TODO @jason:AppPayWalletRechargeCreateReqVO 看下校验; | |
| 69 | 69 | if (Objects.isNull(reqVO.getPayPrice()) && Objects.isNull(reqVO.getPackageId())) { |
| 70 | 70 | throw exception(WALLET_RECHARGE_PACKAGE_AND_PRICE_IS_EMPTY); |
| 71 | 71 | } |
| 72 | - // 1.2 新增钱包充值记录 | |
| 73 | - int payPrice ; | |
| 74 | - int bonusPrice = 0 ; | |
| 72 | + | |
| 73 | + // 1.1 计算充值金额 | |
| 74 | + int payPrice; | |
| 75 | + int bonusPrice = 0; | |
| 75 | 76 | if (Objects.nonNull(reqVO.getPackageId())) { |
| 76 | 77 | PayWalletRechargePackageDO rechargePackage = payWalletRechargePackageService.validWalletRechargePackage(reqVO.getPackageId()); |
| 77 | 78 | payPrice = rechargePackage.getPayPrice(); |
| ... | ... | @@ -79,23 +80,22 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { |
| 79 | 80 | } else { |
| 80 | 81 | payPrice = reqVO.getPayPrice(); |
| 81 | 82 | } |
| 82 | - | |
| 83 | + // 1.2 插入充值记录 | |
| 83 | 84 | PayWalletDO wallet = payWalletService.getOrCreateWallet(userId, userType); |
| 84 | - PayWalletRechargeDO walletRecharge = INSTANCE.convert(wallet.getId(), payPrice, bonusPrice, reqVO.getPackageId()); | |
| 85 | - walletRechargeMapper.insert(walletRecharge); | |
| 85 | + PayWalletRechargeDO recharge = INSTANCE.convert(wallet.getId(), payPrice, bonusPrice, reqVO.getPackageId()); | |
| 86 | + walletRechargeMapper.insert(recharge); | |
| 86 | 87 | |
| 87 | 88 | // 2.1 创建支付单 |
| 88 | 89 | Long payOrderId = payOrderService.createOrder(new PayOrderCreateReqDTO() |
| 89 | - .setAppId(WALLET_PAY_APP_ID).setUserIp(getClientIP()) | |
| 90 | - .setMerchantOrderId(walletRecharge.getId().toString()) // 业务的订单编号 | |
| 91 | - .setSubject(WALLET_RECHARGE_ORDER_SUBJECT).setBody("").setPrice(walletRecharge.getPayPrice()) | |
| 92 | - .setExpireTime(addTime(Duration.ofHours(2L)))); | |
| 90 | + .setAppId(WALLET_PAY_APP_ID).setUserIp(getClientIP()) // TODO @jason:clientIp 从 controller 传递进来噢 | |
| 91 | + .setMerchantOrderId(recharge.getId().toString()) // 业务的订单编号 | |
| 92 | + .setSubject(WALLET_RECHARGE_ORDER_SUBJECT).setBody("") | |
| 93 | + .setPrice(recharge.getPayPrice()) | |
| 94 | + .setExpireTime(addTime(Duration.ofHours(2L)))); // TODO @芋艿:支付超时时间 | |
| 93 | 95 | // 2.2 更新钱包充值记录中支付订单 |
| 94 | - walletRechargeMapper.updateById(new PayWalletRechargeDO().setPayOrderId(payOrderId) | |
| 95 | - .setId(walletRecharge.getId())); | |
| 96 | - | |
| 97 | - walletRecharge.setPayOrderId(payOrderId); | |
| 98 | - return walletRecharge; | |
| 96 | + walletRechargeMapper.updateById(new PayWalletRechargeDO().setId(recharge.getId()).setPayOrderId(payOrderId)); | |
| 97 | + recharge.setPayOrderId(payOrderId); | |
| 98 | + return recharge; | |
| 99 | 99 | } |
| 100 | 100 | |
| 101 | 101 | @Override |
| ... | ... | @@ -136,9 +136,11 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { |
| 136 | 136 | } |
| 137 | 137 | // 1.2 校验钱包充值是否可以发起退款 |
| 138 | 138 | PayWalletDO wallet = validateWalletRechargeCanRefund(walletRecharge); |
| 139 | - // 2 冻结退款的余额, 暂时只处理赠送的余额也全部退回 | |
| 139 | + | |
| 140 | + // 2. 冻结退款的余额,暂时只处理赠送的余额也全部退回 | |
| 140 | 141 | payWalletService.freezePrice(wallet.getId(), walletRecharge.getTotalPrice()); |
| 141 | - // 3 创建退款单 | |
| 142 | + | |
| 143 | + // 3. 创建退款单 | |
| 142 | 144 | String walletRechargeId = String.valueOf(id); |
| 143 | 145 | String refundId = walletRechargeId + "-refund"; |
| 144 | 146 | Long payRefundId = payRefundService.createPayRefund(new PayRefundCreateReqDTO() |
| ... | ... | @@ -146,7 +148,9 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { |
| 146 | 148 | .setMerchantOrderId(walletRechargeId) |
| 147 | 149 | .setMerchantRefundId(refundId) |
| 148 | 150 | .setReason("想退钱").setPrice(walletRecharge.getPayPrice())); |
| 149 | - // 4 更新充值记录退款单号 | |
| 151 | + | |
| 152 | + // 4. 更新充值记录退款单号 | |
| 153 | + // TODO @jaosn:一般新建这种 update 对象,建议是,第一个 set id 属性,容易知道以它为更新 | |
| 150 | 154 | walletRechargeMapper.updateById(new PayWalletRechargeDO().setPayRefundId(payRefundId) |
| 151 | 155 | .setRefundStatus(WAITING.getStatus()).setId(walletRecharge.getId())); |
| 152 | 156 | } |
| ... | ... | @@ -229,6 +233,7 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { |
| 229 | 233 | if (wallet.getBalance() < walletRecharge.getTotalPrice()) { |
| 230 | 234 | throw exception(WALLET_RECHARGE_REFUND_BALANCE_NOT_ENOUGH); |
| 231 | 235 | } |
| 236 | + // TODO @芋艿:需要考虑下,赠送的金额,会不会导致提现超过; | |
| 232 | 237 | return wallet; |
| 233 | 238 | } |
| 234 | 239 | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletService.java
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletServiceImpl.java
| ... | ... | @@ -109,6 +109,7 @@ public class PayWalletServiceImpl implements PayWalletService { |
| 109 | 109 | if (walletTransaction == null) { |
| 110 | 110 | throw exception(WALLET_TRANSACTION_NOT_FOUND); |
| 111 | 111 | } |
| 112 | + // 2. 校验退款是否存在 | |
| 112 | 113 | PayWalletTransactionDO refundTransaction = walletTransactionService.getWalletTransaction( |
| 113 | 114 | String.valueOf(refundId), PAYMENT_REFUND); |
| 114 | 115 | if (refundTransaction != null) { |
| ... | ... | @@ -128,7 +129,7 @@ public class PayWalletServiceImpl implements PayWalletService { |
| 128 | 129 | } |
| 129 | 130 | |
| 130 | 131 | // 2.1 扣除余额 |
| 131 | - int updateCounts = 0 ; | |
| 132 | + int updateCounts; | |
| 132 | 133 | switch (bizType) { |
| 133 | 134 | case PAYMENT: { |
| 134 | 135 | updateCounts = walletMapper.updateWhenConsumption(payWallet.getId(), price); | ... | ... |