Bläddra i källkod

优化点 EN+充电状态推送更新数据库过于频繁问题

skyline 1 år sedan
förälder
incheckning
2ab4c6e2ab

+ 1 - 1
entity/src/main/java/com/kym/entity/common/RedisKeys.java

@@ -15,6 +15,6 @@ public interface RedisKeys {
     String STATION_ID_TO_NAME = "STATION_ID_TO_NAME:";
     String CONNECTOR_ID_TO_PARKING_NO = "CONNECTOR_ID_TO_PARKING_NO:";
     String ADMIN_USER_STATION_IDS = "ADMIN_USER_STATION_IDS:";
-
     String COUPON_ID_TO_USERS = "COUPON_ID_TO_USER_ID:";
+    String CHARGE_ORDER_EQUIP_CHARGE_STATUS = "CHARGE_ORDER_EQUIP_CHARGE_STATUS:";
 }

+ 8 - 4
service/src/main/java/com/kym/service/enplus/impl/EnNotifyServiceImpl.java

@@ -200,7 +200,7 @@ public class EnNotifyServiceImpl implements EnNotifyService {
     public String handleNotificationEquipChargeStatus(JSONObject json) {
         var dataStr = enPlusService.signValidation(json);
         var data = JSONObject.parseObject(dataStr);
-        LOGGER.info("【EN+推送】收到充电状态推送:{},解密数据:{}", json, data);
+        LOGGER.info("【EN+推送】 :{},解密数据:{}", json, data);
         var startChargeSeq = data.getString("StartChargeSeq");
         var chargeOrder = chargeOrderService.getChargingOrderByStartChargeSeq(startChargeSeq);
         // 更新订单信息
@@ -212,7 +212,10 @@ public class EnNotifyServiceImpl implements EnNotifyService {
         chargeOrder.setSumPeriod(data.getIntValue("SumPeriod"));
         chargeOrder.setChargeDetail(data.getString("ChargeDetails"));
         chargeOrder.setChargeStatus(data.getIntValue("StartChargeSeqStat"));
-        // TODO: 2023-09-07 待优化点 EN+一分钟推送一次,同时充电人数多的时候写入数据库过于频繁
+        // 优化点 EN+一分钟推送一次,同时充电人数多的时候写入数据库过于频繁
+        // redis保存(更新)订单信息
+        redisTemplate.opsForHash().put(RedisKeys.CHARGE_ORDER_EQUIP_CHARGE_STATUS, startChargeSeq, dataStr);
+
         chargeOrderService.updateById(chargeOrder);
         return """
                 {
@@ -295,6 +298,8 @@ public class EnNotifyServiceImpl implements EnNotifyService {
 
             // 扣费等资金操作
             deductions(chargeOrder, account, endTime);
+            // redis删除缓存订单信息(订单结算完调用)
+            redisTemplate.opsForHash().delete(RedisKeys.CHARGE_ORDER_EQUIP_CHARGE_STATUS, startChargeSeq);
         }
 
         return """
@@ -314,8 +319,7 @@ public class EnNotifyServiceImpl implements EnNotifyService {
      * @param account
      * @param endTime
      */
-    @Transactional(rollbackFor = Exception.class)
-    void deductions(ChargeOrder chargeOrder, Account account, LocalDateTime endTime) {
+    private void deductions(ChargeOrder chargeOrder, Account account, LocalDateTime endTime) {
         // 订单成功
         chargeOrder.setOrderStatus(ChargeOrder.ORDER_STATUS_成功);
         // 充电结束

+ 20 - 45
service/src/main/java/com/kym/service/miniapp/impl/ChargeServiceImpl.java

@@ -13,6 +13,7 @@ import com.kym.common.utils.OrderUtils;
 import com.kym.entity.admin.Activity;
 import com.kym.entity.admin.ConnectorInfo;
 import com.kym.entity.admin.EquipmentInfo;
+import com.kym.entity.common.RedisKeys;
 import com.kym.entity.enplus.response.EnBusinessPolicy;
 import com.kym.entity.miniapp.*;
 import com.kym.entity.miniapp.delay.DelayChargeOrder;
@@ -28,9 +29,11 @@ import org.slf4j.LoggerFactory;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.context.annotation.Lazy;
+import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 
+import java.math.BigDecimal;
 import java.time.Duration;
 import java.time.LocalDateTime;
 import java.util.Map;
@@ -46,27 +49,18 @@ import java.util.concurrent.TimeUnit;
 public class ChargeServiceImpl implements ChargeService {
 
     private static final Logger LOGGER = LoggerFactory.getLogger(ChargeServiceImpl.class);
-
+    public final StringRedisTemplate redisTemplate;
     private final EquipmentRelationService equipmentRelationService;
-
     private final EquipmentInfoService equipmentInfoService;
-
     private final ConnectorInfoService connectorInfoService;
-
     private final ChargeOrderService chargeOrderService;
-
     private final OrderRechargeRightsService orderRechargeRightsService;
     private final UserRechargeRightsService userRechargeRightsService;
     private final UserCouponService userCouponService;
-
     private final OrderCouponService orderCouponService;
-
     private final AccountService accountService;
-
     private final EnPlusService enPlusService;
-
     private final EnPlusConfig enPlusConfig;
-
     private final DelayService<DelayChargeOrder> startDelayService;
     private final DelayService<DelayChargeOrder> stopDelayService;
 
@@ -75,7 +69,7 @@ public class ChargeServiceImpl implements ChargeService {
                              OrderRechargeRightsService orderRechargeRightsService, UserRechargeRightsService userRechargeRightsService, UserCouponService userCouponService, OrderCouponService orderCouponService,
                              AccountService accountService, EnPlusService enPlusService, EnPlusConfig enPlusConfig,
                              @Qualifier("StartChargeDelayJob") @Lazy DelayService<DelayChargeOrder> startDelayService,
-                             @Qualifier("StopChargeDelayJob") @Lazy DelayService<DelayChargeOrder> stopDelayService) {
+                             @Qualifier("StopChargeDelayJob") @Lazy DelayService<DelayChargeOrder> stopDelayService, StringRedisTemplate redisTemplate) {
         this.equipmentRelationService = equipmentRelationService;
         this.equipmentInfoService = equipmentInfoService;
         this.connectorInfoService = connectorInfoService;
@@ -89,6 +83,7 @@ public class ChargeServiceImpl implements ChargeService {
         this.enPlusConfig = enPlusConfig;
         this.startDelayService = startDelayService;
         this.stopDelayService = stopDelayService;
+        this.redisTemplate = redisTemplate;
     }
 
 
@@ -406,6 +401,7 @@ public class ChargeServiceImpl implements ChargeService {
                     case 1 -> // 设备不存在
                             throw new BusinessException(ResponseEnum.EN_PLUS_EQUIP_NOT_EXIST);
                     case 2 -> // 设备离线
+                        // todo 设备离线,加入重试机制
                             throw new BusinessException(ResponseEnum.EN_PLUS_EQUIP_OFFLINE);
                     case 3 -> // 存在未完成的订单
                             throw new BusinessException(ResponseEnum.EN_PLUS_EQUIP_EXIST_ORDER_UNFINISHED);
@@ -459,41 +455,20 @@ public class ChargeServiceImpl implements ChargeService {
         var userId = StpUtil.getLoginIdAsLong();
         var chargeOrder = chargeOrderService.getChargingOrderByUserId(userId);
         if (chargeOrder != null) {
-            if (chargeOrder.getChargeStatus().equals(ChargeOrder.CHARGE_STATUS_预约中)) {
-                return chargeOrder;
-            }
-            // 查询充电
-            JSONObject data;
-            var startChargeSeq = chargeOrder.getStartChargeSeq();
-            try {
-                data = enPlusService.queryEquipChargeStatus(startChargeSeq);
-            } catch (Exception e) {
-                LOGGER.error("EN+请求设备充电状态异常", e);
-                throw new BusinessException("充电状态查询异常,请稍后重试");
+            // 查询redis缓存,有数据则更新chargeOrder再返回
+            var orderDataStr = redisTemplate.opsForHash().get(RedisKeys.CHARGE_ORDER_EQUIP_CHARGE_STATUS, chargeOrder.getStartChargeSeq());
+            if (CommUtil.isNotEmptyAndNull(orderDataStr)) {
+                var data = JSONObject.parseObject(orderDataStr.toString());
+                // 更新订单信息
+                chargeOrder.setSoc(data.getDoubleValue("Soc"));
+                chargeOrder.setTotalPower(data.getDoubleValue("TotalPower"));
+                chargeOrder.setTotalMoney((data.getBigDecimal("TotalMoney").multiply(BigDecimal.valueOf(100))).intValue());
+                chargeOrder.setElecMoney((data.getBigDecimal("ElecMoney").multiply(BigDecimal.valueOf(100))).intValue());
+                chargeOrder.setServiceMoney((data.getBigDecimal("SeviceMoney").multiply(BigDecimal.valueOf(100))).intValue()); // 这里文档service单词错误,按文档填写
+                chargeOrder.setSumPeriod(data.getIntValue("SumPeriod"));
+                chargeOrder.setChargeDetail(data.getString("ChargeDetails"));
+                chargeOrder.setChargeStatus(data.getIntValue("StartChargeSeqStat"));
             }
-
-            // TODO 存在并发问题,订单刚启动充电,这里可能将订单状态重新更新为启动中,解决方案:屏蔽启动中状态更新
-
-            // 更新订单信息
-            chargeOrderService.lambdaUpdate()
-                    .set(ChargeOrder::getSoc, data.getDoubleValue("Soc"))
-                    .set(ChargeOrder::getTotalPower, data.getDoubleValue("TotalPower"))
-                    .set(ChargeOrder::getTotalMoney, (int) ((data.getDouble("TotalMoney") * 100)))
-                    .set(ChargeOrder::getElecMoney, (int) ((data.getDouble("ElecMoney") * 100)))
-                    .set(ChargeOrder::getServiceMoney, (int) ((data.getDouble("SeviceMoney") * 100))) // 这里文档service单词错误,按文档填写
-                    .set(ChargeOrder::getSumPeriod, (int) (data.getIntValue("SumPeriod")))
-                    .set(ChargeOrder::getChargeDetail, data.getString("ChargeDetails"))
-                    .set(ChargeOrder::getChargeStatus, data.getIntValue("StartChargeSeqStat"))
-                    .eq(ChargeOrder::getStartChargeSeq, startChargeSeq).update();
-
-            chargeOrder.setSoc(data.getDoubleValue("Soc"));
-            chargeOrder.setTotalPower(data.getDoubleValue("TotalPower"));
-            chargeOrder.setTotalMoney((int) ((data.getDouble("TotalMoney") * 100)));
-            chargeOrder.setElecMoney((int) ((data.getDouble("ElecMoney") * 100)));
-            chargeOrder.setServiceMoney((int) ((data.getDouble("SeviceMoney") * 100))); // 这里文档service单词错误,按文档填写
-            chargeOrder.setSumPeriod(data.getIntValue("SumPeriod"));
-            chargeOrder.setChargeDetail(data.getString("ChargeDetails"));
-            chargeOrder.setChargeStatus(data.getIntValue("StartChargeSeqStat"));
             return chargeOrder;
         } else {
             LOGGER.debug("用户:{}无进行中的订单", userId);