mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-10-31 10:18:42 +08:00 
			
		
		
		
	Merge remote-tracking branch 'origin/feature/mall_product' into feature/mall_product
This commit is contained in:
		| @@ -10,6 +10,7 @@ CREATE TABLE `pay_wallet` | ||||
|     `balance`              int      NOT NULL DEFAULT 0 COMMENT '余额,单位分', | ||||
|     `total_expense`        int      NOT NULL DEFAULT 0 COMMENT '累计支出,单位分', | ||||
|     `total_recharge`       int      NOT NULL DEFAULT 0 COMMENT '累计充值,单位分', | ||||
|     `freeze_price`         int      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 '更新者', | ||||
| @@ -62,6 +63,7 @@ CREATE TABLE `pay_wallet_recharge` | ||||
|     `refund_pay_price`              int         NOT NULL DEFAULT 0 COMMENT '退款支付金额', | ||||
|     `refund_bonus_price`            int         NOT NULL DEFAULT 0 COMMENT '退款钱包赠送金额', | ||||
|     `refund_time`                   datetime    NULL COMMENT '退款时间', | ||||
|     `refund_status`                 int         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 '更新者', | ||||
|   | ||||
| @@ -46,6 +46,7 @@ public interface ErrorCodeConstants { | ||||
|     ErrorCode WALLET_TRANSACTION_NOT_FOUND = new ErrorCode(1007007002, "未找到对应的钱包交易"); | ||||
|     ErrorCode WALLET_REFUND_AMOUNT_ERROR = new ErrorCode(1007007003, "钱包退款金额不对"); | ||||
|     ErrorCode WALLET_REFUND_EXIST = new ErrorCode(1007007004, "已经存在钱包退款"); | ||||
|     ErrorCode WALLET_FREEZE_PRICE_NOT_ENOUGH = new ErrorCode(1007007005, "钱包冻结余额不足"); | ||||
|  | ||||
|     // TODO @jason:把钱包充值,单独搞个错误码段哈; | ||||
|  | ||||
| @@ -54,7 +55,12 @@ public interface ErrorCodeConstants { | ||||
|     ErrorCode WALLET_RECHARGE_UPDATE_PAID_PAY_ORDER_ID_ERROR = new ErrorCode(1007007007, "钱包充值更新支付状态失败,支付单编号不匹配"); | ||||
|     ErrorCode WALLET_RECHARGE_UPDATE_PAID_PAY_ORDER_STATUS_NOT_SUCCESS = new ErrorCode(1007007008, "钱包充值更新支付状态失败,支付单状态不是【支付成功】状态"); | ||||
|     ErrorCode WALLET_RECHARGE_UPDATE_PAID_PAY_PRICE_NOT_MATCH = new ErrorCode(1007007009, "钱包充值更新支付状态失败,支付单金额不匹配"); | ||||
|  | ||||
|     ErrorCode WALLET_RECHARGE_REFUND_FAIL_NOT_PAID = new ErrorCode(1007900010, "钱包发起退款失败,钱包充值订单未支付"); | ||||
|     ErrorCode WALLET_RECHARGE_REFUND_FAIL_REFUNDED = new ErrorCode(1007900011, "钱包发起退款失败,钱包充值订单已退款"); | ||||
|     ErrorCode WALLET_RECHARGE_REFUND_BALANCE_NOT_ENOUGH = new ErrorCode(1007900012, "钱包发起退款失败,钱包余额不足"); | ||||
|     ErrorCode WALLET_RECHARGE_REFUND_FAIL_REFUND_ORDER_ID_ERROR = new ErrorCode(1007900013, "钱包退款更新失败,钱包退款单编号不匹配"); | ||||
|     ErrorCode WALLET_RECHARGE_REFUND_FAIL_REFUND_NOT_FOUND = new ErrorCode(1007900014, "钱包退款更新失败,退款订单不存在"); | ||||
|     ErrorCode WALLET_RECHARGE_REFUND_FAIL_REFUND_PRICE_NOT_MATCH = new ErrorCode(1007900015, "钱包退款更新失败,退款单金额不匹配"); | ||||
|     // ========== 示例订单 1007900000 ========== | ||||
|     ErrorCode DEMO_ORDER_NOT_FOUND = new ErrorCode(1007900000, "示例订单不存在"); | ||||
|     ErrorCode DEMO_ORDER_UPDATE_PAID_STATUS_NOT_UNPAID = new ErrorCode(1007900001, "示例订单更新支付状态失败,订单不是【未支付】状态"); | ||||
|   | ||||
| @@ -0,0 +1,48 @@ | ||||
| package cn.iocoder.yudao.module.pay.controller.admin.wallet; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.common.pojo.CommonResult; | ||||
| import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; | ||||
| import cn.iocoder.yudao.module.pay.api.notify.dto.PayRefundNotifyReqDTO; | ||||
| import cn.iocoder.yudao.module.pay.service.wallet.PayWalletRechargeService; | ||||
| import io.swagger.v3.oas.annotations.Operation; | ||||
| import io.swagger.v3.oas.annotations.Parameter; | ||||
| import io.swagger.v3.oas.annotations.tags.Tag; | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
| import org.springframework.validation.annotation.Validated; | ||||
| import org.springframework.web.bind.annotation.*; | ||||
|  | ||||
| import javax.annotation.Resource; | ||||
| import javax.annotation.security.PermitAll; | ||||
|  | ||||
| import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | ||||
| import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; | ||||
|  | ||||
| @Tag(name = "管理后台 - 钱包充值") | ||||
| @RestController | ||||
| @RequestMapping("/pay/wallet-recharge") | ||||
| @Validated | ||||
| @Slf4j | ||||
| public class PayWalletRechargeController { | ||||
|  | ||||
|     @Resource | ||||
|     private PayWalletRechargeService walletRechargeService; | ||||
|  | ||||
|  | ||||
|     @GetMapping("/refund") | ||||
|     @Operation(summary = "发起钱包充值退款") | ||||
|     @Parameter(name = "id", description = "编号", required = true, example = "1024") | ||||
|     public CommonResult<Boolean> refundWalletRecharge(@RequestParam("id") Long id) { | ||||
|         walletRechargeService.refundWalletRecharge(id,getClientIP()); | ||||
|         return success(true); | ||||
|     } | ||||
|  | ||||
|     @PostMapping("/update-refunded") | ||||
|     @Operation(summary = "更新钱包充值为已退款") // 由 pay-module 支付服务,进行回调,可见 PayNotifyJob | ||||
|     @PermitAll // 无需登录, 内部校验实现 | ||||
|     @OperateLog(enable = false) // 禁用操作日志,因为没有操作人 | ||||
|     public CommonResult<Boolean> updateWalletRechargeRefunded(@RequestBody PayRefundNotifyReqDTO notifyReqDTO) { | ||||
|         walletRechargeService.updateWalletRechargeRefunded( | ||||
|                 Long.valueOf(notifyReqDTO.getMerchantOrderId()), notifyReqDTO.getPayRefundId()); | ||||
|         return success(true); | ||||
|     } | ||||
| } | ||||
| @@ -53,7 +53,4 @@ public class AppPayWalletRechargeController { | ||||
|                 notifyReqDTO.getPayOrderId()); | ||||
|         return success(true); | ||||
|     } | ||||
|  | ||||
|     // TODO @jason:管理后台,是不是可以搞个发起退款; | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -42,6 +42,11 @@ public class PayWalletDO extends BaseDO { | ||||
|      */ | ||||
|     private Integer balance; | ||||
|  | ||||
|     /** | ||||
|      * 冻结金额,单位分 | ||||
|      */ | ||||
|     private Integer freezePrice; | ||||
|  | ||||
|     /** | ||||
|      * 累计支出,单位分 | ||||
|      */ | ||||
|   | ||||
| @@ -3,6 +3,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.dal.dataobject.order.PayOrderDO; | ||||
| import cn.iocoder.yudao.module.pay.dal.dataobject.refund.PayRefundDO; | ||||
| import cn.iocoder.yudao.module.pay.enums.refund.PayRefundStatusEnum; | ||||
| import com.baomidou.mybatisplus.annotation.KeySequence; | ||||
| import com.baomidou.mybatisplus.annotation.TableId; | ||||
| import com.baomidou.mybatisplus.annotation.TableName; | ||||
| @@ -99,4 +100,11 @@ public class PayWalletRechargeDO extends BaseDO { | ||||
|      */ | ||||
|     private LocalDateTime refundTime; | ||||
|  | ||||
|     /** | ||||
|      * 退款状态 | ||||
|      * | ||||
|      * 枚举 {@link PayRefundStatusEnum} | ||||
|      */ | ||||
|     private Integer refundStatus; | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -57,6 +57,50 @@ public interface PayWalletMapper extends BaseMapperX<PayWalletDO> { | ||||
|         return update(null, lambdaUpdateWrapper); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 冻结钱包部分余额 | ||||
|      * @param id 钱包 id | ||||
|      * @param price 冻结金额 | ||||
|      */ | ||||
|     default int freezePrice(Long id, Integer price){ | ||||
|         LambdaUpdateWrapper<PayWalletDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<PayWalletDO>() | ||||
|                 .setSql(" balance = balance - " + price | ||||
|                         + ", freeze_price = freeze_price + " + price) | ||||
|                 .eq(PayWalletDO::getId, id) | ||||
|                 .ge(PayWalletDO::getBalance, price); // cas 逻辑 | ||||
|         return update(null, lambdaUpdateWrapper); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 解冻钱包余额 | ||||
|      * @param id 钱包 id | ||||
|      * @param price 解冻金额 | ||||
|      */ | ||||
|     default int unFreezePrice(Long id, Integer price){ | ||||
|         LambdaUpdateWrapper<PayWalletDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<PayWalletDO>() | ||||
|                 .setSql(" balance = balance + " + price | ||||
|                         + ", freeze_price = freeze_price - " + price) | ||||
|                 .eq(PayWalletDO::getId, id) | ||||
|                 .ge(PayWalletDO::getFreezePrice, price); // cas 逻辑 | ||||
|         return update(null, lambdaUpdateWrapper); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 当充值退款时, 更新钱包 | ||||
|      * @param id 钱包 id | ||||
|      * @param price 退款金额 | ||||
|      */ | ||||
|     default  int updateWhenRechargeRefund(Long id, Integer price){ | ||||
|         LambdaUpdateWrapper<PayWalletDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<PayWalletDO>() | ||||
|                 .setSql(" freeze_price = freeze_price - " + price | ||||
|                         + ", total_recharge = total_recharge - " + price) | ||||
|                 .eq(PayWalletDO::getId, id) | ||||
|                 .ge(PayWalletDO::getFreezePrice, price) | ||||
|                 .ge(PayWalletDO::getTotalRecharge, price);// cas 逻辑 | ||||
|         return update(null, lambdaUpdateWrapper); | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -13,6 +13,11 @@ public interface PayWalletRechargeMapper extends BaseMapperX<PayWalletRechargeDO | ||||
|                 .eq(PayWalletRechargeDO::getId, id).eq(PayWalletRechargeDO::getPayStatus, wherePayStatus)); | ||||
|     } | ||||
|  | ||||
|     default  int updateByIdAndRefunded(Long id, Integer whereRefundStatus, PayWalletRechargeDO updateObj){ | ||||
|         return update(updateObj, new LambdaQueryWrapperX<PayWalletRechargeDO>() | ||||
|                 .eq(PayWalletRechargeDO::getId, id).eq(PayWalletRechargeDO::getRefundStatus, whereRefundStatus)); | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -29,4 +29,17 @@ public interface PayWalletRechargeService { | ||||
|      */ | ||||
|     void updateWalletRechargerPaid(Long id, Long payOrderId); | ||||
|  | ||||
|     /** | ||||
|      * 发起钱包充值退款 | ||||
|      * @param id 钱包充值编号 | ||||
|      * @param userIp 用户 ip 地址 | ||||
|      */ | ||||
|     void refundWalletRecharge(Long id, String userIp); | ||||
|  | ||||
|     /** | ||||
|      * 更新钱包充值记录为已退款 | ||||
|      * @param id  钱包充值 id | ||||
|      * @param payRefundId 退款单id | ||||
|      */ | ||||
|     void updateWalletRechargeRefunded(Long id, Long payRefundId); | ||||
| } | ||||
|   | ||||
| @@ -1,15 +1,21 @@ | ||||
| package cn.iocoder.yudao.module.pay.service.wallet; | ||||
|  | ||||
| import cn.hutool.core.lang.Assert; | ||||
| import cn.iocoder.yudao.framework.pay.core.enums.refund.PayRefundStatusRespEnum; | ||||
| import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO; | ||||
| import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundCreateReqDTO; | ||||
| import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.recharge.AppPayWalletRechargeCreateReqVO; | ||||
| import cn.iocoder.yudao.module.pay.convert.wallet.PayWalletRechargeConvert; | ||||
| import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO; | ||||
| 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.PayWalletRechargeDO; | ||||
| import cn.iocoder.yudao.module.pay.dal.mysql.wallet.PayWalletRechargeMapper; | ||||
| import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum; | ||||
| import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum; | ||||
| import cn.iocoder.yudao.module.pay.enums.refund.PayRefundStatusEnum; | ||||
| 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.stereotype.Service; | ||||
| import org.springframework.transaction.annotation.Transactional; | ||||
| @@ -24,6 +30,7 @@ import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.add | ||||
| import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; | ||||
| import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; | ||||
| import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*; | ||||
| import static cn.iocoder.yudao.module.pay.enums.refund.PayRefundStatusEnum.*; | ||||
|  | ||||
| /** | ||||
|  * 钱包充值 Service 实现类 | ||||
| @@ -47,6 +54,8 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { | ||||
|     private PayWalletService payWalletService; | ||||
|     @Resource | ||||
|     private PayOrderService payOrderService; | ||||
|     @Resource | ||||
|     private PayRefundService payRefundService; | ||||
|  | ||||
|     @Override | ||||
|     @Transactional(rollbackFor = Exception.class) | ||||
| @@ -98,6 +107,113 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { | ||||
|                 PayWalletBizTypeEnum.RECHARGE, walletRecharge.getTotalPrice()); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     @Transactional(rollbackFor = Exception.class) | ||||
|     public void refundWalletRecharge(Long id, String userIp) { | ||||
|         // 1.1 获取钱包充值记录 | ||||
|         PayWalletRechargeDO walletRecharge = walletRechargeMapper.selectById(id); | ||||
|         if (walletRecharge == null) { | ||||
|             log.error("[refundWalletRecharge][钱包充值记录不存在,钱包充值记录 id({})]", id); | ||||
|             throw exception(WALLET_RECHARGE_NOT_FOUND); | ||||
|         } | ||||
|         // 1.2 校验钱包充值是否可以发起退款 | ||||
|         PayWalletDO wallet = validateWalletRechargeCanRefund(walletRecharge); | ||||
|         // 2 冻结退款的余额,  暂时只处理赠送的余额也全部退回 | ||||
|         payWalletService.freezePrice(wallet.getId(), walletRecharge.getTotalPrice()); | ||||
|         // 3 创建退款单 | ||||
|         String walletRechargeId = String.valueOf(id); | ||||
|         String refundId = walletRechargeId + "-refund"; | ||||
|         Long payRefundId =  payRefundService.createPayRefund(new PayRefundCreateReqDTO() | ||||
|                 .setAppId(WALLET_PAY_APP_ID).setUserIp(userIp) | ||||
|                 .setMerchantOrderId(walletRechargeId) | ||||
|                 .setMerchantRefundId(refundId) | ||||
|                 .setReason("想退钱").setPrice(walletRecharge.getPayPrice())); | ||||
|         // 4 更新充值记录退款单号 | ||||
|         walletRechargeMapper.updateById(new PayWalletRechargeDO().setPayRefundId(payRefundId) | ||||
|                 .setRefundStatus(WAITING.getStatus()).setId(walletRecharge.getId())); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     @Transactional(rollbackFor = Exception.class) | ||||
|     public void updateWalletRechargeRefunded(Long id, Long payRefundId) { | ||||
|         // 1.1 获取钱包充值记录 | ||||
|         PayWalletRechargeDO walletRecharge = walletRechargeMapper.selectById(id); | ||||
|         if (walletRecharge == null) { | ||||
|             log.error("[updateWalletRechargerPaid][钱包充值记录不存在,钱包充值记录 id({})]", id); | ||||
|             throw exception(WALLET_RECHARGE_NOT_FOUND); | ||||
|         } | ||||
|         // 1.2 校验钱包充值是否可以更新已退款 | ||||
|         PayRefundDO payRefund = validateWalletRechargeCanRefunded(walletRecharge, payRefundId); | ||||
|  | ||||
|         PayWalletRechargeDO updateObj = new PayWalletRechargeDO().setId(id); | ||||
|         // 退款成功 | ||||
|         if (PayRefundStatusEnum.isSuccess(payRefund.getStatus())) { | ||||
|             // 2.1 更新钱包余额 | ||||
|             payWalletService.reduceWalletBalance(walletRecharge.getWalletId(), id, | ||||
|                     PayWalletBizTypeEnum.RECHARGE_REFUND, walletRecharge.getTotalPrice()); | ||||
|  | ||||
|             updateObj.setRefundStatus(SUCCESS.getStatus()).setRefundTime(payRefund.getSuccessTime()) | ||||
|                     .setRefundTotalPrice(walletRecharge.getTotalPrice()).setRefundPayPrice(walletRecharge.getPayPrice()) | ||||
|                     .setRefundBonusPrice(walletRecharge.getBonusPrice()); | ||||
|         } | ||||
|         // 退款失败 | ||||
|         if (PayRefundStatusRespEnum.isFailure(payRefund.getStatus())) { | ||||
|             // 2.2 解冻余额 | ||||
|             payWalletService.unFreezePrice(walletRecharge.getWalletId(), walletRecharge.getTotalPrice()); | ||||
|  | ||||
|             updateObj.setRefundStatus(FAILURE.getStatus()); | ||||
|         } | ||||
|         // 3. 更新钱包充值的退款字段 | ||||
|         walletRechargeMapper.updateByIdAndRefunded(id, WAITING.getStatus(), updateObj); | ||||
|     } | ||||
|  | ||||
|     private PayRefundDO validateWalletRechargeCanRefunded(PayWalletRechargeDO walletRecharge, Long payRefundId) { | ||||
|         // 1. 校验退款订单匹配 | ||||
|         if (notEqual(walletRecharge.getPayRefundId(), payRefundId)) { | ||||
|             log.error("[validateWalletRechargeCanRefunded][钱包充值({}) 退款单不匹配({}),请进行处理!钱包充值的数据是:{}]", | ||||
|                     walletRecharge.getId(), payRefundId, toJsonString(walletRecharge)); | ||||
|             throw exception(WALLET_RECHARGE_REFUND_FAIL_REFUND_ORDER_ID_ERROR); | ||||
|         } | ||||
|  | ||||
|         // 2.1 校验退款订单 | ||||
|         PayRefundDO payRefund = payRefundService.getRefund(payRefundId); | ||||
|         if (payRefund == null) { | ||||
|             log.error("[validateWalletRechargeCanRefunded][payRefund({})不存在]", payRefundId); | ||||
|             throw exception(WALLET_RECHARGE_REFUND_FAIL_REFUND_NOT_FOUND); | ||||
|         } | ||||
|         // 2.2 校验退款金额一致 | ||||
|         if (notEqual(payRefund.getRefundPrice(), walletRecharge.getPayPrice())) { | ||||
|             log.error("[validateWalletRechargeCanRefunded][钱包({}) payRefund({}) 退款金额不匹配,请进行处理!钱包数据是:{},payRefund 数据是:{}]", | ||||
|                     walletRecharge.getId(), payRefundId, toJsonString(walletRecharge), toJsonString(payRefund)); | ||||
|             throw exception(WALLET_RECHARGE_REFUND_FAIL_REFUND_PRICE_NOT_MATCH); | ||||
|         } | ||||
|         // 2.3 校验退款订单商户订单是否匹配 | ||||
|         if (notEqual(payRefund.getMerchantOrderId(), walletRecharge.getId().toString())) { | ||||
|             log.error("[validateWalletRechargeCanRefunded][钱包({}) 退款单不匹配({}),请进行处理!payRefund 数据是:{}]", | ||||
|                     walletRecharge.getId(), payRefundId, toJsonString(payRefund)); | ||||
|             throw exception(WALLET_RECHARGE_REFUND_FAIL_REFUND_ORDER_ID_ERROR); | ||||
|         } | ||||
|         return payRefund; | ||||
|     } | ||||
|  | ||||
|     private PayWalletDO validateWalletRechargeCanRefund(PayWalletRechargeDO walletRecharge) { | ||||
|         // 校验充值订单是否支付 | ||||
|         if (!walletRecharge.getPayStatus()) { | ||||
|             throw exception(WALLET_RECHARGE_REFUND_FAIL_NOT_PAID); | ||||
|         } | ||||
|         // 校验充值订单是否已退款 | ||||
|         if (walletRecharge.getPayRefundId() != null) { | ||||
|             throw exception(WALLET_RECHARGE_REFUND_FAIL_REFUNDED); | ||||
|         } | ||||
|         // 校验钱包余额是否足够 | ||||
|         PayWalletDO wallet = payWalletService.getWallet(walletRecharge.getWalletId()); | ||||
|         Assert.notNull(wallet, "用户钱包({}) 不存在", wallet.getId()); | ||||
|         if (wallet.getBalance() < walletRecharge.getTotalPrice()) { | ||||
|             throw exception(WALLET_RECHARGE_REFUND_BALANCE_NOT_ENOUGH); | ||||
|         } | ||||
|         return wallet; | ||||
|     } | ||||
|  | ||||
|     private PayOrderDO validateWalletRechargerCanPaid(PayWalletRechargeDO walletRecharge, Long payOrderId) { | ||||
|         // 1.1 校验充值记录的支付状态 | ||||
|         if (walletRecharge.getPayStatus()) { | ||||
|   | ||||
| @@ -50,15 +50,14 @@ public interface PayWalletService { | ||||
|     /** | ||||
|      * 扣减钱包余额 | ||||
|      * | ||||
|      * @param userId  用户 id | ||||
|      * @param userType 用户类型 | ||||
|      * @param walletId  钱包 id | ||||
|      * @param bizId 业务关联 id | ||||
|      * @param bizType 业务关联分类 | ||||
|      * @param price 扣减金额 | ||||
|      * @return 钱包流水 | ||||
|      */ | ||||
|     PayWalletTransactionDO reduceWalletBalance(Long userId, Integer userType, | ||||
|                                                Long bizId, PayWalletBizTypeEnum bizType, Integer price); | ||||
|     PayWalletTransactionDO reduceWalletBalance(Long walletId, Long bizId, | ||||
|                                                PayWalletBizTypeEnum bizType, Integer price); | ||||
|  | ||||
|     /** | ||||
|      * 增加钱包余额 | ||||
| @@ -72,4 +71,18 @@ public interface PayWalletService { | ||||
|     PayWalletTransactionDO addWalletBalance(Long walletId, String bizId, | ||||
|                                             PayWalletBizTypeEnum bizType, Integer price); | ||||
|  | ||||
|     /** | ||||
|      * 冻结钱包部分余额 | ||||
|      * | ||||
|      * @param id  钱包编号 | ||||
|      * @param price 冻结金额 | ||||
|      */ | ||||
|     void freezePrice(Long id, Integer price); | ||||
|  | ||||
|     /** | ||||
|      * 解冻钱包余额 | ||||
|      * @param id 钱包编号 | ||||
|      * @param price 解冻金额 | ||||
|      */ | ||||
|     void unFreezePrice(Long id, Integer price); | ||||
| } | ||||
|   | ||||
| @@ -68,8 +68,9 @@ public class PayWalletServiceImpl implements  PayWalletService { | ||||
|         if (orderExtension == null) { | ||||
|             throw exception(PAY_ORDER_EXTENSION_NOT_FOUND); | ||||
|         } | ||||
|         PayWalletDO wallet = getOrCreateWallet(userId, userType); | ||||
|         // 2. 扣减余额 | ||||
|         return reduceWalletBalance(userId, userType, orderExtension.getOrderId(), PAYMENT, price); | ||||
|         return reduceWalletBalance(wallet.getId(), orderExtension.getOrderId(), PAYMENT, price); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
| @@ -116,10 +117,14 @@ public class PayWalletServiceImpl implements  PayWalletService { | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public PayWalletTransactionDO reduceWalletBalance(Long userId, Integer userType, | ||||
|                                                       Long bizId, PayWalletBizTypeEnum bizType, Integer price) { | ||||
|     public PayWalletTransactionDO reduceWalletBalance(Long walletId, Long bizId, | ||||
|                                                       PayWalletBizTypeEnum bizType, Integer price) { | ||||
|         // 1. 获取钱包 | ||||
|         PayWalletDO payWallet = getOrCreateWallet(userId, userType); | ||||
|         PayWalletDO payWallet = getWallet(walletId); | ||||
|         if (payWallet == null) { | ||||
|             log.error("[reduceWalletBalance],用户钱包({})不存在.", walletId); | ||||
|             throw exception(WALLET_NOT_FOUND); | ||||
|         } | ||||
|  | ||||
|         // 2.1 扣除余额 | ||||
|         int updateCounts = 0 ; | ||||
| @@ -129,9 +134,13 @@ public class PayWalletServiceImpl implements  PayWalletService { | ||||
|                 break; | ||||
|             } | ||||
|             case RECHARGE_REFUND: { | ||||
|                 // TODO | ||||
|                 updateCounts = walletMapper.updateWhenRechargeRefund(payWallet.getId(), price); | ||||
|                 break; | ||||
|             } | ||||
|             default: { | ||||
|                 // TODO 其它类型待实现 | ||||
|                 throw new UnsupportedOperationException("待实现"); | ||||
|             } | ||||
|         } | ||||
|         if (updateCounts == 0) { | ||||
|             throw exception(WALLET_BALANCE_NOT_ENOUGH); | ||||
| @@ -163,7 +172,10 @@ public class PayWalletServiceImpl implements  PayWalletService { | ||||
|                 walletMapper.updateWhenRecharge(payWallet.getId(), price); | ||||
|                 break; | ||||
|             } | ||||
|             // TODO 其它类型;这里可以先跑异常;避免有业务搞错; | ||||
|             default: { | ||||
|                 // TODO 其它类型待实现 | ||||
|                 throw new UnsupportedOperationException("待实现"); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // 2. 生成钱包流水 | ||||
| @@ -173,4 +185,20 @@ public class PayWalletServiceImpl implements  PayWalletService { | ||||
|         return walletTransactionService.createWalletTransaction(transactionCreateReqBO); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void freezePrice(Long id, Integer price) { | ||||
|         int updateCounts = walletMapper.freezePrice(id, price); | ||||
|         if (updateCounts == 0) { | ||||
|             throw exception(WALLET_BALANCE_NOT_ENOUGH); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void unFreezePrice(Long id, Integer price) { | ||||
|         int updateCounts = walletMapper.unFreezePrice(id, price); | ||||
|         if (updateCounts == 0) { | ||||
|             throw exception(WALLET_FREEZE_PRICE_NOT_ENOUGH); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 YunaiV
					YunaiV