diff --git a/sql/mysql/pay_wallet.sql b/sql/mysql/pay_wallet.sql index 1fda83769..bc2ad183e 100644 --- a/sql/mysql/pay_wallet.sql +++ b/sql/mysql/pay_wallet.sql @@ -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='会员钱包流水表'; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/AppPayWalletController.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/AppPayWalletController.java index 23515ed33..2c5f2d5f4 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/AppPayWalletController.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/AppPayWalletController.java @@ -37,7 +37,7 @@ public class AppPayWalletController { @Operation(summary = "获取钱包") @PreAuthenticated public CommonResult getPayWallet() { - PayWalletDO wallet = payWalletService.getPayWallet(getLoginUserId(), UserTypeEnum.MEMBER.getValue()); + PayWalletDO wallet = payWalletService.getOrCreatePayWallet(getLoginUserId(), UserTypeEnum.MEMBER.getValue()); return success(PayWalletConvert.INSTANCE.convert(wallet)); } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/transaction/AppPayWalletTransactionRespVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/transaction/AppPayWalletTransactionRespVO.java index b89628bc2..9d17c346e 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/transaction/AppPayWalletTransactionRespVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/transaction/AppPayWalletTransactionRespVO.java @@ -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; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/wallet/PayWalletTransactionDO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/wallet/PayWalletTransactionDO.java index 677febb25..04a869f32 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/wallet/PayWalletTransactionDO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/wallet/PayWalletTransactionDO.java @@ -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; - } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/wallet/PayWalletTransactionMapper.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/wallet/PayWalletTransactionMapper.java index 9e08b2caa..3d329d118 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/wallet/PayWalletTransactionMapper.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/wallet/PayWalletTransactionMapper.java @@ -18,9 +18,9 @@ public interface PayWalletTransactionMapper extends BaseMapperX query = new LambdaQueryWrapperX() .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); diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/wallet/WalletPayClient.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/wallet/WalletPayClient.java index 68985965f..170fd6694 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/wallet/WalletPayClient.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/wallet/WalletPayClient.java @@ -50,7 +50,7 @@ public class WalletPayClient extends AbstractPayClient { 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 { 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); diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletService.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletService.java index 13cddaeeb..370b776a7 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletService.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletService.java @@ -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 金额 */ diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletServiceImpl.java index 5ea1b4945..a3606323b 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletServiceImpl.java @@ -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); } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionServiceImpl.java index e2338219d..1b156576a 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionServiceImpl.java @@ -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 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); }