|
|
|
@ -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(); |
|
|
|
|