|
|
@@ -492,6 +492,95 @@ public class WxPayServiceImpl implements WxPayService {
|
|
|
}
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
+ * 手动确认退款(针对超过365天的订单)
|
|
|
+ *
|
|
|
+ * @param refundLogId 退款记录ID
|
|
|
+ */
|
|
|
+ @DS("db-miniapp")
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public void manualConfirmRefund(long refundLogId) {
|
|
|
+ // 通过退款申请id获取退款申请记录
|
|
|
+ var refundLog = refundLogService.getById(refundLogId);
|
|
|
+ if (refundLog == null) {
|
|
|
+ throw new BusinessException("退款记录不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查退款状态,只能处理已申请状态的退款
|
|
|
+ if (!RefundLog.STATUS_退款已申请.equals(refundLog.getStatus())) {
|
|
|
+ throw new BusinessException("退款状态不正确,只能处理已申请状态的退款");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 验证是否超过退款时限(365天)
|
|
|
+ var payLog = payLogService.lambdaQuery()
|
|
|
+ .eq(PayLog::getOutTradeNo, refundLog.getOutTradeNo())
|
|
|
+ .eq(PayLog::getTradeState, PayLog.STATUS_充值成功)
|
|
|
+ .one();
|
|
|
+
|
|
|
+ if (payLog == null) {
|
|
|
+ throw new BusinessException("找不到对应的支付记录");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查是否超过365天退款时限
|
|
|
+ LocalDateTime paySuccessTime = payLog.getSuccessTime();
|
|
|
+ boolean isOverdue = paySuccessTime.plusDays(365).isBefore(LocalDateTime.now());
|
|
|
+
|
|
|
+ if (!isOverdue) {
|
|
|
+ throw new BusinessException("该订单未超过365天退款时限,应使用正常退款流程");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 钱包流水
|
|
|
+ var walletDetail = new WalletDetail()
|
|
|
+ .setType(WalletDetail.TYPE_提现)
|
|
|
+ .setStatus(WalletDetail.STATUS_待确认)
|
|
|
+ .setUserId(refundLog.getUserId())
|
|
|
+ .setAmount(refundLog.getRefund())
|
|
|
+ .setOrderNo(refundLog.getOutRefundNo());
|
|
|
+ walletDetailService.save(walletDetail);
|
|
|
+
|
|
|
+ // 执行与微信退款成功后相同的业务逻辑
|
|
|
+ processRefundSuccess(refundLog, walletDetail);
|
|
|
+
|
|
|
+ // 记录操作人员信息
|
|
|
+ refundLogService.lambdaUpdate()
|
|
|
+ .set(RefundLog::getAdminUserId, StpUtil.getLoginIdAsLong())
|
|
|
+ .set(RefundLog::getAdminUsername, StpUtil.getSession().getString("username"))
|
|
|
+ .eq(RefundLog::getId, refundLogId)
|
|
|
+ .update();
|
|
|
+
|
|
|
+ LOGGER.info("手动确认退款完成,退款记录ID:{},操作人员:{}", refundLogId, StpUtil.getSession().getString("username"));
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理退款成功的公共逻辑
|
|
|
+ *
|
|
|
+ * @param refundLog 退款记录
|
|
|
+ * @param walletDetail 钱包流水
|
|
|
+ */
|
|
|
+ private void processRefundSuccess(RefundLog refundLog, WalletDetail walletDetail) {
|
|
|
+ // 更新退款记录状态为退款成功
|
|
|
+ LocalDateTime successTime = LocalDateTime.now();
|
|
|
+ refundLogService.lambdaUpdate()
|
|
|
+ .set(RefundLog::getStatus, RefundLog.STATUS_退款成功)
|
|
|
+ .set(RefundLog::getSuccessTime, successTime)
|
|
|
+ .set(RefundLog::getUserReceivedAccount, "线下退款")
|
|
|
+ .eq(RefundLog::getId, refundLog.getId())
|
|
|
+ .update();
|
|
|
+
|
|
|
+ // 冻结金额扣减此次(退款金额+优惠金额),优惠金额字段减去申请退款时的优惠金额
|
|
|
+ accountService.lambdaUpdate().setSql("frozen_amount = (frozen_amount - (%d + %d)) , discount_amount = (discount_amount - %d)"
|
|
|
+ .formatted(refundLog.getRefund(), refundLog.getDiscountAmount(), refundLog.getDiscountAmount()))
|
|
|
+ .eq(Account::getUserId, refundLog.getUserId()).update();
|
|
|
+
|
|
|
+ // 更新资金流水
|
|
|
+ walletDetailService.lambdaUpdate()
|
|
|
+ .set(WalletDetail::getStatus, WalletDetail.STATUS_已确认)
|
|
|
+ .set(WalletDetail::getTransactionTime, successTime)
|
|
|
+ .set(WalletDetail::getAmount, refundLog.getRefund())
|
|
|
+ .eq(WalletDetail::getId, walletDetail.getId()).update();
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 处理退款
|
|
|
*
|