mirror of
				https://github.com/YunaiV/ruoyi-vue-pro.git
				synced 2025-10-31 02:28:03 +08:00 
			
		
		
		
	钱包 review DO 类修改
This commit is contained in:
		| @ -1,5 +1,5 @@ | ||||
| -- ---------------------------- | ||||
| -- 支付-钱包表 | ||||
| -- 会员钱包表 | ||||
| -- ---------------------------- | ||||
| DROP TABLE IF EXISTS `pay_wallet`; | ||||
| CREATE TABLE `pay_wallet` | ||||
| @ -17,28 +17,27 @@ CREATE TABLE `pay_wallet` | ||||
|     `deleted`        bit(1)   NOT NULL DEFAULT b'0' COMMENT '是否删除', | ||||
|     `tenant_id`      bigint   NOT NULL DEFAULT 0 COMMENT '租户编号', | ||||
|     PRIMARY KEY (`id`) USING BTREE | ||||
| ) ENGINE=InnoDB COMMENT='支付钱包表'; | ||||
| ) ENGINE=InnoDB COMMENT='会员钱包表'; | ||||
|  | ||||
| -- ---------------------------- | ||||
| -- 支付- 钱包余额明细表 | ||||
| -- 会员钱包流水表 | ||||
| -- ---------------------------- | ||||
| DROP TABLE IF EXISTS `pay_wallet_transaction`; | ||||
| CREATE TABLE `pay_wallet_transaction` | ||||
| ( | ||||
|     `id`               bigint      NOT NULL AUTO_INCREMENT COMMENT '编号', | ||||
|     `wallet_id`        bigint      NOT NULL COMMENT '会员钱包 id', | ||||
|     `biz_type`         tinyint     NOT NULL COMMENT '关联类型', | ||||
|     `biz_id`           bigint      NOT NULL COMMENT '关联业务编号', | ||||
|     `no`               varchar(64) NOT NULL COMMENT '流水号', | ||||
|     `description`      varchar(255)         COMMENT '操作说明', | ||||
|     `amount`           int         NOT NULL COMMENT '交易金额, 单位分', | ||||
|     `balance`          int         NOT NULL COMMENT '余额, 单位分', | ||||
|     `transaction_time` datetime    NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '交易时间', | ||||
|     `creator`          varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', | ||||
|     `create_time`      datetime    NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', | ||||
|     `updater`          varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', | ||||
|     `update_time`      datetime    NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', | ||||
|     `deleted`          bit(1)      NOT NULL DEFAULT b'0' COMMENT '是否删除', | ||||
|     `tenant_id`        bigint      NOT NULL DEFAULT 0 COMMENT '租户编号', | ||||
|     `id`               bigint       NOT NULL AUTO_INCREMENT COMMENT '编号', | ||||
|     `wallet_id`        bigint       NOT NULL COMMENT '会员钱包 id', | ||||
|     `biz_type`         tinyint      NOT NULL COMMENT '关联类型', | ||||
|     `biz_id`           varchar(64)  NOT NULL COMMENT '关联业务编号', | ||||
|     `no`               varchar(64)  NOT NULL COMMENT '流水号', | ||||
|     `title`            varchar(128) NOT NULL COMMENT '流水标题', | ||||
|     `price`            int          NOT NULL COMMENT '交易金额, 单位分', | ||||
|     `balance`          int          NOT NULL COMMENT '余额, 单位分', | ||||
|     `creator`          varchar(64)  CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', | ||||
|     `create_time`      datetime     NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', | ||||
|     `updater`          varchar(64)  CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', | ||||
|     `update_time`      datetime     NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', | ||||
|     `deleted`          bit(1)       NOT NULL DEFAULT b'0' COMMENT '是否删除', | ||||
|     `tenant_id`        bigint       NOT NULL DEFAULT 0 COMMENT '租户编号', | ||||
|     PRIMARY KEY (`id`) USING BTREE | ||||
| ) ENGINE=InnoDB COMMENT='支付钱包余额明细表'; | ||||
| ) ENGINE=InnoDB COMMENT='会员钱包流水表'; | ||||
|  | ||||
| @ -37,7 +37,7 @@ public class AppPayWalletController { | ||||
|     @Operation(summary = "获取钱包") | ||||
|     @PreAuthenticated | ||||
|     public CommonResult<AppPayWalletRespVO> getPayWallet() { | ||||
|         PayWalletDO wallet = payWalletService.getPayWallet(getLoginUserId(), UserTypeEnum.MEMBER.getValue()); | ||||
|         PayWalletDO wallet = payWalletService.getOrCreatePayWallet(getLoginUserId(), UserTypeEnum.MEMBER.getValue()); | ||||
|         return success(PayWalletConvert.INSTANCE.convert(wallet)); | ||||
|     } | ||||
|  | ||||
|  | ||||
| @ -15,9 +15,6 @@ public class AppPayWalletTransactionRespVO { | ||||
|     @Schema(description = "业务分类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | ||||
|     private Integer bizType; | ||||
|  | ||||
|     @Schema(description = "交易时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") | ||||
|     private LocalDateTime transactionTime; | ||||
|  | ||||
|     @Schema(description = "交易金额,单位分", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") | ||||
|     private Long price; | ||||
|  | ||||
|  | ||||
| @ -7,8 +7,6 @@ import com.baomidou.mybatisplus.annotation.TableId; | ||||
| import com.baomidou.mybatisplus.annotation.TableName; | ||||
| import lombok.Data; | ||||
|  | ||||
| import java.time.LocalDateTime; | ||||
|  | ||||
| /** | ||||
|  * 会员钱包流水 DO | ||||
|  * | ||||
| @ -24,6 +22,7 @@ public class PayWalletTransactionDO extends BaseDO { | ||||
|      */ | ||||
|     @TableId | ||||
|     private Long id; | ||||
|  | ||||
|     /** | ||||
|      * 流水号 | ||||
|      */ | ||||
| @ -42,34 +41,26 @@ public class PayWalletTransactionDO extends BaseDO { | ||||
|      * 枚举 {@link PayWalletBizTypeEnum#getType()} | ||||
|      */ | ||||
|     private Integer bizType; | ||||
|     // TODO @jason:使用 string;因为可能有业务是 string 接入哈。 | ||||
|  | ||||
|     /** | ||||
|      * 关联业务编号 | ||||
|      */ | ||||
|     private Long bizId; | ||||
|     private String bizId; | ||||
|  | ||||
|     // TODO @jason:想了下,改成 title;流水标题;因为账户明细那,会看到这个; | ||||
|     /** | ||||
|      * 附加说明 | ||||
|      * 流水说明 | ||||
|      */ | ||||
|     private String description; | ||||
|     private String title; | ||||
|  | ||||
|     // TODO @jason:使用 price 哈。项目里,金额都是用这个为主; | ||||
|     /** | ||||
|      * 交易金额,单位分 | ||||
|      * | ||||
|      * 正值表示余额增加,负值表示余额减少 | ||||
|      */ | ||||
|     private Integer amount; | ||||
|     private Integer price; | ||||
|  | ||||
|     /** | ||||
|      * 交易后余额,单位分 | ||||
|      */ | ||||
|     private Integer balance; | ||||
|  | ||||
|     // TODO @jason:使用 createTime 就够啦 | ||||
|     /** | ||||
|      * 交易时间 | ||||
|      */ | ||||
|     private LocalDateTime transactionTime; | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -18,9 +18,9 @@ public interface PayWalletTransactionMapper extends BaseMapperX<PayWalletTransac | ||||
|         LambdaQueryWrapperX<PayWalletTransactionDO> query = new LambdaQueryWrapperX<PayWalletTransactionDO>() | ||||
|                 .eq(PayWalletTransactionDO::getWalletId, walletId); | ||||
|         if (Objects.equals(pageReqVO.getType(), AppPayWalletTransactionPageReqVO.TYPE_INCOME)) { | ||||
|             query.gt(PayWalletTransactionDO::getAmount, 0); | ||||
|             query.gt(PayWalletTransactionDO::getPrice, 0); | ||||
|         } else if (Objects.equals(pageReqVO.getType(), AppPayWalletTransactionPageReqVO.TYPE_EXPENSE)) { | ||||
|             query.lt(PayWalletTransactionDO::getAmount, 0); | ||||
|             query.lt(PayWalletTransactionDO::getPrice, 0); | ||||
|         } | ||||
|         query.orderByDesc(PayWalletTransactionDO::getId); | ||||
|         return selectPage(pageReqVO, query); | ||||
|  | ||||
| @ -50,7 +50,7 @@ public class WalletPayClient extends AbstractPayClient<NonePayClientConfig> { | ||||
|             PayWalletTransactionDO transaction = wallService.pay(Long.valueOf(userId), Integer.valueOf(userType), | ||||
|                     reqDTO.getOutTradeNo(), reqDTO.getPrice()); | ||||
|             return PayOrderRespDTO.successOf(transaction.getNo(), transaction.getCreator(), | ||||
|                     transaction.getTransactionTime(), | ||||
|                     transaction.getCreateTime(), | ||||
|                     reqDTO.getOutTradeNo(), transaction); | ||||
|         } catch (Throwable ex) { | ||||
|             log.error("[doUnifiedOrder] 失败", ex); | ||||
| @ -81,7 +81,7 @@ public class WalletPayClient extends AbstractPayClient<NonePayClientConfig> { | ||||
|         try { | ||||
|             PayWalletTransactionDO payWalletTransaction = wallService.refund(reqDTO.getOutRefundNo(), | ||||
|                     reqDTO.getRefundPrice(), reqDTO.getReason()); | ||||
|             return PayRefundRespDTO.successOf(payWalletTransaction.getNo(), payWalletTransaction.getTransactionTime(), | ||||
|             return PayRefundRespDTO.successOf(payWalletTransaction.getNo(), payWalletTransaction.getCreateTime(), | ||||
|                     reqDTO.getOutRefundNo(), payWalletTransaction); | ||||
|         } catch (Throwable ex) { | ||||
|             log.error("[doUnifiedRefund] 失败", ex); | ||||
|  | ||||
| @ -11,18 +11,19 @@ import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum; | ||||
|  */ | ||||
| public interface PayWalletService { | ||||
|  | ||||
|     // TODO @jason:改成 getOrCreateWallet;因为目前解耦,用户注册时,不会创建钱包;需要这里兜底处理; | ||||
|     /** | ||||
|      * 获取钱包信息 | ||||
|      * 获取钱包信息,如果不存在创建钱包。由于用户注册时候不会创建钱包 | ||||
|      * | ||||
|      * @param userId 用户编号 | ||||
|      * @param userType 用户类型 | ||||
|      */ | ||||
|     PayWalletDO getPayWallet(Long userId, Integer userType); | ||||
|     PayWalletDO getOrCreatePayWallet(Long userId, Integer userType); | ||||
|  | ||||
|     /** | ||||
|      * 钱包订单支付 | ||||
|      * | ||||
|      * @param userId  用户 id | ||||
|      * @param userType 用户类型 | ||||
|      * @param outTradeNo 外部订单号 | ||||
|      * @param price 金额 | ||||
|      */ | ||||
|  | ||||
| @ -57,8 +57,19 @@ public class PayWalletServiceImpl implements  PayWalletService { | ||||
|     private PayRefundService payRefundService; | ||||
|  | ||||
|     @Override | ||||
|     public PayWalletDO getPayWallet(Long userId, Integer userType) { | ||||
|         return payWalletMapper.selectByUserIdAndType(userId, userType); | ||||
|     public PayWalletDO getOrCreatePayWallet(Long userId, Integer userType) { | ||||
|         PayWalletDO payWalletDO = payWalletMapper.selectByUserIdAndType(userId, userType); | ||||
|         if (payWalletDO == null) { | ||||
|             payWalletDO = new PayWalletDO(); | ||||
|             payWalletDO.setUserId(userId); | ||||
|             payWalletDO.setUserType(userType); | ||||
|             payWalletDO.setBalance(0); | ||||
|             payWalletDO.setTotalExpense(0L); | ||||
|             payWalletDO.setTotalRecharge(0L); | ||||
|             payWalletDO.setCreateTime(LocalDateTime.now()); | ||||
|             payWalletMapper.insert(payWalletDO); | ||||
|         } | ||||
|         return payWalletDO; | ||||
|     } | ||||
|  | ||||
|  | ||||
| @ -76,8 +87,8 @@ public class PayWalletServiceImpl implements  PayWalletService { | ||||
|     @Override | ||||
|     public PayWalletTransactionDO reduceWalletBalance(Long userId, Integer userType, | ||||
|                                                       Long bizId, PayWalletBizTypeEnum bizType, Integer price) { | ||||
|         // 1.1 判断钱包是否有效 | ||||
|         PayWalletDO payWallet = validatePayWallet(userId, userType); | ||||
|         // 1.1 获取钱包 | ||||
|         PayWalletDO payWallet = getOrCreatePayWallet(userId, userType); | ||||
|         // 1.2 判断余额是否足够 | ||||
|         int afterBalance = payWallet.getBalance() - price; | ||||
|         if (afterBalance < 0) { | ||||
| @ -90,12 +101,11 @@ public class PayWalletServiceImpl implements  PayWalletService { | ||||
|         if (number == 0) { | ||||
|             throw exception(TOO_MANY_REQUESTS); | ||||
|         } | ||||
|  | ||||
|         // 2.2 生成钱包流水 TODO 根据 bizType 生成 NO | ||||
|         String walletNo = noRedisDAO.generate(WALLET_PAY_NO_PREFIX); | ||||
|         // 2.2 生成钱包流水 | ||||
|         String walletNo = generateWalletNo(bizType); | ||||
|         PayWalletTransactionDO walletTransaction = new PayWalletTransactionDO().setWalletId(payWallet.getId()) | ||||
|                 .setNo(walletNo).setAmount(-price).setBalance(afterBalance).setTransactionTime(LocalDateTime.now()) | ||||
|                 .setBizId(bizId).setBizType(bizType.getType()).setDescription(bizType.getDescription()); | ||||
|                 .setNo(walletNo).setPrice(-price).setBalance(afterBalance) | ||||
|                 .setBizId(String.valueOf(bizId)).setBizType(bizType.getType()).setTitle(bizType.getDescription()); | ||||
|         payWalletTransactionService.createWalletTransaction(walletTransaction); | ||||
|         return walletTransaction; | ||||
|     } | ||||
| @ -103,8 +113,8 @@ public class PayWalletServiceImpl implements  PayWalletService { | ||||
|     @Override | ||||
|     public PayWalletTransactionDO addWalletBalance(Long userId, Integer userType, Long bizId, | ||||
|                                                    PayWalletBizTypeEnum bizType, Integer price) { | ||||
|         // 1.1 判断钱包是否有效 | ||||
|         PayWalletDO payWallet = validatePayWallet(userId, userType); | ||||
|         // 1.1 获取钱包 | ||||
|         PayWalletDO payWallet = getOrCreatePayWallet(userId, userType); | ||||
|  | ||||
|         // 2.1 增加余额 | ||||
|         int number = payWalletMapper.updateWhenIncBalance(bizType, payWallet.getBalance(), payWallet.getTotalRecharge(), | ||||
| @ -113,27 +123,31 @@ public class PayWalletServiceImpl implements  PayWalletService { | ||||
|             throw exception(TOO_MANY_REQUESTS); | ||||
|         } | ||||
|  | ||||
|         // 2.2 生成钱包流水 TODO 根据 bizType 生成 NO | ||||
|         String walletNo = noRedisDAO.generate(WALLET_REFUND_NO_PREFIX); | ||||
|         // 2.2 生成钱包流水 | ||||
|         String walletNo = generateWalletNo(bizType); | ||||
|         PayWalletTransactionDO newWalletTransaction = new PayWalletTransactionDO().setWalletId(payWallet.getId()) | ||||
|                 .setNo(walletNo).setAmount(price).setBalance(payWallet.getBalance()+price).setTransactionTime(LocalDateTime.now()) | ||||
|                 .setBizId(bizId).setBizType(bizType.getType()) | ||||
|                 .setDescription(bizType.getDescription()); | ||||
|                 .setNo(walletNo).setPrice(price).setBalance(payWallet.getBalance()+price) | ||||
|                 .setBizId(String.valueOf(bizId)).setBizType(bizType.getType()) | ||||
|                 .setTitle(bizType.getDescription()); | ||||
|         payWalletTransactionService.createWalletTransaction(newWalletTransaction); | ||||
|         return newWalletTransaction; | ||||
|     } | ||||
|  | ||||
|  | ||||
|     private PayWalletDO validatePayWallet(Long userId, Integer userType) { | ||||
|         PayWalletDO payWallet = getPayWallet(userId, userType); | ||||
|         if (payWallet == null) { | ||||
|             log.error("[validatePayWallet] 用户 {} 钱包不存在", userId); | ||||
|             throw exception(WALLET_NOT_FOUND); | ||||
|     private String generateWalletNo(PayWalletBizTypeEnum bizType) { | ||||
|         String no = ""; | ||||
|         switch(bizType){ | ||||
|             case PAYMENT : | ||||
|                 no = noRedisDAO.generate(WALLET_PAY_NO_PREFIX); | ||||
|                 break; | ||||
|             case PAYMENT_REFUND : | ||||
|                 no = noRedisDAO.generate(WALLET_REFUND_NO_PREFIX); | ||||
|                 break; | ||||
|             default : | ||||
|                 // TODO 待增加 | ||||
|         } | ||||
|         return payWallet; | ||||
|         return no; | ||||
|     } | ||||
|  | ||||
|  | ||||
|     @Override | ||||
|     @Transactional(rollbackFor = Exception.class) | ||||
|     public PayWalletTransactionDO refund(String outRefundNo, Integer refundPrice, String reason) { | ||||
| @ -163,7 +177,7 @@ public class PayWalletServiceImpl implements  PayWalletService { | ||||
|             throw exception(WALLET_TRANSACTION_NOT_FOUND); | ||||
|         } | ||||
|         // 原来的支付金额 | ||||
|         int amount = - payWalletTransaction.getAmount(); | ||||
|         int amount = - payWalletTransaction.getPrice(); | ||||
|         if (refundPrice != amount) { | ||||
|             throw exception(WALLET_REFUND_AMOUNT_ERROR); | ||||
|         } | ||||
|  | ||||
| @ -11,9 +11,6 @@ import org.springframework.stereotype.Service; | ||||
|  | ||||
| import javax.annotation.Resource; | ||||
|  | ||||
| import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | ||||
| import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.WALLET_NOT_FOUND; | ||||
|  | ||||
| /** | ||||
|  * 钱包流水 Service 实现类 | ||||
|  * | ||||
| @ -32,11 +29,7 @@ public class PayWalletTransactionServiceImpl implements PayWalletTransactionServ | ||||
|     @Override | ||||
|     public PageResult<PayWalletTransactionDO> getWalletTransactionPage(Long userId, Integer userType, | ||||
|                                                                        AppPayWalletTransactionPageReqVO pageVO) { | ||||
|         PayWalletDO wallet = payWalletService.getPayWallet(userId, userType); | ||||
|         if (wallet == null) { | ||||
|             log.error("[getWalletTransactionPage][用户({}/{}) 钱包不存在", userId, userType); | ||||
|             throw exception(WALLET_NOT_FOUND); | ||||
|         } | ||||
|         PayWalletDO wallet = payWalletService.getOrCreatePayWallet(userId, userType); | ||||
|         return payWalletTransactionMapper.selectPage(wallet.getId(), pageVO); | ||||
|     } | ||||
|  | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 jason
					jason