钱包 review DO 类修改

This commit is contained in:
jason 2023-09-04 14:54:38 +08:00
parent 91b03e7c93
commit cc4c924717
9 changed files with 74 additions and 79 deletions

View File

@ -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='会员钱包流水';

View File

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

View File

@ -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;

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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 金额
*/

View File

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

View File

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