From 0541c0791acea41b584f71fc59e22d4d21ba0883 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期三, 15 四月 2026 11:10:46 +0800
Subject: [PATCH] ``` refactor(energy): 优化实时能耗数据服务实现

---
 src/main/java/com/ruoyi/http/service/impl/RealTimeEnergyConsumptionServiceImpl.java |  110 +++++++++++++++++++++++++++++++++++++++++++++++-------
 src/main/java/com/ruoyi/http/service/controller/JclyController.java                 |    6 ++-
 2 files changed, 99 insertions(+), 17 deletions(-)

diff --git a/src/main/java/com/ruoyi/http/service/controller/JclyController.java b/src/main/java/com/ruoyi/http/service/controller/JclyController.java
index 1da6df7..2f966d2 100644
--- a/src/main/java/com/ruoyi/http/service/controller/JclyController.java
+++ b/src/main/java/com/ruoyi/http/service/controller/JclyController.java
@@ -52,7 +52,8 @@
     public AjaxResult getRealData() {
         List<Map<String,String>> maps = realTimeEnergyConsumptionService
                 .getRealData(Arrays.
-                        asList(DEVICE_GUID,
+                        asList(
+                                DEVICE_GUID,
                                 DEVICE_GUID_2,
                                 DEVICE_GUID_3,
                                 DEVICE_GUID_4,
@@ -63,7 +64,8 @@
                                 DEVICE_GUID_9,
                                 DEVICE_GUID_10,
                                 DEVICE_GUID_11,
-                                DEVICE_GUID_12));
+                                DEVICE_GUID_12
+                        ));
         return AjaxResult.success(maps);
     }
 
diff --git a/src/main/java/com/ruoyi/http/service/impl/RealTimeEnergyConsumptionServiceImpl.java b/src/main/java/com/ruoyi/http/service/impl/RealTimeEnergyConsumptionServiceImpl.java
index dcf21d9..c529eb0 100644
--- a/src/main/java/com/ruoyi/http/service/impl/RealTimeEnergyConsumptionServiceImpl.java
+++ b/src/main/java/com/ruoyi/http/service/impl/RealTimeEnergyConsumptionServiceImpl.java
@@ -3,6 +3,7 @@
 import com.alibaba.fastjson2.JSON;
 import com.alibaba.fastjson2.JSONArray;
 import com.alibaba.fastjson2.JSONObject;
+import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.common.utils.http.HttpUtils;
 import com.ruoyi.http.service.RealTimeEnergyConsumptionService;
 import lombok.extern.slf4j.Slf4j;
@@ -49,11 +50,13 @@
 
     private static final String HISTORY_CACHE_PREFIX = "JCLY:HISTORY:";
 
+    private static final String TOKEN_CACHE_KEY = "JCLY_TOKEN:";
+
     private static final String STATUS_KEY = "status";
 
     private static final String STATUS_MESSAGE_KEY = "statusMessage";
 
-    private static final String STATUS_OK = "ok";
+    private static final String STATUS_ONLINE = "鍦ㄧ嚎";
 
     private static final String STATUS_OFFLINE = "offline";
 
@@ -111,7 +114,7 @@
                 historyItem.put("monitorTimeStr", historyObj.getString("monitorTimeStr"));
                 historyItem.put("position", historyObj.getString("position"));
                 historyItem.put("address", historyObj.getString("address"));
-                historyItem.put(STATUS_KEY, STATUS_OK);
+                historyItem.put(STATUS_KEY, resolveStatusByAlarmState(historyObj.get("alarmState"), STATUS_ONLINE));
 
                 JSONArray paramList = historyObj.getJSONArray("data");
                 if (paramList != null && !paramList.isEmpty()) {
@@ -129,6 +132,8 @@
                             historyItem.put("humidity", fullValue);
                         } else if ("0130".equals(paramCode)) {
                             historyItem.put("co2", fullValue);
+                        } else if ("0042".equals(paramCode)) {
+                            historyItem.put("battery", fullValue);
                         } else if (paramCode != null) {
                             historyItem.put(paramCode, fullValue);
                         }
@@ -176,7 +181,7 @@
     }
 
     public String getToken() {
-        String cachedToken = sanitizeToken(redisTemplate.opsForValue().get("JCLY_TOKEN:"));
+        String cachedToken = sanitizeToken(redisTemplate.opsForValue().get(TOKEN_CACHE_KEY));
         if (cachedToken != null) {
             return cachedToken;
         }
@@ -192,10 +197,11 @@
         if (Integer.valueOf(0).equals(map.get("code"))) {
             Object token = map.get("data");
             log.info("token:{}", token);
-            redisTemplate.opsForValue().set("JCLY_TOKEN:", token.toString(), 60 * 60 * 24);
+            redisTemplate.opsForValue().set(TOKEN_CACHE_KEY, token.toString(), 60 * 60 * 12);
             return token.toString();
         }
-        return result;
+        log.error("get token failed, response={}", result);
+        return null;
     }
 
     private String sanitizeToken(String token) {
@@ -217,6 +223,64 @@
 
     private String stringValue(Object value) {
         return value == null ? null : String.valueOf(value);
+    }
+
+    private String refreshToken() {
+        redisTemplate.delete(TOKEN_CACHE_KEY);
+        return getToken();
+    }
+
+    private boolean isUnauthorizedException(Exception ex) {
+        if (ex == null || ex.getMessage() == null) {
+            return false;
+        }
+        String msg = ex.getMessage().toLowerCase();
+        return msg.contains("401") || msg.contains("unauthorized");
+    }
+
+    private boolean isUnauthorizedResponse(String result) {
+        if (result == null || result.trim().isEmpty()) {
+            return false;
+        }
+        try {
+            JSONObject obj = JSON.parseObject(result);
+            if (obj == null) {
+                return false;
+            }
+            Integer code = obj.getInteger("code");
+            if (code != null && (code == 401 || code == 403)) {
+                return true;
+            }
+            String msg = obj.getString("msg");
+            return msg != null && msg.toLowerCase().contains("unauthorized");
+        } catch (Exception ignore) {
+            return result.contains("401");
+        }
+    }
+
+    private String requestWithTokenRetry(String url, String payload, String token, String scene) {
+        String usedToken = sanitizeToken(token);
+        if (usedToken == null) {
+            usedToken = refreshToken();
+        }
+        try {
+            String result = HttpUtils.sendPostJson(url, payload, usedToken);
+            if (!isUnauthorizedResponse(result) && StringUtils.isNotEmpty(result)) {
+                return result;
+            }
+            log.warn("{} got unauthorized response, refresh token and retry once", scene);
+        } catch (Exception ex) {
+            if (!isUnauthorizedException(ex)) {
+                throw ex;
+            }
+            log.warn("{} got 401 exception, refresh token and retry once", scene);
+        }
+
+        String newToken = refreshToken();
+        if (newToken == null) {
+            throw new RuntimeException("refresh token failed");
+        }
+        return HttpUtils.sendPostJson(url, payload, newToken);
     }
 
     private String concatValueWithUnit(String value, String unitCode) {
@@ -296,7 +360,6 @@
     }
 
     private Map<String, String> parseSingleDevice(JSONObject deviceObj, String fallbackGuid) {
-        String[] targetCodes = {"0100", "0110", "0120", "0130"};
         Map<String, String> deviceData = new HashMap<>();
         String deviceGuid = firstNonBlank(
                 deviceObj.getString("deviceGuid"),
@@ -316,12 +379,10 @@
             return deviceData;
         }
 
-        deviceData.put(STATUS_KEY, STATUS_OK);
-        for (String code : targetCodes) {
-            JSONObject paramObj = getProbeParam(paramList, code);
-            if (paramObj.isEmpty()) {
-                continue;
-            }
+        deviceData.put(STATUS_KEY, resolveStatusByAlarmState(deviceObj.get("alarmState"), STATUS_ONLINE));
+        for (int i = 0; i < paramList.size(); i++) {
+            JSONObject paramObj = paramList.getJSONObject(i);
+            String code = paramObj.getString("paramCode");
             String value = paramObj.getString("value");
             String unitCode = paramObj.getString("unitCode");
             String fullValue = concatValueWithUnit(value, unitCode);
@@ -333,9 +394,28 @@
                 deviceData.put("humidity", fullValue);
             } else if ("0130".equals(code)) {
                 deviceData.put("co2", fullValue);
+            } else if ("0042".equals(code)) {
+                deviceData.put("battery", fullValue);
             }
         }
         return deviceData;
+    }
+
+    private String resolveStatusByAlarmState(Object alarmState, String defaultStatus) {
+        if (alarmState == null) {
+            return defaultStatus;
+        }
+        if (alarmState instanceof Boolean) {
+            return (Boolean) alarmState ? STATUS_OFFLINE : STATUS_ONLINE;
+        }
+        String normalized = String.valueOf(alarmState).trim().toLowerCase();
+        if ("true".equals(normalized) || "1".equals(normalized)) {
+            return STATUS_OFFLINE;
+        }
+        if ("false".equals(normalized) || "0".equals(normalized)) {
+            return STATUS_ONLINE;
+        }
+        return defaultStatus;
     }
 
     public String getRealTimeData(String token, List<String> guidList) {
@@ -350,7 +430,7 @@
             log.info("hit realtime cache: {}", cacheKey);
             return cachedResult;
         }
-        String result = HttpUtils.sendPostJson(URL + REAL_TIME_URL, JSON.toJSONString(param), token);
+        String result = requestWithTokenRetry(URL + REAL_TIME_URL, JSON.toJSONString(param), token, "getRealTimeData");
         log.info("request realtime response: {}", result);
         cacheRemoteResponse(cacheKey, result);
         return result;
@@ -370,7 +450,7 @@
             log.info("hit history cache: {}", cacheKey);
             return cachedResult;
         }
-        String result = HttpUtils.sendPostJson(REAL_HISTORY_URL, JSON.toJSONString(param), token);
+        String result = requestWithTokenRetry(REAL_HISTORY_URL, JSON.toJSONString(param), token, "getHistoryData");
         log.info("request history response: {}", result);
         cacheRemoteResponse(cacheKey, result);
         return result;
@@ -382,4 +462,4 @@
         }
         redisTemplate.opsForValue().set(cacheKey, result, REMOTE_CACHE_TTL_SECONDS_30, TimeUnit.SECONDS);
     }
-}
\ No newline at end of file
+}

--
Gitblit v1.9.3