fix(tenantwithdraworder): 修复提现失败时冻结金额未退还问题
新增 handleWithdrawRefund 逻辑,当状态为 REJECTED/CANCELED/FAILED 时自动返还冻结金额至可提现余额并生成对应流水。
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user