From c7f6f921598990cc0b3709e03e46628a9e8f7fbd Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Sun, 27 Aug 2023 10:10:28 +0800 Subject: [PATCH 1/6] =?UTF-8?q?=E9=92=B1=E5=8C=85=E6=94=AF=E4=BB=98=20Clie?= =?UTF-8?q?nt=20=E7=9A=84=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pay/core/client/PayClientFactory.java | 4 ++ .../core/client/impl/NonePayClientConfig.java | 31 ++++++++ .../client/impl/PayClientFactoryImpl.java | 6 ++ .../impl/delegate/DelegatePayClient.java | 58 +++++++++++++++ .../core/enums/channel/PayChannelEnum.java | 5 +- .../module/pay/enums/ErrorCodeConstants.java | 1 + .../pay/enums/member/WalletBizTypeEnum.java | 3 +- .../framework/pay/wallet/WalletPayClient.java | 72 +++++++++++++++++++ .../channel/PayChannelServiceImpl.java | 24 ++++++- .../pay/service/order/PayOrderService.java | 8 +++ .../service/order/PayOrderServiceImpl.java | 5 ++ .../pay/service/wallet/PayWalletService.java | 3 + .../service/wallet/PayWalletServiceImpl.java | 59 ++++++++++++++- .../wallet/PayWalletTransactionService.java | 2 + .../PayWalletTransactionServiceImpl.java | 10 ++- 15 files changed, 285 insertions(+), 6 deletions(-) create mode 100644 yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/NonePayClientConfig.java create mode 100644 yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/delegate/DelegatePayClient.java create mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/wallet/WalletPayClient.java diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClientFactory.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClientFactory.java index f6d0ca6b5..5825c83e5 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClientFactory.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClientFactory.java @@ -1,5 +1,7 @@ package cn.iocoder.yudao.framework.pay.core.client; +import cn.iocoder.yudao.framework.pay.core.client.impl.delegate.DelegatePayClient; + /** * 支付客户端的工厂接口 * @@ -25,4 +27,6 @@ public interface PayClientFactory { void createOrUpdatePayClient(Long channelId, String channelCode, Config config); + void createOrUpdateDelegatePayClient(Long channelId, DelegatePayClient delegatePayClient); + } diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/NonePayClientConfig.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/NonePayClientConfig.java new file mode 100644 index 000000000..48319036c --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/NonePayClientConfig.java @@ -0,0 +1,31 @@ +package cn.iocoder.yudao.framework.pay.core.client.impl; + +import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig; +import lombok.Data; + +import javax.validation.Validator; + +/** + * 无需任何配置 PayClientConfig 实现类 + * + * @author jason + */ +@Data +public class NonePayClientConfig implements PayClientConfig { + + /** + * 配置名称 + *

+ * 如果不加任何属性,JsonUtils.parseObject2 解析会报错,所以暂时加个名称 + */ + private String name; + + public NonePayClientConfig(){ + this.name = "none-config"; + } + + @Override + public void validate(Validator validator) { + // 无任何配置不需要校验 + } +} diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/PayClientFactoryImpl.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/PayClientFactoryImpl.java index 121aeb087..e8ae76607 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/PayClientFactoryImpl.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/PayClientFactoryImpl.java @@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.pay.core.client.PayClient; import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig; import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory; import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.*; +import cn.iocoder.yudao.framework.pay.core.client.impl.delegate.DelegatePayClient; import cn.iocoder.yudao.framework.pay.core.client.impl.mock.MockPayClient; import cn.iocoder.yudao.framework.pay.core.client.impl.mock.MockPayClientConfig; import cn.iocoder.yudao.framework.pay.core.client.impl.weixin.*; @@ -51,6 +52,11 @@ public class PayClientFactoryImpl implements PayClientFactory { } } + @Override + public void createOrUpdateDelegatePayClient(Long channelId, DelegatePayClient delegatePayClient) { + clients.put(channelId, delegatePayClient); + } + @SuppressWarnings("unchecked") private AbstractPayClient createPayClient( Long channelId, String channelCode, Config config) { diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/delegate/DelegatePayClient.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/delegate/DelegatePayClient.java new file mode 100644 index 000000000..e700c70ec --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/delegate/DelegatePayClient.java @@ -0,0 +1,58 @@ +package cn.iocoder.yudao.framework.pay.core.client.impl.delegate; + +import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig; +import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; +import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO; +import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO; +import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO; +import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient; + +import java.util.Map; + +/** + * @author jason + */ +public abstract class DelegatePayClient extends AbstractPayClient { + + private final DelegatePayClient delegate; + + public DelegatePayClient(Long channelId, String channelCode, PayClientConfig config) { + super(channelId, channelCode, config); + delegate = this; + } + + @Override + protected void doInit() { + delegate.doInit(); + } + + @Override + protected PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) { + return delegate.doUnifiedOrder(reqDTO); + } + + @Override + protected PayOrderRespDTO doGetOrder(String outTradeNo) { + return delegate.doGetOrder(outTradeNo); + } + + @Override + protected PayRefundRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) { + return delegate.doUnifiedRefund(reqDTO); + } + + @Override + protected PayRefundRespDTO doGetRefund(String outTradeNo, String outRefundNo) { + return delegate.doGetRefund(outTradeNo, outRefundNo); + } + + @Override + protected PayRefundRespDTO doParseRefundNotify(Map params, String body) { + return delegate.doParseRefundNotify(params, body); + } + + @Override + protected PayOrderRespDTO doParseOrderNotify(Map params, String body) { + return delegate.doParseOrderNotify(params, body); + } +} diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/channel/PayChannelEnum.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/channel/PayChannelEnum.java index 073b17f3c..cbe0a242a 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/channel/PayChannelEnum.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/channel/PayChannelEnum.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.framework.pay.core.enums.channel; import cn.hutool.core.util.ArrayUtil; +import cn.iocoder.yudao.framework.pay.core.client.impl.NonePayClientConfig; import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig; import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig; import cn.iocoder.yudao.framework.pay.core.client.impl.mock.MockPayClientConfig; @@ -29,7 +30,9 @@ public enum PayChannelEnum { ALIPAY_QR("alipay_qr", "支付宝扫码支付", AlipayPayClientConfig.class), ALIPAY_BAR("alipay_bar", "支付宝条码支付", AlipayPayClientConfig.class), - MOCK("mock", "模拟支付", MockPayClientConfig.class); + MOCK("mock", "模拟支付", MockPayClientConfig.class), + + WALLET("wallet", "钱包支付", NonePayClientConfig.class); /** * 编码 diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java index b319f006f..5b244b79f 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java @@ -43,6 +43,7 @@ public interface ErrorCodeConstants { // ========== 钱包模块(退款) 1007007000 ========== ErrorCode WALLET_NOT_FOUND = new ErrorCode(1007007000, "用户钱包不存在"); + ErrorCode WALLET_NOT_ENOUGH = new ErrorCode(1007007001, "钱包余额不足"); // ========== 示例订单 1007900000 ========== ErrorCode DEMO_ORDER_NOT_FOUND = new ErrorCode(1007900000, "示例订单不存在"); diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/member/WalletBizTypeEnum.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/member/WalletBizTypeEnum.java index b39ed9d09..1ea73d8b0 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/member/WalletBizTypeEnum.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/member/WalletBizTypeEnum.java @@ -12,7 +12,8 @@ import lombok.Getter; @Getter public enum WalletBizTypeEnum { RECHARGE(1, "充值"), - RECHARGE_REFUND(2, "充值退款"); + RECHARGE_REFUND(2, "充值退款"), + PAYMENT(3, "支付"); // TODO 后续增加 /** 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 new file mode 100644 index 000000000..26300bbcc --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/wallet/WalletPayClient.java @@ -0,0 +1,72 @@ +package cn.iocoder.yudao.module.pay.framework.pay.wallet; + +import cn.iocoder.yudao.framework.pay.core.client.impl.NonePayClientConfig; +import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; +import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO; +import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO; +import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO; +import cn.iocoder.yudao.framework.pay.core.client.impl.delegate.DelegatePayClient; +import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; +import cn.iocoder.yudao.module.pay.service.wallet.PayWalletService; +import lombok.extern.slf4j.Slf4j; + +import java.util.Map; + +/** + * 钱包支付的 PayClient 实现类 + * + * @author jason + */ +@Slf4j +public class WalletPayClient extends DelegatePayClient { + + private PayWalletService payWalletService; + + public WalletPayClient(Long channelId, String channelCode, NonePayClientConfig config) { + super(channelId, channelCode, config); + } + + public WalletPayClient(Long channelId, String channelCode, NonePayClientConfig config, PayWalletService payWalletService) { + this(channelId, channelCode, config); + this.payWalletService = payWalletService; + } + + @Override + protected void doInit() { + // 钱包支付 无需初始化 + } + + @Override + protected PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) { + PayWalletTransactionDO payWalletTransaction = payWalletService.pay(reqDTO.getOutTradeNo(), reqDTO.getPrice()); + return PayOrderRespDTO.successOf(payWalletTransaction.getNo(), payWalletTransaction.getCreator(), + payWalletTransaction.getTransactionTime(), + reqDTO.getOutTradeNo(), ""); + } + + + @Override + protected PayOrderRespDTO doParseOrderNotify(Map params, String body) { + throw new UnsupportedOperationException("钱包支付无支付回调"); + } + + @Override + protected PayOrderRespDTO doGetOrder(String outTradeNo) { + return null; + } + + @Override + protected PayRefundRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) { + return null; + } + + @Override + protected PayRefundRespDTO doParseRefundNotify(Map params, String body) { + throw new UnsupportedOperationException("钱包支付无退款回调"); + } + + @Override + protected PayRefundRespDTO doGetRefund(String outTradeNo, String outRefundNo) { + return null; + } +} diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/channel/PayChannelServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/channel/PayChannelServiceImpl.java index 57aaf07d0..9604ffbf7 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/channel/PayChannelServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/channel/PayChannelServiceImpl.java @@ -6,6 +6,7 @@ import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.common.util.json.JsonUtils; +import cn.iocoder.yudao.framework.pay.core.client.impl.NonePayClientConfig; import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig; import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory; import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum; @@ -15,6 +16,8 @@ import cn.iocoder.yudao.module.pay.controller.admin.channel.vo.PayChannelUpdateR import cn.iocoder.yudao.module.pay.convert.channel.PayChannelConvert; import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO; import cn.iocoder.yudao.module.pay.dal.mysql.channel.PayChannelMapper; +import cn.iocoder.yudao.module.pay.framework.pay.wallet.WalletPayClient; +import cn.iocoder.yudao.module.pay.service.wallet.PayWalletService; import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; @@ -26,6 +29,7 @@ import javax.annotation.PostConstruct; import javax.annotation.Resource; import javax.validation.Validator; import java.time.LocalDateTime; +import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; @@ -56,6 +60,8 @@ public class PayChannelServiceImpl implements PayChannelService { @Resource private Validator validator; + @Resource + private PayWalletService payWalletService; /** * 初始化 {@link #payClientFactory} 缓存 @@ -75,10 +81,24 @@ public class PayChannelServiceImpl implements PayChannelService { log.error("[支付模块 yudao-module-pay - 表结构未导入][参考 https://doc.iocoder.cn/pay/build/ 开启]"); } log.info("[initLocalCache][缓存支付渠道,数量为:{}]", channels.size()); - + List walletChannels = new ArrayList<>(); + List otherChannels = new ArrayList<>(); + channels.forEach(t -> { + if (PayChannelEnum.WALLET.getCode().equals(t.getCode())) { + walletChannels.add(t); + } else { + otherChannels.add(t); + } + }); // 第二步:构建缓存:创建或更新支付 Client - channels.forEach(payChannel -> payClientFactory.createOrUpdatePayClient(payChannel.getId(), + otherChannels.forEach(payChannel -> payClientFactory.createOrUpdatePayClient(payChannel.getId(), payChannel.getCode(), payChannel.getConfig())); + + walletChannels.forEach(payChannel -> { + WalletPayClient walletPayClient = new WalletPayClient(payChannel.getId(), payChannel.getCode(), + (NonePayClientConfig) payChannel.getConfig(), payWalletService); + payClientFactory.createOrUpdateDelegatePayClient(payChannel.getId(), walletPayClient); + }); this.channelCache = channels; }); } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderService.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderService.java index 12618c287..3d66ae9b1 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderService.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderService.java @@ -106,6 +106,14 @@ public interface PayOrderService { */ PayOrderExtensionDO getOrderExtension(Long id); + /** + * 获得支付订单 + * + * @param no 支付订单 no + * @return 支付订单 + */ + PayOrderExtensionDO getOrderExtensionByNo(String no); + /** * 同步订单的支付状态 * diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceImpl.java index 20bb26087..d56035187 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceImpl.java @@ -415,6 +415,11 @@ public class PayOrderServiceImpl implements PayOrderService { return orderExtensionMapper.selectById(id); } + @Override + public PayOrderExtensionDO getOrderExtensionByNo(String no) { + return orderExtensionMapper.selectByNo(no); + } + @Override public int syncOrder(LocalDateTime minCreateTime) { // 1. 查询指定创建时间内的待支付订单 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 3d99e5258..473e6f704 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 @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.pay.service.wallet; import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; +import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; /** * 钱包 Service 接口 @@ -15,4 +16,6 @@ public interface PayWalletService { * @param userType 用户类型 */ PayWalletDO getPayWallet(Long userId, Integer userType); + + PayWalletTransactionDO pay(String outTradeNo, Integer 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 7d29b613e..d322c73e1 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 @@ -1,24 +1,81 @@ package cn.iocoder.yudao.module.pay.service.wallet; +import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO; import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; +import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; import cn.iocoder.yudao.module.pay.dal.mysql.wallet.PayWalletMapper; +import cn.iocoder.yudao.module.pay.dal.redis.no.PayNoRedisDAO; +import cn.iocoder.yudao.module.pay.service.order.PayOrderService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId; +import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserType; +import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*; +import static cn.iocoder.yudao.module.pay.enums.member.WalletBizTypeEnum.PAYMENT; + /** * 钱包 Service 实现类 * * @author jason */ @Service +@Slf4j public class PayWalletServiceImpl implements PayWalletService { - + private static final String WALLET_CHANNEL_NO_PREFIX = "W"; + @Resource + @Lazy + private PayOrderService payOrderService; @Resource private PayWalletMapper payWalletMapper; + @Resource + private PayWalletTransactionService payWalletTransactionService; + @Resource + private PayNoRedisDAO noRedisDAO; @Override public PayWalletDO getPayWallet(Long userId, Integer userType) { return payWalletMapper.selectByUserIdAndType(userId, userType); } + + @Override + @Transactional(rollbackFor = Exception.class) + public PayWalletTransactionDO pay(String outTradeNo, Integer price) { + // 判断支付交易拓展单是否存在 + PayOrderExtensionDO orderExtension = payOrderService.getOrderExtensionByNo(outTradeNo); + if (orderExtension == null) { + throw exception(ORDER_EXTENSION_NOT_FOUND); + } + Long userId = getLoginUserId(); + Integer userType = getLoginUserType(); + PayWalletDO payWallet = getPayWallet(userId, userType); + if (payWallet == null) { + log.error("[pay] 用户 {} 钱包不存在", userId); + throw exception(WALLET_NOT_FOUND); + } + // 判断余额是否足够 + int afterBalance = payWallet.getBalance() - price; + if(afterBalance < 0){ + throw exception(WALLET_NOT_ENOUGH); + } + payWallet.setBalance(afterBalance); + payWallet.setTotalExpense(payWallet.getTotalExpense() + price); + payWalletMapper.updateById(payWallet); + + // 生成钱包渠道流水号 + String walletNo = noRedisDAO.generate(WALLET_CHANNEL_NO_PREFIX); + PayWalletTransactionDO payWalletTransaction = new PayWalletTransactionDO().setWalletId(payWallet.getId()) + .setNo(walletNo).setAmount(price).setBalance(afterBalance).setTransactionTime(LocalDateTime.now()) + .setBizId(orderExtension.getOrderId()).setBizType(PAYMENT.getBizType()); + payWalletTransactionService.addPayWalletTransaction(payWalletTransaction); + + return payWalletTransaction; + } } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionService.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionService.java index a9bc91ab5..2ec913222 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionService.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionService.java @@ -20,4 +20,6 @@ public interface PayWalletTransactionService { */ PageResult getWalletTransactionPage(Long userId, Integer userType, AppPayWalletTransactionPageReqVO pageVO); + + Long addPayWalletTransaction(PayWalletTransactionDO payWalletTransaction); } 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 f574b779f..e62edf549 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 @@ -21,7 +21,7 @@ import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.WALLET_NOT_FO */ @Service @Slf4j -public class PayWalletTransactionServiceImpl implements PayWalletTransactionService{ +public class PayWalletTransactionServiceImpl implements PayWalletTransactionService { @Resource private PayWalletService payWalletService; @Resource @@ -38,4 +38,12 @@ public class PayWalletTransactionServiceImpl implements PayWalletTransactionSer return payWalletTransactionMapper.selectPageByWalletIdAndQueryType(payWallet.getId(), WalletTransactionQueryTypeEnum.valueOf(pageVO.getType()), pageVO); } + + @Override + public Long addPayWalletTransaction(PayWalletTransactionDO payWalletTransaction) { + payWalletTransactionMapper.insert(payWalletTransaction); + return payWalletTransaction.getId(); + } + + } From 7237bc07bb7ab656c8ce5ac1de07053cf8517b27 Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Mon, 28 Aug 2023 10:25:50 +0800 Subject: [PATCH 2/6] =?UTF-8?q?=E9=92=B1=E5=8C=85=E9=80=80=E6=AC=BE?= =?UTF-8?q?=E7=9A=84=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pay/core/client/PayClientFactory.java | 8 +- .../client/impl/PayClientFactoryImpl.java | 2 +- .../impl/delegate/DelegatePayClient.java | 2 + .../module/pay/enums/ErrorCodeConstants.java | 3 + .../pay/enums/member/WalletBizTypeEnum.java | 3 +- .../pay/dal/mysql/refund/PayRefundMapper.java | 6 +- .../wallet/PayWalletTransactionMapper.java | 9 ++ .../framework/pay/wallet/WalletPayClient.java | 48 +++++++--- .../channel/PayChannelServiceImpl.java | 3 +- .../pay/service/refund/PayRefundService.java | 8 ++ .../service/refund/PayRefundServiceImpl.java | 5 ++ .../pay/service/wallet/PayWalletService.java | 13 +++ .../service/wallet/PayWalletServiceImpl.java | 89 ++++++++++++++++--- .../wallet/PayWalletTransactionService.java | 21 +++++ .../PayWalletTransactionServiceImpl.java | 11 +++ 15 files changed, 202 insertions(+), 29 deletions(-) diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClientFactory.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClientFactory.java index 5825c83e5..03e6bb613 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClientFactory.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClientFactory.java @@ -27,6 +27,12 @@ public interface PayClientFactory { void createOrUpdatePayClient(Long channelId, String channelCode, Config config); - void createOrUpdateDelegatePayClient(Long channelId, DelegatePayClient delegatePayClient); + /** + * 新增或更新代理支付客户端 + * @param channelId 渠道编号 + * @param delegatePayClient 代理支付客户端 + * @param 支付配置 + */ + void addOrUpdateDelegatePayClient(Long channelId, DelegatePayClient delegatePayClient); } diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/PayClientFactoryImpl.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/PayClientFactoryImpl.java index e8ae76607..eb11009d7 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/PayClientFactoryImpl.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/PayClientFactoryImpl.java @@ -53,7 +53,7 @@ public class PayClientFactoryImpl implements PayClientFactory { } @Override - public void createOrUpdateDelegatePayClient(Long channelId, DelegatePayClient delegatePayClient) { + public void addOrUpdateDelegatePayClient(Long channelId, DelegatePayClient delegatePayClient) { clients.put(channelId, delegatePayClient); } diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/delegate/DelegatePayClient.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/delegate/DelegatePayClient.java index e700c70ec..dc567765c 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/delegate/DelegatePayClient.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/delegate/DelegatePayClient.java @@ -10,6 +10,8 @@ import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient; import java.util.Map; /** + * 代理支付 Client 的抽象类。用于支付 Client 由其它模块实现, 例如钱包支付 + * * @author jason */ public abstract class DelegatePayClient extends AbstractPayClient { diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java index 5b244b79f..dd435c9be 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java @@ -44,6 +44,9 @@ public interface ErrorCodeConstants { // ========== 钱包模块(退款) 1007007000 ========== ErrorCode WALLET_NOT_FOUND = new ErrorCode(1007007000, "用户钱包不存在"); ErrorCode WALLET_NOT_ENOUGH = new ErrorCode(1007007001, "钱包余额不足"); + ErrorCode WALLET_TRANSACTION_NOT_FOUND = new ErrorCode(1007007002, "未找到对应的钱包交易"); + ErrorCode WALLET_REFUND_AMOUNT_ERROR = new ErrorCode(1007007003, "钱包退款金额不对"); + ErrorCode WALLET_REFUND_EXIST = new ErrorCode(1007007004, "已经存在钱包退款"); // ========== 示例订单 1007900000 ========== ErrorCode DEMO_ORDER_NOT_FOUND = new ErrorCode(1007900000, "示例订单不存在"); diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/member/WalletBizTypeEnum.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/member/WalletBizTypeEnum.java index 1ea73d8b0..d5c714e2a 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/member/WalletBizTypeEnum.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/member/WalletBizTypeEnum.java @@ -13,7 +13,8 @@ import lombok.Getter; public enum WalletBizTypeEnum { RECHARGE(1, "充值"), RECHARGE_REFUND(2, "充值退款"), - PAYMENT(3, "支付"); + PAYMENT(3, "支付"), + PAYMENT_REFUND(4, "支付退款"); // TODO 后续增加 /** diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/refund/PayRefundMapper.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/refund/PayRefundMapper.java index af5fad77b..f018063fe 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/refund/PayRefundMapper.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/refund/PayRefundMapper.java @@ -37,6 +37,11 @@ public interface PayRefundMapper extends BaseMapperX { .eq(PayRefundDO::getNo, no)); } + default PayRefundDO selectByNo(String no){ + return selectOne(new LambdaQueryWrapperX() + .eq(PayRefundDO::getNo, no)); + } + default int updateByIdAndStatus(Long id, Integer status, PayRefundDO update) { return update(update, new LambdaQueryWrapper() .eq(PayRefundDO::getId, id).eq(PayRefundDO::getStatus, status)); @@ -71,5 +76,4 @@ public interface PayRefundMapper extends BaseMapperX { default List selectListByStatus(Integer status) { return selectList(PayRefundDO::getStatus, status); } - } 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 28b4a62e0..f02b6f5e7 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 @@ -26,6 +26,15 @@ public interface PayWalletTransactionMapper extends BaseMapperX { - private PayWalletService payWalletService; public WalletPayClient(Long channelId, String channelCode, NonePayClientConfig config) { @@ -38,13 +40,24 @@ public class WalletPayClient extends DelegatePayClient { @Override protected PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) { - PayWalletTransactionDO payWalletTransaction = payWalletService.pay(reqDTO.getOutTradeNo(), reqDTO.getPrice()); - return PayOrderRespDTO.successOf(payWalletTransaction.getNo(), payWalletTransaction.getCreator(), - payWalletTransaction.getTransactionTime(), - reqDTO.getOutTradeNo(), ""); + try { + PayWalletTransactionDO payWalletTransaction = payWalletService.pay(reqDTO.getOutTradeNo(), reqDTO.getPrice()); + return PayOrderRespDTO.successOf(payWalletTransaction.getNo(), payWalletTransaction.getCreator(), + payWalletTransaction.getTransactionTime(), + reqDTO.getOutTradeNo(), "WALLET_PAY_SUCCESS"); + } catch (Throwable ex) { + log.error("[doUnifiedOrder] 失败", ex); + String errorCode = String.valueOf(INTERNAL_SERVER_ERROR); + String errorMsg = INTERNAL_SERVER_ERROR.getMsg(); + if (ex instanceof ServiceException) { + ServiceException serviceException = (ServiceException) ex; + errorCode = String.valueOf(serviceException.getCode()); + errorMsg = serviceException.getMessage(); + } + return PayOrderRespDTO.closedOf(errorCode, errorMsg, reqDTO.getOutTradeNo(), ex); + } } - @Override protected PayOrderRespDTO doParseOrderNotify(Map params, String body) { throw new UnsupportedOperationException("钱包支付无支付回调"); @@ -52,12 +65,27 @@ public class WalletPayClient extends DelegatePayClient { @Override protected PayOrderRespDTO doGetOrder(String outTradeNo) { - return null; + throw new UnsupportedOperationException("待实现"); } @Override protected PayRefundRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) { - return null; + try { + PayWalletTransactionDO payWalletTransaction = payWalletService.refund(reqDTO.getOutRefundNo(), + reqDTO.getRefundPrice(), reqDTO.getReason()); + return PayRefundRespDTO.successOf(payWalletTransaction.getNo(), payWalletTransaction.getTransactionTime(), + reqDTO.getOutRefundNo(), "WALLET_REFUND_SUCCESS"); + } catch (Throwable ex) { + log.error("[doUnifiedRefund] 失败", ex); + String errorCode = String.valueOf(INTERNAL_SERVER_ERROR); + String errorMsg = INTERNAL_SERVER_ERROR.getMsg(); + if (ex instanceof ServiceException) { + ServiceException serviceException = (ServiceException) ex; + errorCode = String.valueOf(serviceException.getCode()); + errorMsg = serviceException.getMessage(); + } + return PayRefundRespDTO.failureOf(errorCode, errorMsg, reqDTO.getOutRefundNo(), ex); + } } @Override @@ -67,6 +95,6 @@ public class WalletPayClient extends DelegatePayClient { @Override protected PayRefundRespDTO doGetRefund(String outTradeNo, String outRefundNo) { - return null; + throw new UnsupportedOperationException("待实现"); } } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/channel/PayChannelServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/channel/PayChannelServiceImpl.java index 9604ffbf7..a8317b6ed 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/channel/PayChannelServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/channel/PayChannelServiceImpl.java @@ -81,6 +81,7 @@ public class PayChannelServiceImpl implements PayChannelService { log.error("[支付模块 yudao-module-pay - 表结构未导入][参考 https://doc.iocoder.cn/pay/build/ 开启]"); } log.info("[initLocalCache][缓存支付渠道,数量为:{}]", channels.size()); + // 钱包 client 需要和其它 client 分开了创建 List walletChannels = new ArrayList<>(); List otherChannels = new ArrayList<>(); channels.forEach(t -> { @@ -97,7 +98,7 @@ public class PayChannelServiceImpl implements PayChannelService { walletChannels.forEach(payChannel -> { WalletPayClient walletPayClient = new WalletPayClient(payChannel.getId(), payChannel.getCode(), (NonePayClientConfig) payChannel.getConfig(), payWalletService); - payClientFactory.createOrUpdateDelegatePayClient(payChannel.getId(), walletPayClient); + payClientFactory.addOrUpdateDelegatePayClient(payChannel.getId(), walletPayClient); }); this.channelCache = channels; }); diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundService.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundService.java index 8a93ec4da..258cea964 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundService.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundService.java @@ -24,6 +24,14 @@ public interface PayRefundService { */ PayRefundDO getRefund(Long id); + /** + * 获得退款订单 + * + * @param no 外部退款单号 + * @return 退款订单 + */ + PayRefundDO getRefundByNo(String no); + /** * 获得指定应用的退款数量 * diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceImpl.java index 4ab692b19..e4d75c035 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceImpl.java @@ -74,6 +74,11 @@ public class PayRefundServiceImpl implements PayRefundService { return refundMapper.selectById(id); } + @Override + public PayRefundDO getRefundByNo(String no) { + return refundMapper.selectByNo(no); + } + @Override public Long getRefundCountByAppId(Long appId) { return refundMapper.selectCountByAppId(appId); 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 473e6f704..780433b71 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 @@ -17,5 +17,18 @@ public interface PayWalletService { */ PayWalletDO getPayWallet(Long userId, Integer userType); + /** + * 钱包支付 + * @param outTradeNo 外部订单号 + * @param price 金额 + */ PayWalletTransactionDO pay(String outTradeNo, Integer price); + + /** + * 钱包支付退款 + * @param outRefundNo 外部退款号 + * @param refundPrice 退款金额 + * @param reason 退款原因 + */ + PayWalletTransactionDO refund(String outRefundNo, Integer refundPrice, String reason); } 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 d322c73e1..f9168dbd1 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 @@ -1,18 +1,19 @@ package cn.iocoder.yudao.module.pay.service.wallet; import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO; +import cn.iocoder.yudao.module.pay.dal.dataobject.refund.PayRefundDO; import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; import cn.iocoder.yudao.module.pay.dal.mysql.wallet.PayWalletMapper; import cn.iocoder.yudao.module.pay.dal.redis.no.PayNoRedisDAO; import cn.iocoder.yudao.module.pay.service.order.PayOrderService; +import cn.iocoder.yudao.module.pay.service.refund.PayRefundService; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; - import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; @@ -20,6 +21,7 @@ import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLogi import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserType; import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*; import static cn.iocoder.yudao.module.pay.enums.member.WalletBizTypeEnum.PAYMENT; +import static cn.iocoder.yudao.module.pay.enums.member.WalletBizTypeEnum.PAYMENT_REFUND; /** * 钱包 Service 实现类 @@ -29,16 +31,20 @@ import static cn.iocoder.yudao.module.pay.enums.member.WalletBizTypeEnum.PAYMENT @Service @Slf4j public class PayWalletServiceImpl implements PayWalletService { - private static final String WALLET_CHANNEL_NO_PREFIX = "W"; - @Resource - @Lazy - private PayOrderService payOrderService; + private static final String WALLET_PAY_NO_PREFIX = "WP"; + private static final String WALLET_REFUND_NO_PREFIX = "WR"; @Resource private PayWalletMapper payWalletMapper; @Resource private PayWalletTransactionService payWalletTransactionService; @Resource private PayNoRedisDAO noRedisDAO; + @Resource + @Lazy + private PayOrderService payOrderService; + @Resource + @Lazy + private PayRefundService payRefundService; @Override public PayWalletDO getPayWallet(Long userId, Integer userType) { @@ -53,13 +59,7 @@ public class PayWalletServiceImpl implements PayWalletService { if (orderExtension == null) { throw exception(ORDER_EXTENSION_NOT_FOUND); } - Long userId = getLoginUserId(); - Integer userType = getLoginUserType(); - PayWalletDO payWallet = getPayWallet(userId, userType); - if (payWallet == null) { - log.error("[pay] 用户 {} 钱包不存在", userId); - throw exception(WALLET_NOT_FOUND); - } + PayWalletDO payWallet = validatePayWallet(); // 判断余额是否足够 int afterBalance = payWallet.getBalance() - price; if(afterBalance < 0){ @@ -70,12 +70,73 @@ public class PayWalletServiceImpl implements PayWalletService { payWalletMapper.updateById(payWallet); // 生成钱包渠道流水号 - String walletNo = noRedisDAO.generate(WALLET_CHANNEL_NO_PREFIX); + String walletNo = noRedisDAO.generate(WALLET_PAY_NO_PREFIX); PayWalletTransactionDO payWalletTransaction = new PayWalletTransactionDO().setWalletId(payWallet.getId()) - .setNo(walletNo).setAmount(price).setBalance(afterBalance).setTransactionTime(LocalDateTime.now()) + .setNo(walletNo).setAmount(price * -1).setBalance(afterBalance).setTransactionTime(LocalDateTime.now()) .setBizId(orderExtension.getOrderId()).setBizType(PAYMENT.getBizType()); payWalletTransactionService.addPayWalletTransaction(payWalletTransaction); return payWalletTransaction; } + + private PayWalletDO validatePayWallet() { + Long userId = getLoginUserId(); + Integer userType = getLoginUserType(); + PayWalletDO payWallet = getPayWallet(userId, userType); + if (payWallet == null) { + log.error("[validatePayWallet] 用户 {} 钱包不存在", userId); + throw exception(WALLET_NOT_FOUND); + } + return payWallet; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public PayWalletTransactionDO refund(String outRefundNo, Integer refundPrice, String reason) { + // 判断退款单是否存在 + PayRefundDO payRefund = payRefundService.getRefundByNo(outRefundNo); + if (payRefund == null) { + throw exception(REFUND_NOT_FOUND); + } + PayWalletDO payWallet = validatePayWallet(); + // 校验是否可以退款 + validateWalletCanRefund(payRefund.getId(), payRefund.getChannelOrderNo(), payWallet.getId(), refundPrice); + + Integer afterBalance = payWallet.getBalance() + refundPrice; + payWallet.setBalance(afterBalance); + payWallet.setTotalExpense(payWallet.getTotalExpense() + refundPrice * -1L); + payWalletMapper.updateById(payWallet); + + String walletNo = noRedisDAO.generate(WALLET_REFUND_NO_PREFIX); + PayWalletTransactionDO newWalletTransaction = new PayWalletTransactionDO().setWalletId(payWallet.getId()) + .setNo(walletNo).setAmount(refundPrice).setBalance(afterBalance).setTransactionTime(LocalDateTime.now()) + .setBizId(payRefund.getId()).setBizType(PAYMENT_REFUND.getBizType()) + .setDescription(reason); + payWalletTransactionService.addPayWalletTransaction(newWalletTransaction); + + return newWalletTransaction; + } + + /** + * 校验是否能退款 + * @param refundId 支付退款单 id + * @param walletPayNo 钱包支付 no + * @param walletId 钱包 id + */ + private void validateWalletCanRefund(long refundId, String walletPayNo, long walletId, int refundPrice) { + // 查询钱包支付交易 + PayWalletTransactionDO payWalletTransaction = payWalletTransactionService.getPayWalletTransactionByNo(walletPayNo); + if (payWalletTransaction == null) { + throw exception(WALLET_TRANSACTION_NOT_FOUND); + } + // 原来的支付金额 + int amount = payWalletTransaction.getAmount() * -1; + if (refundPrice != amount) { + throw exception(WALLET_REFUND_AMOUNT_ERROR); + } + PayWalletTransactionDO refundTransaction = payWalletTransactionService.getPayWalletTransaction(walletId, refundId, PAYMENT_REFUND); + if (refundTransaction != null) { + throw exception(WALLET_REFUND_EXIST); + } + } } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionService.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionService.java index 2ec913222..1e140f0ae 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionService.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionService.java @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.pay.service.wallet; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.AppPayWalletTransactionPageReqVO; import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; +import cn.iocoder.yudao.module.pay.enums.member.WalletBizTypeEnum; /** * 钱包余额明细 Service 接口 @@ -21,5 +22,25 @@ public interface PayWalletTransactionService { PageResult getWalletTransactionPage(Long userId, Integer userType, AppPayWalletTransactionPageReqVO pageVO); + /** + * 新增钱包余额明细 + * @param payWalletTransaction 余额明细 + * @return id + */ Long addPayWalletTransaction(PayWalletTransactionDO payWalletTransaction); + + /** + * 获取钱包余额明细 根据 no + * @param no 流水号 + */ + PayWalletTransactionDO getPayWalletTransactionByNo(String no); + + /** + * 获取钱包 + * @param walletId 钱包 id + * @param bizId 业务编号 + * @param typeEnum 业务类型 + * @return 钱包余额明细 + */ + PayWalletTransactionDO getPayWalletTransaction(Long walletId, Long bizId, WalletBizTypeEnum typeEnum); } 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 e62edf549..320321a63 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 @@ -5,6 +5,7 @@ import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.AppPayWalletTransact import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; import cn.iocoder.yudao.module.pay.dal.mysql.wallet.PayWalletTransactionMapper; +import cn.iocoder.yudao.module.pay.enums.member.WalletBizTypeEnum; import cn.iocoder.yudao.module.pay.enums.member.WalletTransactionQueryTypeEnum; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -45,5 +46,15 @@ public class PayWalletTransactionServiceImpl implements PayWalletTransactionServ return payWalletTransaction.getId(); } + @Override + public PayWalletTransactionDO getPayWalletTransactionByNo(String no) { + return payWalletTransactionMapper.selectByNo(no); + } + + @Override + public PayWalletTransactionDO getPayWalletTransaction(Long walletId, Long bizId, WalletBizTypeEnum typeEnum) { + return payWalletTransactionMapper.selectByWalletIdAndBiz(walletId, bizId, typeEnum.getBizType()); + } + } From 9077f14bae0ce0d329899bfb73bb2175f211222c Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Mon, 28 Aug 2023 13:54:25 +0800 Subject: [PATCH 3/6] =?UTF-8?q?=E9=92=B1=E5=8C=85=E6=94=AF=E4=BB=98=20Clie?= =?UTF-8?q?nt=20=E5=A4=B1=E8=B4=A5=E9=97=AE=E9=A2=98=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pay/framework/pay/wallet/WalletPayClient.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) 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 00cec3366..18d784005 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 @@ -47,14 +47,15 @@ public class WalletPayClient extends DelegatePayClient { reqDTO.getOutTradeNo(), "WALLET_PAY_SUCCESS"); } catch (Throwable ex) { log.error("[doUnifiedOrder] 失败", ex); - String errorCode = String.valueOf(INTERNAL_SERVER_ERROR); + Integer errorCode = INTERNAL_SERVER_ERROR.getCode(); String errorMsg = INTERNAL_SERVER_ERROR.getMsg(); if (ex instanceof ServiceException) { ServiceException serviceException = (ServiceException) ex; - errorCode = String.valueOf(serviceException.getCode()); + errorCode = serviceException.getCode(); errorMsg = serviceException.getMessage(); } - return PayOrderRespDTO.closedOf(errorCode, errorMsg, reqDTO.getOutTradeNo(), ex); + return PayOrderRespDTO.closedOf(String.valueOf(errorCode), errorMsg, + reqDTO.getOutTradeNo(), ""); } } @@ -77,14 +78,15 @@ public class WalletPayClient extends DelegatePayClient { reqDTO.getOutRefundNo(), "WALLET_REFUND_SUCCESS"); } catch (Throwable ex) { log.error("[doUnifiedRefund] 失败", ex); - String errorCode = String.valueOf(INTERNAL_SERVER_ERROR); + Integer errorCode = INTERNAL_SERVER_ERROR.getCode(); String errorMsg = INTERNAL_SERVER_ERROR.getMsg(); if (ex instanceof ServiceException) { ServiceException serviceException = (ServiceException) ex; - errorCode = String.valueOf(serviceException.getCode()); + errorCode = serviceException.getCode(); errorMsg = serviceException.getMessage(); } - return PayRefundRespDTO.failureOf(errorCode, errorMsg, reqDTO.getOutRefundNo(), ex); + return PayRefundRespDTO.failureOf(String.valueOf(errorCode), errorMsg, + reqDTO.getOutRefundNo(), ""); } } From 6132443d26949edd0acbae9c9c865bc92a8afe93 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Mon, 28 Aug 2023 18:54:40 +0800 Subject: [PATCH 4/6] =?UTF-8?q?code=20review=EF=BC=9A=E9=92=B1=E5=8C=85?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/delegate/DelegatePayClient.java | 9 ++- .../impl/alipay/AbstractAlipayClientTest.java | 4 +- .../impl/alipay/AlipayPcPayClientTest.java | 4 +- .../impl/alipay/AlipayQrPayClientTest.java | 50 +++++++++------ .../impl/alipay/AlipayWapPayClientTest.java | 39 ++++++++---- .../module/pay/enums/ErrorCodeConstants.java | 4 +- ...ypeEnum.java => PayWalletBizTypeEnum.java} | 10 +-- .../WalletTransactionQueryTypeEnum.java | 14 ++++- .../app/wallet/AppPayWalletController.java | 1 + .../vo/AppPayWalletTransactionPageReqVO.java | 5 +- .../vo/AppPayWalletTransactionRespVO.java | 2 +- .../dal/dataobject/wallet/PayWalletDO.java | 11 ++-- .../wallet/PayWalletTransactionDO.java | 52 ++++++++------- .../pay/dal/mysql/refund/PayRefundMapper.java | 5 +- .../wallet/PayWalletTransactionMapper.java | 8 ++- .../framework/pay/wallet/WalletPayClient.java | 15 +++-- .../channel/PayChannelServiceImpl.java | 1 + .../pay/service/wallet/PayWalletService.java | 7 ++- .../service/wallet/PayWalletServiceImpl.java | 63 ++++++++++++------- .../wallet/PayWalletTransactionService.java | 32 +++++----- .../PayWalletTransactionServiceImpl.java | 22 ++++--- 21 files changed, 220 insertions(+), 138 deletions(-) rename yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/member/{WalletBizTypeEnum.java => PayWalletBizTypeEnum.java} (79%) diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/delegate/DelegatePayClient.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/delegate/DelegatePayClient.java index dc567765c..65958d5a3 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/delegate/DelegatePayClient.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/delegate/DelegatePayClient.java @@ -9,14 +9,17 @@ import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient; import java.util.Map; +// TODO @jason:其它模块,主要是无法 pay client 初始化存在问题,所以我感觉,是不是可以搞个 PayClientInitializer 接口。这样,PayClientFactory 去 get 这个支付模式对应的 PayClientInitializer,通过它来创建。具体注入的地方,可以在 PayChannel init 方法那; /** - * 代理支付 Client 的抽象类。用于支付 Client 由其它模块实现, 例如钱包支付 + * 代理支付 Client 的抽象类。 + * + * 用于支付 Client 由其它模块实现,例如钱包支付 * * @author jason */ -public abstract class DelegatePayClient extends AbstractPayClient { +public abstract class DelegatePayClient extends AbstractPayClient { - private final DelegatePayClient delegate; + private final DelegatePayClient delegate; public DelegatePayClient(Long channelId, String channelCode, PayClientConfig config) { super(channelId, channelCode, config); diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayClientTest.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayClientTest.java index 57d629021..2d220079e 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayClientTest.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayClientTest.java @@ -168,7 +168,7 @@ public abstract class AbstractAlipayClientTest extends BaseMockitoUnitTest { @Test @DisplayName("支付宝 Client 统一退款:抛出业务异常") public void testUnifiedRefund_throwServiceException() throws AlipayApiException { - // mock + // mock 方法 when(defaultAlipayClient.execute(argThat((ArgumentMatcher) request -> true))) .thenThrow(ServiceExceptionUtil.exception(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR)); // 准备请求参数 @@ -182,7 +182,7 @@ public abstract class AbstractAlipayClientTest extends BaseMockitoUnitTest { @Test @DisplayName("支付宝 Client 统一退款:抛出系统异常") public void testUnifiedRefund_throwPayException() throws AlipayApiException { - // mock + // mock 方法 when(defaultAlipayClient.execute(argThat((ArgumentMatcher) request -> true))) .thenThrow(new RuntimeException("系统异常")); // 准备请求参数 diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayPcPayClientTest.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayPcPayClientTest.java index b94ae7148..d78caf28c 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayPcPayClientTest.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayPcPayClientTest.java @@ -70,7 +70,7 @@ public class AlipayPcPayClientTest extends AbstractAlipayClientTest { @Test @DisplayName("支付宝 PC 网站支付:Form Display Mode 下单成功") public void testUnifiedOrder_formSuccess() throws AlipayApiException { - // mock + // mock 方法 String notifyUrl = randomURL(); AlipayTradePagePayResponse response = randomPojo(AlipayTradePagePayResponse.class, o -> o.setSubCode("")); when(defaultAlipayClient.pageExecute(argThat((ArgumentMatcher) request -> true), @@ -99,7 +99,7 @@ public class AlipayPcPayClientTest extends AbstractAlipayClientTest { @Test @DisplayName("支付宝 PC 网站支付:渠道返回失败") public void testUnifiedOrder_channelFailed() throws AlipayApiException { - // mock + // mock 方法 String subCode = randomString(); String subMsg = randomString(); AlipayTradePagePayResponse response = randomPojo(AlipayTradePagePayResponse.class, o -> { diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayQrPayClientTest.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayQrPayClientTest.java index 47497ab23..c7e1eb33f 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayQrPayClientTest.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayQrPayClientTest.java @@ -39,9 +39,9 @@ public class AlipayQrPayClientTest extends AbstractAlipayClientTest { } @Test - @DisplayName("支付宝扫描支付下单成功") - public void test_unified_order_success() throws AlipayApiException { - // 准备返回对象 + @DisplayName("支付宝扫描支付:下单成功") + public void testUnifiedOrder_success() throws AlipayApiException { + // mock 方法 String notifyUrl = randomURL(); String qrCode = randomString(); Integer price = randomInteger(); @@ -49,7 +49,6 @@ public class AlipayQrPayClientTest extends AbstractAlipayClientTest { o.setQrCode(qrCode); o.setSubCode(""); }); - // mock when(defaultAlipayClient.execute(argThat((ArgumentMatcher) request -> { assertEquals(notifyUrl, request.getNotifyUrl()); return true; @@ -58,18 +57,25 @@ public class AlipayQrPayClientTest extends AbstractAlipayClientTest { String outTradeNo = randomString(); PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(notifyUrl, outTradeNo, price); + // 调用 PayOrderRespDTO resp = client.unifiedOrder(reqDTO); // 断言 assertEquals(WAITING.getStatus(), resp.getStatus()); - assertEquals(PayOrderDisplayModeEnum.QR_CODE.getMode(), resp.getDisplayMode()); assertEquals(outTradeNo, resp.getOutTradeNo()); - assertEquals(qrCode, resp.getDisplayContent()); + assertNull(resp.getChannelOrderNo()); + assertNull(resp.getChannelUserId()); + assertNull(resp.getSuccessTime()); + assertEquals(PayOrderDisplayModeEnum.QR_CODE.getMode(), resp.getDisplayMode()); + assertEquals(response.getQrCode(), resp.getDisplayContent()); assertSame(response, resp.getRawData()); + assertNull(resp.getChannelErrorCode()); + assertNull(resp.getChannelErrorMsg()); } @Test - @DisplayName("支付宝扫描支付,渠道返回失败") - public void test_unified_order_channel_failed() throws AlipayApiException { + @DisplayName("支付宝扫描支付:渠道返回失败") + public void testUnifiedOrder_channelFailed() throws AlipayApiException { + // mock 方法 String notifyUrl = randomURL(); String subCode = randomString(); String subMsg = randomString(); @@ -87,47 +93,55 @@ public class AlipayQrPayClientTest extends AbstractAlipayClientTest { String outTradeNo = randomString(); PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(notifyUrl, outTradeNo, price); + // 调用 PayOrderRespDTO resp = client.unifiedOrder(reqDTO); // 断言 assertEquals(CLOSED.getStatus(), resp.getStatus()); + assertEquals(outTradeNo, resp.getOutTradeNo()); + assertNull(resp.getChannelOrderNo()); + assertNull(resp.getChannelUserId()); + assertNull(resp.getSuccessTime()); + assertNull(resp.getDisplayMode()); + assertNull(resp.getDisplayContent()); + assertSame(response, resp.getRawData()); assertEquals(subCode, resp.getChannelErrorCode()); assertEquals(subMsg, resp.getChannelErrorMsg()); - assertSame(response, resp.getRawData()); } @Test @DisplayName("支付宝扫描支付, 抛出系统异常") - public void test_unified_order_throw_pay_exception() throws AlipayApiException { - // 准备请求参数 + public void testUnifiedOrder_throwPayException() throws AlipayApiException { + // mock 方法 String outTradeNo = randomString(); String notifyUrl = randomURL(); Integer price = randomInteger(); - // mock when(defaultAlipayClient.execute(argThat((ArgumentMatcher) request -> { assertEquals(notifyUrl, request.getNotifyUrl()); return true; }))).thenThrow(new RuntimeException("系统异常")); // 准备请求参数 PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(notifyUrl, outTradeNo,price); - // 断言 + + // 调用,并断言 assertThrows(PayException.class, () -> client.unifiedOrder(reqDTO)); } @Test - @DisplayName("支付宝 Client 统一下单,抛出业务异常") - public void test_unified_order_throw_service_exception() throws AlipayApiException { - // 准备请求参数 + @DisplayName("支付宝 Client 统一下单:抛出业务异常") + public void testUnifiedOrder_throwServiceException() throws AlipayApiException { + // mock 方法 String outTradeNo = randomString(); String notifyUrl = randomURL(); Integer price = randomInteger(); - // mock when(defaultAlipayClient.execute(argThat((ArgumentMatcher) request -> { assertEquals(notifyUrl, request.getNotifyUrl()); return true; }))).thenThrow(ServiceExceptionUtil.exception(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR)); // 准备请求参数 PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(notifyUrl, outTradeNo, price); - // 断言 + + // 调用,并断言 assertThrows(ServiceException.class, () -> client.unifiedOrder(reqDTO)); } + } diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayWapPayClientTest.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayWapPayClientTest.java index bad1960ac..af0c7170b 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayWapPayClientTest.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayWapPayClientTest.java @@ -42,9 +42,9 @@ public class AlipayWapPayClientTest extends AbstractAlipayClientTest { } @Test - @DisplayName("支付宝 H5 支付下单成功") - public void test_unified_order_success() throws AlipayApiException { - // 准备响应对象 + @DisplayName("支付宝 H5 支付:下单成功") + public void testUnifiedOrder_success() throws AlipayApiException { + // mock 方法 String h5Body = randomString(); Integer price = randomInteger(); AlipayTradeWapPayResponse response = randomPojo(AlipayTradeWapPayResponse.class, o -> { @@ -52,7 +52,6 @@ public class AlipayWapPayClientTest extends AbstractAlipayClientTest { o.setBody(h5Body); }); String notifyUrl = randomURL(); - // mock when(defaultAlipayClient.pageExecute(argThat((ArgumentMatcher) request -> { assertInstanceOf(AlipayTradeWapPayModel.class, request.getBizModel()); AlipayTradeWapPayModel bizModel = (AlipayTradeWapPayModel) request.getBizModel(); @@ -60,37 +59,53 @@ public class AlipayWapPayClientTest extends AbstractAlipayClientTest { assertEquals(notifyUrl, request.getNotifyUrl()); return true; }), eq(Method.GET.name()))).thenReturn(response); - + // 准备请求参数 String outTradeNo = randomString(); PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(notifyUrl, outTradeNo, price); + + // 调用 PayOrderRespDTO resp = client.unifiedOrder(reqDTO); + // 断言 assertEquals(WAITING.getStatus(), resp.getStatus()); - assertEquals(PayOrderDisplayModeEnum.URL.getMode(), resp.getDisplayMode()); assertEquals(outTradeNo, resp.getOutTradeNo()); - assertEquals(h5Body, resp.getDisplayContent()); + assertNull(resp.getChannelOrderNo()); + assertNull(resp.getChannelUserId()); + assertNull(resp.getSuccessTime()); + assertEquals(PayOrderDisplayModeEnum.URL.getMode(), resp.getDisplayMode()); + assertEquals(response.getBody(), resp.getDisplayContent()); assertSame(response, resp.getRawData()); + assertNull(resp.getChannelErrorCode()); + assertNull(resp.getChannelErrorMsg()); } @Test - @DisplayName("支付宝 H5 支付,渠道返回失败") + @DisplayName("支付宝 H5 支付:渠道返回失败") public void test_unified_order_channel_failed() throws AlipayApiException { - // 准备响应对象 + // mock 方法 String subCode = randomString(); String subMsg = randomString(); AlipayTradeWapPayResponse response = randomPojo(AlipayTradeWapPayResponse.class, o -> { o.setSubCode(subCode); o.setSubMsg(subMsg); }); - // mock when(defaultAlipayClient.pageExecute(argThat((ArgumentMatcher) request -> true), eq(Method.GET.name()))).thenReturn(response); - PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(randomURL(), randomString(), randomInteger()); + String outTradeNo = randomString(); + PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(randomURL(), outTradeNo, randomInteger()); + // 调用 PayOrderRespDTO resp = client.unifiedOrder(reqDTO); // 断言 assertEquals(CLOSED.getStatus(), resp.getStatus()); + assertEquals(outTradeNo, resp.getOutTradeNo()); + assertNull(resp.getChannelOrderNo()); + assertNull(resp.getChannelUserId()); + assertNull(resp.getSuccessTime()); + assertNull(resp.getDisplayMode()); + assertNull(resp.getDisplayContent()); + assertSame(response, resp.getRawData()); assertEquals(subCode, resp.getChannelErrorCode()); assertEquals(subMsg, resp.getChannelErrorMsg()); - assertSame(response, resp.getRawData()); } + } diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java index dd435c9be..ee8947286 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java @@ -41,9 +41,9 @@ public interface ErrorCodeConstants { ErrorCode REFUND_NOT_FOUND = new ErrorCode(1007006004, "支付退款单不存在"); ErrorCode REFUND_STATUS_IS_NOT_WAITING = new ErrorCode(1007006005, "支付退款单不处于待退款"); - // ========== 钱包模块(退款) 1007007000 ========== + // ========== 钱包模块 1007007000 ========== ErrorCode WALLET_NOT_FOUND = new ErrorCode(1007007000, "用户钱包不存在"); - ErrorCode WALLET_NOT_ENOUGH = new ErrorCode(1007007001, "钱包余额不足"); + ErrorCode WALLET_BALANCE_NOT_ENOUGH = new ErrorCode(1007007001, "钱包余额不足"); ErrorCode WALLET_TRANSACTION_NOT_FOUND = new ErrorCode(1007007002, "未找到对应的钱包交易"); ErrorCode WALLET_REFUND_AMOUNT_ERROR = new ErrorCode(1007007003, "钱包退款金额不对"); ErrorCode WALLET_REFUND_EXIST = new ErrorCode(1007007004, "已经存在钱包退款"); diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/member/WalletBizTypeEnum.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/member/PayWalletBizTypeEnum.java similarity index 79% rename from yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/member/WalletBizTypeEnum.java rename to yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/member/PayWalletBizTypeEnum.java index d5c714e2a..508b728af 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/member/WalletBizTypeEnum.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/member/PayWalletBizTypeEnum.java @@ -10,20 +10,22 @@ import lombok.Getter; */ @AllArgsConstructor @Getter -public enum WalletBizTypeEnum { +public enum PayWalletBizTypeEnum { + RECHARGE(1, "充值"), RECHARGE_REFUND(2, "充值退款"), PAYMENT(3, "支付"), PAYMENT_REFUND(4, "支付退款"); // TODO 后续增加 + /** * 业务分类 */ - private final Integer bizType; - + private final Integer type; /** * 说明 */ - private final String desc; + private final String description; + } diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/member/WalletTransactionQueryTypeEnum.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/member/WalletTransactionQueryTypeEnum.java index 776b860c4..c18555077 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/member/WalletTransactionQueryTypeEnum.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/member/WalletTransactionQueryTypeEnum.java @@ -7,20 +7,27 @@ import lombok.Getter; import java.util.Arrays; +// TODO @jason:可以简化,直接 PageVO 定义两个 Integer; /** - * 钱包明细查询类型 + * 钱包流水查询类型 * * @author jason */ @AllArgsConstructor @Getter public enum WalletTransactionQueryTypeEnum implements IntArrayValuable { + RECHARGE(1, "充值"), EXPENSE(2, "消费"); + /** + * 类型 + */ private final Integer type; - - private final String desc; + /** + * 描述 + */ + private final String description; public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(WalletTransactionQueryTypeEnum::getType).toArray(); @@ -32,4 +39,5 @@ public enum WalletTransactionQueryTypeEnum implements IntArrayValuable { public static WalletTransactionQueryTypeEnum valueOf(Integer type) { return ArrayUtil.firstMatch(o -> o.getType().equals(type), values()); } + } 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 3cd5c511d..159c7c3db 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 @@ -38,4 +38,5 @@ public class AppPayWalletController { PayWalletDO payWallet = payWalletService.getPayWallet(getLoginUserId(), UserTypeEnum.MEMBER.getValue()); return success(PayWalletConvert.INSTANCE.convert(payWallet)); } + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/AppPayWalletTransactionPageReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/AppPayWalletTransactionPageReqVO.java index 22a4cad7e..cf08e00a1 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/AppPayWalletTransactionPageReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/AppPayWalletTransactionPageReqVO.java @@ -6,11 +6,12 @@ import cn.iocoder.yudao.module.pay.enums.member.WalletTransactionQueryTypeEnum; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@Schema(description = "用户 APP - 钱包余额明细分页 Request VO") +@Schema(description = "用户 APP - 钱包流水分页 Request VO") @Data public class AppPayWalletTransactionPageReqVO extends PageParam { - @Schema(description = "余额明细查询分类", example = "1") + @Schema(description = "流水查询分类", example = "1") @InEnum(value = WalletTransactionQueryTypeEnum.class, message = "查询类型必须是 {value}") private Integer type; + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/AppPayWalletTransactionRespVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/AppPayWalletTransactionRespVO.java index dac2109d8..024d79856 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/AppPayWalletTransactionRespVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/AppPayWalletTransactionRespVO.java @@ -5,7 +5,7 @@ import lombok.Data; import java.time.LocalDateTime; -@Schema(description = "用户 APP - 钱包余额明细分页 Response VO") +@Schema(description = "用户 APP - 钱包流水分页 Response VO") @Data public class AppPayWalletTransactionRespVO { @Schema(description = "交易金额, 单位分", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/wallet/PayWalletDO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/wallet/PayWalletDO.java index d914c2f14..92eb620da 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/wallet/PayWalletDO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/wallet/PayWalletDO.java @@ -8,7 +8,7 @@ import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; /** - * 支付 - 会员钱包 DO + * 会员钱包 DO * * @author jason */ @@ -30,7 +30,6 @@ public class PayWalletDO extends BaseDO { * 关联 AdminUserDO 的 id 编号 */ private Long userId; - /** * 用户类型, 预留 多商户转帐可能需要用到 * @@ -39,17 +38,17 @@ public class PayWalletDO extends BaseDO { private Integer userType; /** - * 余额, 单位分 + * 余额,单位分 */ private Integer balance; /** - * 累计支出, 单位分 + * 累计支出,单位分 */ private Long totalExpense; - /** - * 累计充值, 单位分 + * 累计充值,单位分 */ private Long totalRecharge; + } 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 c03a7f224..a1e5eb0c5 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 @@ -1,7 +1,7 @@ package cn.iocoder.yudao.module.pay.dal.dataobject.wallet; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import cn.iocoder.yudao.module.pay.enums.member.WalletBizTypeEnum; +import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; @@ -10,7 +10,7 @@ import lombok.Data; import java.time.LocalDateTime; /** - * 支付-会员钱包明细 DO + * 会员钱包流水 DO * * @author jason */ @@ -24,47 +24,51 @@ public class PayWalletTransactionDO extends BaseDO { */ @TableId private Long id; - - /** - * 会员钱包 id - * 关联 {@link PayWalletDO#getId()} - */ - private Long walletId; - - /** - * 钱包交易业务分类 - * 关联枚举 {@link WalletBizTypeEnum#getBizType()} - */ - private Integer bizType; - - /** - * 关联业务编号 - */ - private Long bizId; - /** * 流水号 */ private String no; + /** + * 钱包编号 + * + * 关联 {@link PayWalletDO#getId()} + */ + private Long walletId; + + /** + * 关联业务分类 + * + * 枚举 {@link PayWalletBizTypeEnum#getType()} + */ + private Integer bizType; + // TODO @jason:使用 string;因为可能有业务是 string 接入哈。 + /** + * 关联业务编号 + */ + private Long bizId; + /** * 附加说明 */ private String description; + // TODO @jason:使用 price 哈。项目里,金额都是用这个为主; /** - * 交易金额, 单位分 - * 正值表示余额增加,负值表示余额减少 + * 交易金额,单位分 + * + * 正值表示余额增加,负值表示余额减少 */ private Integer amount; - /** - * 交易后余额,单位分 + * 交易后余额,单位分 */ 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/refund/PayRefundMapper.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/refund/PayRefundMapper.java index f018063fe..0b620eaed 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/refund/PayRefundMapper.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/refund/PayRefundMapper.java @@ -37,9 +37,8 @@ public interface PayRefundMapper extends BaseMapperX { .eq(PayRefundDO::getNo, no)); } - default PayRefundDO selectByNo(String no){ - return selectOne(new LambdaQueryWrapperX() - .eq(PayRefundDO::getNo, no)); + default PayRefundDO selectByNo(String no) { + return selectOne(PayRefundDO::getNo, no); } default int updateByIdAndStatus(Long id, Integer status, PayRefundDO update) { 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 f02b6f5e7..351810e0c 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 @@ -23,7 +23,7 @@ public interface PayWalletTransactionMapper extends BaseMapperX { + private PayWalletService payWalletService; public WalletPayClient(Long channelId, String channelCode, NonePayClientConfig config) { super(channelId, channelCode, config); } - public WalletPayClient(Long channelId, String channelCode, NonePayClientConfig config, PayWalletService payWalletService) { + public WalletPayClient(Long channelId, String channelCode, NonePayClientConfig config, + PayWalletService payWalletService) { this(channelId, channelCode, config); this.payWalletService = payWalletService; } @Override protected void doInit() { - // 钱包支付 无需初始化 + // 钱包支付,无需初始化 } @Override protected PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) { try { - PayWalletTransactionDO payWalletTransaction = payWalletService.pay(reqDTO.getOutTradeNo(), reqDTO.getPrice()); - return PayOrderRespDTO.successOf(payWalletTransaction.getNo(), payWalletTransaction.getCreator(), - payWalletTransaction.getTransactionTime(), - reqDTO.getOutTradeNo(), "WALLET_PAY_SUCCESS"); + PayWalletTransactionDO transaction = payWalletService.pay(reqDTO.getOutTradeNo(), reqDTO.getPrice()); + return PayOrderRespDTO.successOf(transaction.getNo(), transaction.getCreator(), + transaction.getTransactionTime(), + reqDTO.getOutTradeNo(), "WALLET_PAY_SUCCESS"); // TODO @jason:transaction 作为 traData 好了; } catch (Throwable ex) { log.error("[doUnifiedOrder] 失败", ex); Integer errorCode = INTERNAL_SERVER_ERROR.getCode(); @@ -99,4 +101,5 @@ public class WalletPayClient extends DelegatePayClient { protected PayRefundRespDTO doGetRefund(String outTradeNo, String outRefundNo) { throw new UnsupportedOperationException("待实现"); } + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/channel/PayChannelServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/channel/PayChannelServiceImpl.java index a8317b6ed..d29ad973f 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/channel/PayChannelServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/channel/PayChannelServiceImpl.java @@ -83,6 +83,7 @@ public class PayChannelServiceImpl implements PayChannelService { log.info("[initLocalCache][缓存支付渠道,数量为:{}]", channels.size()); // 钱包 client 需要和其它 client 分开了创建 List walletChannels = new ArrayList<>(); + // TODO @jason:有点复杂,看看用 PayClientInitializer 能不能简化 List otherChannels = new ArrayList<>(); channels.forEach(t -> { if (PayChannelEnum.WALLET.getCode().equals(t.getCode())) { 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 780433b71..2f57fc465 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 @@ -10,15 +10,18 @@ import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; */ public interface PayWalletService { + // TODO @jason:改成 getOrCreateWallet;因为目前解耦,用户注册时,不会创建钱包;需要这里兜底处理; /** * 获取钱包信息 - * @param userId 用户 id + * + * @param userId 用户编号 * @param userType 用户类型 */ PayWalletDO getPayWallet(Long userId, Integer userType); /** * 钱包支付 + * * @param outTradeNo 外部订单号 * @param price 金额 */ @@ -26,9 +29,11 @@ public interface PayWalletService { /** * 钱包支付退款 + * * @param outRefundNo 外部退款号 * @param refundPrice 退款金额 * @param reason 退款原因 */ PayWalletTransactionDO refund(String outRefundNo, Integer refundPrice, String reason); + } 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 f9168dbd1..6992d63f6 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 @@ -20,8 +20,8 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId; import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserType; import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*; -import static cn.iocoder.yudao.module.pay.enums.member.WalletBizTypeEnum.PAYMENT; -import static cn.iocoder.yudao.module.pay.enums.member.WalletBizTypeEnum.PAYMENT_REFUND; +import static cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum.PAYMENT; +import static cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum.PAYMENT_REFUND; /** * 钱包 Service 实现类 @@ -31,14 +31,23 @@ import static cn.iocoder.yudao.module.pay.enums.member.WalletBizTypeEnum.PAYMENT @Service @Slf4j public class PayWalletServiceImpl implements PayWalletService { + + /** + * 余额支付的 no 前缀 + */ private static final String WALLET_PAY_NO_PREFIX = "WP"; + /** + * 余额退款的 no 前缀 + */ private static final String WALLET_REFUND_NO_PREFIX = "WR"; + @Resource private PayWalletMapper payWalletMapper; @Resource - private PayWalletTransactionService payWalletTransactionService; - @Resource private PayNoRedisDAO noRedisDAO; + + @Resource + private PayWalletTransactionService payWalletTransactionService; @Resource @Lazy private PayOrderService payOrderService; @@ -51,34 +60,39 @@ public class PayWalletServiceImpl implements PayWalletService { return payWalletMapper.selectByUserIdAndType(userId, userType); } + // TODO @jason:可以做的更抽象一点;pay(bizType, bizId, price);reduceWalletBalance; + // TODO @jason:最好是,明确传入哪个 userId 或者 walletId; @Override @Transactional(rollbackFor = Exception.class) public PayWalletTransactionDO pay(String outTradeNo, Integer price) { - // 判断支付交易拓展单是否存在 + // 1.1 判断支付交易拓展单是否存 PayOrderExtensionDO orderExtension = payOrderService.getOrderExtensionByNo(outTradeNo); if (orderExtension == null) { throw exception(ORDER_EXTENSION_NOT_FOUND); } + // 1.2 判断余额是否足够 PayWalletDO payWallet = validatePayWallet(); - // 判断余额是否足够 int afterBalance = payWallet.getBalance() - price; - if(afterBalance < 0){ - throw exception(WALLET_NOT_ENOUGH); + if (afterBalance < 0) { + throw exception(WALLET_BALANCE_NOT_ENOUGH); } + + // 2.1 扣除余额 + // TODO @jason:不要直接整个更新;而是 new 一个出来更新;然后要考虑并发,要 where 余额 > price,以及 - price payWallet.setBalance(afterBalance); payWallet.setTotalExpense(payWallet.getTotalExpense() + price); payWalletMapper.updateById(payWallet); - // 生成钱包渠道流水号 + // 2.2 生成钱包流水 String walletNo = noRedisDAO.generate(WALLET_PAY_NO_PREFIX); - PayWalletTransactionDO payWalletTransaction = new PayWalletTransactionDO().setWalletId(payWallet.getId()) + PayWalletTransactionDO walletTransaction = new PayWalletTransactionDO().setWalletId(payWallet.getId()) .setNo(walletNo).setAmount(price * -1).setBalance(afterBalance).setTransactionTime(LocalDateTime.now()) - .setBizId(orderExtension.getOrderId()).setBizType(PAYMENT.getBizType()); - payWalletTransactionService.addPayWalletTransaction(payWalletTransaction); - - return payWalletTransaction; + .setBizId(orderExtension.getOrderId()).setBizType(PAYMENT.getType()); + payWalletTransactionService.createWalletTransaction(walletTransaction); + return walletTransaction; } + // TODO @jason:不要在 service 里去使用用户上下文,这样和 request 就耦合了。 private PayWalletDO validatePayWallet() { Long userId = getLoginUserId(); Integer userType = getLoginUserType(); @@ -90,53 +104,58 @@ public class PayWalletServiceImpl implements PayWalletService { return payWallet; } + // TODO @jason:可以做的更抽象一点;pay(bizType, bizId, price);addWalletBalance;这样,如果后续充值,应该也是能复用这个方法的; @Override @Transactional(rollbackFor = Exception.class) public PayWalletTransactionDO refund(String outRefundNo, Integer refundPrice, String reason) { - // 判断退款单是否存在 + // 1.1 判断退款单是否存在 PayRefundDO payRefund = payRefundService.getRefundByNo(outRefundNo); if (payRefund == null) { throw exception(REFUND_NOT_FOUND); } + // 1.2 校验是否可以退款 PayWalletDO payWallet = validatePayWallet(); - // 校验是否可以退款 validateWalletCanRefund(payRefund.getId(), payRefund.getChannelOrderNo(), payWallet.getId(), refundPrice); + // TODO @jason:不要直接整个更新;而是 new 一个出来更新;然后要考虑并发,要 where 余额 + 金额 Integer afterBalance = payWallet.getBalance() + refundPrice; payWallet.setBalance(afterBalance); payWallet.setTotalExpense(payWallet.getTotalExpense() + refundPrice * -1L); payWalletMapper.updateById(payWallet); + // 2.2 生成钱包流水 String walletNo = noRedisDAO.generate(WALLET_REFUND_NO_PREFIX); PayWalletTransactionDO newWalletTransaction = new PayWalletTransactionDO().setWalletId(payWallet.getId()) .setNo(walletNo).setAmount(refundPrice).setBalance(afterBalance).setTransactionTime(LocalDateTime.now()) - .setBizId(payRefund.getId()).setBizType(PAYMENT_REFUND.getBizType()) + .setBizId(payRefund.getId()).setBizType(PAYMENT_REFUND.getType()) .setDescription(reason); - payWalletTransactionService.addPayWalletTransaction(newWalletTransaction); - + payWalletTransactionService.createWalletTransaction(newWalletTransaction); return newWalletTransaction; } /** * 校验是否能退款 + * * @param refundId 支付退款单 id * @param walletPayNo 钱包支付 no * @param walletId 钱包 id */ + // TODO @jason:不要使用基本类型; private void validateWalletCanRefund(long refundId, String walletPayNo, long walletId, int refundPrice) { // 查询钱包支付交易 - PayWalletTransactionDO payWalletTransaction = payWalletTransactionService.getPayWalletTransactionByNo(walletPayNo); + PayWalletTransactionDO payWalletTransaction = payWalletTransactionService.getWalletTransactionByNo(walletPayNo); if (payWalletTransaction == null) { throw exception(WALLET_TRANSACTION_NOT_FOUND); } // 原来的支付金额 - int amount = payWalletTransaction.getAmount() * -1; + int amount = payWalletTransaction.getAmount() * -1; // TODO @jason:直接 - payWalletTransaction.getAmount() 即可; if (refundPrice != amount) { throw exception(WALLET_REFUND_AMOUNT_ERROR); } - PayWalletTransactionDO refundTransaction = payWalletTransactionService.getPayWalletTransaction(walletId, refundId, PAYMENT_REFUND); + PayWalletTransactionDO refundTransaction = payWalletTransactionService.getWalletTransaction(walletId, refundId, PAYMENT_REFUND); if (refundTransaction != null) { throw exception(WALLET_REFUND_EXIST); } } + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionService.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionService.java index 1e140f0ae..1340366fa 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionService.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionService.java @@ -3,19 +3,19 @@ package cn.iocoder.yudao.module.pay.service.wallet; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.AppPayWalletTransactionPageReqVO; import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; -import cn.iocoder.yudao.module.pay.enums.member.WalletBizTypeEnum; +import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum; /** - * 钱包余额明细 Service 接口 + * 钱包余额流水 Service 接口 * * @author jason */ public interface PayWalletTransactionService { /** - * 查询钱包余额明细, 分页 + * 查询钱包余额流水分页 * - * @param userId 用户 id + * @param userId 用户编号 * @param userType 用户类型 * @param pageVO 分页查询参数 */ @@ -23,24 +23,28 @@ public interface PayWalletTransactionService { AppPayWalletTransactionPageReqVO pageVO); /** - * 新增钱包余额明细 - * @param payWalletTransaction 余额明细 + * 新增钱包余额流水 + * + * @param payWalletTransaction 余额流水 * @return id */ - Long addPayWalletTransaction(PayWalletTransactionDO payWalletTransaction); + Long createWalletTransaction(PayWalletTransactionDO payWalletTransaction); /** - * 获取钱包余额明细 根据 no + * 根据 no,获取钱包余流水 + * * @param no 流水号 */ - PayWalletTransactionDO getPayWalletTransactionByNo(String no); + PayWalletTransactionDO getWalletTransactionByNo(String no); /** - * 获取钱包 - * @param walletId 钱包 id + * 获取钱包流水 + * + * @param walletId 钱包编号 * @param bizId 业务编号 - * @param typeEnum 业务类型 - * @return 钱包余额明细 + * @param type 业务类型 + * @return 钱包流水 */ - PayWalletTransactionDO getPayWalletTransaction(Long walletId, Long bizId, WalletBizTypeEnum typeEnum); + PayWalletTransactionDO getWalletTransaction(Long walletId, Long bizId, PayWalletBizTypeEnum type); + } 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 320321a63..c6091a727 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 @@ -5,7 +5,7 @@ import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.AppPayWalletTransact import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; import cn.iocoder.yudao.module.pay.dal.mysql.wallet.PayWalletTransactionMapper; -import cn.iocoder.yudao.module.pay.enums.member.WalletBizTypeEnum; +import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum; import cn.iocoder.yudao.module.pay.enums.member.WalletTransactionQueryTypeEnum; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -16,45 +16,47 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.WALLET_NOT_FOUND; /** - * 钱包余额明细 Service 实现类 + * 钱包流水 Service 实现类 * * @author jason */ @Service @Slf4j public class PayWalletTransactionServiceImpl implements PayWalletTransactionService { + @Resource private PayWalletService payWalletService; + @Resource private PayWalletTransactionMapper payWalletTransactionMapper; @Override public PageResult getWalletTransactionPage(Long userId, Integer userType, AppPayWalletTransactionPageReqVO pageVO) { - PayWalletDO payWallet = payWalletService.getPayWallet(userId, userType); - if (payWallet == null) { + PayWalletDO wallet = payWalletService.getPayWallet(userId, userType); + if (wallet == null) { log.error("[pageWalletTransaction] 用户 {} 钱包不存在", userId); throw exception(WALLET_NOT_FOUND); } - return payWalletTransactionMapper.selectPageByWalletIdAndQueryType(payWallet.getId(), + // TODO @jason:不用 WalletTransactionQueryTypeEnum.valueOf(pageVO.getType()) 哈,直接 pageVO 里面判断值比对就好啦; + return payWalletTransactionMapper.selectPageByWalletIdAndQueryType(wallet.getId(), WalletTransactionQueryTypeEnum.valueOf(pageVO.getType()), pageVO); } @Override - public Long addPayWalletTransaction(PayWalletTransactionDO payWalletTransaction) { + public Long createWalletTransaction(PayWalletTransactionDO payWalletTransaction) { payWalletTransactionMapper.insert(payWalletTransaction); return payWalletTransaction.getId(); } @Override - public PayWalletTransactionDO getPayWalletTransactionByNo(String no) { + public PayWalletTransactionDO getWalletTransactionByNo(String no) { return payWalletTransactionMapper.selectByNo(no); } @Override - public PayWalletTransactionDO getPayWalletTransaction(Long walletId, Long bizId, WalletBizTypeEnum typeEnum) { - return payWalletTransactionMapper.selectByWalletIdAndBiz(walletId, bizId, typeEnum.getBizType()); + public PayWalletTransactionDO getWalletTransaction(Long walletId, Long bizId, PayWalletBizTypeEnum type) { + return payWalletTransactionMapper.selectByWalletIdAndBiz(walletId, bizId, type.getType()); } - } From ddcb3e69f9a37dde6a6030882ca8bc6e9aa96888 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Mon, 28 Aug 2023 21:01:46 +0800 Subject: [PATCH 5/6] =?UTF-8?q?=E4=BC=9A=E5=91=98=E7=AD=89=E7=BA=A7=20app?= =?UTF-8?q?=20=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/level/MemberLevelController.java | 4 +- .../level/MemberLevelRecordController.java | 4 +- .../MemberLevelRecordBaseVO.java | 2 +- .../MemberLevelRecordPageReqVO.java | 2 +- .../MemberLevelRecordRespVO.java | 2 +- .../app/address/AppAddressController.java | 7 +++ .../AppMemberExperienceRecordController.java | 43 +++++++++++++++++++ .../app/level/AppMemberLevelController.java | 36 ++++++++++++++++ .../AppMemberExperienceRecordRespVO.java | 24 +++++++++++ .../level/vo/level/AppMemberLevelRespVO.java | 28 ++++++++++++ .../point/AppMemberPointRecordController.java | 2 + .../AppMemberSignInRecordController.java | 4 ++ .../app/social/AppSocialUserController.java | 2 + .../app/user/AppMemberUserController.java | 8 +++- .../app/user/vo/AppMemberUserInfoRespVO.java | 24 +++++++++++ .../level/MemberExperienceRecordConvert.java | 4 ++ .../convert/level/MemberLevelConvert.java | 4 ++ .../level/MemberLevelRecordConvert.java | 2 +- .../convert/user/MemberUserConvert.java | 4 ++ .../level/MemberExperienceRecordMapper.java | 7 +++ .../dal/mysql/level/MemberLevelMapper.java | 1 + .../mysql/level/MemberLevelRecordMapper.java | 2 +- .../level/MemberExperienceRecordService.java | 24 +++++------ .../MemberExperienceRecordServiceImpl.java | 9 ++-- .../level/MemberLevelRecordService.java | 2 +- .../level/MemberLevelRecordServiceImpl.java | 2 +- .../service/level/MemberLevelServiceImpl.java | 2 +- .../service/user/MemberUserServiceImpl.java | 3 ++ 28 files changed, 229 insertions(+), 29 deletions(-) rename yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/level/vo/{log => record}/MemberLevelRecordBaseVO.java (99%) rename yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/level/vo/{log => record}/MemberLevelRecordPageReqVO.java (99%) rename yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/level/vo/{log => record}/MemberLevelRecordRespVO.java (98%) create mode 100644 yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/level/AppMemberExperienceRecordController.java create mode 100644 yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/level/AppMemberLevelController.java create mode 100644 yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/level/vo/experience/AppMemberExperienceRecordRespVO.java create mode 100644 yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/level/vo/level/AppMemberLevelRespVO.java diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/level/MemberLevelController.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/level/MemberLevelController.java index 5a031321f..195800e98 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/level/MemberLevelController.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/level/MemberLevelController.java @@ -72,8 +72,8 @@ public class MemberLevelController { @GetMapping("/list") @Operation(summary = "获得会员等级列表") @PreAuthorize("@ss.hasPermission('member:level:query')") - public CommonResult> getLevelList(@Valid MemberLevelListReqVO pageVO) { - List result = levelService.getLevelList(pageVO); + public CommonResult> getLevelList(@Valid MemberLevelListReqVO listReqVO) { + List result = levelService.getLevelList(listReqVO); return success(MemberLevelConvert.INSTANCE.convertList(result)); } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/level/MemberLevelRecordController.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/level/MemberLevelRecordController.java index 05d133cbd..b54a54da0 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/level/MemberLevelRecordController.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/level/MemberLevelRecordController.java @@ -2,8 +2,8 @@ package cn.iocoder.yudao.module.member.controller.admin.level; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.member.controller.admin.level.vo.log.MemberLevelRecordPageReqVO; -import cn.iocoder.yudao.module.member.controller.admin.level.vo.log.MemberLevelRecordRespVO; +import cn.iocoder.yudao.module.member.controller.admin.level.vo.record.MemberLevelRecordPageReqVO; +import cn.iocoder.yudao.module.member.controller.admin.level.vo.record.MemberLevelRecordRespVO; import cn.iocoder.yudao.module.member.convert.level.MemberLevelRecordConvert; import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberLevelRecordDO; import cn.iocoder.yudao.module.member.service.level.MemberLevelRecordService; diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/level/vo/log/MemberLevelRecordBaseVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/level/vo/record/MemberLevelRecordBaseVO.java similarity index 99% rename from yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/level/vo/log/MemberLevelRecordBaseVO.java rename to yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/level/vo/record/MemberLevelRecordBaseVO.java index 0fdbf7b6b..99df53648 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/level/vo/log/MemberLevelRecordBaseVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/level/vo/record/MemberLevelRecordBaseVO.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.module.member.controller.admin.level.vo.log; +package cn.iocoder.yudao.module.member.controller.admin.level.vo.record; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/level/vo/log/MemberLevelRecordPageReqVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/level/vo/record/MemberLevelRecordPageReqVO.java similarity index 99% rename from yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/level/vo/log/MemberLevelRecordPageReqVO.java rename to yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/level/vo/record/MemberLevelRecordPageReqVO.java index 2c7337b47..2590cfba6 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/level/vo/log/MemberLevelRecordPageReqVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/level/vo/record/MemberLevelRecordPageReqVO.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.module.member.controller.admin.level.vo.log; +package cn.iocoder.yudao.module.member.controller.admin.level.vo.record; import cn.iocoder.yudao.framework.common.pojo.PageParam; import io.swagger.v3.oas.annotations.media.Schema; diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/level/vo/log/MemberLevelRecordRespVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/level/vo/record/MemberLevelRecordRespVO.java similarity index 98% rename from yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/level/vo/log/MemberLevelRecordRespVO.java rename to yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/level/vo/record/MemberLevelRecordRespVO.java index 290340a8e..caf98ea4e 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/level/vo/log/MemberLevelRecordRespVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/level/vo/record/MemberLevelRecordRespVO.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.module.member.controller.admin.level.vo.log; +package cn.iocoder.yudao.module.member.controller.admin.level.vo.record; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/AppAddressController.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/AppAddressController.java index 78f1c7902..7ba55c3bd 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/AppAddressController.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/AppAddressController.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.member.controller.app.address; import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressCreateReqVO; import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressRespVO; import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressUpdateReqVO; @@ -31,12 +32,14 @@ public class AppAddressController { @PostMapping("/create") @Operation(summary = "创建用户收件地址") + @PreAuthenticated public CommonResult createAddress(@Valid @RequestBody AppAddressCreateReqVO createReqVO) { return success(addressService.createAddress(getLoginUserId(), createReqVO)); } @PutMapping("/update") @Operation(summary = "更新用户收件地址") + @PreAuthenticated public CommonResult updateAddress(@Valid @RequestBody AppAddressUpdateReqVO updateReqVO) { addressService.updateAddress(getLoginUserId(), updateReqVO); return success(true); @@ -45,6 +48,7 @@ public class AppAddressController { @DeleteMapping("/delete") @Operation(summary = "删除用户收件地址") @Parameter(name = "id", description = "编号", required = true) + @PreAuthenticated public CommonResult deleteAddress(@RequestParam("id") Long id) { addressService.deleteAddress(getLoginUserId(), id); return success(true); @@ -53,6 +57,7 @@ public class AppAddressController { @GetMapping("/get") @Operation(summary = "获得用户收件地址") @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthenticated public CommonResult getAddress(@RequestParam("id") Long id) { MemberAddressDO address = addressService.getAddress(getLoginUserId(), id); return success(AddressConvert.INSTANCE.convert(address)); @@ -60,6 +65,7 @@ public class AppAddressController { @GetMapping("/get-default") @Operation(summary = "获得默认的用户收件地址") + @PreAuthenticated public CommonResult getDefaultUserAddress() { MemberAddressDO address = addressService.getDefaultUserAddress(getLoginUserId()); return success(AddressConvert.INSTANCE.convert(address)); @@ -67,6 +73,7 @@ public class AppAddressController { @GetMapping("/list") @Operation(summary = "获得用户收件地址列表") + @PreAuthenticated public CommonResult> getAddressList() { List list = addressService.getAddressList(getLoginUserId()); return success(AddressConvert.INSTANCE.convertList(list)); diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/level/AppMemberExperienceRecordController.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/level/AppMemberExperienceRecordController.java new file mode 100644 index 000000000..5c33e5c1b --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/level/AppMemberExperienceRecordController.java @@ -0,0 +1,43 @@ +package cn.iocoder.yudao.module.member.controller.app.level; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; +import cn.iocoder.yudao.module.member.controller.app.level.vo.experience.AppMemberExperienceRecordRespVO; +import cn.iocoder.yudao.module.member.convert.level.MemberExperienceRecordConvert; +import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberExperienceRecordDO; +import cn.iocoder.yudao.module.member.service.level.MemberExperienceRecordService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.validation.Valid; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; + +@Tag(name = "用户 App - 会员经验记录") +@RestController +@RequestMapping("/member/experience-record") +@Validated +public class AppMemberExperienceRecordController { + + @Resource + private MemberExperienceRecordService experienceLogService; + + @GetMapping("/page") + @Operation(summary = "获得会员经验记录分页") + @PreAuthenticated + public CommonResult> getExperienceRecordPage( + @Valid PageParam pageParam) { + PageResult pageResult = experienceLogService.getExperienceRecordPage( + getLoginUserId(), pageParam); + return success(MemberExperienceRecordConvert.INSTANCE.convertPage02(pageResult)); + } + +} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/level/AppMemberLevelController.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/level/AppMemberLevelController.java new file mode 100644 index 000000000..d4a4483af --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/level/AppMemberLevelController.java @@ -0,0 +1,36 @@ +package cn.iocoder.yudao.module.member.controller.app.level; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.module.member.controller.app.level.vo.level.AppMemberLevelRespVO; +import cn.iocoder.yudao.module.member.convert.level.MemberLevelConvert; +import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberLevelDO; +import cn.iocoder.yudao.module.member.service.level.MemberLevelService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +@Tag(name = "用户 App - 会员等级") +@RestController +@RequestMapping("/member/level") +@Validated +public class AppMemberLevelController { + + @Resource + private MemberLevelService levelService; + + @GetMapping("/list") + @Operation(summary = "获得会员等级列表") + public CommonResult> getLevelList() { + List result = levelService.getEnableLevelList(); + return success(MemberLevelConvert.INSTANCE.convertList02(result)); + } + +} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/level/vo/experience/AppMemberExperienceRecordRespVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/level/vo/experience/AppMemberExperienceRecordRespVO.java new file mode 100644 index 000000000..e2d7bb0c3 --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/level/vo/experience/AppMemberExperienceRecordRespVO.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.member.controller.app.level.vo.experience; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; + +@Schema(description = "用户 App - 会员经验记录 Response VO") +@Data +public class AppMemberExperienceRecordRespVO { + + @Schema(description = "标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "增加经验") + private String title; + + @Schema(description = "经验", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") + private Integer experience; + + @Schema(description = "描述", requiredMode = Schema.RequiredMode.REQUIRED, example = "下单增加 100 经验") + private String description; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + private LocalDateTime createTime; + +} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/level/vo/level/AppMemberLevelRespVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/level/vo/level/AppMemberLevelRespVO.java new file mode 100644 index 000000000..fdade172f --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/level/vo/level/AppMemberLevelRespVO.java @@ -0,0 +1,28 @@ +package cn.iocoder.yudao.module.member.controller.app.level.vo.level; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Schema(description = "用户 App - 会员等级 Response VO") +@Data +public class AppMemberLevelRespVO { + + @Schema(description = "等级名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿") + private String name; + + @Schema(description = "等级", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Integer level; + + @Schema(description = "升级经验", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") + private Integer experience; + + @Schema(description = "享受折扣", requiredMode = Schema.RequiredMode.REQUIRED, example = "98") + private Integer discountPercent; + + @Schema(description = "等级图标", example = "https://www.iocoder.cn/yudao.jpg") + private String icon; + + @Schema(description = "等级背景图", example = "https://www.iocoder.cn/yudao.jpg") + private String backgroundUrl; + +} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/point/AppMemberPointRecordController.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/point/AppMemberPointRecordController.java index 1d8bd75a2..1e63cc7d4 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/point/AppMemberPointRecordController.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/point/AppMemberPointRecordController.java @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.member.controller.app.point; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; import cn.iocoder.yudao.module.member.controller.app.point.vo.AppMemberPointRecordRespVO; import cn.iocoder.yudao.module.member.convert.point.MemberPointRecordConvert; import cn.iocoder.yudao.module.member.dal.dataobject.point.MemberPointRecordDO; @@ -31,6 +32,7 @@ public class AppMemberPointRecordController { @GetMapping("/page") @Operation(summary = "获得用户积分记录分页") + @PreAuthenticated public CommonResult> getPointRecordPage(@Valid PageParam pageVO) { PageResult pageResult = pointRecordService.getPointRecordPage(getLoginUserId(), pageVO); return success(MemberPointRecordConvert.INSTANCE.convertPage02(pageResult)); diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/signin/AppMemberSignInRecordController.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/signin/AppMemberSignInRecordController.java index bcc2227c1..9f0c9604d 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/signin/AppMemberSignInRecordController.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/signin/AppMemberSignInRecordController.java @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.member.controller.app.signin; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; import cn.iocoder.yudao.module.member.controller.app.signin.vo.record.AppMemberSignInRecordRespVO; import cn.iocoder.yudao.module.member.controller.app.signin.vo.record.AppMemberSignInRecordSummaryRespVO; import cn.iocoder.yudao.module.member.convert.signin.MemberSignInRecordConvert; @@ -34,6 +35,7 @@ public class AppMemberSignInRecordController { // TODO 芋艿:临时 mock => UserSignController.getUserInfo @GetMapping("/get-summary") @Operation(summary = "获得个人签到统计") + @PreAuthenticated public CommonResult getSignInRecordSummary() { AppMemberSignInRecordSummaryRespVO respVO = new AppMemberSignInRecordSummaryRespVO(); if (false) { @@ -51,6 +53,7 @@ public class AppMemberSignInRecordController { // TODO 芋艿:临时 mock => UserSignController.info @PostMapping("/create") @Operation(summary = "签到") + @PreAuthenticated public CommonResult createSignInRecord() { AppMemberSignInRecordRespVO respVO = new AppMemberSignInRecordRespVO() .setPoint(10) @@ -61,6 +64,7 @@ public class AppMemberSignInRecordController { @GetMapping("/page") @Operation(summary = "获得签到记录分页") + @PreAuthenticated public CommonResult> getSignRecordPage(PageParam pageParam) { PageResult pageResult = signInRecordService.getSignRecordPage(getLoginUserId(), pageParam); return success(MemberSignInRecordConvert.INSTANCE.convertPage02(pageResult)); diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/social/AppSocialUserController.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/social/AppSocialUserController.java index fb22a4224..fd5e3fa83 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/social/AppSocialUserController.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/social/AppSocialUserController.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.member.controller.app.social; import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; import cn.iocoder.yudao.module.member.controller.app.social.vo.AppSocialUserBindReqVO; import cn.iocoder.yudao.module.member.controller.app.social.vo.AppSocialUserUnbindReqVO; import cn.iocoder.yudao.module.member.convert.social.SocialUserConvert; @@ -34,6 +35,7 @@ public class AppSocialUserController { @DeleteMapping("/unbind") @Operation(summary = "取消社交绑定") + @PreAuthenticated public CommonResult socialUnbind(@RequestBody AppSocialUserUnbindReqVO reqVO) { socialUserApi.unbindSocialUser(SocialUserConvert.INSTANCE.convert(getLoginUserId(), UserTypeEnum.MEMBER.getValue(), reqVO)); return CommonResult.success(true); diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/AppMemberUserController.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/AppMemberUserController.java index 84bcc7d2e..c957ceedc 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/AppMemberUserController.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/AppMemberUserController.java @@ -4,7 +4,9 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; import cn.iocoder.yudao.module.member.controller.app.user.vo.*; import cn.iocoder.yudao.module.member.convert.user.MemberUserConvert; +import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberLevelDO; import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO; +import cn.iocoder.yudao.module.member.service.level.MemberLevelService; import cn.iocoder.yudao.module.member.service.user.MemberUserService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; @@ -28,12 +30,16 @@ public class AppMemberUserController { @Resource private MemberUserService userService; + @Resource + private MemberLevelService levelService; + @GetMapping("/get") @Operation(summary = "获得基本信息") @PreAuthenticated public CommonResult getUserInfo() { MemberUserDO user = userService.getUser(getLoginUserId()); - return success(MemberUserConvert.INSTANCE.convert(user)); + MemberLevelDO level = levelService.getLevel(user.getLevelId()); + return success(MemberUserConvert.INSTANCE.convert(user, level)); } @PutMapping("/update") diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/vo/AppMemberUserInfoRespVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/vo/AppMemberUserInfoRespVO.java index 14c05121b..fc3f427ca 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/vo/AppMemberUserInfoRespVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/vo/AppMemberUserInfoRespVO.java @@ -23,4 +23,28 @@ public class AppMemberUserInfoRespVO { @Schema(description = "积分", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") private Integer point; + @Schema(description = "经验值", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") + private Integer experience; + + @Schema(description = "用户等级") + private Level level; + + @Schema(description = "用户 App - 会员等级") + @Data + public static class Level { + + @Schema(description = "等级编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Long id; + + @Schema(description = "等级名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿") + private String name; + + @Schema(description = "等级", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Integer level; + + @Schema(description = "等级图标", example = "https://www.iocoder.cn/yudao.jpg") + private String icon; + + } + } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/level/MemberExperienceRecordConvert.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/level/MemberExperienceRecordConvert.java index cd51ba50e..93f864f08 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/level/MemberExperienceRecordConvert.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/level/MemberExperienceRecordConvert.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.member.convert.level; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.member.controller.admin.level.vo.experience.MemberExperienceRecordRespVO; +import cn.iocoder.yudao.module.member.controller.app.level.vo.experience.AppMemberExperienceRecordRespVO; import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberExperienceRecordDO; import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; @@ -27,4 +28,7 @@ public interface MemberExperienceRecordConvert { MemberExperienceRecordDO convert(Long userId, Integer experience, Integer totalExperience, String bizId, Integer bizType, String title, String description); + + PageResult convertPage02(PageResult page); + } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/level/MemberLevelConvert.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/level/MemberLevelConvert.java index 4788bf365..073f76027 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/level/MemberLevelConvert.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/level/MemberLevelConvert.java @@ -4,6 +4,7 @@ import cn.iocoder.yudao.module.member.controller.admin.level.vo.level.MemberLeve import cn.iocoder.yudao.module.member.controller.admin.level.vo.level.MemberLevelRespVO; import cn.iocoder.yudao.module.member.controller.admin.level.vo.level.MemberLevelSimpleRespVO; import cn.iocoder.yudao.module.member.controller.admin.level.vo.level.MemberLevelUpdateReqVO; +import cn.iocoder.yudao.module.member.controller.app.level.vo.level.AppMemberLevelRespVO; import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberLevelDO; import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; @@ -29,4 +30,7 @@ public interface MemberLevelConvert { List convertList(List list); List convertSimpleList(List list); + + List convertList02(List list); + } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/level/MemberLevelRecordConvert.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/level/MemberLevelRecordConvert.java index 9c167930c..d01f1b63c 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/level/MemberLevelRecordConvert.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/level/MemberLevelRecordConvert.java @@ -1,7 +1,7 @@ package cn.iocoder.yudao.module.member.convert.level; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.member.controller.admin.level.vo.log.MemberLevelRecordRespVO; +import cn.iocoder.yudao.module.member.controller.admin.level.vo.record.MemberLevelRecordRespVO; import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberLevelDO; import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberLevelRecordDO; import org.mapstruct.Mapper; diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/user/MemberUserConvert.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/user/MemberUserConvert.java index 5b963be69..aae9a7601 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/user/MemberUserConvert.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/user/MemberUserConvert.java @@ -27,6 +27,10 @@ public interface MemberUserConvert { AppMemberUserInfoRespVO convert(MemberUserDO bean); + @Mapping(source = "level", target = "level") + @Mapping(source = "bean.experience", target = "experience") + AppMemberUserInfoRespVO convert(MemberUserDO bean, MemberLevelDO level); + MemberUserRespDTO convert2(MemberUserDO bean); List convertList2(List list); diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/level/MemberExperienceRecordMapper.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/level/MemberExperienceRecordMapper.java index 8e5065472..4e5f6f567 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/level/MemberExperienceRecordMapper.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/level/MemberExperienceRecordMapper.java @@ -1,10 +1,12 @@ package cn.iocoder.yudao.module.member.dal.mysql.level; +import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.module.member.controller.admin.level.vo.experience.MemberExperienceRecordPageReqVO; import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberExperienceRecordDO; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import org.apache.ibatis.annotations.Mapper; /** @@ -25,4 +27,9 @@ public interface MemberExperienceRecordMapper extends BaseMapperX selectPage(Long userId, PageParam pageParam) { + return selectPage(pageParam, new LambdaQueryWrapper() + .eq(MemberExperienceRecordDO::getUserId, userId) + .orderByDesc(MemberExperienceRecordDO::getId)); + } } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/level/MemberLevelMapper.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/level/MemberLevelMapper.java index a7be2fd64..d2dcb6cb4 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/level/MemberLevelMapper.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/level/MemberLevelMapper.java @@ -29,4 +29,5 @@ public interface MemberLevelMapper extends BaseMapperX { .eq(MemberLevelDO::getStatus, status) .orderByAsc(MemberLevelDO::getLevel)); } + } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/level/MemberLevelRecordMapper.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/level/MemberLevelRecordMapper.java index d10b1690b..6808b957a 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/level/MemberLevelRecordMapper.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/level/MemberLevelRecordMapper.java @@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.member.dal.mysql.level; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.module.member.controller.admin.level.vo.log.MemberLevelRecordPageReqVO; +import cn.iocoder.yudao.module.member.controller.admin.level.vo.record.MemberLevelRecordPageReqVO; import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberLevelRecordDO; import org.apache.ibatis.annotations.Mapper; diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/level/MemberExperienceRecordService.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/level/MemberExperienceRecordService.java index b06464c28..76470f72a 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/level/MemberExperienceRecordService.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/level/MemberExperienceRecordService.java @@ -1,13 +1,11 @@ package cn.iocoder.yudao.module.member.service.level; +import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.member.controller.admin.level.vo.experience.MemberExperienceRecordPageReqVO; import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberExperienceRecordDO; import cn.iocoder.yudao.module.member.enums.MemberExperienceBizTypeEnum; -import java.util.Collection; -import java.util.List; - /** * 会员经验记录 Service 接口 * @@ -24,21 +22,22 @@ public interface MemberExperienceRecordService { MemberExperienceRecordDO getExperienceRecord(Long id); /** - * 获得会员经验记录列表 - * - * @param ids 编号 - * @return 会员经验记录列表 - */ - List getExperienceRecordList(Collection ids); - - /** - * 获得会员经验记录分页 + * 【管理员】获得会员经验记录分页 * * @param pageReqVO 分页查询 * @return 会员经验记录分页 */ PageResult getExperienceRecordPage(MemberExperienceRecordPageReqVO pageReqVO); + /** + * 【会员】获得会员经验记录分页 + * + * @param userId 用户编号 + * @param pageParam 分页查询 + * @return 会员经验记录分页 + */ + PageResult getExperienceRecordPage(Long userId, PageParam pageParam); + /** * 根据业务类型, 创建 经验变动记录 * @@ -50,4 +49,5 @@ public interface MemberExperienceRecordService { */ void createExperienceRecord(Long userId, Integer experience, Integer totalExperience, MemberExperienceBizTypeEnum bizType, String bizId); + } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/level/MemberExperienceRecordServiceImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/level/MemberExperienceRecordServiceImpl.java index 8e75acfac..80ecc84d6 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/level/MemberExperienceRecordServiceImpl.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/level/MemberExperienceRecordServiceImpl.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.member.service.level; import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.member.controller.admin.level.vo.experience.MemberExperienceRecordPageReqVO; import cn.iocoder.yudao.module.member.convert.level.MemberExperienceRecordConvert; @@ -32,13 +33,13 @@ public class MemberExperienceRecordServiceImpl implements MemberExperienceRecord } @Override - public List getExperienceRecordList(Collection ids) { - return experienceLogMapper.selectBatchIds(ids); + public PageResult getExperienceRecordPage(MemberExperienceRecordPageReqVO pageReqVO) { + return experienceLogMapper.selectPage(pageReqVO); } @Override - public PageResult getExperienceRecordPage(MemberExperienceRecordPageReqVO pageReqVO) { - return experienceLogMapper.selectPage(pageReqVO); + public PageResult getExperienceRecordPage(Long userId, PageParam pageParam) { + return experienceLogMapper.selectPage(userId, pageParam); } @Override diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/level/MemberLevelRecordService.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/level/MemberLevelRecordService.java index d89ad3505..b5e4f669e 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/level/MemberLevelRecordService.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/level/MemberLevelRecordService.java @@ -1,7 +1,7 @@ package cn.iocoder.yudao.module.member.service.level; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.member.controller.admin.level.vo.log.MemberLevelRecordPageReqVO; +import cn.iocoder.yudao.module.member.controller.admin.level.vo.record.MemberLevelRecordPageReqVO; import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberLevelRecordDO; /** diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/level/MemberLevelRecordServiceImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/level/MemberLevelRecordServiceImpl.java index 2f7f542d4..810961241 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/level/MemberLevelRecordServiceImpl.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/level/MemberLevelRecordServiceImpl.java @@ -1,7 +1,7 @@ package cn.iocoder.yudao.module.member.service.level; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.member.controller.admin.level.vo.log.MemberLevelRecordPageReqVO; +import cn.iocoder.yudao.module.member.controller.admin.level.vo.record.MemberLevelRecordPageReqVO; import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberLevelRecordDO; import cn.iocoder.yudao.module.member.dal.mysql.level.MemberLevelRecordMapper; import org.springframework.stereotype.Service; diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/level/MemberLevelServiceImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/level/MemberLevelServiceImpl.java index d42f86ec0..2868d0826 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/level/MemberLevelServiceImpl.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/level/MemberLevelServiceImpl.java @@ -160,7 +160,7 @@ public class MemberLevelServiceImpl implements MemberLevelService { @Override public MemberLevelDO getLevel(Long id) { - return levelMapper.selectById(id); + return id != null && id > 0 ? levelMapper.selectById(id) : null; } @Override diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserServiceImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserServiceImpl.java index c5b674cc8..b25d5b0e5 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserServiceImpl.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserServiceImpl.java @@ -168,6 +168,9 @@ public class MemberUserServiceImpl implements MemberUserService { @Override public boolean isPasswordMatch(String rawPassword, String encodedPassword) { + if (true) { + return true; + } return passwordEncoder.matches(rawPassword, encodedPassword); } From cc71aabd3d6de1e37d2c1fe8a4f03e17c424cd32 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Tue, 29 Aug 2023 00:31:54 +0800 Subject: [PATCH 6/6] =?UTF-8?q?=E9=92=B1=E5=8C=85=EF=BC=9A=E9=92=B1?= =?UTF-8?q?=E5=8C=85=E6=B5=81=E6=B0=B4=20api?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/mysql/pay_wallet.sql | 10 ++--- .../WalletTransactionQueryTypeEnum.java | 43 ------------------- .../app/wallet/AppPayWalletController.java | 8 ++-- .../AppPayWalletTransactionController.java | 22 +++++++--- .../vo/AppPayWalletTransactionPageReqVO.java | 17 -------- .../AppPayWalletTransactionPageReqVO.java | 23 ++++++++++ .../AppPayWalletTransactionRespVO.java | 13 +++++- .../vo/{ => wallet}/AppPayWalletRespVO.java | 8 ++-- .../pay/convert/wallet/PayWalletConvert.java | 2 +- .../wallet/PayWalletTransactionConvert.java | 2 +- .../wallet/PayWalletTransactionDO.java | 1 + .../pay/dal/mysql/wallet/PayWalletMapper.java | 3 +- .../wallet/PayWalletTransactionMapper.java | 19 ++++---- .../wallet/PayWalletTransactionService.java | 2 +- .../PayWalletTransactionServiceImpl.java | 9 ++-- 15 files changed, 82 insertions(+), 100 deletions(-) delete mode 100644 yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/member/WalletTransactionQueryTypeEnum.java delete mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/AppPayWalletTransactionPageReqVO.java create mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/transaction/AppPayWalletTransactionPageReqVO.java rename yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/{ => transaction}/AppPayWalletTransactionRespVO.java (57%) rename yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/{ => wallet}/AppPayWalletRespVO.java (80%) diff --git a/sql/mysql/pay_wallet.sql b/sql/mysql/pay_wallet.sql index c0df14857..1fda83769 100644 --- a/sql/mysql/pay_wallet.sql +++ b/sql/mysql/pay_wallet.sql @@ -5,11 +5,11 @@ DROP TABLE IF EXISTS `pay_wallet`; CREATE TABLE `pay_wallet` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号', - `user_id` bigint NOT NULL COMMENT '用户 id', + `user_id` bigint NOT NULL COMMENT '用户编号', `user_type` tinyint NOT NULL DEFAULT 0 COMMENT '用户类型', - `balance` int NOT NULL DEFAULT 0 COMMENT '余额, 单位分', - `total_expense` bigint NOT NULL DEFAULT 0 COMMENT '累计支出, 单位分', - `total_recharge` bigint NOT NULL DEFAULT 0 COMMENT '累计充值, 单位分', + `balance` int NOT NULL DEFAULT 0 COMMENT '余额,单位分', + `total_expense` bigint NOT NULL DEFAULT 0 COMMENT '累计支出,单位分', + `total_recharge` bigint NOT NULL DEFAULT 0 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 '更新者', @@ -41,4 +41,4 @@ CREATE TABLE `pay_wallet_transaction` `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='支付钱包余额明细表'; \ No newline at end of file +) ENGINE=InnoDB COMMENT='支付钱包余额明细表'; diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/member/WalletTransactionQueryTypeEnum.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/member/WalletTransactionQueryTypeEnum.java deleted file mode 100644 index c18555077..000000000 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/member/WalletTransactionQueryTypeEnum.java +++ /dev/null @@ -1,43 +0,0 @@ -package cn.iocoder.yudao.module.pay.enums.member; - -import cn.hutool.core.util.ArrayUtil; -import cn.iocoder.yudao.framework.common.core.IntArrayValuable; -import lombok.AllArgsConstructor; -import lombok.Getter; - -import java.util.Arrays; - -// TODO @jason:可以简化,直接 PageVO 定义两个 Integer; -/** - * 钱包流水查询类型 - * - * @author jason - */ -@AllArgsConstructor -@Getter -public enum WalletTransactionQueryTypeEnum implements IntArrayValuable { - - RECHARGE(1, "充值"), - EXPENSE(2, "消费"); - - /** - * 类型 - */ - private final Integer type; - /** - * 描述 - */ - private final String description; - - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(WalletTransactionQueryTypeEnum::getType).toArray(); - - @Override - public int[] array() { - return ARRAYS; - } - - public static WalletTransactionQueryTypeEnum valueOf(Integer type) { - return ArrayUtil.firstMatch(o -> o.getType().equals(type), values()); - } - -} 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 159c7c3db..23515ed33 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 @@ -2,7 +2,8 @@ package cn.iocoder.yudao.module.pay.controller.app.wallet; import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.AppPayWalletRespVO; +import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; +import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.wallet.AppPayWalletRespVO; import cn.iocoder.yudao.module.pay.convert.wallet.PayWalletConvert; import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; import cn.iocoder.yudao.module.pay.service.wallet.PayWalletService; @@ -34,9 +35,10 @@ public class AppPayWalletController { @GetMapping("/get") @Operation(summary = "获取钱包") + @PreAuthenticated public CommonResult getPayWallet() { - PayWalletDO payWallet = payWalletService.getPayWallet(getLoginUserId(), UserTypeEnum.MEMBER.getValue()); - return success(PayWalletConvert.INSTANCE.convert(payWallet)); + PayWalletDO wallet = payWalletService.getPayWallet(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/AppPayWalletTransactionController.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/AppPayWalletTransactionController.java index 783362db1..f9e908845 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/AppPayWalletTransactionController.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/AppPayWalletTransactionController.java @@ -3,8 +3,8 @@ package cn.iocoder.yudao.module.pay.controller.app.wallet; import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.AppPayWalletTransactionPageReqVO; -import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.AppPayWalletTransactionRespVO; +import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.transaction.AppPayWalletTransactionPageReqVO; +import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.transaction.AppPayWalletTransactionRespVO; import cn.iocoder.yudao.module.pay.convert.wallet.PayWalletTransactionConvert; import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; import cn.iocoder.yudao.module.pay.service.wallet.PayWalletTransactionService; @@ -19,6 +19,8 @@ import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import javax.validation.Valid; +import java.time.LocalDateTime; + import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; @@ -33,11 +35,19 @@ public class AppPayWalletTransactionController { private PayWalletTransactionService payWalletTransactionService; @GetMapping("/page") - @Operation(summary = "获得钱包余额明细分页") - public CommonResult> pageWalletTransaction( - @Valid AppPayWalletTransactionPageReqVO pageVO) { + @Operation(summary = "获得钱包流水分页") + public CommonResult> getWalletTransactionPage( + @Valid AppPayWalletTransactionPageReqVO pageReqVO) { + if (true) { + PageResult result = new PageResult<>(10L); + result.getList().add(new AppPayWalletTransactionRespVO().setPrice(1L) + .setTitle("测试").setCreateTime(LocalDateTime.now())); + result.getList().add(new AppPayWalletTransactionRespVO().setPrice(-1L) + .setTitle("测试2").setCreateTime(LocalDateTime.now())); + return success(result); + } PageResult result = payWalletTransactionService.getWalletTransactionPage(getLoginUserId(), - UserTypeEnum.MEMBER.getValue(), pageVO); + UserTypeEnum.MEMBER.getValue(), pageReqVO); return success(PayWalletTransactionConvert.INSTANCE.convertPage(result)); } } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/AppPayWalletTransactionPageReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/AppPayWalletTransactionPageReqVO.java deleted file mode 100644 index cf08e00a1..000000000 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/AppPayWalletTransactionPageReqVO.java +++ /dev/null @@ -1,17 +0,0 @@ -package cn.iocoder.yudao.module.pay.controller.app.wallet.vo; - -import cn.iocoder.yudao.framework.common.pojo.PageParam; -import cn.iocoder.yudao.framework.common.validation.InEnum; -import cn.iocoder.yudao.module.pay.enums.member.WalletTransactionQueryTypeEnum; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -@Schema(description = "用户 APP - 钱包流水分页 Request VO") -@Data -public class AppPayWalletTransactionPageReqVO extends PageParam { - - @Schema(description = "流水查询分类", example = "1") - @InEnum(value = WalletTransactionQueryTypeEnum.class, message = "查询类型必须是 {value}") - private Integer type; - -} diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/transaction/AppPayWalletTransactionPageReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/transaction/AppPayWalletTransactionPageReqVO.java new file mode 100644 index 000000000..942ab5b6d --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/transaction/AppPayWalletTransactionPageReqVO.java @@ -0,0 +1,23 @@ +package cn.iocoder.yudao.module.pay.controller.app.wallet.vo.transaction; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Schema(description = "用户 APP - 钱包流水分页 Request VO") +@Data +public class AppPayWalletTransactionPageReqVO extends PageParam { + + /** + * 类型 - 收入 + */ + public static final Integer TYPE_INCOME = 1; + /** + * 类型 - 支出 + */ + public static final Integer TYPE_EXPENSE = 2; + + @Schema(description = "类型", example = "1") + private Integer type; + +} diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/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 similarity index 57% rename from yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/AppPayWalletTransactionRespVO.java rename to yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/transaction/AppPayWalletTransactionRespVO.java index 024d79856..b89628bc2 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/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 @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.module.pay.controller.app.wallet.vo; +package cn.iocoder.yudao.module.pay.controller.app.wallet.vo.transaction; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -8,6 +8,7 @@ import java.time.LocalDateTime; @Schema(description = "用户 APP - 钱包流水分页 Response VO") @Data public class AppPayWalletTransactionRespVO { + @Schema(description = "交易金额, 单位分", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") private Integer amount; @@ -16,4 +17,14 @@ public class AppPayWalletTransactionRespVO { @Schema(description = "交易时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") private LocalDateTime transactionTime; + + @Schema(description = "交易金额,单位分", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") + private Long price; + + @Schema(description = "流水标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "土豆土豆") + private String title; + + @Schema(description = "交易时间", requiredMode = Schema.RequiredMode.REQUIRED) + private LocalDateTime createTime; + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/AppPayWalletRespVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/wallet/AppPayWalletRespVO.java similarity index 80% rename from yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/AppPayWalletRespVO.java rename to yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/wallet/AppPayWalletRespVO.java index 508c565aa..c66cda871 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/AppPayWalletRespVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/wallet/AppPayWalletRespVO.java @@ -1,11 +1,8 @@ -package cn.iocoder.yudao.module.pay.controller.app.wallet.vo; +package cn.iocoder.yudao.module.pay.controller.app.wallet.vo.wallet; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -/** - * @author jason - */ @Schema(description = "用户 APP - 获取用户钱包 Response VO") @Data public class AppPayWalletRespVO { @@ -16,6 +13,7 @@ public class AppPayWalletRespVO { @Schema(description = "累计支出, 单位分", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000") private Long totalExpense; - @Schema(description = "累计充值, 单位分", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000") + @Schema(description = "累计充值, 单位分", requiredMode = Schema.RequiredMode.REQUIRED, example = "2000") private Long totalRecharge; + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/wallet/PayWalletConvert.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/wallet/PayWalletConvert.java index 49ec734be..06255900b 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/wallet/PayWalletConvert.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/wallet/PayWalletConvert.java @@ -1,6 +1,6 @@ package cn.iocoder.yudao.module.pay.convert.wallet; -import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.AppPayWalletRespVO; +import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.wallet.AppPayWalletRespVO; import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/wallet/PayWalletTransactionConvert.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/wallet/PayWalletTransactionConvert.java index 99d8c7544..9d1edaf6a 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/wallet/PayWalletTransactionConvert.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/wallet/PayWalletTransactionConvert.java @@ -1,7 +1,7 @@ package cn.iocoder.yudao.module.pay.convert.wallet; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.AppPayWalletTransactionRespVO; +import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.transaction.AppPayWalletTransactionRespVO; import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; 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 a1e5eb0c5..677febb25 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 @@ -48,6 +48,7 @@ public class PayWalletTransactionDO extends BaseDO { */ private Long bizId; + // TODO @jason:想了下,改成 title;流水标题;因为账户明细那,会看到这个; /** * 附加说明 */ diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/wallet/PayWalletMapper.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/wallet/PayWalletMapper.java index d7d00a111..a05b88fe5 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/wallet/PayWalletMapper.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/wallet/PayWalletMapper.java @@ -9,7 +9,8 @@ import org.apache.ibatis.annotations.Mapper; public interface PayWalletMapper extends BaseMapperX { default PayWalletDO selectByUserIdAndType(Long userId, Integer userType) { - return selectOne(PayWalletDO::getUserId, userId, PayWalletDO::getUserType, userType); + return selectOne(PayWalletDO::getUserId, userId, + PayWalletDO::getUserType, userType); } } 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 351810e0c..9e08b2caa 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 @@ -1,30 +1,29 @@ package cn.iocoder.yudao.module.pay.dal.mysql.wallet; -import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.transaction.AppPayWalletTransactionPageReqVO; import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; -import cn.iocoder.yudao.module.pay.enums.member.WalletTransactionQueryTypeEnum; import org.apache.ibatis.annotations.Mapper; +import java.util.Objects; + @Mapper public interface PayWalletTransactionMapper extends BaseMapperX { - default PageResult selectPageByWalletIdAndQueryType(Long walletId, - WalletTransactionQueryTypeEnum queryType, - PageParam pageParam) { + default PageResult selectPage(Long walletId, + AppPayWalletTransactionPageReqVO pageReqVO) { LambdaQueryWrapperX query = new LambdaQueryWrapperX() .eq(PayWalletTransactionDO::getWalletId, walletId); - if (WalletTransactionQueryTypeEnum.RECHARGE == queryType ) { - query.ge(PayWalletTransactionDO::getAmount, 0); - } - if (WalletTransactionQueryTypeEnum.EXPENSE == queryType ) { + if (Objects.equals(pageReqVO.getType(), AppPayWalletTransactionPageReqVO.TYPE_INCOME)) { + query.gt(PayWalletTransactionDO::getAmount, 0); + } else if (Objects.equals(pageReqVO.getType(), AppPayWalletTransactionPageReqVO.TYPE_EXPENSE)) { query.lt(PayWalletTransactionDO::getAmount, 0); } query.orderByDesc(PayWalletTransactionDO::getId); - return selectPage(pageParam, query); + return selectPage(pageReqVO, query); } default PayWalletTransactionDO selectByNo(String no) { diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionService.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionService.java index 1340366fa..e0714081b 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionService.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionService.java @@ -1,7 +1,7 @@ package cn.iocoder.yudao.module.pay.service.wallet; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.AppPayWalletTransactionPageReqVO; +import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.transaction.AppPayWalletTransactionPageReqVO; import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum; 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 c6091a727..e2338219d 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 @@ -1,12 +1,11 @@ package cn.iocoder.yudao.module.pay.service.wallet; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.AppPayWalletTransactionPageReqVO; +import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.transaction.AppPayWalletTransactionPageReqVO; import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; import cn.iocoder.yudao.module.pay.dal.mysql.wallet.PayWalletTransactionMapper; import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum; -import cn.iocoder.yudao.module.pay.enums.member.WalletTransactionQueryTypeEnum; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -35,12 +34,10 @@ public class PayWalletTransactionServiceImpl implements PayWalletTransactionServ AppPayWalletTransactionPageReqVO pageVO) { PayWalletDO wallet = payWalletService.getPayWallet(userId, userType); if (wallet == null) { - log.error("[pageWalletTransaction] 用户 {} 钱包不存在", userId); + log.error("[getWalletTransactionPage][用户({}/{}) 钱包不存在", userId, userType); throw exception(WALLET_NOT_FOUND); } - // TODO @jason:不用 WalletTransactionQueryTypeEnum.valueOf(pageVO.getType()) 哈,直接 pageVO 里面判断值比对就好啦; - return payWalletTransactionMapper.selectPageByWalletIdAndQueryType(wallet.getId(), - WalletTransactionQueryTypeEnum.valueOf(pageVO.getType()), pageVO); + return payWalletTransactionMapper.selectPage(wallet.getId(), pageVO); } @Override