diff --git a/keyboard-server/src/main/java/com/yolo/keyboard/service/tenantwithdraworder/KeyboardTenantWithdrawOrderServiceImpl.java b/keyboard-server/src/main/java/com/yolo/keyboard/service/tenantwithdraworder/KeyboardTenantWithdrawOrderServiceImpl.java index 5759bce..5b5889b 100644 --- a/keyboard-server/src/main/java/com/yolo/keyboard/service/tenantwithdraworder/KeyboardTenantWithdrawOrderServiceImpl.java +++ b/keyboard-server/src/main/java/com/yolo/keyboard/service/tenantwithdraworder/KeyboardTenantWithdrawOrderServiceImpl.java @@ -75,38 +75,128 @@ public class KeyboardTenantWithdrawOrderServiceImpl implements KeyboardTenantWit KeyboardTenantWithdrawOrderDO updateObj = BeanUtils.toBean(updateReqVO, KeyboardTenantWithdrawOrderDO.class); tenantWithdrawOrderMapper.updateById(updateObj); - // 如果提现状态更新为成功(PAID),则扣除提现用户的冻结金额并创建流水记录 String newStatus = updateReqVO.getStatus(); - if ("PAID".equals(newStatus) && !"PAID".equals(existingOrder.getStatus())) { - // 获取提现用户的余额记录 - TenantBalanceDO balance = tenantBalanceMapper.selectById(existingOrder.getTenantId()); - if (balance != null) { - // 扣除冻结金额 - BigDecimal frozenAmt = balance.getFrozenAmt() != null ? balance.getFrozenAmt() : BigDecimal.ZERO; - BigDecimal withdrawAmount = existingOrder.getAmount(); - BigDecimal newFrozenAmt = frozenAmt.subtract(withdrawAmount); - // 确保冻结金额不为负数 - if (newFrozenAmt.compareTo(BigDecimal.ZERO) < 0) { - newFrozenAmt = BigDecimal.ZERO; - } - balance.setFrozenAmt(newFrozenAmt); - tenantBalanceMapper.updateById(balance); + String oldStatus = existingOrder.getStatus(); - // 创建提现成功的流水记录 - TenantBalanceTransactionDO transaction = TenantBalanceTransactionDO.builder() - .bizNo(existingOrder.getBizNo()) - .points(withdrawAmount.negate()) // 提现金额(负数表示支出) - .balance(balance.getWithdrawableBalance() != null ? balance.getWithdrawableBalance() : BigDecimal.ZERO) // 当前可提现余额 - .tenantId(existingOrder.getTenantId()) - .type("WITHDRAW_SUCCESS") - .description("提现成功") - .orderId(existingOrder.getWithdrawNo()) - .operatorId(TenantContextHolder.getTenantId()) - .createdAt(LocalDateTime.now()) - .build(); - tenantBalanceTransactionMapper.insert(transaction); - } + // 如果提现状态更新为成功(PAID),则扣除提现用户的冻结金额并创建流水记录 + if ("PAID".equals(newStatus) && !"PAID".equals(oldStatus)) { + handleWithdrawSuccess(existingOrder); } + // 如果提现状态更新为已拒绝、已取消、打款失败,则返还冻结金额到可提现余额并创建流水记录 + else if (isRefundStatus(newStatus) && !isRefundStatus(oldStatus)) { + handleWithdrawRefund(existingOrder, newStatus, updateReqVO.getReason()); + } + } + + /** + * 判断是否为需要退还冻结金额的状态 + */ + private boolean isRefundStatus(String status) { + return "REJECTED".equals(status) || "CANCELED".equals(status) || "FAILED".equals(status); + } + + /** + * 处理提现成功:扣除冻结金额并记录流水 + */ + private void handleWithdrawSuccess(KeyboardTenantWithdrawOrderDO order) { + TenantBalanceDO balance = tenantBalanceMapper.selectById(order.getTenantId()); + if (balance == null) { + return; + } + + // 扣除冻结金额 + BigDecimal frozenAmt = balance.getFrozenAmt() != null ? balance.getFrozenAmt() : BigDecimal.ZERO; + BigDecimal withdrawAmount = order.getAmount(); + BigDecimal newFrozenAmt = frozenAmt.subtract(withdrawAmount); + if (newFrozenAmt.compareTo(BigDecimal.ZERO) < 0) { + newFrozenAmt = BigDecimal.ZERO; + } + balance.setFrozenAmt(newFrozenAmt); + tenantBalanceMapper.updateById(balance); + + // 创建提现成功的流水记录 + TenantBalanceTransactionDO transaction = TenantBalanceTransactionDO.builder() + .bizNo(order.getBizNo()) + .points(withdrawAmount.negate()) // 提现金额(负数表示支出) + .balance(balance.getWithdrawableBalance() != null ? balance.getWithdrawableBalance() : BigDecimal.ZERO) + .tenantId(order.getTenantId()) + .type("WITHDRAW_SUCCESS") + .description("提现成功") + .orderId(order.getWithdrawNo()) + .operatorId(TenantContextHolder.getTenantId()) + .createdAt(LocalDateTime.now()) + .build(); + tenantBalanceTransactionMapper.insert(transaction); + } + + /** + * 处理提现退还:返还冻结金额到可提现余额并记录流水 + * + * @param order 提现订单 + * @param newStatus 新状态 + * @param reason 拒绝/失败/取消原因 + */ + private void handleWithdrawRefund(KeyboardTenantWithdrawOrderDO order, String newStatus, String reason) { + TenantBalanceDO balance = tenantBalanceMapper.selectById(order.getTenantId()); + if (balance == null) { + return; + } + + BigDecimal withdrawAmount = order.getAmount(); + + // 扣除冻结金额 + BigDecimal frozenAmt = balance.getFrozenAmt() != null ? balance.getFrozenAmt() : BigDecimal.ZERO; + BigDecimal newFrozenAmt = frozenAmt.subtract(withdrawAmount); + if (newFrozenAmt.compareTo(BigDecimal.ZERO) < 0) { + newFrozenAmt = BigDecimal.ZERO; + } + balance.setFrozenAmt(newFrozenAmt); + + // 返还到可提现余额 + BigDecimal withdrawableBalance = balance.getWithdrawableBalance() != null ? balance.getWithdrawableBalance() : BigDecimal.ZERO; + BigDecimal newWithdrawableBalance = withdrawableBalance.add(withdrawAmount); + balance.setWithdrawableBalance(newWithdrawableBalance); + + tenantBalanceMapper.updateById(balance); + + // 根据状态确定流水类型和描述 + String type; + String description; + switch (newStatus) { + case "REJECTED": + type = "WITHDRAW_REJECTED"; + description = "提现被拒绝,金额已退还"; + break; + case "CANCELED": + type = "WITHDRAW_CANCELED"; + description = "提现已取消,金额已退还"; + break; + case "FAILED": + type = "WITHDRAW_FAILED"; + description = "提现打款失败,金额已退还"; + break; + default: + type = "WITHDRAW_REFUND"; + description = "提现退还"; + } + + // 备注:优先使用传入的原因,如果没有则使用默认描述 + String remark = (reason != null && !reason.trim().isEmpty()) ? reason : description; + + // 创建退还流水记录 + TenantBalanceTransactionDO transaction = TenantBalanceTransactionDO.builder() + .bizNo(order.getBizNo()) + .points(withdrawAmount) // 退还金额(正数表示收入) + .balance(newWithdrawableBalance) // 退还后的可提现余额 + .tenantId(order.getTenantId()) + .type(type) + .description(description) + .remark(remark) + .orderId(order.getWithdrawNo()) + .operatorId(TenantContextHolder.getTenantId()) + .createdAt(LocalDateTime.now()) + .build(); + tenantBalanceTransactionMapper.insert(transaction); } @Override