Commit 5858f57fe91ed97693ed10a4bec399aa263bf757

Authored by jason
1 parent 557b09a1

钱包 review 修改

sql/mysql/pay_wallet.sql
... ... @@ -8,8 +8,8 @@ CREATE TABLE `pay_wallet`
8 8 `user_id` bigint NOT NULL COMMENT '用户编号',
9 9 `user_type` tinyint NOT NULL DEFAULT 0 COMMENT '用户类型',
10 10 `balance` int NOT NULL DEFAULT 0 COMMENT '余额,单位分',
11   - `total_expense` bigint NOT NULL DEFAULT 0 COMMENT '累计支出,单位分',
12   - `total_recharge` bigint NOT NULL DEFAULT 0 COMMENT '累计充值,单位分',
  11 + `total_expense` int NOT NULL DEFAULT 0 COMMENT '累计支出,单位分',
  12 + `total_recharge` int NOT NULL DEFAULT 0 COMMENT '累计充值,单位分',
13 13 `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者',
14 14 `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
15 15 `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者',
... ...
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/wallet/AppPayWalletRespVO.java
... ... @@ -11,9 +11,9 @@ public class AppPayWalletRespVO {
11 11 private Integer balance;
12 12  
13 13 @Schema(description = "累计支出, 单位分", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000")
14   - private Long totalExpense;
  14 + private Integer totalExpense;
15 15  
16 16 @Schema(description = "累计充值, 单位分", requiredMode = Schema.RequiredMode.REQUIRED, example = "2000")
17   - private Long totalRecharge;
  17 + private Integer totalRecharge;
18 18  
19 19 }
... ...
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/wallet/PayWalletTransactionConvert.java
... ... @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.pay.convert.wallet;
3 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 4 import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.transaction.AppPayWalletTransactionRespVO;
5 5 import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO;
  6 +import cn.iocoder.yudao.module.pay.service.wallet.bo.CreateWalletTransactionBO;
6 7 import org.mapstruct.Mapper;
7 8 import org.mapstruct.factory.Mappers;
8 9  
... ... @@ -12,4 +13,6 @@ public interface PayWalletTransactionConvert {
12 13 PayWalletTransactionConvert INSTANCE = Mappers.getMapper(PayWalletTransactionConvert.class);
13 14  
14 15 PageResult<AppPayWalletTransactionRespVO> convertPage(PageResult<PayWalletTransactionDO> page);
  16 +
  17 + PayWalletTransactionDO convert(CreateWalletTransactionBO bo);
15 18 }
... ...
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/wallet/PayWalletDO.java
... ... @@ -37,8 +37,6 @@ public class PayWalletDO extends BaseDO {
37 37 */
38 38 private Integer userType;
39 39  
40   - // TODO @jason:三个都搞 integer?应该要统一哈
41   -
42 40 /**
43 41 * 余额,单位分
44 42 */
... ... @@ -47,10 +45,10 @@ public class PayWalletDO extends BaseDO {
47 45 /**
48 46 * 累计支出,单位分
49 47 */
50   - private Long totalExpense;
  48 + private Integer totalExpense;
51 49 /**
52 50 * 累计充值,单位分
53 51 */
54   - private Long totalRecharge;
  52 + private Integer totalRecharge;
55 53  
56 54 }
... ...
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/wallet/PayWalletMapper.java
... ... @@ -3,8 +3,7 @@ package cn.iocoder.yudao.module.pay.dal.mysql.wallet;
3 3  
4 4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5 5 import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO;
6   -import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum;
7   -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  6 +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
8 7 import org.apache.ibatis.annotations.Mapper;
9 8  
10 9 @Mapper
... ... @@ -15,56 +14,31 @@ public interface PayWalletMapper extends BaseMapperX&lt;PayWalletDO&gt; {
15 14 PayWalletDO::getUserType, userType);
16 15 }
17 16  
18   - // TODO @jason:减少时,需要 update price -= ? where price >= ?,避免并发问题。现在基于 price 来过滤,虽然也能解决并发问题,但是冲突概率会高一点;可以看到 TradeBrokerageUserMapper 的做法;
19 17 /**
20   - * 当余额减少时候更新
  18 + * 当消费退款时候, 更新钱包
21 19 *
22   - * @param bizType 业务类型
23   - * @param balance 当前余额
24   - * @param totalRecharge 当前累计充值
25   - * @param totalExpense 当前累计支出
26   - * @param price 支出的金额
  20 + * @param price 消费金额
27 21 * @param id 钱包 id
28 22 */
29   - default int updateWhenDecBalance(PayWalletBizTypeEnum bizType, Integer balance, Long totalRecharge,
30   - Long totalExpense, Integer price, Long id) {
31   - // TODO @jason:这种偏判断的,最红放在 service 层;mapper 可以写多个方法;
32   - PayWalletDO updateDO = new PayWalletDO().setBalance(balance - price);
33   - if(bizType == PayWalletBizTypeEnum.PAYMENT){
34   - updateDO.setTotalExpense(totalExpense + price);
35   - }
36   - if (bizType == PayWalletBizTypeEnum.RECHARGE_REFUND) {
37   - updateDO.setTotalRecharge(totalRecharge - price);
38   - }
39   - return update(updateDO,
40   - new LambdaQueryWrapper<PayWalletDO>().eq(PayWalletDO::getId, id)
41   - .eq(PayWalletDO::getBalance, balance)
42   - .ge(PayWalletDO::getBalance, price));
  23 + default int updateWhenConsumptionRefund(Integer price, Long id){
  24 + LambdaUpdateWrapper<PayWalletDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<PayWalletDO>()
  25 + .setSql(" balance = balance + " + price + ", total_expense = total_expense - " + price)
  26 + .eq(PayWalletDO::getId, id);
  27 + return update(null, lambdaUpdateWrapper);
43 28 }
44 29  
45   - // TODO @jason:类似上面的修改建议哈;
46 30 /**
47   - * 当余额增加时候更新
  31 + * 当消费时候, 更新钱包
48 32 *
49   - * @param bizType 业务类型
50   - * @param balance 当前余额
51   - * @param totalRecharge 当前累计充值
52   - * @param totalExpense 当前累计支出
53   - * @param price 金额
  33 + * @param price 消费金额
54 34 * @param id 钱包 id
55 35 */
56   - default int updateWhenIncBalance(PayWalletBizTypeEnum bizType, Integer balance, Long totalRecharge,
57   - Long totalExpense, Integer price, Long id) {
58   - PayWalletDO updateDO = new PayWalletDO().setBalance(balance + price);
59   - if (bizType == PayWalletBizTypeEnum.PAYMENT_REFUND) {
60   - updateDO.setTotalExpense(totalExpense - price);
61   - }
62   - if (bizType == PayWalletBizTypeEnum.RECHARGE) {
63   - updateDO.setTotalExpense(totalRecharge + price);
64   - }
65   - return update(updateDO,
66   - new LambdaQueryWrapper<PayWalletDO>().eq(PayWalletDO::getId, id)
67   - .eq(PayWalletDO::getBalance, balance));
  36 + default int updateWhenConsumption(Integer price, Long id){
  37 + LambdaUpdateWrapper<PayWalletDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<PayWalletDO>()
  38 + .setSql(" balance = balance - " + price + ", total_expense = total_expense + " + price)
  39 + .eq(PayWalletDO::getId, id)
  40 + .ge(PayWalletDO::getBalance, price); // cas 逻辑
  41 + return update(null, lambdaUpdateWrapper);
68 42 }
69 43 }
70 44  
... ...
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/wallet/WalletPayClient.java
... ... @@ -62,13 +62,12 @@ public class WalletPayClient extends AbstractPayClient&lt;NonePayClientConfig&gt; {
62 62 @Override
63 63 protected PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) {
64 64 try {
65   - // TODO @jason:直接 getLong 和 getInt 会不会更简洁哈
66   - String userId = MapUtil.getStr(reqDTO.getChannelExtras(), USER_ID_KEY);
67   - String userType = MapUtil.getStr(reqDTO.getChannelExtras(), USER_TYPE_KEY);
68   - Assert.notEmpty(userId, "用户 id 不能为空");
69   - Assert.notEmpty(userType, "用户类型不能为空");
70   - PayWalletTransactionDO transaction = wallService.orderPay(Long.valueOf(userId), Integer.valueOf(userType),
71   - reqDTO.getOutTradeNo(), reqDTO.getPrice());
  65 + Long userId = MapUtil.getLong(reqDTO.getChannelExtras(), USER_ID_KEY);
  66 + Integer userType = MapUtil.getInt(reqDTO.getChannelExtras(), USER_TYPE_KEY);
  67 + Assert.notNull(userId, "用户 id 不能为空");
  68 + Assert.notNull(userType, "用户类型不能为空");
  69 + PayWalletTransactionDO transaction = wallService.orderPay(userId, userType, reqDTO.getOutTradeNo(),
  70 + reqDTO.getPrice());
72 71 return PayOrderRespDTO.successOf(transaction.getNo(), transaction.getCreator(),
73 72 transaction.getCreateTime(),
74 73 reqDTO.getOutTradeNo(), transaction);
... ...
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletServiceImpl.java
... ... @@ -6,10 +6,10 @@ import cn.iocoder.yudao.module.pay.dal.dataobject.refund.PayRefundDO;
6 6 import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO;
7 7 import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO;
8 8 import cn.iocoder.yudao.module.pay.dal.mysql.wallet.PayWalletMapper;
9   -import cn.iocoder.yudao.module.pay.dal.redis.no.PayNoRedisDAO;
10 9 import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum;
11 10 import cn.iocoder.yudao.module.pay.service.order.PayOrderService;
12 11 import cn.iocoder.yudao.module.pay.service.refund.PayRefundService;
  12 +import cn.iocoder.yudao.module.pay.service.wallet.bo.CreateWalletTransactionBO;
13 13 import lombok.extern.slf4j.Slf4j;
14 14 import org.springframework.context.annotation.Lazy;
15 15 import org.springframework.stereotype.Service;
... ... @@ -18,7 +18,6 @@ import org.springframework.transaction.annotation.Transactional;
18 18 import javax.annotation.Resource;
19 19 import java.time.LocalDateTime;
20 20  
21   -import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.TOO_MANY_REQUESTS;
22 21 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
23 22 import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*;
24 23 import static cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum.PAYMENT;
... ... @@ -33,21 +32,9 @@ import static cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum.PAYM
33 32 @Slf4j
34 33 public class PayWalletServiceImpl implements PayWalletService {
35 34  
36   - /**
37   - * 余额支付的 no 前缀
38   - */
39   - private static final String WALLET_PAY_NO_PREFIX = "WP";
40   - /**
41   - * 余额退款的 no 前缀
42   - */
43   - private static final String WALLET_REFUND_NO_PREFIX = "WR";
44   -
45 35 @Resource
46 36 private PayWalletMapper walletMapper;
47 37 @Resource
48   - private PayNoRedisDAO noRedisDAO;
49   -
50   - @Resource
51 38 private PayWalletTransactionService walletTransactionService;
52 39 @Resource
53 40 @Lazy
... ... @@ -61,7 +48,7 @@ public class PayWalletServiceImpl implements PayWalletService {
61 48 PayWalletDO wallet = walletMapper.selectByUserIdAndType(userId, userType);
62 49 if (wallet == null) {
63 50 wallet = new PayWalletDO().setUserId(userId).setUserType(userType)
64   - .setBalance(0).setTotalExpense(0L).setTotalRecharge(0L);
  51 + .setBalance(0).setTotalExpense(0).setTotalRecharge(0);
65 52 wallet.setCreateTime(LocalDateTime.now());
66 53 walletMapper.insert(wallet);
67 54 }
... ... @@ -127,68 +114,50 @@ public class PayWalletServiceImpl implements PayWalletService {
127 114 Long bizId, PayWalletBizTypeEnum bizType, Integer price) {
128 115 // 1.1 获取钱包
129 116 PayWalletDO payWallet = getOrCreateWallet(userId, userType);
130   - // 1.2 判断余额是否足够
131   - int afterBalance = payWallet.getBalance() - price;
132   - if (afterBalance < 0) {
133   - throw exception(WALLET_BALANCE_NOT_ENOUGH);
134   - }
135   -
136   - // TODO jason:建议基于 where price >= 来做哈;然后抛出 WALLET_BALANCE_NOT_ENOUGH
137 117 // 2.1 扣除余额
138   - int number = walletMapper.updateWhenDecBalance(bizType, payWallet.getBalance(),
139   - payWallet.getTotalRecharge(), payWallet.getTotalExpense(), price, payWallet.getId());
  118 + int number = 0 ;
  119 + switch (bizType) {
  120 + case PAYMENT: {
  121 + number = walletMapper.updateWhenConsumption(price, payWallet.getId());
  122 + break;
  123 + }
  124 + case RECHARGE_REFUND: {
  125 + // TODO
  126 + break;
  127 + }
  128 + }
140 129 if (number == 0) {
141   - throw exception(TOO_MANY_REQUESTS);
  130 + throw exception(WALLET_BALANCE_NOT_ENOUGH);
142 131 }
143   -
  132 + int afterBalance = payWallet.getBalance() - price;
144 133 // 2.2 生成钱包流水
145   - // TODO @jason:walletNo 交给 payWalletTransactionService 自己生成哈;
146   - String walletNo = generateWalletNo(bizType);
147   - PayWalletTransactionDO walletTransaction = new PayWalletTransactionDO().setWalletId(payWallet.getId())
148   - .setNo(walletNo).setPrice(-price).setBalance(afterBalance)
149   - .setBizId(String.valueOf(bizId)).setBizType(bizType.getType()).setTitle(bizType.getDescription());
150   - // TODO @jason:是不是可以 createWalletTransaction 搞个 bo 参数,然后 PayWalletTransactionDO 交回给 walletTransactionService 更好;然后把参数简化下
151   - walletTransactionService.createWalletTransaction(walletTransaction);
152   - return walletTransaction;
  134 + CreateWalletTransactionBO bo = new CreateWalletTransactionBO().setWalletId(payWallet.getId())
  135 + .setPrice(-price).setBalance(afterBalance).setBizId(String.valueOf(bizId))
  136 + .setBizType(bizType.getType()).setTitle(bizType.getDescription());
  137 + return walletTransactionService.createWalletTransaction(bo);
153 138 }
154 139  
155 140 @Override
156 141 public PayWalletTransactionDO addWalletBalance(Long userId, Integer userType,
157 142 Long bizId, PayWalletBizTypeEnum bizType, Integer price) {
158   - // 1.1 获取钱包
  143 + // 获取钱包
159 144 PayWalletDO payWallet = getOrCreateWallet(userId, userType);
160   -
161   - // 2.1 增加余额
162   - // TODO @jason:类似上面的思路哈;
163   - int number = walletMapper.updateWhenIncBalance(bizType, payWallet.getBalance(), payWallet.getTotalRecharge(),
164   - payWallet.getTotalExpense(), price, payWallet.getId());
165   - if (number == 0) {
166   - throw exception(TOO_MANY_REQUESTS);
167   - }
168   -
169   - // 2.2 生成钱包流水
170   - String walletNo = generateWalletNo(bizType);
171   - PayWalletTransactionDO newWalletTransaction = new PayWalletTransactionDO().setWalletId(payWallet.getId())
172   - .setNo(walletNo).setPrice(price).setBalance(payWallet.getBalance()+price)
173   - .setBizId(String.valueOf(bizId)).setBizType(bizType.getType())
174   - .setTitle(bizType.getDescription());
175   - walletTransactionService.createWalletTransaction(newWalletTransaction);
176   - return newWalletTransaction;
177   - }
178   -
179   - private String generateWalletNo(PayWalletBizTypeEnum bizType) {
180   - // TODO @jason:对于余额来说,是不是直接 W+序号就行了,它其实不关注业务;;;不然就耦合啦
181   - String no = "";
182   - switch(bizType){
183   - case PAYMENT:
184   - no = noRedisDAO.generate(WALLET_PAY_NO_PREFIX);
  145 + switch (bizType) {
  146 + case PAYMENT_REFUND: {
  147 + // 更新退款
  148 + walletMapper.updateWhenConsumptionRefund(price, payWallet.getId());
185 149 break;
186   - case PAYMENT_REFUND:
187   - no = noRedisDAO.generate(WALLET_REFUND_NO_PREFIX);
  150 + }
  151 + case RECHARGE: {
  152 + //TODO
188 153 break;
189   - default :
  154 + }
190 155 }
191   - return no;
  156 + // 2.2 生成钱包流水
  157 + CreateWalletTransactionBO bo = new CreateWalletTransactionBO().setWalletId(payWallet.getId())
  158 + .setPrice(price).setBalance(payWallet.getBalance()+price).setBizId(String.valueOf(bizId))
  159 + .setBizType(bizType.getType()).setTitle(bizType.getDescription());
  160 + return walletTransactionService.createWalletTransaction(bo);
192 161 }
193 162  
194 163 }
... ...
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionService.java
... ... @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 4 import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.transaction.AppPayWalletTransactionPageReqVO;
5 5 import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO;
6 6 import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum;
  7 +import cn.iocoder.yudao.module.pay.service.wallet.bo.CreateWalletTransactionBO;
7 8  
8 9 /**
9 10 * 钱包余额流水 Service 接口
... ... @@ -25,10 +26,10 @@ public interface PayWalletTransactionService {
25 26 /**
26 27 * 新增钱包余额流水
27 28 *
28   - * @param payWalletTransaction 余额流水
29   - * @return id
  29 + * @param bo 创建钱包流水 bo
  30 + * @return 新建的钱包 do
30 31 */
31   - Long createWalletTransaction(PayWalletTransactionDO payWalletTransaction);
  32 + PayWalletTransactionDO createWalletTransaction(CreateWalletTransactionBO bo);
32 33  
33 34 /**
34 35 * 根据 no,获取钱包余流水
... ...
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionServiceImpl.java
... ... @@ -2,10 +2,13 @@ package cn.iocoder.yudao.module.pay.service.wallet;
2 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 4 import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.transaction.AppPayWalletTransactionPageReqVO;
  5 +import cn.iocoder.yudao.module.pay.convert.wallet.PayWalletTransactionConvert;
5 6 import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO;
6 7 import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO;
7 8 import cn.iocoder.yudao.module.pay.dal.mysql.wallet.PayWalletTransactionMapper;
  9 +import cn.iocoder.yudao.module.pay.dal.redis.no.PayNoRedisDAO;
8 10 import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum;
  11 +import cn.iocoder.yudao.module.pay.service.wallet.bo.CreateWalletTransactionBO;
9 12 import lombok.extern.slf4j.Slf4j;
10 13 import org.springframework.stereotype.Service;
11 14  
... ... @@ -19,11 +22,16 @@ import javax.annotation.Resource;
19 22 @Service
20 23 @Slf4j
21 24 public class PayWalletTransactionServiceImpl implements PayWalletTransactionService {
22   -
  25 + /**
  26 + * 钱包流水的 no 前缀
  27 + */
  28 + private static final String WALLET_NO_PREFIX = "W";
23 29 @Resource
24 30 private PayWalletService payWalletService;
25 31 @Resource
26 32 private PayWalletTransactionMapper payWalletTransactionMapper;
  33 + @Resource
  34 + private PayNoRedisDAO noRedisDAO;
27 35  
28 36 @Override
29 37 public PageResult<PayWalletTransactionDO> getWalletTransactionPage(Long userId, Integer userType,
... ... @@ -33,9 +41,11 @@ public class PayWalletTransactionServiceImpl implements PayWalletTransactionServ
33 41 }
34 42  
35 43 @Override
36   - public Long createWalletTransaction(PayWalletTransactionDO payWalletTransaction) {
37   - payWalletTransactionMapper.insert(payWalletTransaction);
38   - return payWalletTransaction.getId();
  44 + public PayWalletTransactionDO createWalletTransaction(CreateWalletTransactionBO bo) {
  45 + PayWalletTransactionDO transactionDO = PayWalletTransactionConvert.INSTANCE.convert(bo);
  46 + transactionDO.setNo(noRedisDAO.generate(WALLET_NO_PREFIX));
  47 + payWalletTransactionMapper.insert(transactionDO);
  48 + return transactionDO;
39 49 }
40 50  
41 51 @Override
... ...
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/bo/CreateWalletTransactionBO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.pay.service.wallet.bo;
  2 +
  3 +import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum;
  4 +import lombok.Data;
  5 +
  6 +/**
  7 + * 创建钱包流水 BO
  8 + *
  9 + * @author jason
  10 + */
  11 +@Data
  12 +public class CreateWalletTransactionBO {
  13 +
  14 + /**
  15 + * 钱包编号
  16 + *
  17 + */
  18 + private Long walletId;
  19 +
  20 + /**
  21 + * 交易金额,单位分
  22 + *
  23 + * 正值表示余额增加,负值表示余额减少
  24 + */
  25 + private Integer price;
  26 +
  27 + /**
  28 + * 交易后余额,单位分
  29 + */
  30 + private Integer balance;
  31 +
  32 + /**
  33 + * 关联业务分类
  34 + *
  35 + * 枚举 {@link PayWalletBizTypeEnum#getType()}
  36 + */
  37 + private Integer bizType;
  38 +
  39 + /**
  40 + * 关联业务编号
  41 + */
  42 + private String bizId;
  43 +
  44 + /**
  45 + * 流水说明
  46 + */
  47 + private String title;
  48 +}
... ...