From 5808d624e6346d17bf147f486833e299dd3d2ac7 Mon Sep 17 00:00:00 2001 From: huangqizhen <15552608129@163.com> Date: Tue, 17 Mar 2026 14:00:06 +0800 Subject: [PATCH] =?UTF-8?q?3.17=20=E7=8E=B0=E9=87=91=E9=80=80=E6=AC=BE?= =?UTF-8?q?=E6=A0=A1=E9=AA=8C=E4=B8=8E=E4=BF=AE=E6=94=B9=E9=92=B1=E5=8C=85?= =?UTF-8?q?=E4=BD=99=E9=A2=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../serviceImpl/cash/CashRefundServiceImpl.java | 91 +++++++++++++++++----- .../demo/serviceImpl/coin/AuditServiceImpl.java | 83 +++++++++++++++++--- 2 files changed, 143 insertions(+), 31 deletions(-) diff --git a/src/main/java/com/example/demo/serviceImpl/cash/CashRefundServiceImpl.java b/src/main/java/com/example/demo/serviceImpl/cash/CashRefundServiceImpl.java index 18e3bba..0127acb 100644 --- a/src/main/java/com/example/demo/serviceImpl/cash/CashRefundServiceImpl.java +++ b/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 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 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(); diff --git a/src/main/java/com/example/demo/serviceImpl/coin/AuditServiceImpl.java b/src/main/java/com/example/demo/serviceImpl/coin/AuditServiceImpl.java index a3e7936..a4ffbaa 100644 --- a/src/main/java/com/example/demo/serviceImpl/coin/AuditServiceImpl.java +++ b/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 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 userWalletList = walletService.selectUserWalletRecord(order.getJwcode(), oldOrderCode); +// UserRegionWallet userRegionWallet = new UserRegionWallet(); + // 钱包更新 - 按原始扣款流水 wallet_id 优先级顺序原路退回(1-10,越小优先级越高) +// 1. 查询原始扣款流水(type=1 消耗,status=0 正常) + List 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) {