From 619860d979f17b5cdcb22e89ace2d90d4eaf1ee5 Mon Sep 17 00:00:00 2001
From: puzhibing <393733352@qq.com>
Date: 星期五, 11 九月 2026 16:35:35 +0800
Subject: [PATCH] 添加幂等校验

---
 ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/iotda/utils/listener/IotMessageListener.java |   19 +++++++++++++++++++
 1 files changed, 19 insertions(+), 0 deletions(-)

diff --git a/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/iotda/utils/listener/IotMessageListener.java b/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/iotda/utils/listener/IotMessageListener.java
index 3e5ae6b..b4a3c23 100644
--- a/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/iotda/utils/listener/IotMessageListener.java
+++ b/ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/iotda/utils/listener/IotMessageListener.java
@@ -316,6 +316,21 @@
                 long CHARGING_PILE_STARTS_CHARGING = System.currentTimeMillis();
                 
                 ChargingPileStartsChargingMessage chargingPileStartsChargingMessage = JSON.parseObject(content.toJSONString(),ChargingPileStartsChargingMessage.class);
+                // 幂等防护:IoT平台会对启动申请并发/重复推送(同桩同枪同启动方式同卡/VIN),
+                // 重复申请直接忽略,防止重复建单及硬件收到一失败一成功多个应答(order侧枪锁tryLock(0)快速失败所致)
+                String startIdemAccount = chargingPileStartsChargingMessage.getStart_method() != null
+                        && chargingPileStartsChargingMessage.getStart_method() == 3
+                        ? chargingPileStartsChargingMessage.getVin()
+                        : chargingPileStartsChargingMessage.getAccount();
+                String startIdemKey = "IOT_START_CHARGING_IDEM:" + chargingPileStartsChargingMessage.getCharging_pile_code()
+                        + ":" + chargingPileStartsChargingMessage.getCharging_gun_code()
+                        + ":" + chargingPileStartsChargingMessage.getStart_method()
+                        + ":" + startIdemAccount;
+                Boolean startIdemFirst = redisTemplate.opsForValue().setIfAbsent(startIdemKey, System.currentTimeMillis(), 60, TimeUnit.SECONDS);
+                if (!Boolean.TRUE.equals(startIdemFirst)) {
+                    log.warn("CHARGING_PILE_STARTS_CHARGING重复申请,幂等忽略 key={}", startIdemKey);
+                    break;
+                }
                 chargingMessage.setChargingPileStartsChargingMessage(chargingPileStartsChargingMessage);
                 chargingMessageUtil.handleMessage(chargingMessage);
                 // 按启动方式执行真实业务鉴权建单(1=刷卡SD订单,2=账号暂不支持,3=VIN码VD订单)
@@ -359,6 +374,10 @@
                     platformConfirmationCharging.setFailure_cause(startVO == null ? null : startVO.getFailureCause());
                 }
                 iotMessageProduce.sendMessage(platformConfirmationCharging.getCharging_pile_code(), ServiceIdMenu.PLATFORM_CONFIRMATION_CHARGING.getKey(),messageUtil.platformConfirmationCharging(platformConfirmationCharging));
+                // 鉴权/建单失败时删除幂等键,放行设备重试(避免60秒内重新刷卡/VIN启动被误拦);成功则保留键至TTL过期
+                if (!Integer.valueOf(1).equals(platformConfirmationCharging.getAuthentication())) {
+                    redisTemplate.delete(startIdemKey);
+                }
     
                 log.warn("CHARGING_PILE_STARTS_CHARGING消息处理:{} 毫秒", System.currentTimeMillis() - CHARGING_PILE_STARTS_CHARGING);
                 break;

--
Gitblit v1.7.1