From cc4c924717b862a85765f918a8205cdcfcc80f41 Mon Sep 17 00:00:00 2001
From: jason <2667446@qq.com>
Date: Mon, 4 Sep 2023 14:54:38 +0800
Subject: [PATCH] =?UTF-8?q?=E9=92=B1=E5=8C=85=20review=20DO=20=E7=B1=BB?=
 =?UTF-8?q?=E4=BF=AE=E6=94=B9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 sql/mysql/pay_wallet.sql                      | 37 ++++++-----
 .../app/wallet/AppPayWalletController.java    |  2 +-
 .../AppPayWalletTransactionRespVO.java        |  3 -
 .../wallet/PayWalletTransactionDO.java        | 23 ++-----
 .../wallet/PayWalletTransactionMapper.java    |  4 +-
 .../framework/pay/wallet/WalletPayClient.java |  4 +-
 .../pay/service/wallet/PayWalletService.java  |  7 +-
 .../service/wallet/PayWalletServiceImpl.java  | 64 +++++++++++--------
 .../PayWalletTransactionServiceImpl.java      |  9 +--
 9 files changed, 74 insertions(+), 79 deletions(-)

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<AppPayWalletRespVO> 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<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);
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<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);
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<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);
     }