Browse Source

3.17 现金退款校验与修改钱包余额

milestone-20260224-现金钱包
huangqizhen 3 weeks ago
parent
commit
5808d624e6
  1. 91
      src/main/java/com/example/demo/serviceImpl/cash/CashRefundServiceImpl.java
  2. 83
      src/main/java/com/example/demo/serviceImpl/coin/AuditServiceImpl.java

91
src/main/java/com/example/demo/serviceImpl/cash/CashRefundServiceImpl.java

@ -20,6 +20,7 @@ import com.example.demo.service.coin.TranslationService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -236,7 +237,7 @@ public class CashRefundServiceImpl implements RefundService {
walletMapper.insert(new UserRegionWallet(null, cashRecordRefund.getJwcode(), wallet, BigDecimal.ZERO, new Date(), new Date()));
log.warn("用户钱包不存在,已初始化钱包");
}
if (userRegionWallet.getCurrentPermanentGold().compareTo(BigDecimal.valueOf(cashRecordRefund.getPermanentGold())) < 0) {
if (userRegionWallet.getCurrentPermanentGold().compareTo(BigDecimal.valueOf(cashRecordRefund.getPartRefundGold())) < 0) {
throw new BusinessException("用户钱包金币不足");
}
@ -502,24 +503,76 @@ public class CashRefundServiceImpl implements RefundService {
user.setCurrentFreeDecember(BigDecimal.valueOf(-userGoldRecord.getFreeDecember())); //当前十二月免费金币
auditMapper.updateUserGold(user);
//钱包更新
// 钱包更新 - 按原始扣款流水 wallet_id 优先级顺序原路退回1-10越小优先级越高
String orderCodeA = "XJ" + orderCode.substring(4);
List<UserWalletRecord> userWalletList = walletService.selectUserWalletRecord(userGoldRecord.getJwcode(), orderCodeA);
UserRegionWallet userRegionWallet = new UserRegionWallet();
for (UserWalletRecord userWalletRecord : userWalletList){
userRegionWallet.setJwcode(userWalletRecord.getJwcode());
userRegionWallet.setWalletId(userWalletRecord.getWalletId());
userRegionWallet.setCurrentPermanentGold(BigDecimal.valueOf(-(userGoldRecord.getFreeDecember()+userGoldRecord.getFreeJune()+userGoldRecord.getPermanentGold())));
walletService.updateUserGoldRecord(userRegionWallet);
walletService.updateUserWalletRecord(userWalletRecord.getId());
UserWalletRecord userWalletRecord1 = new UserWalletRecord();
userWalletRecord1.setType(2);
userWalletRecord1.setJwcode(userWalletRecord.getJwcode());
userWalletRecord1.setWalletId(userWalletRecord.getWalletId());
userWalletRecord1.setAmount(-userWalletRecord.getAmount());
userWalletRecord1.setOrderCode("TK"+orderCodeA);
userWalletRecord1.setDescription(userWalletRecord.getDescription()+"退款");
walletService.addUserWalletRecord(userWalletRecord1);
// 1. 查询原始扣款流水type=1 消耗status=0 正常
List<UserWalletRecord> originalRecords = walletService.selectUserWalletRecord(userGoldRecord.getJwcode(), orderCodeA);
if (!CollectionUtils.isEmpty(originalRecords)) {
// 过滤扣款记录并按 wallet_id 升序排序1 10越小优先级越高
originalRecords = originalRecords.stream()
.filter(r -> r.getType() == 1 && r.getStatus() == 0)
.sorted(Comparator.comparing(UserWalletRecord::getWalletId))
.collect(Collectors.toList());
// 2. 本次退款总金额取绝对值兼容负数
BigDecimal totalRefundAmount = BigDecimal.valueOf(userGoldRecord.getPermanentGold()).abs()
.add(BigDecimal.valueOf(userGoldRecord.getTaskGold()).abs())
.add(BigDecimal.valueOf(userGoldRecord.getFreeJune()).abs())
.add(BigDecimal.valueOf(userGoldRecord.getFreeDecember()).abs());
if (totalRefundAmount.compareTo(BigDecimal.ZERO) > 0) {
BigDecimal remainingRefund = totalRefundAmount;
// 3. 按原始流水顺序退回支持多钱包部分退款优先退前面的
for (UserWalletRecord record : originalRecords) {
if (remainingRefund.compareTo(BigDecimal.ZERO) <= 0) {
break;
}
Integer walletId = record.getWalletId();
// 🔥 关键取绝对值兼容消耗存负数的情况
BigDecimal originalAmount = BigDecimal.valueOf(record.getAmount()).abs();
if (originalAmount.compareTo(BigDecimal.ZERO) <= 0) {
continue;
}
// 4. 计算本次退回金额 = min(原扣金额剩余待退金额)
BigDecimal refundAmount = originalAmount.min(remainingRefund);
if (refundAmount.compareTo(BigDecimal.ZERO) <= 0) {
continue;
}
// 5. 插入退款流水记录type=2 退款amount 存正数
UserWalletRecord refundRecord = new UserWalletRecord();
refundRecord.setType(2);
refundRecord.setJwcode(userGoldRecord.getJwcode());
refundRecord.setWalletId(walletId);
refundRecord.setAmount(refundAmount.intValue()); // 退款存正数
refundRecord.setOrderCode("TK" + orderCodeA);
refundRecord.setDescription(record.getDescription() + "退款");
refundRecord.setStatus(0);
walletService.addUserWalletRecord(refundRecord);
// 6. 查询并更新钱包余额覆盖更新先查后改
UserRegionWallet currentWallet = walletMapper.selectWallet(userGoldRecord.getJwcode(), walletId);
if (currentWallet == null) {
log.error("钱包记录不存在,无法退款 | jwcode={}, walletId={}", userGoldRecord.getJwcode(), walletId);
continue;
}
// 7. 计算新余额 + 覆盖更新
BigDecimal newBalance = currentWallet.getCurrentPermanentGold().add(refundAmount);
currentWallet.setCurrentPermanentGold(newBalance);
walletService.updateUserGoldRecord(currentWallet);
// 8. 更新原流水状态为已退款保持你原有的逻辑
walletService.updateUserWalletRecord(record.getId());
// 9. 扣减剩余待退金额
remainingRefund = remainingRefund.subtract(refundAmount);
}
}
}
GoldTistV2.addCoinNew(userGoldRecord.getJwcode().toString(), 58, //退款免费+永久金币-充值
@ -809,7 +862,7 @@ public class CashRefundServiceImpl implements RefundService {
walletMapper.insert(new UserRegionWallet(null, cashRecordRefund.getJwcode(), wallet, BigDecimal.ZERO, new Date(), new Date()));
log.warn("用户钱包不存在,已初始化钱包");
}
if (userRegionWallet.getCurrentPermanentGold().compareTo(BigDecimal.valueOf(cashRecordRefund.getPermanentGold())) < 0) {
if (userRegionWallet.getCurrentPermanentGold().compareTo(BigDecimal.valueOf(cashRecordRefund.getPartRefundGold())) < 0) {
throw new BusinessException("用户钱包金币不足");
}
CashRecordDone cashRecordDonetwo = new CashRecordDone();

83
src/main/java/com/example/demo/serviceImpl/coin/AuditServiceImpl.java

@ -23,6 +23,7 @@ import com.example.demo.service.coin.GeneralService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -30,10 +31,8 @@ import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;
/**
* @program: gold-java
@ -211,16 +210,76 @@ public class AuditServiceImpl implements AuditService {
auditMapper.updateUserGold(update);
//钱包更新
List<UserWalletRecord> userWalletList = walletService.selectUserWalletRecord(order.getJwcode(), oldOrderCode);
UserRegionWallet userRegionWallet = new UserRegionWallet();
for (UserWalletRecord userWalletRecord : userWalletList){
userRegionWallet.setJwcode(userWalletRecord.getJwcode());
userRegionWallet.setWalletId(userWalletRecord.getWalletId());
userRegionWallet.setCurrentPermanentGold(BigDecimal.valueOf(-(order.getPermanentGold()+order.getTaskGold()+order.getFreeJune()+order.getFreeDecember())));
walletService.updateUserGoldRecord(userRegionWallet);
walletService.updateUserWalletRecord(userWalletRecord.getId());
// List<UserWalletRecord> userWalletList = walletService.selectUserWalletRecord(order.getJwcode(), oldOrderCode);
// UserRegionWallet userRegionWallet = new UserRegionWallet();
// 钱包更新 - 按原始扣款流水 wallet_id 优先级顺序原路退回1-10越小优先级越高
// 1. 查询原始扣款流水type=1 消耗status=0 正常
List<UserWalletRecord> originalRecords = walletService.selectUserWalletRecord(order.getJwcode(), oldOrderCode);
if (!CollectionUtils.isEmpty(originalRecords)) {
// 过滤扣款记录并按 wallet_id 升序排序1 10越小优先级越高
originalRecords = originalRecords.stream()
.filter(r -> r.getType() == 1 && r.getStatus() == 0)
.sorted(Comparator.comparing(UserWalletRecord::getWalletId))
.collect(Collectors.toList());
// 2. 本次退款总金额
BigDecimal totalRefundAmount = BigDecimal.valueOf(order.getPermanentGold())
.add(BigDecimal.valueOf(order.getTaskGold()))
.add(BigDecimal.valueOf(order.getFreeJune()))
.add(BigDecimal.valueOf(order.getFreeDecember()));
if (totalRefundAmount.compareTo(BigDecimal.ZERO) > 0) {
BigDecimal remainingRefund = totalRefundAmount;
// 3. 按原始流水顺序退回
for (UserWalletRecord record : originalRecords) {
if (remainingRefund.compareTo(BigDecimal.ZERO) <= 0) {
break;
}
Integer walletId = record.getWalletId();
// 🔥 关键修正取绝对值兼容负数存储
BigDecimal originalAmount = BigDecimal.valueOf(record.getAmount()).abs();
if (originalAmount.compareTo(BigDecimal.ZERO) <= 0) {
continue;
}
// 4. 计算本次退回金额 = min(原扣金额剩余待退金额)
BigDecimal refundAmount = originalAmount.min(remainingRefund);
if (refundAmount.compareTo(BigDecimal.ZERO) <= 0) {
continue;
}
// 5. 插入退款流水记录type=2 退款
UserWalletRecord refundRecord = new UserWalletRecord();
refundRecord.setJwcode(order.getJwcode());
refundRecord.setWalletId(walletId);
refundRecord.setType(2); // 退款类型
refundRecord.setAmount(refundAmount.intValue()); // 🔥 退款存正数
refundRecord.setOrderCode(order.getOrderCode());
refundRecord.setDescription("订单退款");
refundRecord.setStatus(0);
walletService.addUserWalletRecord(refundRecord);
// 6. 查询并更新钱包余额覆盖更新先查后改
UserRegionWallet currentWallet = walletMapper.selectWallet(order.getJwcode(), walletId);
if (currentWallet == null) {
log.error("钱包记录不存在,无法退款 | jwcode={}, walletId={}", order.getJwcode(), walletId);
continue;
}
// 7. 计算新余额 + 覆盖更新
BigDecimal newBalance = currentWallet.getCurrentPermanentGold().add(refundAmount);
currentWallet.setCurrentPermanentGold(newBalance);
walletService.updateUserGoldRecord(currentWallet);
// 8. 扣减剩余待退金额
remainingRefund = remainingRefund.subtract(refundAmount);
}
}
}
//商品消费退款
//erp增加退款数据
if (oldOrder.getType() == 1) {

Loading…
Cancel
Save