From 42a45016f77155cb6871293d0bc9c526b21dc619 Mon Sep 17 00:00:00 2001 From: xxm1995 Date: Tue, 27 Jun 2023 16:19:34 +0800 Subject: [PATCH] =?UTF-8?q?feat=20=E9=92=B1=E5=8C=85=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E9=A2=84=E5=86=BB=E7=BB=93=E9=A2=9D=E5=BA=A6=E6=93=8D=E4=BD=9C?= =?UTF-8?q?,=20=E6=96=B0=E5=A2=9E=E4=B8=AA=E4=BA=BA=E9=92=B1=E5=8C=85,=20?= =?UTF-8?q?=E5=82=A8=E5=80=BC=E5=8D=A1=E8=B0=83=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dax-pay/pom.xml | 1 - .../daxpay/code/pay/PayWayExtraCode.java | 3 + .../daxpay/code/paymodel/VoucherCode.java | 16 +-- .../controller/WalletAdminController.java | 106 ++++++++++++++++++ .../daxpay/controller/WalletController.java | 96 +++------------- .../core/cashier/service/CashierService.java | 1 - .../voucher/dao/VoucherLogManager.java | 2 +- .../core/channel/voucher/entity/Voucher.java | 25 ++++- .../channel/voucher/entity/VoucherLog.java | 4 +- .../voucher/service/VoucherPayService.java | 84 +++++++++++--- .../core/channel/wallet/entity/Wallet.java | 1 + .../wallet/service/WalletPayService.java | 6 +- .../wallet/service/WalletQueryService.java | 37 +++++- .../channel/wallet/service/WalletService.java | 36 +----- .../core/pay/strategy/VoucherStrategy.java | 15 ++- .../core/pay/strategy/WalletPayStrategy.java | 25 +++-- .../dto/channel/voucher/VoucherDto.java | 4 +- .../param/channel/wallet/WalletPayParam.java | 4 + .../platform/daxpay/util/PayWaylUtil.java | 6 +- 19 files changed, 308 insertions(+), 164 deletions(-) create mode 100644 dax-pay/src/main/java/cn/bootx/platform/daxpay/controller/WalletAdminController.java diff --git a/dax-pay/pom.xml b/dax-pay/pom.xml index 59ddf8320..b7287fa71 100644 --- a/dax-pay/pom.xml +++ b/dax-pay/pom.xml @@ -9,7 +9,6 @@ 1.3.0 - cn.bootx.platform dax-pay diff --git a/dax-pay/src/main/java/cn/bootx/platform/daxpay/code/pay/PayWayExtraCode.java b/dax-pay/src/main/java/cn/bootx/platform/daxpay/code/pay/PayWayExtraCode.java index aee3f2cb0..21e787a9b 100644 --- a/dax-pay/src/main/java/cn/bootx/platform/daxpay/code/pay/PayWayExtraCode.java +++ b/dax-pay/src/main/java/cn/bootx/platform/daxpay/code/pay/PayWayExtraCode.java @@ -20,6 +20,9 @@ public interface PayWayExtraCode { /** 钱包ID */ String WALLET_ID = "wallet_id"; + /** 用户ID */ + String USER_ID = "user_id"; + /** 同步通知路径 支付完成跳转的页面地址 */ String RETURN_URL = "return_url"; diff --git a/dax-pay/src/main/java/cn/bootx/platform/daxpay/code/paymodel/VoucherCode.java b/dax-pay/src/main/java/cn/bootx/platform/daxpay/code/paymodel/VoucherCode.java index 1eb270231..9bdf4e5d7 100644 --- a/dax-pay/src/main/java/cn/bootx/platform/daxpay/code/paymodel/VoucherCode.java +++ b/dax-pay/src/main/java/cn/bootx/platform/daxpay/code/paymodel/VoucherCode.java @@ -9,38 +9,38 @@ package cn.bootx.platform.daxpay.code.paymodel; public interface VoucherCode { /** - * 状态-启用 + * 状态-正常 */ - int STATUS_NORMAL = 1; + String STATUS_NORMAL = "normal"; /** * 状态-停用 */ - int STATUS_FORBIDDEN = 2; + String STATUS_FORBIDDEN = "forbidden"; /** * 储值卡日志-开通 */ - int LOG_ACTIVE = 1; + String LOG_ACTIVE = "active"; /** * 储值卡日志-支付 */ - int LOG_PAY = 2; + String LOG_PAY = "pay"; /** * 储值卡日志-退款 */ - int LOG_CLOSE = 3; + String LOG_CLOSE = "close"; /** * 储值卡日志-退款 */ - int LOG_REFUND = 4; + String LOG_REFUND = "refund"; /** * 储值卡日志-Admin余额变动 */ - int LOG_ADMIN_CHANGER = 4; + String LOG_ADMIN_CHANGER = "changer"; } diff --git a/dax-pay/src/main/java/cn/bootx/platform/daxpay/controller/WalletAdminController.java b/dax-pay/src/main/java/cn/bootx/platform/daxpay/controller/WalletAdminController.java new file mode 100644 index 000000000..6d16340f4 --- /dev/null +++ b/dax-pay/src/main/java/cn/bootx/platform/daxpay/controller/WalletAdminController.java @@ -0,0 +1,106 @@ +package cn.bootx.platform.daxpay.controller; + +import cn.bootx.platform.common.core.annotation.OperateLog; +import cn.bootx.platform.common.core.rest.PageResult; +import cn.bootx.platform.common.core.rest.Res; +import cn.bootx.platform.common.core.rest.ResResult; +import cn.bootx.platform.common.core.rest.param.PageParam; +import cn.bootx.platform.daxpay.core.channel.wallet.service.WalletService; +import cn.bootx.platform.daxpay.core.channel.wallet.service.WalletQueryService; +import cn.bootx.platform.daxpay.dto.channel.wallet.WalletDto; +import cn.bootx.platform.daxpay.dto.channel.wallet.WalletInfoDto; +import cn.bootx.platform.daxpay.param.channel.wallet.WalletPayParam; +import cn.bootx.platform.daxpay.param.channel.wallet.WalletRechargeParam; +import cn.bootx.platform.iam.dto.user.UserInfoDto; +import cn.bootx.platform.iam.param.user.UserInfoParam; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.AllArgsConstructor; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 钱包 + * + * @author xxm + * @since 2021/2/24 + */ +@Tag(name = "钱包相关的接口") +@RestController +@RequestMapping("/wallet/admin") +@AllArgsConstructor +public class WalletAdminController { + + private final WalletService walletService; + + private final WalletQueryService walletQueryService; + + @Operation(summary = "开通用户钱包操作") + @PostMapping("/createWallet") + public ResResult createWallet(Long userId) { + walletService.createWallet(userId); + return Res.ok(); + } + + @Operation(summary = "批量开通用户钱包操作") + @PostMapping("/createWalletBatch") + public ResResult createWalletBatch(@RequestBody List userIds) { + walletService.createWalletBatch(userIds); + return Res.ok(); + } + + @Operation(summary = "解锁钱包") + @OperateLog(title = "解锁钱包", businessType = OperateLog.BusinessType.UPDATE, saveParam = true) + @PostMapping("/unlock") + public ResResult unlock(Long walletId) { + walletService.unlock(walletId); + return Res.ok(); + } + + @Operation(summary = "锁定钱包") + @OperateLog(title = "锁定钱包", businessType = OperateLog.BusinessType.UPDATE, saveParam = true) + @PostMapping("/lock") + public ResResult lock(Long walletId) { + walletService.lock(walletId); + return Res.ok(); + } + + @Operation(summary = "充值操作(增减余额)") + @PostMapping("/changerBalance") + public ResResult changerBalance(@RequestBody WalletRechargeParam param) { + walletService.changerBalance(param); + return Res.ok(); + } + + @Operation(summary = "分页") + @GetMapping("/page") + public ResResult> page(PageParam pageParam, WalletPayParam param) { + return Res.ok(walletQueryService.page(pageParam, param)); + } + + @Operation(summary = "分页(未开通钱包的用户)") + @GetMapping("/pageByNotWallet") + public ResResult> pageByNotWallet(PageParam pageParam, UserInfoParam param) { + return Res.ok(walletQueryService.pageByNotWallet(pageParam, param)); + } + + @Operation(summary = "根据用户ID查询钱包") + @GetMapping("/findByUserId") + public ResResult findByUserId(Long userId) { + return Res.ok(walletQueryService.findByUserId(userId)); + } + + @Operation(summary = "根据钱包ID查询钱包") + @GetMapping("/findById") + public ResResult findById(Long walletId) { + return Res.ok(walletQueryService.findById(walletId)); + } + + @Operation(summary = "获取钱包综合信息") + @GetMapping("/getWalletInfo") + public ResResult getWalletInfo(Long walletId) { + return Res.ok(walletQueryService.getWalletInfo(walletId)); + } + +} diff --git a/dax-pay/src/main/java/cn/bootx/platform/daxpay/controller/WalletController.java b/dax-pay/src/main/java/cn/bootx/platform/daxpay/controller/WalletController.java index 287a9c695..89b0efa4b 100644 --- a/dax-pay/src/main/java/cn/bootx/platform/daxpay/controller/WalletController.java +++ b/dax-pay/src/main/java/cn/bootx/platform/daxpay/controller/WalletController.java @@ -1,89 +1,26 @@ package cn.bootx.platform.daxpay.controller; +import cn.bootx.platform.common.core.rest.Res; +import cn.bootx.platform.common.core.rest.ResResult; import cn.bootx.platform.daxpay.core.channel.wallet.service.WalletQueryService; import cn.bootx.platform.daxpay.core.channel.wallet.service.WalletService; import cn.bootx.platform.daxpay.dto.channel.wallet.WalletDto; -import cn.bootx.platform.daxpay.dto.channel.wallet.WalletInfoDto; -import cn.bootx.platform.daxpay.param.channel.wallet.WalletPayParam; -import cn.bootx.platform.daxpay.param.channel.wallet.WalletRechargeParam; -import cn.bootx.platform.common.core.annotation.OperateLog; -import cn.bootx.platform.common.core.rest.PageResult; -import cn.bootx.platform.common.core.rest.Res; -import cn.bootx.platform.common.core.rest.ResResult; -import cn.bootx.platform.common.core.rest.param.PageParam; -import cn.bootx.platform.iam.dto.user.UserInfoDto; -import cn.bootx.platform.iam.param.user.UserInfoParam; +import cn.bootx.platform.starter.auth.util.SecurityUtil; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.AllArgsConstructor; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; -import java.util.List; - -/** - * 钱包 - * - * @author xxm - * @since 2021/2/24 - */ @Tag(name = "钱包相关的接口") @RestController @RequestMapping("/wallet") @AllArgsConstructor public class WalletController { - - private final WalletService walletService; - private final WalletQueryService walletQueryService; - - @Operation(summary = "开通用户钱包操作") - @PostMapping("createWallet") - public ResResult createWallet(Long userId) { - walletService.createWallet(userId); - return Res.ok(); - } - - @Operation(summary = "批量开通用户钱包操作") - @PostMapping("createWalletBatch") - public ResResult createWalletBatch(@RequestBody List userIds) { - walletService.createWalletBatch(userIds); - return Res.ok(); - } - - @Operation(summary = "解锁钱包") - @OperateLog(title = "解锁钱包", businessType = OperateLog.BusinessType.UPDATE, saveParam = true) - @PostMapping("/unlock") - public ResResult unlock(Long walletId) { - walletService.unlock(walletId); - return Res.ok(); - } - - @Operation(summary = "锁定钱包") - @OperateLog(title = "锁定钱包", businessType = OperateLog.BusinessType.UPDATE, saveParam = true) - @PostMapping("/lock") - public ResResult lock(Long walletId) { - walletService.lock(walletId); - return Res.ok(); - } - - @Operation(summary = "充值操作(增减余额)") - @PostMapping("/changerBalance") - public ResResult changerBalance(@RequestBody WalletRechargeParam param) { - walletService.changerBalance(param); - return Res.ok(); - } - - @Operation(summary = "分页") - @GetMapping("/page") - public ResResult> page(PageParam pageParam, WalletPayParam param) { - return Res.ok(walletQueryService.page(pageParam, param)); - } - - @Operation(summary = "分页") - @GetMapping("/pageByNotWallet") - public ResResult> pageByNotWallet(PageParam pageParam, UserInfoParam param) { - return Res.ok(walletQueryService.pageByNotWallet(pageParam, param)); - } + private final WalletService walletService; @Operation(summary = "根据用户查询钱包") @GetMapping("/findByUser") @@ -91,16 +28,11 @@ public class WalletController { return Res.ok(walletQueryService.findByUser()); } - @Operation(summary = "根据钱包ID查询钱包") - @GetMapping("/findById") - public ResResult findById(Long walletId) { - return Res.ok(walletQueryService.findById(walletId)); + @Operation(summary = "开通用户钱包操作") + @PostMapping("/createWallet") + public ResResult createWallet() { + Long userId = SecurityUtil.getUserId(); + walletService.createWallet(userId); + return Res.ok(); } - - @Operation(summary = "获取钱包综合信息") - @GetMapping("/getWalletInfo") - public ResResult getWalletInfo(Long walletId) { - return Res.ok(walletQueryService.getWalletInfo(walletId)); - } - } diff --git a/dax-pay/src/main/java/cn/bootx/platform/daxpay/core/cashier/service/CashierService.java b/dax-pay/src/main/java/cn/bootx/platform/daxpay/core/cashier/service/CashierService.java index 13bf9b90a..f9924ce86 100644 --- a/dax-pay/src/main/java/cn/bootx/platform/daxpay/core/cashier/service/CashierService.java +++ b/dax-pay/src/main/java/cn/bootx/platform/daxpay/core/cashier/service/CashierService.java @@ -79,7 +79,6 @@ public class CashierService { map.put(PayWayExtraCode.AUTH_CODE, param.getAuthCode()); map.put(PayWayExtraCode.OPEN_ID, param.getOpenId()); map.put(PayWayExtraCode.VOUCHER_NO, param.getVoucherNo()); - map.put(PayWayExtraCode.WALLET_ID, param.getWalletId()); String extraParamsJson = PayWaylUtil.buildExtraParamsJson(param.getPayChannel(), map); payWayParam.setExtraParamsJson(extraParamsJson); diff --git a/dax-pay/src/main/java/cn/bootx/platform/daxpay/core/channel/voucher/dao/VoucherLogManager.java b/dax-pay/src/main/java/cn/bootx/platform/daxpay/core/channel/voucher/dao/VoucherLogManager.java index 93cfcf5f6..f0f43ddfd 100644 --- a/dax-pay/src/main/java/cn/bootx/platform/daxpay/core/channel/voucher/dao/VoucherLogManager.java +++ b/dax-pay/src/main/java/cn/bootx/platform/daxpay/core/channel/voucher/dao/VoucherLogManager.java @@ -20,7 +20,7 @@ public class VoucherLogManager extends BaseManager /** * 根据支付id和类型进行查询 */ - public List findByPaymentIdAndType(Long paymentId, int type) { + public List findByPaymentIdAndType(Long paymentId, String type) { return lambdaQuery().eq(VoucherLog::getPaymentId, paymentId).eq(VoucherLog::getType, type).list(); } diff --git a/dax-pay/src/main/java/cn/bootx/platform/daxpay/core/channel/voucher/entity/Voucher.java b/dax-pay/src/main/java/cn/bootx/platform/daxpay/core/channel/voucher/entity/Voucher.java index 3a093eede..be3d50868 100644 --- a/dax-pay/src/main/java/cn/bootx/platform/daxpay/core/channel/voucher/entity/Voucher.java +++ b/dax-pay/src/main/java/cn/bootx/platform/daxpay/core/channel/voucher/entity/Voucher.java @@ -1,5 +1,9 @@ package cn.bootx.platform.daxpay.core.channel.voucher.entity; +import cn.bootx.mybatis.table.modify.annotation.DbColumn; +import cn.bootx.mybatis.table.modify.annotation.DbComment; +import cn.bootx.mybatis.table.modify.annotation.DbTable; +import cn.bootx.mybatis.table.modify.mybatis.mysq.annotation.DbMySqlIndex; import cn.bootx.platform.common.core.function.EntityBaseFunction; import cn.bootx.platform.common.mybatisplus.base.MpBaseEntity; import cn.bootx.platform.daxpay.code.paymodel.VoucherCode; @@ -21,36 +25,51 @@ import java.time.LocalDateTime; */ @EqualsAndHashCode(callSuper = true) @Data +@DbTable(comment = "储值卡") @Accessors(chain = true) @TableName("pay_voucher") public class Voucher extends MpBaseEntity implements EntityBaseFunction { /** 卡号 */ + @DbComment("卡号") + @DbMySqlIndex(comment = "卡号索引") private String cardNo; /** 生成批次号 */ + @DbComment("生成批次号") private Long batchNo; /** 面值 */ + @DbComment("面值") private BigDecimal faceValue; /** 余额 */ + @DbComment("余额") private BigDecimal balance; + /** 预冻结额度 */ + @DbColumn(comment = "预冻结额度") + private BigDecimal freezeBalance; + + /** 是否长期有效 */ - private Boolean enduring; + @DbComment("是否长期有效") + private boolean enduring; /** 开始时间 */ + @DbComment("开始时间") private LocalDateTime startTime; /** 结束时间 */ + @DbComment("结束时间") private LocalDateTime endTime; /** * 状态 - * @see VoucherCode + * @see VoucherCode#STATUS_FORBIDDEN */ - private Integer status; + @DbComment("状态") + private String status; @Override public VoucherDto toDto() { diff --git a/dax-pay/src/main/java/cn/bootx/platform/daxpay/core/channel/voucher/entity/VoucherLog.java b/dax-pay/src/main/java/cn/bootx/platform/daxpay/core/channel/voucher/entity/VoucherLog.java index db3dcb425..22ed5c62d 100644 --- a/dax-pay/src/main/java/cn/bootx/platform/daxpay/core/channel/voucher/entity/VoucherLog.java +++ b/dax-pay/src/main/java/cn/bootx/platform/daxpay/core/channel/voucher/entity/VoucherLog.java @@ -32,9 +32,9 @@ public class VoucherLog extends MpBaseEntity { /** * 类型 - * @see VoucherCode + * @see VoucherCode#LOG_PAY */ - private Integer type; + private String type; /** 交易记录ID */ private Long paymentId; diff --git a/dax-pay/src/main/java/cn/bootx/platform/daxpay/core/channel/voucher/service/VoucherPayService.java b/dax-pay/src/main/java/cn/bootx/platform/daxpay/core/channel/voucher/service/VoucherPayService.java index 84f1d214b..d42aeea9b 100644 --- a/dax-pay/src/main/java/cn/bootx/platform/daxpay/core/channel/voucher/service/VoucherPayService.java +++ b/dax-pay/src/main/java/cn/bootx/platform/daxpay/core/channel/voucher/service/VoucherPayService.java @@ -5,15 +5,15 @@ import cn.bootx.platform.common.core.util.BigDecimalUtil; import cn.bootx.platform.common.core.util.LocalDateTimeUtil; import cn.bootx.platform.daxpay.code.paymodel.VoucherCode; import cn.bootx.platform.daxpay.core.channel.voucher.dao.VoucherLogManager; -import cn.bootx.platform.daxpay.core.payment.entity.Payment; import cn.bootx.platform.daxpay.core.channel.voucher.dao.VoucherManager; import cn.bootx.platform.daxpay.core.channel.voucher.dao.VoucherPaymentManager; import cn.bootx.platform.daxpay.core.channel.voucher.entity.Voucher; import cn.bootx.platform.daxpay.core.channel.voucher.entity.VoucherLog; import cn.bootx.platform.daxpay.core.channel.voucher.entity.VoucherPayment; +import cn.bootx.platform.daxpay.core.payment.entity.Payment; import cn.bootx.platform.daxpay.exception.payment.PayFailureException; -import cn.bootx.platform.daxpay.param.pay.PayWayParam; import cn.bootx.platform.daxpay.param.channel.voucher.VoucherPayParam; +import cn.bootx.platform.daxpay.param.pay.PayWayParam; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONException; import cn.hutool.json.JSONUtil; @@ -82,11 +82,25 @@ public class VoucherPayService { throw new PayFailureException("储值卡余额不足"); } - return vouchers; + return sort(vouchers); } /** - * 支付 TODO 有期限的在前面, 同样有期限到期时间短的在前面, 同样到期日金额小的在前面 + * 支付前冻结余额 + */ + public void freezeBalance(BigDecimal amount, Payment payment, List vouchers){ + + } + + /** + * 支付成功 + */ + public void paySuccess(Long paymentId){ + + } + + /** + * 直接支付 */ public void pay(BigDecimal amount, Payment payment, List vouchers) { vouchers.sort((o1, o2) -> BigDecimalUtil.compareTo(o1.getBalance(), o2.getBalance())); @@ -122,15 +136,17 @@ public class VoucherPayService { voucherLogManager.saveAll(voucherLogs); } + /** - * 取消支付 + * 取消支付, 可配置解除冻结金额 + * @param freeze 是否是冻结模式, 是的话对冻结金额进行解冻, 不是的话返还扣减的金额 */ - public void close(Long paymentId) { + public void close(Long paymentId,boolean freeze) { // 查找支付记录日志 List voucherLogs = voucherLogManager.findByPaymentIdAndType(paymentId, VoucherCode.LOG_PAY); // 查出关联的储值卡 Map voucherLogMap = voucherLogs.stream() - .collect(Collectors.toMap(VoucherLog::getVoucherId, Function.identity())); + .collect(Collectors.toMap(VoucherLog::getVoucherId, Function.identity())); List vouchers = voucherManager.findAllByIds(voucherLogMap.keySet()); // 执行退款并记录日志 List logs = new ArrayList<>(); @@ -138,11 +154,11 @@ public class VoucherPayService { VoucherLog voucherLog = voucherLogMap.get(voucher.getId()); voucher.setBalance(voucher.getBalance().add(voucherLog.getAmount())); VoucherLog log = new VoucherLog().setAmount(voucherLog.getAmount()) - .setPaymentId(paymentId) - .setBusinessId(voucherLog.getBusinessId()) - .setVoucherId(voucher.getId()) - .setVoucherNo(voucher.getCardNo()) - .setType(VoucherCode.LOG_CLOSE); + .setPaymentId(paymentId) + .setBusinessId(voucherLog.getBusinessId()) + .setVoucherId(voucher.getId()) + .setVoucherNo(voucher.getCardNo()) + .setType(VoucherCode.LOG_CLOSE); logs.add(log); } voucherManager.updateAllById(vouchers); @@ -177,9 +193,51 @@ public class VoucherPayService { private boolean check(List vouchers) { // 判断有效期 return vouchers.stream() - .filter(voucher -> !Objects.equals(voucher.getEnduring(), true)) + .filter(voucher -> !Objects.equals(voucher.isEnduring(), true)) .allMatch(voucher -> LocalDateTimeUtil.between(LocalDateTime.now(), voucher.getStartTime(), voucher.getEndTime())); } + /** + * 对储值卡进行排序 + * 有期限的在前面, 同样有期限到期时间短的在前面, 同样到期日余额小的在前面, 金额一样id小的前面 + */ + private List sort(List vouchers){ + vouchers.sort(this::compareTime); + return vouchers; + } + + /** + * 比较储值卡的期限 + */ + private int compareTime(Voucher v1,Voucher v2){ + // 期限对比, 都为长期 + if (v1.isEnduring()&&v2.isEnduring()){ + // 比较余额 + return compareBalance(v1,v2); + } + // 都不为长期, 且金额一致 + if (Objects.equals(v1.getEndTime(),v2.getEndTime())){ + // 比较余额 + return compareBalance(v1,v2); + } + // 期限对比 其中一个为长期 + if (v1.isEnduring()^v2.isEnduring()){ + return v1.isEnduring()?1:-1; + } + // 比较期限 + return v1.getEndTime().compareTo(v2.getEndTime()); + } + + /** + * 比较储值卡的余额, 余额一致比较主键 + */ + private int compareBalance(Voucher v1,Voucher v2) { + int i = BigDecimalUtil.compareTo(v1.getBalance(), v2.getBalance()); + if (i==0){ + return Long.compare(v1.getId(),v2.getId()); + } + return i; + } + } diff --git a/dax-pay/src/main/java/cn/bootx/platform/daxpay/core/channel/wallet/entity/Wallet.java b/dax-pay/src/main/java/cn/bootx/platform/daxpay/core/channel/wallet/entity/Wallet.java index ba647f948..c38d3b827 100644 --- a/dax-pay/src/main/java/cn/bootx/platform/daxpay/core/channel/wallet/entity/Wallet.java +++ b/dax-pay/src/main/java/cn/bootx/platform/daxpay/core/channel/wallet/entity/Wallet.java @@ -45,6 +45,7 @@ public class Wallet extends MpBaseEntity implements EntityBaseFunction { Optional walletOpt = walletManager.findById(walletPayment.getWalletId()); diff --git a/dax-pay/src/main/java/cn/bootx/platform/daxpay/core/channel/wallet/service/WalletQueryService.java b/dax-pay/src/main/java/cn/bootx/platform/daxpay/core/channel/wallet/service/WalletQueryService.java index d9064a1e5..d49095789 100644 --- a/dax-pay/src/main/java/cn/bootx/platform/daxpay/core/channel/wallet/service/WalletQueryService.java +++ b/dax-pay/src/main/java/cn/bootx/platform/daxpay/core/channel/wallet/service/WalletQueryService.java @@ -1,5 +1,6 @@ package cn.bootx.platform.daxpay.core.channel.wallet.service; +import cn.bootx.platform.common.core.entity.UserDetail; import cn.bootx.platform.common.core.exception.DataNotExistException; import cn.bootx.platform.common.core.rest.PageResult; import cn.bootx.platform.common.core.rest.param.PageParam; @@ -18,6 +19,8 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import java.util.Objects; + /** * 钱包 * @@ -34,18 +37,26 @@ public class WalletQueryService { private final UserQueryService userQueryService; /** - * 根据ID查询Wallet + * 根据钱包ID查询Wallet */ public WalletDto findById(Long walletId) { return walletManager.findById(walletId).map(Wallet::toDto).orElseThrow(DataNotExistException::new); } + + /** + * 根据用户ID查询钱包 + */ + public WalletDto findByUserId(Long userId) { + return walletManager.findByUser(userId).map(Wallet::toDto).orElseThrow(DataNotExistException::new); + } + /** * 根据用户ID查询钱包 */ public WalletDto findByUser() { Long userId = SecurityUtil.getUserId(); - return walletManager.findByUser(userId).map(Wallet::toDto).orElseThrow(DataNotExistException::new); + return walletManager.findByUser(userId).map(Wallet::toDto).orElse(null); } /** @@ -74,4 +85,26 @@ public class WalletQueryService { return MpUtil.convert2DtoPageResult(walletManager.pageByNotWallet(pageParam, userInfoParam)); } + + /** + * 获取钱包, 获取顺序: 1. 显式传入的钱包ID 2. 显式传入的用户ID 3. 从系统中获取到的用户ID + * + */ + public Wallet getWallet(Long walletId,Long userId){ + Wallet wallet = null; + // 首先根据钱包ID查询 + if (Objects.nonNull(walletId)) { + wallet = walletManager.findById(walletId).orElseThrow(null); + } + if (Objects.nonNull(wallet)){ + return wallet; + } + // 根据用户id查询 + if (Objects.isNull(userId)){ + userId = SecurityUtil.getCurrentUser().map(UserDetail::getId).orElse(null); + } + return walletManager.findByUser(userId).orElse(null); + + } + } diff --git a/dax-pay/src/main/java/cn/bootx/platform/daxpay/core/channel/wallet/service/WalletService.java b/dax-pay/src/main/java/cn/bootx/platform/daxpay/core/channel/wallet/service/WalletService.java index b7b5a8a7d..028a12c58 100644 --- a/dax-pay/src/main/java/cn/bootx/platform/daxpay/core/channel/wallet/service/WalletService.java +++ b/dax-pay/src/main/java/cn/bootx/platform/daxpay/core/channel/wallet/service/WalletService.java @@ -8,8 +8,6 @@ import cn.bootx.platform.daxpay.core.channel.wallet.dao.WalletLogManager; import cn.bootx.platform.daxpay.core.channel.wallet.dao.WalletManager; import cn.bootx.platform.daxpay.core.channel.wallet.entity.Wallet; import cn.bootx.platform.daxpay.core.channel.wallet.entity.WalletLog; -import cn.bootx.platform.daxpay.exception.waller.WalletBannedException; -import cn.bootx.platform.daxpay.exception.waller.WalletNotExistsException; import cn.bootx.platform.daxpay.param.channel.wallet.WalletRechargeParam; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -18,14 +16,12 @@ import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.util.List; -import java.util.Objects; import java.util.stream.Collectors; /** - * 钱包的相关操作 * * @author xxm - * @since 2020/12/8 + * @since 2023/6/26 */ @Slf4j @Service @@ -79,8 +75,8 @@ public class WalletService { .setUserId(wallet.getUserId()) .setAmount(BigDecimal.ZERO) .setType(WalletCode.LOG_ACTIVE) - .setRemark("激活钱包") - .setOperationSource(WalletCode.OPERATION_SOURCE_USER)) + .setRemark("批量开通钱包") + .setOperationSource(WalletCode.OPERATION_SOURCE_ADMIN)) .collect(Collectors.toList()); walletLogManager.saveAll(walletLogs); } @@ -142,30 +138,4 @@ public class WalletService { .setOperationSource(WalletCode.OPERATION_SOURCE_ADMIN); walletLogManager.save(walletLog); } - - /** - * 查询钱包,如果钱包不存在或者钱包被禁用将抛出异常 - */ - public Wallet getNormalWalletById(Long walletId) { - // 查询Wallet - Wallet wallet = walletManager.findById(walletId).orElseThrow(WalletNotExistsException::new); - // 是否被禁用 - if (Objects.equals(WalletCode.STATUS_FORBIDDEN, wallet.getStatus())) { - throw new WalletBannedException(); - } - return wallet; - } - - /** - * 查询钱包,如果钱包不存在或者钱包被禁用将抛出异常 - */ - public Wallet getNormalWalletByUserId(Long userId) { - // 查询Wallet - Wallet wallet = walletManager.findByUser(userId).orElseThrow(WalletNotExistsException::new); - // 是否被禁用 - if (Objects.equals(WalletCode.STATUS_FORBIDDEN, wallet.getStatus())) { - throw new WalletBannedException(); - } - return wallet; - } } diff --git a/dax-pay/src/main/java/cn/bootx/platform/daxpay/core/pay/strategy/VoucherStrategy.java b/dax-pay/src/main/java/cn/bootx/platform/daxpay/core/pay/strategy/VoucherStrategy.java index 9f721aa9a..ece20a97d 100644 --- a/dax-pay/src/main/java/cn/bootx/platform/daxpay/core/pay/strategy/VoucherStrategy.java +++ b/dax-pay/src/main/java/cn/bootx/platform/daxpay/core/pay/strategy/VoucherStrategy.java @@ -45,7 +45,7 @@ public class VoucherStrategy extends AbsPayStrategy { */ @Override public void doBeforePayHandler() { - // 获取并校验余额 + // 获取并校验储值卡 this.vouchers = voucherPayService.getAndCheckVoucher(this.getPayWayParam()); } @@ -54,8 +54,12 @@ public class VoucherStrategy extends AbsPayStrategy { */ @Override public void doPayHandler() { - voucherPayService.pay(getPayWayParam().getAmount(), this.getPayment(), this.vouchers); - voucherPaymentService.savePayment(getPayment(), getPayParam(), getPayWayParam(), vouchers); + if (this.getPayment().isAsyncPayMode()){ + voucherPayService.freezeBalance(this.getPayWayParam().getAmount(), this.getPayment(), this.vouchers); + } else { + voucherPayService.pay(this.getPayWayParam().getAmount(), this.getPayment(), this.vouchers); + } + voucherPaymentService.savePayment(this.getPayment(), getPayParam(), getPayWayParam(), vouchers); } /** @@ -63,6 +67,9 @@ public class VoucherStrategy extends AbsPayStrategy { */ @Override public void doSuccessHandler() { + if (this.getPayment().isAsyncPayMode()){ + voucherPayService.paySuccess(this.getPayment().getId()); + } voucherPaymentService.updateSuccess(this.getPayment().getId()); } @@ -71,7 +78,7 @@ public class VoucherStrategy extends AbsPayStrategy { */ @Override public void doCloseHandler() { - voucherPayService.close(this.getPayment().getId()); + voucherPayService.close(this.getPayment().getId(), this.getPayment().isAsyncPayMode()); voucherPaymentService.updateClose(this.getPayment().getId()); } diff --git a/dax-pay/src/main/java/cn/bootx/platform/daxpay/core/pay/strategy/WalletPayStrategy.java b/dax-pay/src/main/java/cn/bootx/platform/daxpay/core/pay/strategy/WalletPayStrategy.java index d5c1ea21d..da5385595 100644 --- a/dax-pay/src/main/java/cn/bootx/platform/daxpay/core/pay/strategy/WalletPayStrategy.java +++ b/dax-pay/src/main/java/cn/bootx/platform/daxpay/core/pay/strategy/WalletPayStrategy.java @@ -2,13 +2,15 @@ package cn.bootx.platform.daxpay.core.pay.strategy; import cn.bootx.platform.common.core.util.BigDecimalUtil; import cn.bootx.platform.daxpay.code.pay.PayChannelEnum; +import cn.bootx.platform.daxpay.code.paymodel.WalletCode; import cn.bootx.platform.daxpay.core.channel.wallet.entity.Wallet; import cn.bootx.platform.daxpay.core.channel.wallet.service.WalletPayService; import cn.bootx.platform.daxpay.core.channel.wallet.service.WalletPaymentService; -import cn.bootx.platform.daxpay.core.channel.wallet.service.WalletService; +import cn.bootx.platform.daxpay.core.channel.wallet.service.WalletQueryService; import cn.bootx.platform.daxpay.core.pay.func.AbsPayStrategy; import cn.bootx.platform.daxpay.core.payment.service.PaymentService; import cn.bootx.platform.daxpay.exception.payment.PayFailureException; +import cn.bootx.platform.daxpay.exception.waller.WalletBannedException; import cn.bootx.platform.daxpay.exception.waller.WalletLackOfBalanceException; import cn.bootx.platform.daxpay.param.channel.wallet.WalletPayParam; import cn.hutool.core.util.StrUtil; @@ -18,6 +20,8 @@ import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; +import java.util.Objects; + import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROTOTYPE; /** @@ -35,7 +39,7 @@ public class WalletPayStrategy extends AbsPayStrategy { private final WalletPayService walletPayService; - private final WalletService walletService; + private final WalletQueryService walletQueryService; private final PaymentService paymentService; @@ -51,17 +55,22 @@ public class WalletPayStrategy extends AbsPayStrategy { */ @Override public void doBeforePayHandler() { + WalletPayParam walletPayParam = new WalletPayParam(); try { // 钱包参数验证 String extraParamsJson = this.getPayWayParam().getExtraParamsJson(); if (StrUtil.isNotBlank(extraParamsJson)) { - WalletPayParam walletPayParam = JSONUtil.toBean(extraParamsJson, WalletPayParam.class); - this.wallet = walletService.getNormalWalletById(walletPayParam.getWalletId()); + walletPayParam = JSONUtil.toBean(extraParamsJson, WalletPayParam.class); } - } - catch (JSONException e) { + } catch (JSONException e) { throw new PayFailureException("支付参数错误"); } + // 获取钱包 + this.wallet = walletQueryService.getWallet(walletPayParam.getWalletId(),walletPayParam.getUserId()); + // 是否被禁用 + if (Objects.equals(WalletCode.STATUS_FORBIDDEN, this.wallet.getStatus())) { + throw new WalletBannedException(); + } // 判断余额 if (BigDecimalUtil.compareTo(this.wallet.getBalance(), getPayWayParam().getAmount()) < 0) { throw new WalletLackOfBalanceException(); @@ -88,7 +97,7 @@ public class WalletPayStrategy extends AbsPayStrategy { @Override public void doSuccessHandler() { if (this.getPayment().isAsyncPayMode()){ - walletPayService.success(this.getPayment().getId()); + walletPayService.paySuccess(this.getPayment().getId()); } walletPaymentService.updateSuccess(this.getPayment().getId()); } @@ -99,7 +108,7 @@ public class WalletPayStrategy extends AbsPayStrategy { @Override public void doCloseHandler() { if (this.getPayment().isAsyncPayMode()){ - walletPayService.success(this.getPayment().getId()); + walletPayService.paySuccess(this.getPayment().getId()); } walletPayService.close(this.getPayment().getId(),this.getPayment().isAsyncPayMode()); walletPaymentService.updateClose(this.getPayment().getId()); diff --git a/dax-pay/src/main/java/cn/bootx/platform/daxpay/dto/channel/voucher/VoucherDto.java b/dax-pay/src/main/java/cn/bootx/platform/daxpay/dto/channel/voucher/VoucherDto.java index d096303fd..77b6513b2 100644 --- a/dax-pay/src/main/java/cn/bootx/platform/daxpay/dto/channel/voucher/VoucherDto.java +++ b/dax-pay/src/main/java/cn/bootx/platform/daxpay/dto/channel/voucher/VoucherDto.java @@ -42,9 +42,9 @@ public class VoucherDto extends BaseDto { private LocalDateTime endTime; /** - * @see VoucherCode + * @see VoucherCode#STATUS_FORBIDDEN */ @Schema(description = "状态") - private Integer status; + private String status; } diff --git a/dax-pay/src/main/java/cn/bootx/platform/daxpay/param/channel/wallet/WalletPayParam.java b/dax-pay/src/main/java/cn/bootx/platform/daxpay/param/channel/wallet/WalletPayParam.java index 70de5321c..277ddc839 100644 --- a/dax-pay/src/main/java/cn/bootx/platform/daxpay/param/channel/wallet/WalletPayParam.java +++ b/dax-pay/src/main/java/cn/bootx/platform/daxpay/param/channel/wallet/WalletPayParam.java @@ -22,4 +22,8 @@ public class WalletPayParam implements Serializable { @Schema(description = "钱包ID") private Long walletId; + @Schema(description = "用户ID") + private Long userId; + + } diff --git a/dax-pay/src/main/java/cn/bootx/platform/daxpay/util/PayWaylUtil.java b/dax-pay/src/main/java/cn/bootx/platform/daxpay/util/PayWaylUtil.java index 0730a5d09..5ace50e2d 100644 --- a/dax-pay/src/main/java/cn/bootx/platform/daxpay/util/PayWaylUtil.java +++ b/dax-pay/src/main/java/cn/bootx/platform/daxpay/util/PayWaylUtil.java @@ -101,7 +101,11 @@ public class PayWaylUtil { } case WALLET: { String walletId = map.get(PayWayExtraCode.WALLET_ID); - return JSONUtil.toJsonStr(new WalletPayParam().setWalletId(Long.valueOf(walletId))); + String userId = map.get(PayWayExtraCode.USER_ID); + WalletPayParam walletPayParam = new WalletPayParam() + .setWalletId(Long.valueOf(walletId)) + .setUserId(Long.valueOf(userId)); + return JSONUtil.toJsonStr(walletPayParam); } default: { return null;