diff --git a/smart-switch-service/src/main/java/com/ruoyi/common/constants/DictTypeConstants.java b/smart-switch-service/src/main/java/com/ruoyi/common/constants/DictTypeConstants.java index 2e14b38a..b5c484e6 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/common/constants/DictTypeConstants.java +++ b/smart-switch-service/src/main/java/com/ruoyi/common/constants/DictTypeConstants.java @@ -11,4 +11,6 @@ public class DictTypeConstants { public static final String TIME_UNIT = "time_unit"; // 设备服务费类型 public static final String SERVICE_TYPE = "service_type"; + // 提现打款方式 + public static final String WITHDRAW_TYPE = "withdraw_type"; } diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/domain/TransactionBill.java b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/domain/TransactionBill.java index 41341778..b9562cf4 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/domain/TransactionBill.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/domain/TransactionBill.java @@ -187,6 +187,12 @@ public class TransactionBill extends BaseEntity implements Payable @ApiModelProperty("服务费退款金额") private BigDecimal refundServiceAmount; + @ApiModelProperty("支付凭证") + private String payPicture; + + @ApiModelProperty("提现方式") + private String withdrawType; + /** * 获取价格(分) */ diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/domain/dto/WithdrawApprovalDTO.java b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/domain/dto/WithdrawApprovalDTO.java new file mode 100644 index 00000000..238947b7 --- /dev/null +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/domain/dto/WithdrawApprovalDTO.java @@ -0,0 +1,34 @@ +package com.ruoyi.ss.transactionBill.domain.dto; + +import com.ruoyi.common.constants.DictTypeConstants; +import com.ruoyi.system.valid.DictValid; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * 提现审核DTO + * @author wjh + * 2024/7/27 + */ +@Data +public class WithdrawApprovalDTO { + + @ApiModelProperty("订单ID") + @NotNull(message = "订单ID不能为空") + private Long billId; + + @ApiModelProperty("审核意见") + private String remark; + + @ApiModelProperty("打款方式") + @NotBlank(message = "打款方式不能为空") + @DictValid(type = DictTypeConstants.WITHDRAW_TYPE, message = "非法的打款方式") + private String withdrawType; + + @ApiModelProperty("支付凭证") + private String payPicture; +} + diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/domain/enums/TransactionBillPayType.java b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/domain/enums/TransactionBillPayType.java index c4164753..c8604bf8 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/domain/enums/TransactionBillPayType.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/domain/enums/TransactionBillPayType.java @@ -18,7 +18,9 @@ public enum TransactionBillPayType { WECHAT(1L, "微信支付", AccountType.WECHAT), ALI(2L, "支付宝", AccountType.ALIPAY), - BANK(3L, "银行卡", AccountType.BANK_CARD); + BANK(3L, "银行卡", AccountType.BANK_CARD), + BALANCE(4L, "余额支付", null) + ; private final Long type; private final String name; diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/domain/enums/WithdrawType.java b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/domain/enums/WithdrawType.java new file mode 100644 index 00000000..66455971 --- /dev/null +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/domain/enums/WithdrawType.java @@ -0,0 +1,20 @@ +package com.ruoyi.ss.transactionBill.domain.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * @author wjh + * 2024/7/27 + */ +@Getter +@AllArgsConstructor +public enum WithdrawType { + + ONLINE("1", "线上提现"), + OFFLINE("2", "线下提现"); + + private final String type; + private final String msg; + +} diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/mapper/TransactionBillMapper.java b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/mapper/TransactionBillMapper.java index 07ebf5c8..a0b56b8c 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/mapper/TransactionBillMapper.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/mapper/TransactionBillMapper.java @@ -118,7 +118,7 @@ public interface TransactionBillMapper * 提现成功 * @param billId id */ - int withdrawSuccess(Long billId); + int withdrawSuccess(@Param("billId") Long billId, @Param("payTime")LocalDateTime payTime); /** * 提现失败 diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/mapper/TransactionBillMapper.xml b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/mapper/TransactionBillMapper.xml index 9bc35723..95a004aa 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/mapper/TransactionBillMapper.xml +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/mapper/TransactionBillMapper.xml @@ -46,6 +46,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" stb.refund_amount, stb.refund_mch_amount, stb.refund_service_amount, + stb.pay_picture, + stb.withdraw_type, su.user_name as user_name, su1.user_name as mch_name, su1.phonenumber as mch_mobile @@ -233,6 +235,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" refund_amount, refund_mch_amount, refund_service_amount, + pay_picture, + withdraw_type, #{billNo}, @@ -271,6 +275,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{refundAmount}, #{refundMchAmount}, #{refundServiceAmount}, + #{payPicture}, + #{withdrawType}, @@ -326,6 +332,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" refund_amount = #{data.refundAmount}, refund_mch_amount = #{data.refundMchAmount}, refund_service_amount = #{data.refundServiceAmount}, + pay_picture = #{data.payPicture}, + withdraw_type = #{data.withdrawType}, @@ -397,7 +405,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" update sm_transaction_bill - set status = '14' + set status = '14', + pay_time = #{payTime} where bill_id = #{billId} and status = '16' diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/TransactionBillService.java b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/TransactionBillService.java index d569780e..03b0f981 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/TransactionBillService.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/TransactionBillService.java @@ -6,9 +6,11 @@ import com.ruoyi.ss.transactionBill.domain.TransactionBillQuery; import com.ruoyi.ss.transactionBill.domain.TransactionBillVo; import com.ruoyi.ss.transactionBill.domain.bo.TransactionBillBO; import com.ruoyi.ss.transactionBill.domain.dto.BillRefundDTO; +import com.ruoyi.ss.transactionBill.domain.dto.WithdrawApprovalDTO; import com.ruoyi.ss.transactionBill.domain.enums.TransactionBillStatus; import java.math.BigDecimal; +import java.time.LocalDateTime; import java.util.Date; import java.util.List; import java.util.Map; @@ -125,17 +127,17 @@ public interface TransactionBillService /** * 提现审核通过 - * @param billId id - * @param remark 审核意见 + * + * @param dto id */ - boolean passWithdraw(Long billId, String remark); + boolean passWithdraw(WithdrawApprovalDTO dto); /** * 提现审核拒绝 - * @param billId id - * @param remark 审核意见 + * + * @param dto id */ - boolean rejectWithdraw(Long billId, String remark); + boolean rejectWithdraw(WithdrawApprovalDTO dto); /** * 提现打款 @@ -145,9 +147,11 @@ public interface TransactionBillService /** * 提现成功 - * @param billId id + * + * @param billId id + * @param payTime */ - void withdrawSuccess(Long billId); + void withdrawSuccess(Long billId, LocalDateTime payTime); /** * 提现失败 diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/TransactionBillServiceImpl.java b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/TransactionBillServiceImpl.java index b371004c..1b8b0212 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/TransactionBillServiceImpl.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/TransactionBillServiceImpl.java @@ -29,6 +29,7 @@ import com.ruoyi.ss.transactionBill.domain.TransactionBillQuery; import com.ruoyi.ss.transactionBill.domain.TransactionBillVo; import com.ruoyi.ss.transactionBill.domain.bo.TransactionBillBO; import com.ruoyi.ss.transactionBill.domain.dto.BillRefundDTO; +import com.ruoyi.ss.transactionBill.domain.dto.WithdrawApprovalDTO; import com.ruoyi.ss.transactionBill.domain.enums.*; import com.ruoyi.ss.transactionBill.mapper.TransactionBillMapper; import com.ruoyi.ss.transactionBill.service.TransactionBillService; @@ -437,6 +438,7 @@ public class TransactionBillServiceImpl implements TransactionBillService { bill.setAfterBalance(afterUser.getBalance()); bill.setAccountNo(accountNo); bill.setChannelId(data.getChannelId()); + bill.setWithdrawType(WithdrawType.ONLINE.getType()); ServiceUtil.assertion(this.insertSmTransactionBill(bill) != 1, "提现申请失败"); return bill.getBillNo(); @@ -448,41 +450,65 @@ public class TransactionBillServiceImpl implements TransactionBillService { /** * 提现审核通过 - * @param billId id - * @param remark 审核意见 + * + * @param dto id */ @Override - @Transactional - public boolean passWithdraw(Long billId, String remark) { + public boolean passWithdraw(WithdrawApprovalDTO dto) { + ServiceUtil.assertion(dto.getBillId() == null, "提现申请ID不允许为空"); + ServiceUtil.assertion(!redisLock.lock(RedisLockKey.APPROVAL_WITHDRAW, dto.getBillId()), "该提现申请正在审核,请刷新后重试"); try { - ServiceUtil.assertion(!redisLock.lock(RedisLockKey.APPROVAL_WITHDRAW, billId.toString()), "该提现申请正在审核,请刷新后重试"); + transactionTemplate.execute(status -> { + int updateCount = this.approvalWithdraw(dto, TransactionBillStatus.WITHDRAW_PASSED); + ServiceUtil.assertion(updateCount != 1, "提现审核失败,请刷新后重试"); + return updateCount; + }); - int updateCount = transactionBillMapper.doPassWithdraw(billId, remark); - ServiceUtil.assertion(updateCount != 1, "提现审核失败,请刷新后重试"); + this.payWithdraw(dto.getBillId()); return true; } finally { - redisLock.unlock(RedisLockKey.APPROVAL_WITHDRAW, billId.toString()); + redisLock.unlock(RedisLockKey.APPROVAL_WITHDRAW, dto.toString()); } } + /** + * 审核操作 + */ + private int approvalWithdraw(WithdrawApprovalDTO dto, TransactionBillStatus status) { + TransactionBill data = new TransactionBill(); + data.setStatus(status.getStatus()); + data.setRemark(dto.getRemark()); + data.setPayPicture(dto.getPayPicture()); + data.setWithdrawType(dto.getWithdrawType()); + TransactionBillQuery query = new TransactionBillQuery(); + query.setBillId(dto.getBillId()); + query.setType(TransactionBillType.WITHDRAW.getType()); + query.setStatus(TransactionBillStatus.WITHDRAW_APPROVING.getStatus()); + return this.updateByQuery(data, query); + } + @Override - @Transactional - public boolean rejectWithdraw(Long billId, String remark) { + public boolean rejectWithdraw(WithdrawApprovalDTO dto) { + ServiceUtil.assertion(dto.getBillId() == null, "提现申请ID不允许为空"); + ServiceUtil.assertion(!redisLock.lock(RedisLockKey.APPROVAL_WITHDRAW, dto.getBillId()), "该提现申请正在审核,请刷新后重试"); try { - ServiceUtil.assertion(!redisLock.lock(RedisLockKey.APPROVAL_WITHDRAW, billId.toString()), "该提现申请正在审核,请刷新后重试"); + transactionTemplate.execute(status -> { + // 审核 + int updateCount = this.approvalWithdraw(dto, TransactionBillStatus.WITHDRAW_REJECTED); + ServiceUtil.assertion(updateCount != 1, "提现审核失败,请刷新后重试"); - int updateCount = transactionBillMapper.doRejectWithdraw(billId, remark); - ServiceUtil.assertion(updateCount != 1, "提现审核失败,请刷新后重试"); + // 返还客户余额 + TransactionBill bill = transactionBillMapper.selectSmTransactionBillByBillId(dto.getBillId()); + ServiceUtil.assertion(bill == null || bill.getUserId() == null, "数据不存在"); + userService.addBalance(bill.getUserId(), bill.getMoney(), "提现驳回"); - // 返还客户余额 - TransactionBill bill = transactionBillMapper.selectSmTransactionBillByBillId(billId); - ServiceUtil.assertion(bill == null || bill.getUserId() == null, "数据不存在"); - userService.addBalance(bill.getUserId(), bill.getMoney(), "提现驳回"); + return updateCount; + }); return true; } finally { - redisLock.unlock(RedisLockKey.APPROVAL_WITHDRAW, billId.toString()); + redisLock.unlock(RedisLockKey.APPROVAL_WITHDRAW, dto.toString()); } } @@ -491,39 +517,59 @@ public class TransactionBillServiceImpl implements TransactionBillService { * @param billId 提现单id */ @Override - @Transactional public boolean payWithdraw(Long billId) { ServiceUtil.assertion(billId == null, "参数错误:提现打款id不允许为空"); + ServiceUtil.assertion(!redisLock.lock(RedisLockKey.PAY_WITHDRAW, billId), "该提现申请正在打款,请刷新后重试"); try { - ServiceUtil.assertion(!redisLock.lock(RedisLockKey.PAY_WITHDRAW, billId.toString()), "该提现申请正在打款,请刷新后重试"); - - TransactionBill bill = transactionBillMapper.selectSmTransactionBillByBillId(billId); + TransactionBillVo bill = transactionBillMapper.selectSmTransactionBillByBillId(billId); ServiceUtil.assertion(bill == null, "单据不存在"); - // 更新为打款中 - int updateCount = transactionBillMapper.doPayWithdraw(billId); - ServiceUtil.assertion(updateCount != 1, "单据状态发生变化,请刷新后重试"); + transactionTemplate.execute(status -> { + // 更新为打款中 + int updateCount = transactionBillMapper.doPayWithdraw(billId); + ServiceUtil.assertion(updateCount != 1, "单据状态发生变化,请刷新后重试"); - // 发起打款 - if (TransactionBillPayType.WECHAT.getType().equals(bill.getChannelId())) { - InitiateBatchTransferResponse res = wxPayService.payWithdraw(billId); - log.debug(String.valueOf(res)); - } else { - throw new ServiceException("其他打款方式正在开发中"); - } + // 发起打款(线上) + if (WithdrawType.ONLINE.getType().equals(bill.getWithdrawType())) { + // 微信 + if (TransactionBillPayType.WECHAT.getType().equals(bill.getChannelId())) { + InitiateBatchTransferResponse res = wxPayService.payWithdraw(billId); + log.debug(String.valueOf(res)); + } else { + throw new ServiceException("其他打款渠道正在开发中"); + } + } + // 线下 + else if(WithdrawType.OFFLINE.getType().equals(bill.getWithdrawType())) { + this.payWithdrawByOffline(bill); + } else { + throw new ServiceException("不支持的打款方式"); + } + + return updateCount; + }); return true; } finally { - redisLock.unlock(RedisLockKey.PAY_WITHDRAW, billId.toString()); + redisLock.unlock(RedisLockKey.PAY_WITHDRAW, billId); } } + /** + * 线下打款 + */ + private void payWithdrawByOffline(TransactionBillVo bill) { + this.withdrawSuccess(bill.getBillId(), LocalDateTime.now()); + } + @Override - @Transactional - public void withdrawSuccess(Long billId) { - // 修改状态 - int updateCount = transactionBillMapper.withdrawSuccess(billId); - ServiceUtil.assertion(updateCount != 1, "单据状态发生变化,请刷新后重试"); + public void withdrawSuccess(Long billId, LocalDateTime payTime) { + transactionTemplate.execute(status -> { + // 修改状态 + int updateCount = transactionBillMapper.withdrawSuccess(billId, payTime); + ServiceUtil.assertion(updateCount != 1, "单据状态发生变化,请刷新后重试"); + return updateCount; + }); } @Override diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/wxPay/service/WxPayService.java b/smart-switch-service/src/main/java/com/ruoyi/ss/wxPay/service/WxPayService.java index 4f769bde..a70be9d6 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/wxPay/service/WxPayService.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/wxPay/service/WxPayService.java @@ -45,6 +45,7 @@ import org.springframework.transaction.annotation.Transactional; import javax.servlet.http.HttpServletRequest; import java.math.BigDecimal; +import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.Objects; @@ -273,7 +274,7 @@ public class WxPayService implements IWxPayService { // 修改订单状态 if (TransferBatchStatus.FINISHED.getStatus().equals(transferBatchGet.getBatchStatus())) { // 提现成功 - transactionBillService.withdrawSuccess(bill.getBillId()); + transactionBillService.withdrawSuccess(bill.getBillId(), LocalDateTime.now()); } else if (TransferBatchStatus.CLOSED.getStatus().equals(transferBatchGet.getBatchStatus())) { // 提现失败 transactionBillService.withdrawFailed(bill.getBillId()); diff --git a/smart-switch-web/src/main/java/com/ruoyi/web/controller/ss/SmTransactionBillController.java b/smart-switch-web/src/main/java/com/ruoyi/web/controller/ss/SmTransactionBillController.java index 9c0fd960..53bbc772 100644 --- a/smart-switch-web/src/main/java/com/ruoyi/web/controller/ss/SmTransactionBillController.java +++ b/smart-switch-web/src/main/java/com/ruoyi/web/controller/ss/SmTransactionBillController.java @@ -1,15 +1,13 @@ package com.ruoyi.web.controller.ss; -import java.util.Arrays; import java.util.List; -import java.util.Objects; import javax.servlet.http.HttpServletResponse; import com.ruoyi.common.core.domain.model.LoginUser; -import com.ruoyi.ss.transactionBill.domain.bo.TransactionBillBO; import com.ruoyi.ss.transactionBill.domain.TransactionBillQuery; import com.ruoyi.ss.transactionBill.domain.TransactionBillVo; import com.ruoyi.ss.transactionBill.domain.dto.BillRefundDTO; +import com.ruoyi.ss.transactionBill.domain.dto.WithdrawApprovalDTO; import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiOperation; import org.springframework.security.access.prepost.PreAuthorize; @@ -124,18 +122,18 @@ public class SmTransactionBillController extends BaseController @PreAuthorize("@ss.hasPermi('system:bill:approval')") @PutMapping("/withdraw/pass") @Log(title = "同意提现申请", businessType = BusinessType.UPDATE) - public AjaxResult passWithdraw(@RequestBody TransactionBillBO bo) + public AjaxResult passWithdraw(@RequestBody @Validated WithdrawApprovalDTO dto) { - return success(smTransactionBillService.passWithdraw(bo.getBillId(), bo.getRemark())); + return success(smTransactionBillService.passWithdraw(dto)); } @ApiOperation("拒绝提现申请") @PreAuthorize("@ss.hasPermi('system:bill:approval')") @PutMapping("/withdraw/reject") @Log(title = "拒绝提现申请", businessType = BusinessType.UPDATE) - public AjaxResult rejectWithdraw(@RequestBody TransactionBillBO bo) + public AjaxResult rejectWithdraw(@RequestBody @Validated WithdrawApprovalDTO dto) { - return success(smTransactionBillService.rejectWithdraw(bo.getBillId(), bo.getRemark())); + return success(smTransactionBillService.rejectWithdraw(dto)); } @ApiOperation("提现打款")