# PayBeforeUtil 整合 BenefitPointsUtil 示例 ## 整合说明 本文档展示如何在 `PayBeforeUtil.createPayBefore` 方法中整合 `BenefitPointsUtil` 的抵扣计算功能,简化原有的复杂逻辑。 ## 原有代码分析 ### 原有 PayBeforeUtil.createPayBefore 中的抵扣逻辑 ```java // 原有代码片段 try { SiteConfig configQuery = new SiteConfig(); configQuery.setName("config_one"); List configList = siteConfigService.selectSiteConfigList(configQuery); if (configList != null && !configList.isEmpty()) { String configValue = configList.get(0).getValue(); if (configValue != null && !configValue.trim().isEmpty()) { com.alibaba.fastjson2.JSONObject configJson = com.alibaba.fastjson2.JSONObject.parseObject(configValue); // 服务金抵扣 if (servicetype != null && servicetype == 1) { Integer serviceFee = configJson.getInteger("servicefee"); if (serviceFee != null && serviceFee > 0) { Users userDb = usersService.selectUsersById(user.getId()); if (userDb != null && userDb.getServicefee() != null && userDb.getServicefee().compareTo(BigDecimal.ZERO) > 0) { BigDecimal serviceRate = BigDecimal.valueOf(serviceFee).divide(BigDecimal.valueOf(100), 4, BigDecimal.ROUND_HALF_UP); serviceMoney = userDb.getServicefee().multiply(serviceRate); } } } // 购物金抵扣 if (servicetype != null && servicetype == 2) { Integer consumption = configJson.getInteger("consumption"); if (consumption != null && consumption > 0) { Users userDb = usersService.selectUsersById(user.getId()); if (userDb != null && userDb.getConsumption() != null && userDb.getConsumption().compareTo(BigDecimal.ZERO) > 0) { BigDecimal consumptionRate = BigDecimal.valueOf(consumption).divide(BigDecimal.valueOf(100), 4, BigDecimal.ROUND_HALF_UP); shopMoney = userDb.getConsumption().multiply(consumptionRate); } } } } } } catch (Exception e) { // 异常处理 } ``` ## 整合后的代码 ### 使用 BenefitPointsUtil 简化后的代码 ```java // 整合后的代码 try { // 使用 BenefitPointsUtil 进行抵扣计算 BenefitPointsUtil.BenefitDeductionResult deductionResult = BenefitPointsUtil.getBenefitDeduction(user, amount, servicetype); if (deductionResult.isSuccess()) { serviceMoney = deductionResult.getServiceMoney(); // 服务金抵扣金额 shopMoney = deductionResult.getShopMoney(); // 消费金抵扣金额 BigDecimal finalAmount = deductionResult.getFinalAmount(); // 最终支付金额 log.info("【抵扣计算】用户ID: {}, 原金额: {}, 服务金抵扣: {}, 消费金抵扣: {}, 最终金额: {}", user.getId(), amount, serviceMoney, shopMoney, finalAmount); } else { log.warn("【抵扣计算失败】用户ID: {}, 错误: {}", user.getId(), deductionResult.getMessage()); serviceMoney = BigDecimal.ZERO; shopMoney = BigDecimal.ZERO; } } catch (Exception e) { log.error("【抵扣计算异常】用户ID: {}, 异常: {}", user.getId(), e.getMessage(), e); serviceMoney = BigDecimal.ZERO; shopMoney = BigDecimal.ZERO; } ``` ## 完整的 PayBeforeUtil 整合示例 ```java package com.ruoyi.system.ControllerUtil; import com.alibaba.fastjson2.JSONObject; import com.ruoyi.common.utils.spring.SpringUtils; import com.ruoyi.system.domain.SiteConfig; import com.ruoyi.system.domain.Users; import com.ruoyi.system.domain.UsersPayBefor; import com.ruoyi.system.service.IUsersPayBeforService; import com.ruoyi.system.service.ISiteConfigService; import com.ruoyi.system.service.IUsersService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.math.BigDecimal; import java.util.Date; import java.util.List; import com.ruoyi.system.domain.OrderLog; /** * 预支付工具类(整合版本) * * @author ruoyi * @date 2025-07-17 */ @Component public class PayBeforeUtil { private static final IUsersPayBeforService usersPayBeforService = SpringUtils.getBean(IUsersPayBeforService.class); private static final ISiteConfigService siteConfigService = SpringUtils.getBean(ISiteConfigService.class); private static final IUsersService usersService = SpringUtils.getBean(IUsersService.class); /** * 创建预支付记录(整合版本) * * @param user 用户信息 * @param amount 支付金额 * @param orderId 订单号 * @param oid 订单ID * @param serviceId 服务ID * @param orderType 订单类型 * @param sku SKU规格信息 * @param grouporderid 拼团订单ID * @param addressid 地址ID * @param maketime 预约时间 * @param attachments 附件信息 * @param servicetype 服务类型:1=服务金抵扣,2=消费金抵扣 * @param baojiaid 报价ID * @param lastorderid 上一个订单ID * @return 预支付记录ID,失败返回null */ public String createPayBefore(Users user, BigDecimal amount, String orderId, Long oid, Long serviceId, Long orderType, String sku, String grouporderid, Long addressid, String maketime, String attachments, Long servicetype, Long baojiaid, String lastorderid) { try { // 计算会员优惠和服务金抵扣 BigDecimal memberMoney = BigDecimal.ZERO; BigDecimal serviceMoney = BigDecimal.ZERO; BigDecimal shopMoney = BigDecimal.ZERO; // 使用 BenefitPointsUtil 进行抵扣计算 try { BenefitPointsUtil.BenefitDeductionResult deductionResult = BenefitPointsUtil.getBenefitDeduction(user, amount, servicetype); if (deductionResult.isSuccess()) { serviceMoney = deductionResult.getServiceMoney(); // 服务金抵扣金额 shopMoney = deductionResult.getShopMoney(); // 消费金抵扣金额 System.out.println("【抵扣计算成功】用户ID: " + user.getId() + ", 服务金抵扣: " + serviceMoney + ", 消费金抵扣: " + shopMoney); } else { System.out.println("【抵扣计算失败】用户ID: " + user.getId() + ", 错误: " + deductionResult.getMessage()); } } catch (Exception e) { System.out.println("【抵扣计算异常】用户ID: " + user.getId() + ", 异常: " + e.getMessage()); serviceMoney = BigDecimal.ZERO; shopMoney = BigDecimal.ZERO; } // 会员优惠计算(保持原有逻辑) try { SiteConfig configQuery = new SiteConfig(); configQuery.setName("config_one"); List configList = siteConfigService.selectSiteConfigList(configQuery); if (configList != null && !configList.isEmpty()) { String configValue = configList.get(0).getValue(); if (configValue != null && !configValue.trim().isEmpty()) { JSONObject configJson = JSONObject.parseObject(configValue); // 会员优惠 if (user.getIsmember() != null && user.getIsmember() == 1) { Integer memberDiscount = configJson.getInteger("member_discount"); if (memberDiscount != null && memberDiscount > 0) { BigDecimal discountRate = BigDecimal.valueOf(memberDiscount) .divide(BigDecimal.valueOf(100), 4, BigDecimal.ROUND_HALF_UP); memberMoney = amount.multiply(discountRate); } } } } } catch (Exception e) { memberMoney = BigDecimal.ZERO; System.out.println("【会员优惠计算异常】用户ID: " + user.getId() + ", 异常: " + e.getMessage()); } // 计算最终支付金额 BigDecimal finalAmount = amount.subtract(memberMoney).subtract(serviceMoney).subtract(shopMoney); if (finalAmount.compareTo(BigDecimal.ZERO) < 0) { finalAmount = BigDecimal.ZERO; } System.out.println("【最终计算】用户ID: " + user.getId() + ", 原金额: " + amount + ", 会员优惠: " + memberMoney + ", 服务金抵扣: " + serviceMoney + ", 消费金抵扣: " + shopMoney + ", 最终金额: " + finalAmount); // 创建预支付记录 UsersPayBefor payBefore = new UsersPayBefor(); payBefore.setUid(user.getId()); payBefore.setAmount(finalAmount); payBefore.setOrderId(orderId); payBefore.setOid(oid); payBefore.setServiceId(serviceId); payBefore.setOrderType(orderType); payBefore.setSku(sku); payBefore.setGrouporderid(grouporderid); payBefore.setAddressid(addressid); payBefore.setMaketime(maketime); payBefore.setAttachments(attachments); payBefore.setServicetype(servicetype); payBefore.setBaojiaid(baojiaid); payBefore.setLastorderid(lastorderid); payBefore.setStatus(1L); // 待支付状态 payBefore.setCreatedAt(new Date()); payBefore.setUpdatedAt(new Date()); int insertResult = usersPayBeforService.insertUsersPayBefor(payBefore); if (insertResult > 0) { System.out.println("【预支付创建成功】用户ID: " + user.getId() + ", 预支付ID: " + payBefore.getId()); return payBefore.getId().toString(); } else { System.out.println("【预支付创建失败】用户ID: " + user.getId()); return null; } } catch (Exception e) { System.out.println("【预支付创建异常】用户ID: " + user.getId() + ", 异常: " + e.getMessage()); return null; } } // 其他方法保持不变... } ``` ## 整合优势 ### 1. 代码简化 - **原有代码**:约 50 行复杂的配置解析和抵扣计算逻辑 - **整合后代码**:约 10 行简洁的调用逻辑 ### 2. 功能增强 - **统一配置管理**:所有抵扣相关配置统一在 `BenefitPointsUtil` 中处理 - **错误处理完善**:提供详细的错误信息和日志记录 - **类型安全**:使用 `BigDecimal` 确保金额计算精度 ### 3. 维护性提升 - **逻辑集中**:抵扣计算逻辑集中在 `BenefitPointsUtil` 中 - **易于测试**:提供专门的测试接口 - **易于扩展**:可以轻松添加新的抵扣类型 ### 4. 性能优化 - **减少重复查询**:避免重复查询用户信息和配置信息 - **缓存友好**:为后续添加配置缓存奠定基础 ## 使用建议 1. **逐步迁移**:建议先在测试环境中验证整合效果 2. **保留原有逻辑**:在完全验证前,可以保留原有逻辑作为备选 3. **监控日志**:密切关注抵扣计算的日志输出 4. **性能监控**:对比整合前后的性能表现 ## 测试验证 可以使用以下测试接口验证整合效果: ```http # 测试抵扣计算 POST /system/benefit/test/deduction Content-Type: application/x-www-form-urlencoded userId=123&amount=100.00&serviceType=1 # 测试余额查询 GET /system/benefit/test/balance/123 ``` 通过这种整合方式,可以大大简化 `PayBeforeUtil` 中的抵扣计算逻辑,提高代码的可维护性和可读性。