package com.ruoyi.http.service.impl; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; import com.ruoyi.common.utils.http.HttpUtils; import com.ruoyi.http.service.RealTimeEnergyConsumptionService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; import java.time.Instant; import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; /** * @author :yys * @date : 2026/1/27 16:02 */ @Service @Slf4j public class RealTimeEnergyConsumptionServiceImpl implements RealTimeEnergyConsumptionService { private static final long REMOTE_CACHE_TTL_SECONDS = 10L; // 缓存TTL,10秒 private static final long REMOTE_CACHE_TTL_SECONDS_30 = 30L; // 缓存TTL,30秒 private static final String URL = "https://new.e-elitech.cn/api/data-api"; private static final String TOKEN_URL = "/elitechAccess/getToken"; private static final String REAL_TIME_URL = "/elitechAccess/v2/getRealTimeData"; private static final String REAL_HISTORY_URL = URL + "/elitechAccess/v2/getHistoryData"; private static final String KET_ID = "75804708"; private static final String KEY_SECRET = "xTUGToozKpYgUPqTsZzB"; private static final String USER_NAME = "用户30773662"; private static final String PASS_WORD = "y17775163675"; private static final String REAL_TIME_CACHE_PREFIX = "JCLY:REAL_TIME:"; private static final String HISTORY_CACHE_PREFIX = "JCLY:HISTORY:"; @Autowired private RedisTemplate redisTemplate; private static JSONObject getProbeParam(JSONArray paramList, String targetCode) { if (paramList == null) { return new JSONObject(); } for (int i = 0; i < paramList.size(); i++) { JSONObject paramObj = paramList.getJSONObject(i); if (targetCode.equals(paramObj.getString("paramCode"))) { return paramObj; } } return new JSONObject(); } public List> getHistoryData(String guid, long startTime, long endTime) { List> resultList = new ArrayList<>(); String historyData = requestHistoryData(getToken(), guid, startTime, endTime); Map resultMap = JSON.parseObject(historyData, Map.class); if (!Integer.valueOf(0).equals(resultMap.get("code"))) { return resultList; } JSONArray historyList = JSON.parseArray(String.valueOf(resultMap.get("data"))); if (historyList == null || historyList.isEmpty()) { return resultList; } for (int i = 0; i < historyList.size(); i++) { JSONObject historyObj = historyList.getJSONObject(i); Map historyItem = new HashMap<>(); historyItem.put("guid", firstNonBlank( historyObj.getString("deviceGuid"), historyObj.getString("guid"), guid )); historyItem.put("subUId", stringValue(historyObj.get("subUid"))); historyItem.put("monitorTimeStamp", stringValue(historyObj.get("monitorTimeStamp"))); historyItem.put("monitorTimeStr", historyObj.getString("monitorTimeStr")); historyItem.put("position", historyObj.getString("position")); historyItem.put("address", historyObj.getString("address")); JSONArray paramList = historyObj.getJSONArray("data"); if (paramList != null && !paramList.isEmpty()) { for (int j = 0; j < paramList.size(); j++) { JSONObject paramObj = paramList.getJSONObject(j); String paramName = paramObj.getString("paramName"); String paramCode = paramObj.getString("paramCode"); String value = paramObj.getString("value"); String unitCode = paramObj.getString("unitCode"); String fullValue = value == null ? null : value + (unitCode == null ? "" : unitCode); switch (paramName) { case "探头1": historyItem.put("light", fullValue); break; case "探头2": historyItem.put("temperature", fullValue); break; case "探头3": historyItem.put("humidity", fullValue); break; case "探头4": historyItem.put("co2", fullValue); break; default: if (paramCode != null) { historyItem.put(paramCode, fullValue); } break; } } } resultList.add(historyItem); } return resultList; } public List> getRealData(List guidList) { log.info("开始获取实时数据"); List> listMaps = new ArrayList<>(); String realTimeData = getRealTimeData(getToken(), guidList); Map map = JSON.parseObject(realTimeData, Map.class); if (!Integer.valueOf(0).equals(map.get("code"))) { return listMaps; } JSONArray deviceList = JSON.parseArray(String.valueOf(map.get("data"))); if (deviceList == null || deviceList.isEmpty()) { return listMaps; } String[] targetCodes = {"0100", "0110", "0120", "0130"}; for (int deviceIndex = 0; deviceIndex < deviceList.size(); deviceIndex++) { JSONObject deviceObj = deviceList.getJSONObject(deviceIndex); JSONArray paramList = deviceObj.getJSONArray("data"); Map deviceData = new HashMap<>(); String deviceGuid = firstNonBlank( deviceObj.getString("deviceGuid"), deviceObj.getString("guid"), deviceObj.getString("devGuid"), deviceObj.getString("sn") ); if (deviceGuid != null) { deviceData.put("guid", deviceGuid); } for (String code : targetCodes) { JSONObject paramObj = getProbeParam(paramList, code); if (paramObj.isEmpty()) { continue; } String paramName = paramObj.getString("paramName"); String value = paramObj.getString("value"); String unitCode = paramObj.getString("unitCode"); log.info("{}: {} {}", paramName, value, unitCode); switch (paramName) { case "探头1": deviceData.put("light", value + unitCode); break; case "探头2": deviceData.put("temperature", value + unitCode); break; case "探头3": deviceData.put("humidity", value + unitCode); break; case "探头4": deviceData.put("co2", value + unitCode); break; default: break; } } listMaps.add(deviceData); } return listMaps; } public static void main(String[] args) { System.out.println(); } public String getToken() { String cachedToken = sanitizeToken(redisTemplate.opsForValue().get("JCLY_TOKEN:")); if (cachedToken != null) { return cachedToken; } Map param = new HashMap<>(); param.put("keyId", KET_ID); param.put("keySecret", KEY_SECRET); param.put("userName", USER_NAME); param.put("password", PASS_WORD); log.info("请求参数:{}", JSON.toJSONString(param)); String result = HttpUtils.sendPostJson(URL + TOKEN_URL, JSON.toJSONString(param)); log.info("返回结果:{}", result); Map map = JSON.parseObject(result, Map.class); 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); return token.toString(); } return result; } private String sanitizeToken(String token) { if (token == null) { return null; } String cleanedToken = token.replace("\0", "").trim(); return cleanedToken.isEmpty() ? null : cleanedToken; } private String firstNonBlank(String... values) { for (String value : values) { if (value != null && !value.trim().isEmpty()) { return value; } } return null; } private String stringValue(Object value) { return value == null ? null : String.valueOf(value); } public String getRealTimeData(String token, List guidList) { Map param = new HashMap<>(); param.put("keyId", KET_ID); param.put("keySecret", KEY_SECRET); param.put("deviceGuids", guidList); log.info("请求参数:{}", JSON.toJSONString(param)); String cacheKey = REAL_TIME_CACHE_PREFIX + JSON.toJSONString(param); String cachedResult = sanitizeToken(redisTemplate.opsForValue().get(cacheKey)); if (cachedResult != null) { log.info("命中实时数据缓存:{}", cacheKey); return cachedResult; } String result = HttpUtils.sendPostJson(URL + REAL_TIME_URL, JSON.toJSONString(param), token); log.info("返回结果:{}", result); cacheRemoteResponse(cacheKey, result); return result; } public String requestHistoryData(String token, String guid, long startTime, long endTime) { Map param = new HashMap<>(); param.put("keyId", KET_ID); param.put("keySecret", KEY_SECRET); param.put("deviceGuid", guid); param.put("startTime", startTime); param.put("endTime", endTime); log.info("历史数据请求参数:{}", JSON.toJSONString(param)); String cacheKey = HISTORY_CACHE_PREFIX + JSON.toJSONString(param); String cachedResult = sanitizeToken(redisTemplate.opsForValue().get(cacheKey)); if (cachedResult != null) { log.info("命中历史数据缓存:{}", cacheKey); return cachedResult; } String result = HttpUtils.sendPostJson(REAL_HISTORY_URL, JSON.toJSONString(param), token); log.info("历史数据返回结果:{}", result); cacheRemoteResponse(cacheKey, result); return result; } private void cacheRemoteResponse(String cacheKey, String result) { if (result == null || result.trim().isEmpty()) { return; } redisTemplate.opsForValue().set(cacheKey, result, REMOTE_CACHE_TTL_SECONDS_30, TimeUnit.SECONDS); } }