Просмотр исходного кода

设备状态增加缓存,设备变为空闲时,校验是否有预约信息,防止预约中的客户提前拔枪造成异常。

skyline 2 лет назад
Родитель
Сommit
b40596713b

+ 23 - 7
service/src/main/java/com/kym/service/enplus/impl/EnNotifyServiceImpl.java

@@ -29,6 +29,8 @@ import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Collectors;
 
 /**
  * @author skyline
@@ -40,10 +42,14 @@ import java.time.format.DateTimeFormatter;
 public class EnNotifyServiceImpl implements EnNotifyService {
     private static final Logger LOGGER = LoggerFactory.getLogger(EnNotifyServiceImpl.class);
 
+    public static ConcurrentHashMap<String, Integer> equipmentStatusCache = new ConcurrentHashMap<>();
+
     private final EnPlusService enPlusService;
 
     private final ChargeOrderService chargeOrderService;
 
+    private final ChargeService chargeService;
+
     private final AccountService accountService;
 
     private final WalletDetailService walletDetailService;
@@ -64,11 +70,12 @@ public class EnNotifyServiceImpl implements EnNotifyService {
     private String notifyEmail;
 
     public EnNotifyServiceImpl(EnPlusService enPlusService, ChargeOrderService chargeOrderService,
-                               AccountService accountService, WalletDetailService walletDetailService,
+                               ChargeService chargeService, AccountService accountService, WalletDetailService walletDetailService,
                                MonitorLogService monitorLogService, EquipmentInfoService equipmentInfoService,
                                UserRechargeRightsService userRechargeRightsService, OrderRechargeRightsService orderRechargeRightsService, KymCache kymCache, RedisDBChangeUtil redisDBChangeUtil) {
         this.enPlusService = enPlusService;
         this.chargeOrderService = chargeOrderService;
+        this.chargeService = chargeService;
         this.accountService = accountService;
         this.walletDetailService = walletDetailService;
         this.monitorLogService = monitorLogService;
@@ -77,6 +84,7 @@ public class EnNotifyServiceImpl implements EnNotifyService {
         this.orderRechargeRightsService = orderRechargeRightsService;
         this.kymCache = kymCache;
         this.redisDBChangeUtil = redisDBChangeUtil;
+        equipmentStatusCache.putAll(equipmentInfoService.list().stream().collect(Collectors.toMap(EquipmentInfo::getEquipmentId, EquipmentInfo::getServiceStatus)));
     }
 
     /**
@@ -92,15 +100,20 @@ public class EnNotifyServiceImpl implements EnNotifyService {
         LOGGER.info("【EN+推送】收到充电桩设备状态变化推送:\n{} \n 解密数据:{}", json, data);
         // 更新数据库,存入redis,发送邮件通知
         var connectorStatusInfo = JSONObject.parseObject(data).getJSONObject("ConnectorStatusInfo").toJavaObject(EnConnectorStatusInfo.class);
+        var connectorId = connectorStatusInfo.getConnectorId();
+        var equipmentId = connectorId.substring(0, 16);
+
         equipmentInfoService.lambdaUpdate()
-                .eq(EquipmentInfo::getEquipmentId, connectorStatusInfo.getConnectorId().substring(0, 16))
+                .eq(EquipmentInfo::getEquipmentId, equipmentId)
                 .set(EquipmentInfo::getServiceStatus, connectorStatusInfo.getStatus())
                 .update();
 
         // 切换到admin对应的db
         redisDBChangeUtil.setDataBase(0);
 
-        if (connectorStatusInfo.getStatus() == 0) {
+        var connectorStatus = connectorStatusInfo.getStatus();
+
+        if (connectorStatus == 0) {
             LOGGER.info("充电桩设备离线:{}", connectorStatusInfo.getConnectorId());
             // 如果设备离线,则存入redis
             var monitorLog = new MonitorLog()
@@ -113,9 +126,6 @@ public class EnNotifyServiceImpl implements EnNotifyService {
 
             // 离线设备放入队列,5分钟之后如果还未恢复则放入长时间离线设备集合中并发送提醒,上线后发送提醒
             redisDBChangeUtil.redisTemplate.opsForZSet().add(RedisKeys.OFFLINE, connectorStatusInfo.getConnectorId(), System.currentTimeMillis() + 5 * 60 * 1000);
-
-//            MailUtil.send(notifyEmail, "【设备离线通知】", "站点:%s,设备%s离线"
-//                    .formatted(kymCache.getStationName(monitorLog.getStationId()), kymCache.getShortId(monitorLog.getSn())), false);
         } else {
             // 先删除离线设备队列的记录,再删除离线超时队列中的记录
             var isDelete = redisDBChangeUtil.redisTemplate.opsForZSet().remove(RedisKeys.OFFLINE, connectorStatusInfo.getConnectorId());
@@ -129,13 +139,19 @@ public class EnNotifyServiceImpl implements EnNotifyService {
                         .set(MonitorLog::getIsRecover, MonitorLog.IS_RECOVER_已恢复) // 设置为已恢复
                         .update();
             }
-
             if (exist != null && exist > 0) {
                 MailUtil.send(notifyEmail, "【设备上线通知】", "站点:%s,设备%s恢复上线"
                         .formatted(kymCache.getStationNameByConnectorId(connectorStatusInfo.getConnectorId()), kymCache.getShortId(connectorStatusInfo.getConnectorId())), false);
             }
         }
 
+        // 设备状态变为空闲,校验是否有预约订单,有则清除预约订单数据。
+        if (connectorStatus == 1 && equipmentStatusCache.get(equipmentId) != 1) {
+            LOGGER.info("设备:{}状态转为空闲,清除设备预约数据...", connectorId);
+            chargeService.cancelBookingByConnector(connectorId);
+        }
+        equipmentStatusCache.put(equipmentId, connectorStatus);
+
         return """
                 {
                     "Status":%d

+ 3 - 0
service/src/main/java/com/kym/service/miniapp/ChargeService.java

@@ -14,6 +14,9 @@ import java.util.Map;
  */
 public interface ChargeService {
 
+    void cancelBookingByConnector(String connectorId);
+
+
     Map<String, String> queryStartCharge(Long userId, String connectorId, Long userRechargeRightsId, Boolean isBooking, LocalDateTime startTime, LocalDateTime endTime);
 
     @DS("db-admin")

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

@@ -25,6 +25,7 @@ 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.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 
 import java.time.Duration;
@@ -130,6 +131,25 @@ public class ChargeServiceImpl implements ChargeService {
                 .eq(ChargeOrder::getOrderStatus, ChargeOrder.ORDER_STATUS_未知)
                 .eq(ChargeOrder::getChargeStatus, ChargeOrder.CHARGE_STATUS_预约中)
                 .one();
+        cancelBookByChargeOrder(chargeOrder);
+    }
+
+    /**
+     * 取消预约
+     */
+    @Override
+    @Async
+    public void cancelBookingByConnector(String connectorId) {
+        var chargeOrder = chargeOrderService.lambdaQuery()
+                .eq(ChargeOrder::getConnectorId,connectorId)
+                .eq(ChargeOrder::getIsBooking, ChargeOrder.IS_BOOKING_是)
+                .eq(ChargeOrder::getOrderStatus, ChargeOrder.ORDER_STATUS_未知)
+                .eq(ChargeOrder::getChargeStatus, ChargeOrder.CHARGE_STATUS_预约中)
+                .one();
+        cancelBookByChargeOrder(chargeOrder);
+    }
+
+    public void cancelBookByChargeOrder(ChargeOrder chargeOrder){
         if (chargeOrder != null) {
             // 清除启动/停止队列信息
             startDelayService.removeFromDelayQueue(chargeOrder.getStartChargeSeq());
@@ -140,7 +160,6 @@ public class ChargeServiceImpl implements ChargeService {
                     .eq(ChargeOrder::getIsBooking, ChargeOrder.IS_BOOKING_是)
                     .set(ChargeOrder::getOrderStatus, ChargeOrder.ORDER_STATUS_取消)
                     .set(ChargeOrder::getChargeStatus, ChargeOrder.CHARGE_STATUS_已取消)
-//                    .set(ChargeOrder::getStopReason, ChargeOrder.STOP_REASON_用户手动停止)
                     .update();
         } else {
             throw new BusinessException("用户没有预约中的订单");