ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/dto/ExchangeCodeConsumeDTO.java
@@ -18,4 +18,7 @@ @ApiModelProperty("扣减金额") private BigDecimal amount; @ApiModelProperty("????/?????") private String refundNo; } ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/factory/OtherFallbackFactory.java
@@ -162,6 +162,11 @@ return R.fail("扣减兑换码余额失败:" + throwable.getMessage()); } @Override public R<ExchangeCodeConsumeResultVO> refundExchangeCodeBalance(ExchangeCodeConsumeDTO dto) { return R.fail("?????????:" + throwable.getMessage()); } @Override public R<Page<TExchangeCodeUseRecord>> exchangeCodeUseRecordPage(ExchangeCodeUseRecordQuery query) { return R.fail("查询兑换码流水失败:" + throwable.getMessage()); } ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/feignClient/OtherClient.java
@@ -114,6 +114,9 @@ @PostMapping(value = "/exchange-code-package/consumeBalance") R<ExchangeCodeConsumeResultVO> consumeExchangeCodeBalance(@RequestBody ExchangeCodeConsumeDTO dto); @PostMapping(value = "/exchange-code-package/refundBalance") R<ExchangeCodeConsumeResultVO> refundExchangeCodeBalance(@RequestBody ExchangeCodeConsumeDTO dto); @PostMapping(value = "/exchange-code-package/useRecord/page") R<Page<TExchangeCodeUseRecord>> exchangeCodeUseRecordPage(@RequestBody ExchangeCodeUseRecordQuery query); ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java
@@ -441,6 +441,23 @@ appUser.setBalance(money(appUser.getBalance()).add(delta).setScale(2, RoundingMode.HALF_UP)); appUserClient.updateAppUser(appUser); } private void recordBalanceRefund(TChargingOrder chargingOrder, BigDecimal refundAmount, String refundNo) { if (chargingOrder == null || chargingOrder.getAppUserId() == null || chargingOrder.getId() == null || refundAmount == null || refundAmount.compareTo(BigDecimal.ZERO) <= 0) { return; } ExchangeCodeConsumeDTO refundDTO = new ExchangeCodeConsumeDTO(); refundDTO.setUserId(chargingOrder.getAppUserId()); refundDTO.setOrderId(chargingOrder.getId()); refundDTO.setAmount(refundAmount); refundDTO.setRefundNo(refundNo); R<ExchangeCodeConsumeResultVO> result = otherClient.refundExchangeCodeBalance(refundDTO); if (result == null || result.getCode() != 200) { throw new RuntimeException("??????????"); } } @Override public AjaxResult paymentChargingOrder(AddChargingOrder addChargingOrder) { Long userId = tokenService.getLoginUserApplet().getUserId(); @@ -1145,6 +1162,7 @@ if (thirdRefundAmount.compareTo(BigDecimal.ZERO) == 0) { if (balanceRefundAmount.compareTo(BigDecimal.ZERO) > 0) { changeUserBalance(chargingOrder.getAppUserId(), balanceRefundAmount); recordBalanceRefund(chargingOrder, balanceRefundAmount, chargingOrderRefund.getRefundCode()); } chargingOrderRefund.setRefundStatus(2); chargingOrderRefund.setRefundSerialNumber("BALANCE"); @@ -1379,6 +1397,7 @@ if (money(order.getBalanceRefundAmount()).compareTo(BigDecimal.ZERO) > 0) { changeUserBalance(order.getAppUserId(), money(order.getBalanceRefundAmount())); recordBalanceRefund(order, money(order.getBalanceRefundAmount()), one.getRefundCode()); } TChargingOrder chargingOrder = new TChargingOrder(); chargingOrder.setId(one.getChargingOrderId()); @@ -2976,6 +2995,10 @@ chargingOrderRefund.setPayAmount(rechargeAmount); chargingOrderRefund.setRefundTime(LocalDateTime.now()); chargingOrderRefundService.save(chargingOrderRefund); if (balanceRefundAmount.compareTo(BigDecimal.ZERO) > 0) { changeUserBalance(chargingOrder.getAppUserId(), balanceRefundAmount); recordBalanceRefund(chargingOrder, balanceRefundAmount, chargingOrderRefund.getRefundCode()); } chargingOrder.setRefundStatus(2); chargingOrder.setRefundTime(LocalDateTime.now()); ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/TExchangeCodePackageController.java
@@ -187,6 +187,12 @@ return R.ok(exchangeCodePackageService.consumeBalance(dto)); } @PostMapping("/refundBalance") @ApiOperation(value = "?????????", tags = {"??-???"}) public R<ExchangeCodeConsumeResultVO> refundBalance(@RequestBody ExchangeCodeConsumeDTO dto) { return R.ok(exchangeCodePackageService.refundBalance(dto)); } @PostMapping("/useRecord/page") @ApiOperation(value = "兑换码余额流水分页", tags = {"小程序-兑换码"}) public R<Page<TExchangeCodeUseRecord>> useRecordPage(@RequestBody ExchangeCodeUseRecordQuery query) { ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/TExchangeCodePackageService.java
@@ -49,6 +49,8 @@ ExchangeCodeConsumeResultVO consumeBalance(ExchangeCodeConsumeDTO dto); ExchangeCodeConsumeResultVO refundBalance(ExchangeCodeConsumeDTO dto); Page<TExchangeCodeUseRecord> useRecordPage(ExchangeCodeUseRecordQuery query); TExchangeCodeUseRecord useRecordDetail(Long id, Long userId); ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/TExchangeCodePackageServiceImpl.java
@@ -356,6 +356,7 @@ List<TExchangeCodeUseRecord> existingRecords = useRecordMapper.selectList(new QueryWrapper<TExchangeCodeUseRecord>() .eq("order_id", dto.getOrderId()) .gt("order_id", 0) .eq("change_type", USE_RECORD_TYPE_CONSUME) .eq("del_flag", 0)); if (!existingRecords.isEmpty()) { BigDecimal deducted = existingRecords.stream() @@ -399,6 +400,70 @@ return resultVO; } @Override @Transactional(rollbackFor = Exception.class) public ExchangeCodeConsumeResultVO refundBalance(ExchangeCodeConsumeDTO dto) { if (dto == null || dto.getUserId() == null || dto.getOrderId() == null || dto.getAmount() == null) { throw new ServiceException("????????"); } ExchangeCodeConsumeResultVO resultVO = new ExchangeCodeConsumeResultVO(); BigDecimal remainingRefund = dto.getAmount().setScale(2, RoundingMode.HALF_UP); if (remainingRefund.compareTo(BigDecimal.ZERO) <= 0) { resultVO.setDeductedAmount(BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP)); return resultVO; } List<TExchangeCodeUseRecord> existingRecords = useRecordMapper.selectList(new QueryWrapper<TExchangeCodeUseRecord>() .eq("order_id", dto.getOrderId()) .eq("change_type", USE_RECORD_TYPE_REFUND) .eq(dto.getRefundNo() != null && !dto.getRefundNo().isEmpty(), "refund_no", dto.getRefundNo()) .eq("del_flag", 0)); if (!existingRecords.isEmpty()) { BigDecimal refunded = existingRecords.stream() .map(TExchangeCodeUseRecord::getUsedAmount) .filter(Objects::nonNull) .reduce(BigDecimal.ZERO, BigDecimal::add) .setScale(2, RoundingMode.HALF_UP); resultVO.setDeductedAmount(refunded); return resultVO; } List<TExchangeCodeUseRecord> consumeRecords = useRecordMapper.selectList(new QueryWrapper<TExchangeCodeUseRecord>() .eq("order_id", dto.getOrderId()) .eq("user_id", dto.getUserId()) .eq("change_type", USE_RECORD_TYPE_CONSUME) .eq("del_flag", 0) .orderByDesc("id")); BigDecimal refundedAmount = BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP); for (TExchangeCodeUseRecord consumeRecord : consumeRecords) { if (remainingRefund.compareTo(BigDecimal.ZERO) <= 0) { break; } if (consumeRecord.getDetailId() == null) { continue; } TExchangeCodeDetail detail = codeDetailMapper.selectById(consumeRecord.getDetailId()); if (detail == null) { continue; } BigDecimal useAmount = defaultMoney(consumeRecord.getUsedAmount()); BigDecimal refundAmount = remainingRefund.min(useAmount).setScale(2, RoundingMode.HALF_UP); detail.setUsedAmount(defaultMoney(detail.getUsedAmount()).subtract(refundAmount).max(BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP)); codeDetailMapper.updateById(detail); TExchangeCodeUseRecord record = new TExchangeCodeUseRecord(); record.setDetailId(detail.getId()); record.setOrderId(dto.getOrderId()); record.setRefundNo(dto.getRefundNo()); record.setUserId(dto.getUserId()); record.setChangeType(USE_RECORD_TYPE_REFUND); record.setUsedAmount(refundAmount); record.setGiftUsedAmount(calculateGiftUsedAmount(refundAmount, detail)); useRecordMapper.insert(record); remainingRefund = remainingRefund.subtract(refundAmount); refundedAmount = refundedAmount.add(refundAmount); } resultVO.setDeductedAmount(refundedAmount.setScale(2, RoundingMode.HALF_UP)); return resultVO; } private BigDecimal calculateGiftUsedAmount(BigDecimal useAmount, TExchangeCodeDetail detail) { if (useAmount == null || detail == null || detail.getGiftRatio() == null) { return BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);