|
|
@@ -7,28 +7,34 @@ import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
|
|
import com.kym.common.cache.ConnectorStatusCache;
|
|
|
import com.kym.common.config.RedisDBChangeUtil;
|
|
|
import com.kym.entity.admin.ConnectorInfo;
|
|
|
-import com.kym.entity.admin.Coupon;
|
|
|
import com.kym.entity.admin.EquipmentInfo;
|
|
|
import com.kym.entity.admin.MonitorLog;
|
|
|
import com.kym.entity.common.RedisKeys;
|
|
|
import com.kym.entity.enplus.EnConnectorStatusInfo;
|
|
|
-import com.kym.entity.miniapp.*;
|
|
|
+import com.kym.entity.miniapp.Account;
|
|
|
+import com.kym.entity.miniapp.ChargeOrder;
|
|
|
+import com.kym.entity.miniapp.WalletDetail;
|
|
|
+import com.kym.entity.miniapp.other.DiscountCompute;
|
|
|
import com.kym.service.admin.ConnectorInfoService;
|
|
|
import com.kym.service.admin.EquipmentInfoService;
|
|
|
import com.kym.service.admin.MonitorLogService;
|
|
|
import com.kym.service.cache.KymCache;
|
|
|
import com.kym.service.enplus.EnNotifyService;
|
|
|
import com.kym.service.enplus.EnPlusService;
|
|
|
-import com.kym.service.miniapp.*;
|
|
|
+import com.kym.service.factory.DiscountStrategyFactory;
|
|
|
+import com.kym.service.miniapp.AccountService;
|
|
|
+import com.kym.service.miniapp.ChargeOrderService;
|
|
|
+import com.kym.service.miniapp.ChargeService;
|
|
|
+import com.kym.service.miniapp.WalletDetailService;
|
|
|
import jakarta.annotation.PostConstruct;
|
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
|
+import org.springframework.data.redis.core.StringRedisTemplate;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
|
import java.math.BigDecimal;
|
|
|
-import java.math.RoundingMode;
|
|
|
import java.time.LocalDateTime;
|
|
|
import java.time.format.DateTimeFormatter;
|
|
|
import java.util.stream.Collectors;
|
|
|
@@ -59,15 +65,8 @@ public class EnNotifyServiceImpl implements EnNotifyService {
|
|
|
|
|
|
private final ConnectorInfoService connectorInfoService;
|
|
|
|
|
|
- private final UserRechargeRightsService userRechargeRightsService;
|
|
|
|
|
|
- private final OrderRechargeRightsService orderRechargeRightsService;
|
|
|
-
|
|
|
- private final OrderCouponService orderCouponService;
|
|
|
-
|
|
|
- private final UserCouponService userCouponService;
|
|
|
-
|
|
|
- private final RedisDBChangeUtil redisDBChangeUtil;
|
|
|
+ public final StringRedisTemplate redisTemplate;
|
|
|
|
|
|
@Value("${kym.notify-email}")
|
|
|
private String notifyEmail;
|
|
|
@@ -75,7 +74,7 @@ public class EnNotifyServiceImpl implements EnNotifyService {
|
|
|
public EnNotifyServiceImpl(EnPlusService enPlusService, ChargeOrderService chargeOrderService,
|
|
|
ChargeService chargeService, AccountService accountService, WalletDetailService walletDetailService,
|
|
|
MonitorLogService monitorLogService, EquipmentInfoService equipmentInfoService,
|
|
|
- ConnectorInfoService connectorInfoService, UserRechargeRightsService userRechargeRightsService, OrderRechargeRightsService orderRechargeRightsService, OrderCouponService orderCouponService, UserCouponService userCouponService, RedisDBChangeUtil redisDBChangeUtil) {
|
|
|
+ ConnectorInfoService connectorInfoService, StringRedisTemplate redisTemplate) {
|
|
|
this.enPlusService = enPlusService;
|
|
|
this.chargeOrderService = chargeOrderService;
|
|
|
this.chargeService = chargeService;
|
|
|
@@ -84,11 +83,7 @@ public class EnNotifyServiceImpl implements EnNotifyService {
|
|
|
this.monitorLogService = monitorLogService;
|
|
|
this.equipmentInfoService = equipmentInfoService;
|
|
|
this.connectorInfoService = connectorInfoService;
|
|
|
- this.userRechargeRightsService = userRechargeRightsService;
|
|
|
- this.orderRechargeRightsService = orderRechargeRightsService;
|
|
|
- this.orderCouponService = orderCouponService;
|
|
|
- this.userCouponService = userCouponService;
|
|
|
- this.redisDBChangeUtil = redisDBChangeUtil;
|
|
|
+ this.redisTemplate = redisTemplate;
|
|
|
}
|
|
|
|
|
|
@PostConstruct
|
|
|
@@ -122,8 +117,6 @@ public class EnNotifyServiceImpl implements EnNotifyService {
|
|
|
.set(ConnectorInfo::getStatus, connectorStatusInfo.getStatus())
|
|
|
.update();
|
|
|
|
|
|
- // 切换到admin对应的db
|
|
|
- redisDBChangeUtil.setDataBase(0);
|
|
|
|
|
|
var connectorStatus = connectorStatusInfo.getStatus();
|
|
|
|
|
|
@@ -139,11 +132,11 @@ public class EnNotifyServiceImpl implements EnNotifyService {
|
|
|
monitorLogService.save(monitorLog);
|
|
|
|
|
|
// 离线设备放入队列,5分钟之后如果还未恢复则放入长时间离线设备集合中并发送提醒,上线后发送提醒
|
|
|
- redisDBChangeUtil.redisTemplate.opsForZSet().add(RedisKeys.OFFLINE, connectorStatusInfo.getConnectorId(), System.currentTimeMillis() + 5 * 60 * 1000);
|
|
|
+ redisTemplate.opsForZSet().add(RedisKeys.OFFLINE, connectorStatusInfo.getConnectorId(), System.currentTimeMillis() + 5 * 60 * 1000);
|
|
|
} else {
|
|
|
// 先删除离线设备队列的记录,再删除离线超时队列中的记录
|
|
|
- var isDelete = redisDBChangeUtil.redisTemplate.opsForZSet().remove(RedisKeys.OFFLINE, connectorStatusInfo.getConnectorId());
|
|
|
- var exist = redisDBChangeUtil.redisTemplate.opsForSet().remove(RedisKeys.OFFLINE_EXPIRED, connectorStatusInfo.getConnectorId());
|
|
|
+ var isDelete = redisTemplate.opsForZSet().remove(RedisKeys.OFFLINE, connectorStatusInfo.getConnectorId());
|
|
|
+ var exist = redisTemplate.opsForSet().remove(RedisKeys.OFFLINE_EXPIRED, connectorStatusInfo.getConnectorId());
|
|
|
if ((isDelete != null && isDelete > 0) || (exist != null && exist > 0)) {
|
|
|
// 更新设备监控表
|
|
|
monitorLogService.lambdaUpdate()
|
|
|
@@ -304,13 +297,16 @@ public class EnNotifyServiceImpl implements EnNotifyService {
|
|
|
// 结束时间
|
|
|
var endTime = LocalDateTime.parse(data.getString("EndTime"), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
|
|
|
|
|
- // todo 判断适用哪种优惠
|
|
|
+ // 处理充值权益优惠逻辑/优惠券优惠逻辑
|
|
|
+ // 优惠金额
|
|
|
+ var discountCompute = DiscountStrategyFactory.getDiscountStrategy(chargeOrder.getDiscountType()).computeDiscount(new DiscountCompute(chargeOrder, account, endTime));
|
|
|
|
|
|
- // 处理充值权益优惠逻辑
|
|
|
- handleRechargeRights(chargeOrder, account, endTime);
|
|
|
+ // 更新订单优惠金额
|
|
|
+ updateOrderDiscount(chargeOrder, discountCompute);
|
|
|
+
|
|
|
+ // 扣费等资金操作
|
|
|
+ deductions(discountCompute.chargeOrder, discountCompute.account, endTime);
|
|
|
|
|
|
- // 处理优惠券优惠逻辑
|
|
|
- handleCoupon(chargeOrder, account, endTime);
|
|
|
}
|
|
|
return """
|
|
|
{
|
|
|
@@ -321,179 +317,27 @@ public class EnNotifyServiceImpl implements EnNotifyService {
|
|
|
""".formatted(startChargeSeq, chargeOrder.getConnectorId(), 0);
|
|
|
}
|
|
|
|
|
|
- private void handleCoupon(ChargeOrder chargeOrder, Account account, LocalDateTime endTime) {
|
|
|
- try {
|
|
|
- if (chargeOrder.getServiceMoney() <= 0) {
|
|
|
- LOGGER.info("订单:{} 服务费不合法", chargeOrder.getStartChargeSeq());
|
|
|
- return; // 服务费不合法,直接返回
|
|
|
- }
|
|
|
-
|
|
|
- // 获取订单优惠券
|
|
|
- var orderCoupon = orderCouponService.lambdaQuery()
|
|
|
- .eq(OrderCoupon::getStartChargeSeq, chargeOrder.getStartChargeSeq())
|
|
|
- .eq(OrderCoupon::getUserId, chargeOrder.getUserId())
|
|
|
- .one();
|
|
|
- if (orderCoupon == null) {
|
|
|
- return; // 没有优惠券,直接返回
|
|
|
- }
|
|
|
-
|
|
|
- // 查询用户优惠券信息
|
|
|
- var userCoupon = userCouponService.lambdaQuery()
|
|
|
- .eq(UserCoupon::getId, orderCoupon.getCouponId()) // 假设COUPON_ID是通用的,否则需要根据类型查询不同的字段
|
|
|
- .eq(UserCoupon::getUserId, chargeOrder.getUserId())
|
|
|
- .one();
|
|
|
- if (userCoupon == null) {
|
|
|
- return; // 没有找到用户优惠券,直接返回
|
|
|
- }
|
|
|
-
|
|
|
- // 检查是否达到使用门槛
|
|
|
- if (chargeOrder.getServiceMoney() < userCoupon.getMinServiceMoney()) {
|
|
|
- LOGGER.info("订单:{}优惠券{}使用失败:服务费未达到优惠券使用门槛", chargeOrder.getStartChargeSeq(), userCoupon.getCouponId());
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- // 根据优惠券类型处理
|
|
|
- processCouponDiscount(chargeOrder, userCoupon, orderCoupon.getCouponType());
|
|
|
-
|
|
|
- // 执行账户扣费等操作
|
|
|
- deductions(chargeOrder, account, endTime);
|
|
|
- } catch (Exception e) {
|
|
|
- LOGGER.error("处理优惠券失败", e);
|
|
|
- // 可以添加一些错误处理逻辑,比如重试机制、发送告警等
|
|
|
- }
|
|
|
- }
|
|
|
|
|
|
/**
|
|
|
- * 处理优惠券优惠逻辑
|
|
|
+ * 更新订单优惠金额
|
|
|
*
|
|
|
* @param chargeOrder
|
|
|
- * @param userCoupon
|
|
|
- * @param couponType
|
|
|
+ * @param discountCompute
|
|
|
*/
|
|
|
- private void processCouponDiscount(ChargeOrder chargeOrder, UserCoupon userCoupon, String couponType) {
|
|
|
- int discountAmount;
|
|
|
- switch (couponType) {
|
|
|
- case Coupon.COUPON_TYPE_折扣券:
|
|
|
- discountAmount = chargeOrder.getServiceMoney() * (100 - userCoupon.getDiscount()) / 100;
|
|
|
- updateOrderAndCoupon(chargeOrder, userCoupon, discountAmount);
|
|
|
- break;
|
|
|
- case Coupon.COUPON_TYPE_满减券:
|
|
|
- discountAmount = chargeOrder.getServiceMoney() - userCoupon.getDiscount();
|
|
|
- updateOrderAndCoupon(chargeOrder, userCoupon, discountAmount);
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 更新订单和优惠券信息
|
|
|
- *
|
|
|
- * @param chargeOrder
|
|
|
- * @param userCoupon
|
|
|
- * @param discountAmount
|
|
|
- */
|
|
|
- private void updateOrderAndCoupon(ChargeOrder chargeOrder, UserCoupon userCoupon, int discountAmount) {
|
|
|
- chargeOrder.setDiscountAmount(discountAmount);
|
|
|
- chargeOrder.setServiceMoneyDiscount(discountAmount);
|
|
|
+ void updateOrderDiscount(ChargeOrder chargeOrder, DiscountCompute discountCompute) {
|
|
|
+ chargeOrder.setDiscountAmount(discountCompute.discountAmount);
|
|
|
+ chargeOrder.setServiceMoneyDiscount(discountCompute.discountAmount);
|
|
|
chargeOrderService.updateById(chargeOrder);
|
|
|
- userCoupon.setDiscount(discountAmount);
|
|
|
- userCouponService.updateById(userCoupon);
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- /**
|
|
|
- * 处理订单权益
|
|
|
- *
|
|
|
- * @param chargeOrder
|
|
|
- * @param account
|
|
|
- * @param endTime
|
|
|
- */
|
|
|
- private void handleRechargeRights(ChargeOrder chargeOrder, Account account, LocalDateTime endTime) {
|
|
|
- // 获取订单权益,计算订单优惠金额,实付金额,服务费优惠金额
|
|
|
- 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 (userRechargeRights.getStatus() == UserRechargeRights.STATUS_有效) {
|
|
|
- if (chargeOrder.getPayAmount() <= userRechargeRights.getRightsBalance()) {
|
|
|
- userRechargeRights
|
|
|
- // 用户权益包余额扣减当前订单实付金额
|
|
|
- .setRightsBalance(userRechargeRights.getRightsBalance() - chargeOrder.getPayAmount())
|
|
|
- .setDiscountAmount(userRechargeRights.getDiscountAmount() + serviceMoneyDiscount);
|
|
|
-
|
|
|
- // 账户设置优惠不可退金额
|
|
|
- account.setDiscountAmount(account.getDiscountAmount() + serviceMoneyDiscount);
|
|
|
- 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);
|
|
|
- // 此权益包消耗完毕,账户设置优惠不可退金额
|
|
|
- account.setDiscountAmount(account.getDiscountAmount() + realDiscountAmount);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 更新订单权益的最终优惠金额
|
|
|
- orderRechargeRightsService.updateById(orderRechargeRights);
|
|
|
- // 更新用户权益金等
|
|
|
- userRechargeRightsService.updateById(userRechargeRights);
|
|
|
-
|
|
|
- // 执行账户扣费等操作
|
|
|
- deductions(chargeOrder, account, endTime);
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 账户扣费等操作
|
|
|
+ * 扣费等资金操作
|
|
|
*
|
|
|
* @param chargeOrder
|
|
|
* @param account
|
|
|
* @param endTime
|
|
|
*/
|
|
|
- private void deductions(ChargeOrder chargeOrder, Account account, LocalDateTime endTime) {
|
|
|
+ void deductions(ChargeOrder chargeOrder, Account account, LocalDateTime endTime) {
|
|
|
// 订单成功
|
|
|
chargeOrder.setOrderStatus(ChargeOrder.ORDER_STATUS_成功);
|
|
|
// 充电结束
|