|
|
@@ -37,88 +37,85 @@ public class RechargeRightsDiscountHandle implements DiscountService {
|
|
|
public void computeDiscount(ChargeOrder chargeOrder, Account account) {
|
|
|
int discountAmount;
|
|
|
|
|
|
- try {
|
|
|
- // 获取订单权益,计算订单优惠金额,实付金额,服务费优惠金额
|
|
|
- var orderRechargeRights = orderRechargeRightsService.lambdaQuery()
|
|
|
- .eq(OrderRechargeRights::getStartChargeSeq, chargeOrder.getStartChargeSeq())
|
|
|
- .eq(OrderRechargeRights::getUserId, chargeOrder.getUserId())
|
|
|
+ // 获取订单权益,计算订单优惠金额,实付金额,服务费优惠金额
|
|
|
+ var orderRechargeRights = orderRechargeRightsService.lambdaQuery()
|
|
|
+ .eq(OrderRechargeRights::getStartChargeSeq, chargeOrder.getStartChargeSeq())
|
|
|
+ .eq(OrderRechargeRights::getUserId, chargeOrder.getUserId())
|
|
|
+ .one();
|
|
|
+ if (orderRechargeRights != null) {
|
|
|
+ // 获取折扣,计算优惠
|
|
|
+ var discount = orderRechargeRights.getDiscount();
|
|
|
+ // 服务费优惠金额只保留到分,分以下不进行四舍五入
|
|
|
+ var serviceMoneyDiscount = (int) (chargeOrder.getServiceMoney() * (BigDecimal.valueOf(1).subtract(BigDecimal.valueOf(discount).divide(BigDecimal.valueOf(100)))).doubleValue());
|
|
|
+ chargeOrder
|
|
|
+ .setPayAmount(chargeOrder.getTotalMoney() - serviceMoneyDiscount)
|
|
|
+ .setDiscountAmount(serviceMoneyDiscount)
|
|
|
+ .setServiceMoneyDiscount(serviceMoneyDiscount);
|
|
|
+
|
|
|
+ orderRechargeRights.setDiscountAmount(serviceMoneyDiscount);
|
|
|
+
|
|
|
+ // 用户充值权益
|
|
|
+ var userRechargeRights = userRechargeRightsService.lambdaQuery()
|
|
|
+ .eq(UserRechargeRights::getId, orderRechargeRights.getUserRightsId())
|
|
|
+ .eq(UserRechargeRights::getUserId, chargeOrder.getUserId())
|
|
|
+ .eq(UserRechargeRights::getRightsId, orderRechargeRights.getRightsId())
|
|
|
.one();
|
|
|
- if (orderRechargeRights != null) {
|
|
|
- // 获取折扣,计算优惠
|
|
|
- var discount = orderRechargeRights.getDiscount();
|
|
|
- // 服务费优惠金额只保留到分,分以下不进行四舍五入
|
|
|
- var serviceMoneyDiscount = (int) (chargeOrder.getServiceMoney() * (BigDecimal.valueOf(1).subtract(BigDecimal.valueOf(discount).divide(BigDecimal.valueOf(100)))).doubleValue());
|
|
|
- chargeOrder
|
|
|
- .setPayAmount(chargeOrder.getTotalMoney() - serviceMoneyDiscount)
|
|
|
- .setDiscountAmount(serviceMoneyDiscount)
|
|
|
- .setServiceMoneyDiscount(serviceMoneyDiscount);
|
|
|
-
|
|
|
- orderRechargeRights.setDiscountAmount(serviceMoneyDiscount);
|
|
|
-
|
|
|
- // 用户充值权益
|
|
|
- var userRechargeRights = userRechargeRightsService.lambdaQuery()
|
|
|
- .eq(UserRechargeRights::getId, orderRechargeRights.getUserRightsId())
|
|
|
- .eq(UserRechargeRights::getUserId, chargeOrder.getUserId())
|
|
|
- .eq(UserRechargeRights::getRightsId, orderRechargeRights.getRightsId())
|
|
|
- .one();
|
|
|
-
|
|
|
- // 用户当前权益金余额是否足够支付本次充电费用
|
|
|
- if (userRechargeRights.getStatus() == UserRechargeRights.STATUS_有效) {
|
|
|
- if (chargeOrder.getPayAmount() <= userRechargeRights.getRightsBalance()) {
|
|
|
- userRechargeRights
|
|
|
- // 用户权益包余额扣减当前订单实付金额
|
|
|
- .setRightsBalance(userRechargeRights.getRightsBalance() - chargeOrder.getPayAmount())
|
|
|
- .setDiscountAmount(userRechargeRights.getDiscountAmount() + serviceMoneyDiscount);
|
|
|
-
|
|
|
- // 账户设置优惠不可退金额
|
|
|
- discountAmount = account.getDiscountAmount() + serviceMoneyDiscount;
|
|
|
- account.setDiscountAmount(discountAmount);
|
|
|
- // 权益失效时更新状态
|
|
|
- if (chargeOrder.getPayAmount().intValue() == userRechargeRights.getRightsBalance().intValue()) {
|
|
|
- userRechargeRights.setStatus(UserRechargeRights.STATUS_无效);
|
|
|
- }
|
|
|
- } else {
|
|
|
- // 不足(用户当前权益金余额是否足够支付本次充电费用)
|
|
|
- // 如果优惠后的实付金额大于权益金余额,那么实际优惠金额需要通过权益金余额反推
|
|
|
- // 通过权益金余额,反推最多扣减多少服务费
|
|
|
- // rightBalance = elecMoney + serviceMoney * (1-discount)
|
|
|
- // 订单中elecMoney与serviceMoney的比值是一定的
|
|
|
- var ratio = BigDecimal.valueOf(chargeOrder.getElecMoney()).divide(BigDecimal.valueOf(chargeOrder.getServiceMoney()), 2, RoundingMode.HALF_UP);
|
|
|
- // (ratio * realServiceMoney) + (realServiceMoney * (100 - discount)/100) = rightBalance
|
|
|
- var discountRate = BigDecimal.valueOf(discount).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
|
|
|
- var userRightBalance = BigDecimal.valueOf(userRechargeRights.getRightsBalance());
|
|
|
- // 真实可以覆盖的服务费金额
|
|
|
- var realServiceMoney = userRightBalance.divide(ratio.add(BigDecimal.valueOf(1)).subtract(discountRate), 2, RoundingMode.HALF_UP);
|
|
|
- // 实际优惠金额 = 实际可以覆盖的服务费金额 * 折扣率
|
|
|
- var realDiscountAmount = realServiceMoney.multiply(BigDecimal.valueOf(1).subtract(discountRate)).intValue();
|
|
|
- chargeOrder
|
|
|
- // 实付金额
|
|
|
- .setPayAmount(chargeOrder.getTotalMoney() - realDiscountAmount)
|
|
|
- .setDiscountAmount(realDiscountAmount)
|
|
|
- .setServiceMoneyDiscount(realDiscountAmount);
|
|
|
- // 余额扣完,总优惠金额加上最后一次真实优惠金额,此条用户权益结束,状态设置为无效
|
|
|
- userRechargeRights
|
|
|
- .setRightsBalance(0)
|
|
|
- .setDiscountAmount(userRechargeRights.getDiscountAmount() + realDiscountAmount)
|
|
|
- .setStatus(UserRechargeRights.STATUS_无效);
|
|
|
-
|
|
|
- orderRechargeRights.setDiscountAmount(realDiscountAmount);
|
|
|
- // 此权益包消耗完毕,账户设置优惠不可退金额
|
|
|
- discountAmount = account.getDiscountAmount() + realDiscountAmount;
|
|
|
- account.setDiscountAmount(discountAmount);
|
|
|
+ if (userRechargeRights == null) {
|
|
|
+ log.error("订单{}的用户充值权益{}不存在,跳过优惠处理", chargeOrder.getStartChargeSeq(), orderRechargeRights.getUserRightsId());
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 用户当前权益金余额是否足够支付本次充电费用
|
|
|
+ if (userRechargeRights.getStatus() == UserRechargeRights.STATUS_有效) {
|
|
|
+ if (chargeOrder.getPayAmount() <= userRechargeRights.getRightsBalance()) {
|
|
|
+ userRechargeRights
|
|
|
+ // 用户权益包余额扣减当前订单实付金额
|
|
|
+ .setRightsBalance(userRechargeRights.getRightsBalance() - chargeOrder.getPayAmount())
|
|
|
+ .setDiscountAmount(userRechargeRights.getDiscountAmount() + serviceMoneyDiscount);
|
|
|
+
|
|
|
+ // 账户设置优惠不可退金额
|
|
|
+ discountAmount = account.getDiscountAmount() + serviceMoneyDiscount;
|
|
|
+ account.setDiscountAmount(discountAmount);
|
|
|
+ // 权益失效时更新状态
|
|
|
+ if (chargeOrder.getPayAmount().intValue() == userRechargeRights.getRightsBalance().intValue()) {
|
|
|
+ userRechargeRights.setStatus(UserRechargeRights.STATUS_无效);
|
|
|
}
|
|
|
+ } else {
|
|
|
+ // 不足(用户当前权益金余额是否足够支付本次充电费用)
|
|
|
+ // 如果优惠后的实付金额大于权益金余额,那么实际优惠金额需要通过权益金余额反推
|
|
|
+ // 通过权益金余额,反推最多扣减多少服务费
|
|
|
+ // rightBalance = elecMoney + serviceMoney * (1-discount)
|
|
|
+ // 订单中elecMoney与serviceMoney的比值是一定的
|
|
|
+ var ratio = BigDecimal.valueOf(chargeOrder.getElecMoney()).divide(BigDecimal.valueOf(chargeOrder.getServiceMoney()), 2, RoundingMode.HALF_UP);
|
|
|
+ // (ratio * realServiceMoney) + (realServiceMoney * (100 - discount)/100) = rightBalance
|
|
|
+ var discountRate = BigDecimal.valueOf(discount).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
|
|
|
+ var userRightBalance = BigDecimal.valueOf(userRechargeRights.getRightsBalance());
|
|
|
+ // 真实可以覆盖的服务费金额
|
|
|
+ var realServiceMoney = userRightBalance.divide(ratio.add(BigDecimal.valueOf(1)).subtract(discountRate), 2, RoundingMode.HALF_UP);
|
|
|
+ // 实际优惠金额 = 实际可以覆盖的服务费金额 * 折扣率
|
|
|
+ var realDiscountAmount = realServiceMoney.multiply(BigDecimal.valueOf(1).subtract(discountRate)).intValue();
|
|
|
+ chargeOrder
|
|
|
+ // 实付金额
|
|
|
+ .setPayAmount(chargeOrder.getTotalMoney() - realDiscountAmount)
|
|
|
+ .setDiscountAmount(realDiscountAmount)
|
|
|
+ .setServiceMoneyDiscount(realDiscountAmount);
|
|
|
+ // 余额扣完,总优惠金额加上最后一次真实优惠金额,此条用户权益结束,状态设置为无效
|
|
|
+ userRechargeRights
|
|
|
+ .setRightsBalance(0)
|
|
|
+ .setDiscountAmount(userRechargeRights.getDiscountAmount() + realDiscountAmount)
|
|
|
+ .setStatus(UserRechargeRights.STATUS_无效);
|
|
|
+
|
|
|
+ orderRechargeRights.setDiscountAmount(realDiscountAmount);
|
|
|
+ // 此权益包消耗完毕,账户设置优惠不可退金额
|
|
|
+ discountAmount = account.getDiscountAmount() + realDiscountAmount;
|
|
|
+ account.setDiscountAmount(discountAmount);
|
|
|
}
|
|
|
-
|
|
|
- // 更新订单权益的最终优惠金额
|
|
|
- orderRechargeRightsService.updateById(orderRechargeRights);
|
|
|
- // 更新用户权益金等
|
|
|
- userRechargeRightsService.updateById(userRechargeRights);
|
|
|
}
|
|
|
|
|
|
-
|
|
|
- } catch (Exception e) {
|
|
|
- log.error("处理充值优惠失败", e);
|
|
|
- // 可以添加一些错误处理逻辑,比如重试机制、发送告警等
|
|
|
+ // 更新订单权益的最终优惠金额
|
|
|
+ orderRechargeRightsService.updateById(orderRechargeRights);
|
|
|
+ // 更新用户权益金等
|
|
|
+ userRechargeRightsService.updateById(userRechargeRights);
|
|
|
}
|
|
|
}
|
|
|
|