diff --git a/shgx-admin/src/main/java/com/shgx/web/controller/dryingroom/DryEquipmentInfoController.java b/shgx-admin/src/main/java/com/shgx/web/controller/dryingroom/DryEquipmentInfoController.java index fdea08a..dff43b2 100644 --- a/shgx-admin/src/main/java/com/shgx/web/controller/dryingroom/DryEquipmentInfoController.java +++ b/shgx-admin/src/main/java/com/shgx/web/controller/dryingroom/DryEquipmentInfoController.java @@ -3,6 +3,7 @@ package com.shgx.web.controller.dryingroom; import java.util.List; import javax.servlet.http.HttpServletResponse; +import com.shgx.dryingroom.collect.AutoCollectService; import com.shgx.dryingroom.web.domain.DryEquipmentInfo; import com.shgx.dryingroom.web.domain.dto.ParamThresholdDTO; import com.shgx.dryingroom.web.service.IDryEquipmentInfoService; @@ -40,6 +41,9 @@ public class DryEquipmentInfoController extends BaseController @Autowired private IDryEquipmentInfoService dryEquipmentInfoService; + @Autowired + private AutoCollectService autoCollectService; + /** * 查询设备信息列表 */ @@ -83,7 +87,9 @@ public class DryEquipmentInfoController extends BaseController @PostMapping public AjaxResult add(@RequestBody DryEquipmentInfo dryEquipmentInfo) { - return toAjax(dryEquipmentInfoService.insertDryEquipmentInfo(dryEquipmentInfo)); + int result = dryEquipmentInfoService.insertDryEquipmentInfo(dryEquipmentInfo); + autoCollectService.manualPushMqttDataWithStatusNormal(); + return toAjax(result); } /** @@ -94,7 +100,9 @@ public class DryEquipmentInfoController extends BaseController @PutMapping public AjaxResult edit(@RequestBody DryEquipmentInfo dryEquipmentInfo) { - return toAjax(dryEquipmentInfoService.updateDryEquipmentInfo(dryEquipmentInfo)); + int result = dryEquipmentInfoService.updateDryEquipmentInfo(dryEquipmentInfo); + autoCollectService.manualPushMqttDataWithStatusNormal(); + return toAjax(result); } /** diff --git a/shgx-admin/src/main/java/com/shgx/web/controller/dryingroom/DryEquipmentScreenController.java b/shgx-admin/src/main/java/com/shgx/web/controller/dryingroom/DryEquipmentScreenController.java index 304d1dd..a3713fb 100644 --- a/shgx-admin/src/main/java/com/shgx/web/controller/dryingroom/DryEquipmentScreenController.java +++ b/shgx-admin/src/main/java/com/shgx/web/controller/dryingroom/DryEquipmentScreenController.java @@ -57,7 +57,6 @@ public class DryEquipmentScreenController extends BaseController { * @return */ @Anonymous - @PermitAll @PostMapping("/closeAlarm") public AjaxResult closeAlarm(){ // MqttConsole c = new MqttConsole(); diff --git a/shgx-dryingroom/src/main/java/com/shgx/dryingroom/alarm/AlarmLightService.java b/shgx-dryingroom/src/main/java/com/shgx/dryingroom/alarm/AlarmLightService.java index a6967f5..c469011 100644 --- a/shgx-dryingroom/src/main/java/com/shgx/dryingroom/alarm/AlarmLightService.java +++ b/shgx-dryingroom/src/main/java/com/shgx/dryingroom/alarm/AlarmLightService.java @@ -295,7 +295,7 @@ public class AlarmLightService { com.alibaba.fastjson2.JSONObject json = com.alibaba.fastjson2.JSONObject.parseObject(payload); // 仅处理“equipment_alarm”类型的指令 if (!"equipment_alarm".equals(json.getString("type"))) { - log.debug("忽略非报警类型的MQTT指令:type={}", json.getString("type")); +// log.debug("忽略非报警类型的MQTT指令:type={}", json.getString("type")); return; } diff --git a/shgx-dryingroom/src/main/java/com/shgx/dryingroom/collect/AutoCollectService.java b/shgx-dryingroom/src/main/java/com/shgx/dryingroom/collect/AutoCollectService.java index 477b594..f20f9bf 100644 --- a/shgx-dryingroom/src/main/java/com/shgx/dryingroom/collect/AutoCollectService.java +++ b/shgx-dryingroom/src/main/java/com/shgx/dryingroom/collect/AutoCollectService.java @@ -3,7 +3,6 @@ package com.shgx.dryingroom.collect; import com.alibaba.fastjson2.JSONObject; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.shgx.common.utils.DateUtils; -import com.shgx.common.utils.StringUtils; import com.shgx.dryingroom.alarm.AlarmLightService; import com.shgx.dryingroom.mqtt.MqttDataHandler; import com.shgx.dryingroom.mqtt.MqttService; @@ -13,25 +12,21 @@ import com.shgx.dryingroom.web.mapper.*; import lombok.extern.slf4j.Slf4j; import com.baomidou.dynamic.datasource.annotation.DS; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import org.apache.commons.collections4.CollectionUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import javax.annotation.PostConstruct; import javax.annotation.Resource; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.*; -import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Function; -import java.util.stream.Collectors; -import java.util.stream.IntStream; /** - * 自动采集服务(优化版) + * 自动采集服务 */ @Slf4j @Service @@ -48,7 +43,7 @@ public class AutoCollectService { private DryParamThresholdMapper thresholdMapper; @Resource - private DryAlarmLogMapper alarmLogMapper; + private DryAlarmLogMapper logMapper; @Resource private MqttService mqttService; @@ -56,11 +51,11 @@ public class AutoCollectService { @Resource private AlarmLightService alarmLightService; - // 设备缓存(设备ID→设备详情,仅加载一次) - private Map equipmentInfoCache; + // 设备缓存(设备ID→设备详情,使用线程安全的ConcurrentHashMap) + private Map equipmentInfoCache = new ConcurrentHashMap<>(); - // 规则缓存:Key=ruleCode,Value=规则完整信息(线程安全) - private static final Map RULE_CACHE = new ConcurrentHashMap<>(); + // 规则缓存:Key=规则编码,Value=规则完整信息 + private Map ruleCache = new ConcurrentHashMap<>(); // Redis Key 前缀 private static final String REDIS_EQUIP_PREFIX = "dry_equipment:"; @@ -74,8 +69,6 @@ public class AutoCollectService { // 参数编码常量 private static final String PARAM_TEMP = "TEMP"; private static final String PARAM_DEW = "DEW"; - // 默认规则码 - private static final String DEFAULT_RULE_CODE = "DEFAULT_RULE"; @Resource private RedisTemplate redisTemplate; @@ -83,25 +76,23 @@ public class AutoCollectService { @Autowired private DryParamThresholdMapper ruleMapper; - // 默认阈值对象(单例,节约内存) - private static volatile DryParamThreshold defaultThreshold; + @Autowired + private DryEquipmentParamRelationMapper relationMapper; + + // 缓存版本号,用于快速判断 + private volatile int cacheVersion = 1; + private volatile int ruleCacheVersion = 1; /** - * 获取默认阈值(线程安全单例) + * 初始化加载缓存 */ - private DryParamThreshold getDefaultThreshold() { - if (defaultThreshold == null) { - synchronized (this) { - if (defaultThreshold == null) { - defaultThreshold = new DryParamThreshold(); - defaultThreshold.setRuleCode(DEFAULT_RULE_CODE); - defaultThreshold.setIsEnabled("1"); - defaultThreshold.setMaxValue("0"); - defaultThreshold.setMinValue("0"); - } - } - } - return defaultThreshold; + @PostConstruct + public void initCache() { + log.info("========== 初始化缓存 =========="); + refreshEquipmentCache(); + refreshRuleCache(); + log.info("缓存初始化完成,设备缓存:{}条,规则缓存:{}条", + equipmentInfoCache.size(), ruleCache.size()); } // ==================== 独立任务1:每5分钟持久化Redis数据到数据库 ==================== @@ -110,35 +101,44 @@ public class AutoCollectService { public void persistRedisDataToDb() { log.info("===== 【持久化任务】开始执行Redis数据→数据库 ====="); - try { - // 1. 确保缓存已加载 - ensureCachesLoaded(); + // 1. 检查设备缓存是否为空 + if (equipmentInfoCache.isEmpty()) { + loadEquipmentCache(); + } - // 2. 扫描Redis中所有设备数据Key - Set redisKeys = Optional.ofNullable(redisTemplate.keys(REDIS_EQUIP_PREFIX + "*")) - .orElse(Collections.emptySet()); + // 2. 扫描Redis中所有设备数据Key + Set redisKeys = redisTemplate.keys(REDIS_EQUIP_PREFIX + "*:*"); + if (redisKeys == null || redisKeys.isEmpty()) { + log.warn("【持久化任务】Redis中无待持久化数据"); + } - if (redisKeys.isEmpty()) { - log.warn("【持久化任务】Redis中无待持久化数据"); - return; + // 3. 解析Redis数据,转换为DryMonitoringData + List dbDataList = new ArrayList<>(); + for (String redisKey : redisKeys) { + try { + MqttDataHandler.EquipmentData redisData = (MqttDataHandler.EquipmentData) redisTemplate.opsForValue().get(redisKey); + if (redisData == null) continue; + + // 转换为数据库实体 + EquipmentScreenDTO.DryingDTO dbData = convertToDryingDTO(redisData); + DryMonitoringData result = convertToDryMonitoringData(dbData); + if (result == null || result.getDataValue() == null || result.getDataValue().isEmpty()) continue; + +// // 报警判断(持久化时顺便校验,不影响前端推送) +// judgeAlarm(dbData); + + dbDataList.add(result); + } catch (Exception e) { + log.error("【持久化任务】解析Redis数据失败 → Key:{}", redisKey, e); } + } - // 3. 批量转换并持久化 - List dbDataList = redisKeys.stream() - .map(this::convertRedisDataToEntity) - .filter(Objects::nonNull) - .collect(Collectors.toList()); - - // 4. 批量写入数据库 - if (CollectionUtils.isNotEmpty(dbDataList)) { - monitoringDataMapper.batchInsert(dbDataList); - log.info("【持久化任务】✅ 成功 - 共{}条数据写入dry_monitoring_data表", dbDataList.size()); - } else { - log.warn("【持久化任务】无有效数据可持久化"); - } - } catch (Exception e) { - log.error("【持久化任务】执行异常", e); - throw e; + // 4. 批量写入数据库 + if (!dbDataList.isEmpty()) { + monitoringDataMapper.batchInsert(dbDataList); + log.info("【持久化任务】✅ 成功 - 共{}条数据写入dry_monitoring_data表", dbDataList.size()); + } else { + log.warn("【持久化任务】无有效数据可持久化"); } log.info("===== 【持久化任务】执行结束 ====="); @@ -149,514 +149,572 @@ public class AutoCollectService { public void pushRedisDataToFrontend() { log.info("===== 【前端推送任务】开始执行Redis数据→前端 ====="); + // 1. 加载设备和规则缓存(首次执行时) + if (equipmentInfoCache == null || equipmentInfoCache.isEmpty()) { + loadEquipmentCache(); + if (equipmentInfoCache.isEmpty()) { + log.warn("【前端推送任务】未加载到设备信息"); + return; + } + } + if (ruleCache == null || ruleCache.isEmpty()) { + loadRuleCache(); + if (ruleCache.isEmpty()) { + log.warn("【前端推送任务】未加载到规则信息"); + } + } + + // 2. 从Redis读取26台设备的最新数据 + List dryingList = buildFrontendDataList(); + + // 3. 组装JSON并推送(同时包含两种DTO) try { - // 1. 确保缓存已加载 - ensureCachesLoaded(); - - // 2. 批量构建前端数据(并行处理提高效率) - List dryingList = buildFrontendDataListInParallel(); - - // 3. 组装并推送 - pushDataToFrontend(dryingList, null); + JSONObject pushData = new JSONObject(); + pushData.put("dryingData", dryingList); + pushData.put("dryingTotal", dryingList.size()); + pushData.put("pushTime", LocalDateTime.now().format(DATETIME_FORMATTER)); + String jsonStr = pushData.toJSONString(); + // 发送到前端MQTT主题(仅推送,不涉及数据库) + boolean success = mqttService.sendMessage(FRONTEND_TOPIC, jsonStr); + if (success) { + log.info("【前端推送任务】✅ 成功 → 主题:{},温度数据:{}条", FRONTEND_TOPIC, dryingList.size()); + } else { + log.warn("【前端推送任务】❌ 失败 → 主题:{}", FRONTEND_TOPIC); + } } catch (Exception e) { - log.error("【前端推送任务】执行异常", e); + log.error("【前端推送任务】推送异常", e); } log.info("===== 【前端推送任务】执行结束 ====="); } - // ==================== 核心工具方法(优化版) ==================== + // ==================== 工具方法 ==================== /** - * 确保缓存已加载 + * 公开方法:刷新设备缓存 */ - private void ensureCachesLoaded() { - if (equipmentInfoCache == null || equipmentInfoCache.isEmpty()) { - loadEquipmentCache(); - } - if (RULE_CACHE.isEmpty()) { - loadRuleCache(); - } - } + public synchronized void refreshEquipmentCache() { + log.info("开始刷新设备缓存..."); + try { + // 清空缓存 + equipmentInfoCache.clear(); - /** - * 加载设备缓存(优化版) - */ - private void loadEquipmentCache() { - log.info("加载设备信息缓存..."); + // 重新加载 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + List equipmentList = equipmentInfoMapper.selectList(queryWrapper); - List equipmentList = equipmentInfoMapper.selectList( - new LambdaQueryWrapper() - .eq(DryEquipmentInfo::getEquipmentType, "1") - .select( - DryEquipmentInfo::getEquipmentCode, - DryEquipmentInfo::getEquipmentName, - DryEquipmentInfo::getLocation, - DryEquipmentInfo::getRuleCode, - DryEquipmentInfo::getSetTem - ) - ); - - if (CollectionUtils.isEmpty(equipmentList)) { - equipmentInfoCache = Collections.emptyMap(); - log.warn("未加载到设备信息"); - return; - } - - // 预分配大小的Map,减少扩容开销 - equipmentInfoCache = new HashMap<>(equipmentList.size() * 2); - int validCount = 0; - int invalidCount = 0; - - for (DryEquipmentInfo eq : equipmentList) { - try { - String location = eq.getLocation(); - if (StringUtils.isEmpty(location)) { - invalidCount++; - continue; + // 构建缓存:key=设备ID(格式化后:001-030),value=设备详情 + for (DryEquipmentInfo equipment : equipmentList) { + try { + if (equipment.getLocation() == null || equipment.getLocation().isEmpty()) { + log.warn("设备location为空,跳过该设备 → 设备编码:{}", equipment.getEquipmentCode()); + continue; + } + // 格式化为三位数 + String locationKey = String.format("%03d", Integer.parseInt(equipment.getLocation())); + equipmentInfoCache.put(locationKey, equipment); + } catch (NumberFormatException e) { + log.warn("设备location格式异常 → location:{},设备编码:{}", equipment.getLocation(), equipment.getEquipmentCode()); } - - // 格式化为三位数 - String key = String.format("%03d", Integer.parseInt(location)); - equipmentInfoCache.put(key, eq); - validCount++; - } catch (NumberFormatException e) { - invalidCount++; } - } - log.info("设备缓存加载完成:有效{}台,无效{}台", validCount, invalidCount); + cacheVersion++; + log.info("设备缓存刷新完成,共{}台设备,缓存版本:{}", equipmentInfoCache.size(), cacheVersion); + + } catch (Exception e) { + log.error("刷新设备缓存失败", e); + } } /** - * 加载规则缓存(优化版 - 核心算法优化) + * 公开方法:刷新规则缓存 */ - public void loadRuleCache() { - log.info("加载设备使用的规则缓存..."); - RULE_CACHE.clear(); + public synchronized void refreshRuleCache() { + log.info("开始刷新规则缓存..."); + try { + // 清空缓存 + ruleCache.clear(); - // 1. 查询所有设备,收集ruleCode - List equipmentList = equipmentInfoMapper.selectList( - new LambdaQueryWrapper() - .select(DryEquipmentInfo::getRuleCode) - ); + // 查询所有启用状态的规则 + LambdaQueryWrapper ruleWrapper = new LambdaQueryWrapper<>(); + ruleWrapper.eq(DryParamThreshold::getIsEnabled, "1"); + List validRuleList = ruleMapper.selectList(ruleWrapper); - if (CollectionUtils.isEmpty(equipmentList)) { - log.warn("无有效设备,规则缓存加载完成(空)"); - return; + // 构建缓存 + for (DryParamThreshold threshold : validRuleList) { + ruleCache.put(threshold.getRuleCode(), threshold); + } + + // 添加默认规则(如果不存在) + String DEFAULT_RULE_CODE = "DEFAULT_RULE"; + if (!ruleCache.containsKey(DEFAULT_RULE_CODE)) { + DryParamThreshold defaultThreshold = new DryParamThreshold(); + defaultThreshold.setRuleCode(DEFAULT_RULE_CODE); + defaultThreshold.setIsEnabled("1"); + defaultThreshold.setMaxValue("0"); + defaultThreshold.setMinValue("0"); + ruleCache.put(DEFAULT_RULE_CODE, defaultThreshold); + } + + ruleCacheVersion++; + log.info("规则缓存刷新完成,共{}条规则,缓存版本:{}", ruleCache.size(), ruleCacheVersion); + + } catch (Exception e) { + log.error("刷新规则缓存失败", e); + } + } + + /** + * 公开方法:立即推送数据到前端 + */ + public void triggerImmediatePush() { + try { + log.info("触发立即推送数据到前端..."); + + // 构建数据 + List dryingList = buildFrontendDataList(); + + // 组装JSON并推送 + JSONObject pushData = new JSONObject(); + pushData.put("dryingData", dryingList); + pushData.put("dryingTotal", dryingList.size()); + pushData.put("pushTime", LocalDateTime.now().format(DATETIME_FORMATTER)); + pushData.put("triggerType", "manual"); // 标记为手动触发 + + String jsonStr = pushData.toJSONString(); + boolean success = mqttService.sendMessage(FRONTEND_TOPIC, jsonStr); + + if (success) { + log.info("✅ 立即推送成功 → 主题:{},数据:{}条", FRONTEND_TOPIC, dryingList.size()); + } else { + log.warn("❌ 立即推送失败 → 主题:{}", FRONTEND_TOPIC); + } + + } catch (Exception e) { + log.error("立即推送异常", e); + } + } + + /** + * 获取缓存统计信息 + */ + public Map getCacheStats() { + Map stats = new HashMap<>(); + stats.put("equipmentCacheSize", equipmentInfoCache.size()); + stats.put("ruleCacheSize", ruleCache.size()); + stats.put("cacheVersion", cacheVersion); + stats.put("ruleCacheVersion", ruleCacheVersion); + return stats; + } + + /** + * 增强的设备信息获取方法(支持缓存降级) + */ + private DryEquipmentInfo getEquipmentInfoWithFallback(String equipmentId) { + // 1. 先查缓存 + DryEquipmentInfo cachedInfo = equipmentInfoCache.get(equipmentId); + if (cachedInfo != null) { + return cachedInfo; } - // 2. 收集所有设备使用的ruleCode(去重) - Set usedRuleCodes = equipmentList.stream() - .map(eq -> { - String ruleCode = eq.getRuleCode(); - return StringUtils.isEmpty(ruleCode) ? DEFAULT_RULE_CODE : ruleCode.trim(); - }) - .collect(Collectors.toSet()); - - // 3. 放入默认规则(节约内存,所有默认规则共享一个对象) - RULE_CACHE.put(DEFAULT_RULE_CODE, getDefaultThreshold()); - - // 4. 批量查询其他规则 - Set customRuleCodes = usedRuleCodes.stream() - .filter(code -> !DEFAULT_RULE_CODE.equals(code)) - .collect(Collectors.toSet()); - - if (!customRuleCodes.isEmpty()) { - // 批量查询数据库 - List dbRules = ruleMapper.selectList( - new LambdaQueryWrapper() - .in(DryParamThreshold::getRuleCode, customRuleCodes) - .eq(DryParamThreshold::getIsEnabled, "1") - .select( - DryParamThreshold::getRuleCode, - DryParamThreshold::getMinValue, - DryParamThreshold::getMaxValue, - DryParamThreshold::getParamCode - ) + // 2. 缓存中没有,从数据库查询(缓存降级) + try { + DryEquipmentInfo dbInfo = equipmentInfoMapper.selectOne( + new LambdaQueryWrapper() + .eq(DryEquipmentInfo::getLocation, equipmentId) ); - // 转为Map便于快速查找 - Map dbRuleMap = dbRules.stream() - .collect(Collectors.toMap( - DryParamThreshold::getRuleCode, - Function.identity(), - (oldVal, newVal) -> oldVal - )); - - // 5. 填充缓存 - int validCount = 0; - int missingCount = 0; - - for (String ruleCode : customRuleCodes) { - DryParamThreshold threshold = dbRuleMap.get(ruleCode); - if (threshold != null) { - RULE_CACHE.put(ruleCode, threshold); - validCount++; - } else { - // 创建默认值的阈值对象(每个缺失规则独立对象,因为ruleCode不同) - DryParamThreshold emptyThreshold = new DryParamThreshold(); - emptyThreshold.setRuleCode(ruleCode); - emptyThreshold.setIsEnabled("1"); - emptyThreshold.setMaxValue("0"); - emptyThreshold.setMinValue("0"); - RULE_CACHE.put(ruleCode, emptyThreshold); - missingCount++; - } + // 3. 如果数据库中有,更新缓存 + if (dbInfo != null) { + equipmentInfoCache.put(equipmentId, dbInfo); + log.debug("设备{}从数据库加载并更新到缓存", equipmentId); } - log.info("规则加载统计:总计{}条,有效{}条,缺失{}条", - customRuleCodes.size(), validCount, missingCount); - } + return dbInfo; - log.info("规则缓存加载完成:共{}条规则", RULE_CACHE.size()); + } catch (Exception e) { + log.error("查询设备信息失败:{}", equipmentId, e); + return null; + } } /** - * 并行构建前端数据(优化性能) + * 增强的规则获取方法(支持缓存降级) */ - private List buildFrontendDataListInParallel() { - List result = new ArrayList<>(TOTAL_EQUIPMENT); - - // 使用并行流处理设备数据 - List equipmentIds = new ArrayList<>(TOTAL_EQUIPMENT); - for (int i = 1; i <= TOTAL_EQUIPMENT; i++) { - equipmentIds.add(i); + private DryParamThreshold getRuleWithFallback(String ruleCode) { + if (ruleCode == null || ruleCode.trim().isEmpty()) { + // 使用默认规则 + return ruleCache.get("DEFAULT_RULE"); } - result = equipmentIds.parallelStream() - .map(this::buildEquipmentData) - .filter(Objects::nonNull) - .collect(Collectors.toList()); + // 1. 先查缓存 + DryParamThreshold cachedRule = ruleCache.get(ruleCode); + if (cachedRule != null) { + return cachedRule; + } + + // 2. 缓存中没有,从数据库查询(缓存降级) + try { + DryParamThreshold dbRule = ruleMapper.selectOne( + new LambdaQueryWrapper() + .eq(DryParamThreshold::getRuleCode, ruleCode) + .eq(DryParamThreshold::getIsEnabled, "1") + ); + + // 3. 如果数据库中有,更新缓存 + if (dbRule != null) { + ruleCache.put(ruleCode, dbRule); + log.debug("规则{}从数据库加载并更新到缓存", ruleCode); + } + + return dbRule; + + } catch (Exception e) { + log.error("查询规则信息失败:{}", ruleCode, e); + return ruleCache.get("DEFAULT_RULE"); // 降级到默认规则 + } + } + + /** + * 加载设备缓存 + */ + private void loadEquipmentCache() { + // 现在通过refreshEquipmentCache方法统一管理 + if (equipmentInfoCache.isEmpty()) { + refreshEquipmentCache(); + } + } + + /** + * 加载规则缓存 + */ + public void loadRuleCache() { + // 现在通过refreshRuleCache方法统一管理 + if (ruleCache.isEmpty()) { + refreshRuleCache(); + } + } + + /** + * 从Redis读取干燥机温度数据 + */ + private List buildFrontendDataList() { + List result = new ArrayList<>(); + + // 遍历1-26台干燥机(001-026) + for (int i = 1; i <= TOTAL_EQUIPMENT; i++) { + String equipmentId = String.format("%03d", i); // 格式化设备ID:001-026 + + // 使用增强的方法获取设备信息 + DryEquipmentInfo equipmentInfo = getEquipmentInfoWithFallback(equipmentId); + + // 获取设备状态(直接从数据库获取最新状态,确保实时性) + String status = "1"; // 默认正常 + if (equipmentInfo != null && equipmentInfo.getEquipmentCode() != null) { + DryEquipmentInfo latestStatus = equipmentInfoMapper.selectOne( + new LambdaQueryWrapper() + .eq(DryEquipmentInfo::getEquipmentCode, equipmentInfo.getEquipmentCode()) + .select(DryEquipmentInfo::getStatus) + ); + if (latestStatus != null && latestStatus.getStatus() != null) { + status = latestStatus.getStatus(); + } + } + + // 读取Redis温度数据 + String redisKey = REDIS_EQUIP_PREFIX + equipmentId + ":" + PARAM_TEMP; + MqttDataHandler.EquipmentData redisData = (MqttDataHandler.EquipmentData) redisTemplate.opsForValue().get(redisKey); + + // 构造DryingDTO,无数据填0 + EquipmentScreenDTO.DryingDTO dbData = new EquipmentScreenDTO.DryingDTO(); + EquipmentScreenDTO.ParamDTO paramDTO = new EquipmentScreenDTO.ParamDTO(); + + // 基础信息 + dbData.setEquipmentCode(equipmentInfo != null ? equipmentInfo.getEquipmentCode() : "GZ-" + equipmentId); + dbData.setEquipmentName(equipmentInfo != null ? equipmentInfo.getEquipmentName() : "干燥机" + equipmentId); + dbData.setEquipmentType("1"); // 干燥机类型标识 + dbData.setStatus(status); // 使用最新状态 + + // 温度值:有数据显示实际值,无数据填0 + if (redisData != null && redisData.getValue() != null) { + dbData.setDataValue(String.valueOf(redisData.getValue())); + } else { + dbData.setDataValue("0"); + } + + // 设定温度:无值填0 + String setTem = "0"; + if (equipmentInfo != null && equipmentInfo.getSetTem() != null) { + setTem = equipmentInfo.getSetTem(); + } + dbData.setSetTem(setTem); + + // 阈值:使用增强的方法获取规则 + String ruleCode = equipmentInfo != null ? equipmentInfo.getRuleCode() : null; + DryParamThreshold rule = getRuleWithFallback(ruleCode); + if (rule != null) { + paramDTO.minValue = rule.getMinValue() != null ? rule.getMinValue() : "0"; + paramDTO.maxValue = rule.getMaxValue() != null ? rule.getMaxValue() : "0"; + } else { + paramDTO.minValue = "0"; + paramDTO.maxValue = "0"; + } + dbData.setParamDTO(paramDTO); + + // 报警判断(0值是否报警按规则处理) + if (equipmentInfo != null) { + judgeAlarm(dbData, equipmentInfo); + } + + result.add(dbData); + } return result; } /** - * 构建单个设备数据 + * Redis数据转换为DryingDTO(修改为使用增强的缓存方法) */ - private EquipmentScreenDTO.DryingDTO buildEquipmentData(int equipmentId) { - String equipmentKey = String.format("%03d", equipmentId); - - // 1. 获取设备信息 - DryEquipmentInfo equipmentInfo = equipmentInfoCache.get(equipmentKey); - if (equipmentInfo == null) { - equipmentInfo = createDefaultEquipment(equipmentKey); + private EquipmentScreenDTO.DryingDTO convertToDryingDTO(MqttDataHandler.EquipmentData redisData) { + if (redisData == null) { + log.error("【转换失败】redisData为null,无法转换"); + return null; } - // 2. 获取设备状态(缓存状态,避免重复查询) - String status = getEquipmentStatus(equipmentInfo.getEquipmentCode()); + String equipmentId = redisData.getEquipmentId(); + if (equipmentId == null || equipmentId.isEmpty()) { + log.error("【转换失败】redisData的equipmentId为空"); + return null; + } - // 3. 读取Redis数据 - String redisKey = REDIS_EQUIP_PREFIX + equipmentKey + ":" + PARAM_TEMP; - Double redisValue = getRedisValue(redisKey); + // 使用增强的缓存方法 + DryEquipmentInfo equipmentInfo = getEquipmentInfoWithFallback(equipmentId); + if (equipmentInfo == null) { + log.warn("【持久化任务】设备ID{}无对应信息,跳过", equipmentId); + return null; + } - // 4. 获取规则阈值 - DryParamThreshold rule = getRuleThreshold(equipmentInfo.getRuleCode()); - - // 5. 构建DTO - EquipmentScreenDTO.DryingDTO dto = new EquipmentScreenDTO.DryingDTO(); - dto.setEquipmentCode(equipmentInfo.getEquipmentCode()); - dto.setEquipmentName(equipmentInfo.getEquipmentName()); - dto.setEquipmentType("1"); - dto.setStatus(status); - dto.setDataValue(redisValue != null ? String.valueOf(redisValue) : "0"); - dto.setSetTem(StringUtils.defaultIfEmpty(equipmentInfo.getSetTem(), "0")); - - EquipmentScreenDTO.ParamDTO paramDTO = new EquipmentScreenDTO.ParamDTO(); - paramDTO.minValue = StringUtils.defaultIfEmpty(rule.getMinValue(), "0"); - paramDTO.maxValue = StringUtils.defaultIfEmpty(rule.getMaxValue(), "0"); - dto.setParamDTO(paramDTO); - - // 6. 判断报警(异步处理,不阻塞主流程) - checkAlarmAsync(dto, equipmentInfo, redisValue); - - return dto; - } - - /** - * 获取设备状态(带缓存) - */ - private String getEquipmentStatus(String equipmentCode) { - try { - DryEquipmentInfo eq = equipmentInfoMapper.selectOne( + String status = "1"; + if (equipmentInfo.getEquipmentCode() != null) { + DryEquipmentInfo latestStatus = equipmentInfoMapper.selectOne( new LambdaQueryWrapper() - .eq(DryEquipmentInfo::getEquipmentCode, equipmentCode) + .eq(DryEquipmentInfo::getEquipmentCode, equipmentInfo.getEquipmentCode()) .select(DryEquipmentInfo::getStatus) ); - return eq != null && eq.getStatus() != null ? eq.getStatus() : "1"; - } catch (Exception e) { - log.warn("获取设备状态失败: {}", equipmentCode, e); - return "1"; - } - } - - /** - * 获取Redis值 - */ - private Double getRedisValue(String redisKey) { - try { - MqttDataHandler.EquipmentData data = (MqttDataHandler.EquipmentData) - redisTemplate.opsForValue().get(redisKey); - return data != null ? data.getValue() : null; - } catch (Exception e) { - log.warn("读取Redis数据失败: {}", redisKey, e); - return null; - } - } - - /** - * 获取规则阈值 - */ - private DryParamThreshold getRuleThreshold(String ruleCode) { - if (StringUtils.isEmpty(ruleCode)) { - return getDefaultThreshold(); - } - return RULE_CACHE.getOrDefault(ruleCode.trim(), getDefaultThreshold()); - } - - /** - * 创建默认设备 - */ - private DryEquipmentInfo createDefaultEquipment(String equipmentId) { - DryEquipmentInfo eq = new DryEquipmentInfo(); - eq.setEquipmentCode("GZ-" + equipmentId); - eq.setEquipmentName("干燥机" + equipmentId); - eq.setRuleCode(""); - eq.setSetTem("0"); - return eq; - } - - /** - * 异步检查报警 - */ - private void checkAlarmAsync(EquipmentScreenDTO.DryingDTO dto, DryEquipmentInfo equipmentInfo, Double value) { - if (value == null) return; - - // 使用CompletableFuture异步处理报警判断 - CompletableFuture.runAsync(() -> { - try { - judgeAlarm(dto, equipmentInfo); - } catch (Exception e) { - log.error("异步报警判断失败: {}", dto.getEquipmentCode(), e); + if (latestStatus != null && latestStatus.getStatus() != null) { + status = latestStatus.getStatus(); } - }); + } + + EquipmentScreenDTO.DryingDTO dbData = new EquipmentScreenDTO.DryingDTO(); + EquipmentScreenDTO.ParamDTO paramDTO = new EquipmentScreenDTO.ParamDTO(); + dbData.setEquipmentCode(equipmentInfo.getEquipmentCode()); + dbData.setEquipmentName(equipmentInfo.getEquipmentName()); + + if (redisData.getValue() != null) { + dbData.setDataValue(String.valueOf(redisData.getValue())); + } else { + dbData.setDataValue(null); + } + + dbData.setEquipmentType("1"); + dbData.setStatus(status); + dbData.setSetTem(equipmentInfo.getSetTem()); + + // 使用增强的规则获取方法 + String ruleCode = equipmentInfo.getRuleCode(); + DryParamThreshold rule = getRuleWithFallback(ruleCode); + if (rule != null) { + paramDTO.minValue = rule.getMinValue(); + paramDTO.maxValue = rule.getMaxValue(); + } else { + paramDTO.minValue = "0"; + paramDTO.maxValue = "0"; + log.warn("【转换DryingDTO】设备{}的规则{}在缓存中不存在,阈值设为默认值", + equipmentInfo.getEquipmentCode(), ruleCode); + } + dbData.setParamDTO(paramDTO); + + return dbData; } /** - * 优化后的报警判断 + * DryingDTO转换为数据库实体 + */ + private DryMonitoringData convertToDryMonitoringData(EquipmentScreenDTO.DryingDTO data) { + DryMonitoringData dryMonitoringData = new DryMonitoringData(); + dryMonitoringData.setEquipmentCode(data.getEquipmentCode()); + dryMonitoringData.setParamCode("TEMP"); + dryMonitoringData.setDataValue(data.getDataValue()); + dryMonitoringData.setCollectTime(LocalDateTime.now()); + dryMonitoringData.setDataStatus(data.getStatus()); + dryMonitoringData.setCollectorCode("模拟量采集器"); + return dryMonitoringData; + } + + /** + * 温度报警判断 */ private void judgeAlarm(EquipmentScreenDTO.DryingDTO data, DryEquipmentInfo equipmentInfo) { - if (data == null || equipmentInfo == null) { + // 入参判空 + if (data == null) { + log.warn("【报警判断】数据为空,跳过"); return; } - String equipmentCode = data.getEquipmentCode(); - if (StringUtils.isEmpty(equipmentCode)) { + if (equipmentCode == null || equipmentCode.isEmpty()) { + log.warn("【报警判断】设备编码为空,跳过"); + return; + } + if (equipmentInfo == null || equipmentInfo.getRuleCode() == null || equipmentInfo.getRuleCode().isEmpty()) { + log.warn("设备编码{}未查询到关联的ruleCode(设备不存在/ruleCode为空)", equipmentCode); return; } - String ruleCode = equipmentInfo.getRuleCode(); - if (StringUtils.isEmpty(ruleCode)) { - ruleCode = DEFAULT_RULE_CODE; - } + // 用ruleCode查询DryParamThreshold表的规则信息 + List thresholds = thresholdMapper.selectList(new LambdaQueryWrapper().eq(DryParamThreshold::getRuleCode, equipmentInfo.getRuleCode()) + .eq(DryParamThreshold::getIsEnabled, "1")); - // 1. 从缓存获取规则(快速路径) - DryParamThreshold threshold = RULE_CACHE.get(ruleCode); - if (threshold == null || !"1".equals(threshold.getIsEnabled())) { + // 无规则则返回 + if (thresholds.isEmpty()) { + log.warn("设备编码{}对应的ruleCode{}未查询到阈值规则", equipmentCode, equipmentInfo.getRuleCode()); return; } - try { - // 2. 解析阈值和当前值 - double max = parseThresholdValue(threshold.getMaxValue()); - double min = parseThresholdValue(threshold.getMinValue()); - double currentValue = parseThresholdValue(data.getDataValue()); + // 5. 报警判断 + DryAlarmLog alarmLog = new DryAlarmLog(); + LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); + boolean isAlarm = false; - // 3. 判断是否报警 - if (currentValue > max || currentValue < min) { - // 4. 创建报警记录 - DryAlarmLog alarmLog = new DryAlarmLog(); - alarmLog.setEquipmentCode(equipmentCode); - alarmLog.setParamCode(threshold.getParamCode()); - alarmLog.setAlarmValue(data.getDataValue()); - alarmLog.setAlarmType(currentValue > max ? "1" : "2"); - alarmLog.setAlarmTime(LocalDateTime.now()); - alarmLog.setCreateBy("system"); - alarmLog.setCreateTime(DateUtils.getNowDate()); - - // 5. 批量操作:更新设备状态和插入报警记录 - updateEquipmentStatusAndLogAlarm(equipmentCode, alarmLog); - - // 6. 触发报警灯 - alarmLightService.triggerAllAlarmsByEquipment(equipmentCode); - - // 7. 更新DTO状态 - data.setStatus("2"); + for (DryParamThreshold threshold : thresholds) { + // 增加阈值对象空判断 + if (threshold == null) { + log.warn("【报警判断】设备编码{}的阈值规则为空,跳过", equipmentCode); + continue; + } + // 规则过滤 + if (!threshold.getRuleCode().equals(equipmentInfo.getRuleCode()) && !threshold.getIsEnabled().equals("1") && !threshold.getParamCode().equals("TEMP")) { + continue; + } + + try { + // 阈值空判断 + if (threshold.getMaxValue() == null || threshold.getMinValue() == null) { + log.warn("【报警判断】设备编码{}的阈值为空,跳过", equipmentCode); + continue; + } + double max = parseThresholdValue(threshold.getMaxValue()); + double min = parseThresholdValue(threshold.getMinValue()); + double value = parseThresholdValue(data.getDataValue()); + + if (value > max) { + alarmLog.setAlarmType("1"); // 超上限 + isAlarm = true; + } else if (value < min) { + alarmLog.setAlarmType("2"); // 超下限 + isAlarm = true; + } + + if (isAlarm) { + alarmLog.setEquipmentCode(equipmentCode); + alarmLog.setParamCode(threshold.getParamCode()); + alarmLog.setAlarmValue(data.getDataValue()); + alarmLog.setAlarmTime(LocalDateTime.now()); + alarmLog.setCreateBy("system"); + alarmLog.setCreateTime(DateUtils.getNowDate()); + logMapper.insert(alarmLog); + + // 更新设备状态为报警 + updateWrapper.eq(DryEquipmentInfo::getEquipmentCode, equipmentCode).set(DryEquipmentInfo::getStatus, '2'); + equipmentInfoMapper.update(null, updateWrapper); + + // 触发报警灯 + alarmLightService.triggerAllAlarmsByEquipment(equipmentCode); + break; + } + } catch (Exception e) { + log.error("【报警判断】设备编码{}校验异常", equipmentCode, e); } - } catch (Exception e) { - log.error("报警判断失败: {}", equipmentCode, e); } } /** - * 批量更新设备状态和记录报警 - */ - private void updateEquipmentStatusAndLogAlarm(String equipmentCode, DryAlarmLog alarmLog) { - try { - // 更新设备状态 - equipmentInfoMapper.update(null, - new LambdaUpdateWrapper() - .eq(DryEquipmentInfo::getEquipmentCode, equipmentCode) - .set(DryEquipmentInfo::getStatus, '2') - ); - - // 插入报警记录 - alarmLogMapper.insert(alarmLog); - } catch (Exception e) { - log.error("更新设备状态和报警记录失败: {}", equipmentCode, e); - } - } - - /** - * 推送数据到前端 - */ - private void pushDataToFrontend(List dryingList, - List drynessList) { - try { - JSONObject pushData = new JSONObject(); - pushData.put("dryingData", dryingList); - pushData.put("dryingTotal", dryingList != null ? dryingList.size() : 0); - - if (drynessList != null) { - pushData.put("drynessData", drynessList); - pushData.put("drynessTotal", drynessList.size()); - } - - pushData.put("pushTime", LocalDateTime.now().format(DATETIME_FORMATTER)); - - boolean success = mqttService.sendMessage(FRONTEND_TOPIC, pushData.toJSONString()); - - if (!success) { - log.warn("MQTT推送失败: {}", FRONTEND_TOPIC); - } - } catch (Exception e) { - log.error("推送数据到前端失败", e); - } - } - - /** - * 转换Redis数据为数据库实体 - */ - private DryMonitoringData convertRedisDataToEntity(String redisKey) { - try { - MqttDataHandler.EquipmentData redisData = (MqttDataHandler.EquipmentData) - redisTemplate.opsForValue().get(redisKey); - - if (redisData == null || redisData.getValue() == null) { - return null; - } - - String equipmentId = redisData.getEquipmentId(); - if (StringUtils.isEmpty(equipmentId)) { - return null; - } - - DryEquipmentInfo equipmentInfo = equipmentInfoCache.get(equipmentId); - if (equipmentInfo == null) { - return null; - } - - DryMonitoringData entity = new DryMonitoringData(); - entity.setEquipmentCode(equipmentInfo.getEquipmentCode()); - entity.setParamCode(PARAM_TEMP); - entity.setDataValue(String.valueOf(redisData.getValue())); - entity.setCollectTime(LocalDateTime.now()); - entity.setDataStatus(getEquipmentStatus(equipmentInfo.getEquipmentCode())); - entity.setCollectorCode("模拟量采集器"); - - return entity; - } catch (Exception e) { - log.error("转换Redis数据失败: {}", redisKey, e); - return null; - } - } - - /** - * 阈值解析工具(优化版) + * 阈值解析工具(原有逻辑不变)0 */ private double parseThresholdValue(String valueStr) { - if (StringUtils.isEmpty(valueStr)) { - return 0.0; + if (valueStr == null || valueStr.trim().isEmpty()) { + throw new IllegalArgumentException("阈值不能为空"); } - try { - // 移除所有非数字、小数点、负号的字符 String cleanValue = valueStr.replaceAll("[^\\d.-]", "").trim(); - if (StringUtils.isEmpty(cleanValue)) { - return 0.0; - } return Double.parseDouble(cleanValue); } catch (NumberFormatException e) { - log.warn("解析阈值失败,使用默认值0: {}", valueStr); - return 0.0; + log.error("解析阈值失败:{}", valueStr, e); + throw new RuntimeException("阈值格式错误:" + valueStr); } } - // ==================== 手动推送方法 ==================== - /** - * 手动推送MQTT数据(一键关闭报警后调用) + * 手动推送MQTT数据(修改为使用新的触发方法) */ public void manualPushMqttDataWithStatusNormal() { log.info("===== 【手动推送任务】开始执行(一键关闭报警后) ====="); - - try { - ensureCachesLoaded(); - - // 批量构建数据 - List dryingList = buildFrontendDataListWithStatusNormal(); - - // 推送数据 - pushDataToFrontend(dryingList, null); - - } catch (Exception e) { - log.error("手动推送失败", e); - } - + triggerImmediatePush(); log.info("===== 【手动推送任务】执行结束 ====="); } /** - * 构建正常状态的设备数据 + * 构建干燥机数据(强制将status改为1)- 修改为使用增强的方法 */ private List buildFrontendDataListWithStatusNormal() { - return IntStream.rangeClosed(1, TOTAL_EQUIPMENT) - .mapToObj(i -> { - String equipmentKey = String.format("%03d", i); - DryEquipmentInfo equipmentInfo = equipmentInfoCache.getOrDefault( - equipmentKey, createDefaultEquipment(equipmentKey) - ); + List result = new ArrayList<>(); - EquipmentScreenDTO.DryingDTO dto = new EquipmentScreenDTO.DryingDTO(); - dto.setEquipmentCode(equipmentInfo.getEquipmentCode()); - dto.setEquipmentName(equipmentInfo.getEquipmentName()); - dto.setEquipmentType("1"); - dto.setStatus("1"); // 强制设为正常状态 + for (int i = 1; i <= TOTAL_EQUIPMENT; i++) { + String equipmentId = String.format("%03d", i); - Double redisValue = getRedisValue(REDIS_EQUIP_PREFIX + equipmentKey + ":" + PARAM_TEMP); - dto.setDataValue(redisValue != null ? String.valueOf(redisValue) : "0"); - dto.setSetTem(StringUtils.defaultIfEmpty(equipmentInfo.getSetTem(), "0")); + // 使用增强的方法获取设备信息 + DryEquipmentInfo equipmentInfo = getEquipmentInfoWithFallback(equipmentId); - DryParamThreshold rule = getRuleThreshold(equipmentInfo.getRuleCode()); - EquipmentScreenDTO.ParamDTO paramDTO = new EquipmentScreenDTO.ParamDTO(); - paramDTO.minValue = StringUtils.defaultIfEmpty(rule.getMinValue(), "0"); - paramDTO.maxValue = StringUtils.defaultIfEmpty(rule.getMaxValue(), "0"); - dto.setParamDTO(paramDTO); + // 构造DryingDTO + EquipmentScreenDTO.DryingDTO dbData = new EquipmentScreenDTO.DryingDTO(); + EquipmentScreenDTO.ParamDTO paramDTO = new EquipmentScreenDTO.ParamDTO(); - return dto; - }) - .collect(Collectors.toList()); + // 基础信息 + dbData.setEquipmentCode(equipmentInfo != null ? equipmentInfo.getEquipmentCode() : "GZ-" + equipmentId); + dbData.setEquipmentName(equipmentInfo != null ? equipmentInfo.getEquipmentName() : "干燥机" + equipmentId); + dbData.setEquipmentType("1"); + // 核心:强制将状态改为1(正常) + dbData.setStatus("1"); + + // 读取Redis温度数据 + String redisKey = REDIS_EQUIP_PREFIX + equipmentId + ":" + PARAM_TEMP; + MqttDataHandler.EquipmentData redisData = (MqttDataHandler.EquipmentData) redisTemplate.opsForValue().get(redisKey); + + if (redisData != null && redisData.getValue() != null) { + dbData.setDataValue(String.valueOf(redisData.getValue())); + } else { + dbData.setDataValue("0"); + } + + dbData.setSetTem(equipmentInfo != null && equipmentInfo.getSetTem() != null ? equipmentInfo.getSetTem() : "0"); + + // 使用增强的规则获取方法 + String ruleCode = equipmentInfo != null ? equipmentInfo.getRuleCode() : null; + DryParamThreshold rule = getRuleWithFallback(ruleCode); + if (rule != null) { + paramDTO.minValue = rule.getMinValue() != null ? rule.getMinValue() : "0"; + paramDTO.maxValue = rule.getMaxValue() != null ? rule.getMaxValue() : "0"; + } else { + paramDTO.minValue = "0"; + paramDTO.maxValue = "0"; + } + dbData.setParamDTO(paramDTO); + + result.add(dbData); + } + + return result; } + } \ No newline at end of file diff --git a/shgx-dryingroom/src/main/java/com/shgx/dryingroom/collect/CacheSyncService.java b/shgx-dryingroom/src/main/java/com/shgx/dryingroom/collect/CacheSyncService.java new file mode 100644 index 0000000..e379970 --- /dev/null +++ b/shgx-dryingroom/src/main/java/com/shgx/dryingroom/collect/CacheSyncService.java @@ -0,0 +1,79 @@ +package com.shgx.dryingroom.collect; + +import com.shgx.dryingroom.collect.AutoCollectService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import javax.annotation.PostConstruct; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * 缓存同步管理服务 + */ +@Slf4j +@Service +public class CacheSyncService { + + @Autowired + private AutoCollectService autoCollectService; + + // 缓存同步计数器 + private final AtomicInteger syncCounter = new AtomicInteger(0); + + /** + * 初始化 + */ + @PostConstruct + public void init() { + log.info("缓存同步服务初始化完成"); + } + + /** + * 通知缓存更新 + * @param cacheType 缓存类型:EQUIPMENT, RULE, ALL + */ + public void notifyCacheUpdate(String cacheType) { + int count = syncCounter.incrementAndGet(); + log.info("收到缓存更新通知[{}],类型:{},累计通知次数:{}", count, cacheType, count); + + try { + switch (cacheType.toUpperCase()) { + case "EQUIPMENT": + autoCollectService.refreshEquipmentCache(); + break; + case "RULE": + autoCollectService.refreshRuleCache(); + break; + case "ALL": + autoCollectService.refreshEquipmentCache(); + autoCollectService.refreshRuleCache(); + break; + default: + log.warn("未知的缓存类型:{},默认刷新全部", cacheType); + autoCollectService.refreshEquipmentCache(); + autoCollectService.refreshRuleCache(); + } + + log.info("缓存更新完成[{}]", count); + + } catch (Exception e) { + log.error("缓存更新失败[{}]", count, e); + } + } + + /** + * 通知缓存更新并立即推送 + */ + public void notifyCacheUpdateAndPush(String cacheType) { + notifyCacheUpdate(cacheType); + autoCollectService.triggerImmediatePush(); + } + + /** + * 获取同步统计 + */ + public int getSyncCount() { + return syncCounter.get(); + } +} \ No newline at end of file diff --git a/shgx-dryingroom/src/main/java/com/shgx/dryingroom/mqtt/MqttDataHandler.java b/shgx-dryingroom/src/main/java/com/shgx/dryingroom/mqtt/MqttDataHandler.java index 6117ed7..8599a89 100644 --- a/shgx-dryingroom/src/main/java/com/shgx/dryingroom/mqtt/MqttDataHandler.java +++ b/shgx-dryingroom/src/main/java/com/shgx/dryingroom/mqtt/MqttDataHandler.java @@ -75,8 +75,8 @@ public class MqttDataHandler implements Consumer { // 3. 存储到Redis(设备ID-温度参数) String redisKey = REDIS_EQUIP_PREFIX + formatEquipId + ":" + PARAM_TEMP; redisTemplate.opsForValue().set(redisKey, new EquipmentData(time, paramValue, PARAM_TEMP, formatEquipId)); - log.info("✅ 存储设备数据 - 设备:{},参数:{},值:{},Key:{}", - formatEquipId, PARAM_TEMP, paramValue, redisKey); +// log.info("✅ 存储设备数据 - 设备:{},参数:{},值:{},Key:{}", +// formatEquipId, PARAM_TEMP, paramValue, redisKey); } } catch (Exception e) { log.error("❌ 处理MQTT设备数据失败:{}", e.getMessage(), e); diff --git a/shgx-dryingroom/src/main/java/com/shgx/dryingroom/mqtt/MqttService.java b/shgx-dryingroom/src/main/java/com/shgx/dryingroom/mqtt/MqttService.java index 4d6643b..834bbed 100644 --- a/shgx-dryingroom/src/main/java/com/shgx/dryingroom/mqtt/MqttService.java +++ b/shgx-dryingroom/src/main/java/com/shgx/dryingroom/mqtt/MqttService.java @@ -108,7 +108,7 @@ public class MqttService implements MqttCallback { @Override public void messageArrived(String topic, MqttMessage message) throws Exception { String payload = new String(message.getPayload()); - log.info("📨 收到消息 - 主题: {}, QoS: {}, 内容: {}", topic, message.getQos(), payload); +// log.info("📨 收到消息 - 主题: {}, QoS: {}, 内容: {}", topic, message.getQos(), payload); // 控制台显示 System.out.println("\n🎯 收到客户端消息:"); diff --git a/shgx-dryingroom/src/main/java/com/shgx/dryingroom/web/service/impl/DryEquipmentInfoServiceImpl.java b/shgx-dryingroom/src/main/java/com/shgx/dryingroom/web/service/impl/DryEquipmentInfoServiceImpl.java index 24a9ba0..d140ae8 100644 --- a/shgx-dryingroom/src/main/java/com/shgx/dryingroom/web/service/impl/DryEquipmentInfoServiceImpl.java +++ b/shgx-dryingroom/src/main/java/com/shgx/dryingroom/web/service/impl/DryEquipmentInfoServiceImpl.java @@ -6,11 +6,11 @@ import java.util.List; import com.baomidou.dynamic.datasource.annotation.DS; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.shgx.common.utils.DateUtils; import com.shgx.common.utils.SecurityUtils; import com.shgx.dryingroom.alarm.AlarmLightService; import com.shgx.dryingroom.collect.AutoCollectService; +import com.shgx.dryingroom.collect.CacheSyncService; import com.shgx.dryingroom.web.domain.DryEquipmentParamRelation; import com.shgx.dryingroom.web.domain.DryParamThreshold; import com.shgx.dryingroom.web.domain.dto.ParamThresholdDTO; @@ -47,6 +47,10 @@ public class DryEquipmentInfoServiceImpl implements IDryEquipmentInfoService { @Autowired private AutoCollectService autoCollectService; + // 新增:缓存同步服务 + @Autowired + private CacheSyncService cacheSyncService; + /** * 查询设备信息 * @@ -103,9 +107,19 @@ public class DryEquipmentInfoServiceImpl implements IDryEquipmentInfoService { dryEquipmentInfo.setCreateBy(SecurityUtils.getUsername()); dryEquipmentInfo.setCreateTime(DateUtils.getNowDate()); - autoCollectService.loadRuleCache(); + // 新增:先刷新缓存,再插入数据 + autoCollectService.refreshEquipmentCache(); + if (dryEquipmentInfo.getRuleCode() != null && !dryEquipmentInfo.getRuleCode().trim().isEmpty()) { + autoCollectService.refreshRuleCache(); + } - return dryEquipmentInfoMapper.insert(dryEquipmentInfo); + // 插入数据 + int result = dryEquipmentInfoMapper.insert(dryEquipmentInfo); + + // 新增:立即推送数据到前端 + autoCollectService.triggerImmediatePush(); + + return result; } /** @@ -116,6 +130,11 @@ public class DryEquipmentInfoServiceImpl implements IDryEquipmentInfoService { */ @Override public int updateDryEquipmentInfo(DryEquipmentInfo dryEquipmentInfo) { + // 先查询旧的设备信息,用于判断规则是否变更 + DryEquipmentInfo oldInfo = dryEquipmentInfoMapper.selectById(dryEquipmentInfo.getId()); + String oldRuleCode = oldInfo != null ? oldInfo.getRuleCode() : null; + String newRuleCode = dryEquipmentInfo.getRuleCode(); + // 查找对应规则 LambdaQueryWrapper paramWrapper = new LambdaQueryWrapper<>(); paramWrapper.eq(DryParamThreshold::getRuleCode, dryEquipmentInfo.getRuleCode()); @@ -125,34 +144,47 @@ public class DryEquipmentInfoServiceImpl implements IDryEquipmentInfoService { dryEquipmentInfo.setRuleName(param.getRuleName()); dryEquipmentInfo.setSetTem(param.getMaxValue()); - // 更新设备规则关系表 - boolean isRelationExist = false; // 标记:是否已存在匹配记录 - LambdaQueryWrapper relationWrapper = new LambdaQueryWrapper<>(); - relationWrapper.eq(DryEquipmentParamRelation::getEquipmentCode, dryEquipmentInfo.getEquipmentCode()); - List relationList = relationMapper.selectList(relationWrapper); - for (DryEquipmentParamRelation relation : relationList) { - if (relation.getRuleCode().equals(dryEquipmentInfo.getRuleCode())) { - isRelationExist = true; // 标记为已存在 - break; - } + // 更新设备规则关系表 + boolean isRelationExist = false; // 标记:是否已存在匹配记录 + LambdaQueryWrapper relationWrapper = new LambdaQueryWrapper<>(); + relationWrapper.eq(DryEquipmentParamRelation::getEquipmentCode, dryEquipmentInfo.getEquipmentCode()); + List relationList = relationMapper.selectList(relationWrapper); + for (DryEquipmentParamRelation relation : relationList) { + if (relation.getRuleCode().equals(dryEquipmentInfo.getRuleCode())) { + isRelationExist = true; // 标记为已存在 + break; } + } - // 仅当不存在时,才执行插入操作 - if (!isRelationExist) { - DryEquipmentParamRelation relation = new DryEquipmentParamRelation(); - relation.setEquipmentCode(dryEquipmentInfo.getEquipmentCode()); - relation.setEquipmentName(dryEquipmentInfo.getEquipmentName()); - relation.setRuleCode(dryEquipmentInfo.getRuleCode()); - relation.setRuleName(dryEquipmentInfo.getRuleName()); - relationMapper.insert(relation); - } - - autoCollectService.loadRuleCache(); + // 仅当不存在时,才执行插入操作 + if (!isRelationExist) { + DryEquipmentParamRelation relation = new DryEquipmentParamRelation(); + relation.setEquipmentCode(dryEquipmentInfo.getEquipmentCode()); + relation.setEquipmentName(dryEquipmentInfo.getEquipmentName()); + relation.setRuleCode(dryEquipmentInfo.getRuleCode()); + relation.setRuleName(dryEquipmentInfo.getRuleName()); + relationMapper.insert(relation); + } dryEquipmentInfo.setUpdateBy(SecurityUtils.getUsername()); dryEquipmentInfo.setUpdateTime(DateUtils.getNowDate()); - return dryEquipmentInfoMapper.updateById(dryEquipmentInfo); + // 更新数据库 + int result = dryEquipmentInfoMapper.updateById(dryEquipmentInfo); + + // 新增:判断规则是否变更,更新相应缓存 + boolean ruleChanged = (oldRuleCode == null && newRuleCode != null) || + (oldRuleCode != null && !oldRuleCode.equals(newRuleCode)); + + if (ruleChanged) { + // 规则变更,刷新所有缓存 + cacheSyncService.notifyCacheUpdateAndPush("ALL"); + } else { + // 只刷新设备缓存 + cacheSyncService.notifyCacheUpdateAndPush("EQUIPMENT"); + } + + return result; } /** @@ -165,7 +197,13 @@ public class DryEquipmentInfoServiceImpl implements IDryEquipmentInfoService { public int deleteDryEquipmentInfoByIds(Long[] ids) { List idList = Arrays.asList(ids); - return dryEquipmentInfoMapper.deleteByIds(idList); + // 执行删除 + int result = dryEquipmentInfoMapper.deleteByIds(idList); + + // 新增:刷新缓存并推送 + cacheSyncService.notifyCacheUpdateAndPush("ALL"); + + return result; } /** @@ -176,7 +214,13 @@ public class DryEquipmentInfoServiceImpl implements IDryEquipmentInfoService { */ @Override public int deleteDryEquipmentInfoById(Long id) { - return dryEquipmentInfoMapper.deleteById(id); + // 执行删除 + int result = dryEquipmentInfoMapper.deleteById(id); + + // 新增:刷新缓存并推送 + cacheSyncService.notifyCacheUpdateAndPush("ALL"); + + return result; } /** @@ -198,7 +242,14 @@ public class DryEquipmentInfoServiceImpl implements IDryEquipmentInfoService { alarmLightService.triggerAllAlarmsByEquipment(equipmentInfo.getEquipmentCode()); } } - return dryEquipmentInfoMapper.updateById(info); + + // 更新数据库 + int result = dryEquipmentInfoMapper.updateById(info); + + // 新增:刷新缓存并立即推送 + cacheSyncService.notifyCacheUpdateAndPush("EQUIPMENT"); + + return result; } /** @@ -218,4 +269,4 @@ public class DryEquipmentInfoServiceImpl implements IDryEquipmentInfoService { } return result; } -} +} \ No newline at end of file diff --git a/shgx-dryingroom/src/main/java/com/shgx/dryingroom/web/service/impl/DryParamThresholdServiceImpl.java b/shgx-dryingroom/src/main/java/com/shgx/dryingroom/web/service/impl/DryParamThresholdServiceImpl.java index f0d2e8f..749c24d 100644 --- a/shgx-dryingroom/src/main/java/com/shgx/dryingroom/web/service/impl/DryParamThresholdServiceImpl.java +++ b/shgx-dryingroom/src/main/java/com/shgx/dryingroom/web/service/impl/DryParamThresholdServiceImpl.java @@ -14,7 +14,9 @@ import com.shgx.common.utils.DateUtils; import com.shgx.common.utils.SecurityUtils; import com.shgx.common.utils.StringUtils; import com.shgx.common.utils.uuid.UUID; + import com.shgx.dryingroom.collect.AutoCollectService; +import com.shgx.dryingroom.collect.CacheSyncService; import com.shgx.dryingroom.web.domain.DryEquipmentInfo; import com.shgx.dryingroom.web.domain.DryEquipmentParamRelation; import com.shgx.dryingroom.web.mapper.DryEquipmentInfoMapper; @@ -36,7 +38,7 @@ import static org.apache.naming.SelectorContext.prefix; /** * 参数阈值Service业务层处理 - * + * * @author shgx * @date 2025-10-16 */ @@ -56,6 +58,10 @@ public class DryParamThresholdServiceImpl implements IDryParamThresholdService @Autowired private DryEquipmentInfoMapper infoMapper; + // 新增:缓存同步服务 + @Autowired + private CacheSyncService cacheSyncService; + /** * 查询参数阈值 * @@ -92,6 +98,7 @@ public class DryParamThresholdServiceImpl implements IDryParamThresholdService * @return 结果 */ @Override + @Transactional(rollbackFor = Exception.class) public int insertDryParamThreshold(DryParamThreshold dryParamThreshold) { // 校验 ruleName 是否已存在于数据库 @@ -114,10 +121,13 @@ public class DryParamThresholdServiceImpl implements IDryParamThresholdService dryParamThreshold.setCreateBy(SecurityUtils.getUsername()); dryParamThreshold.setCreateTime(DateUtils.getNowDate()); - // 重新加载缓存 - autoCollectService.loadRuleCache(); + // 新增数据 + int result = dryParamThresholdMapper.insert(dryParamThreshold); - return dryParamThresholdMapper.insert(dryParamThreshold); + // 新增:同步刷新规则缓存并立即推送 + cacheSyncService.notifyCacheUpdateAndPush("RULE"); + + return result; } /** @@ -127,23 +137,60 @@ public class DryParamThresholdServiceImpl implements IDryParamThresholdService * @return 结果 */ @Override + @Transactional(rollbackFor = Exception.class) public int updateDryParamThreshold(DryParamThreshold dryParamThreshold) { + // 先查询旧的规则信息,用于判断是否需要刷新设备缓存 + DryParamThreshold oldThreshold = dryParamThresholdMapper.selectById(dryParamThreshold.getId()); + String oldRuleCode = oldThreshold != null ? oldThreshold.getRuleCode() : null; + String newRuleCode = dryParamThreshold.getRuleCode(); + + // 记录是否启停状态变更 + boolean enabledStatusChanged = oldThreshold != null && + !StringUtils.equals(oldThreshold.getIsEnabled(), dryParamThreshold.getIsEnabled()); + + // 记录阈值是否变更 + boolean thresholdChanged = oldThreshold != null && + (!StringUtils.equals(oldThreshold.getMaxValue(), dryParamThreshold.getMaxValue()) || + !StringUtils.equals(oldThreshold.getMinValue(), dryParamThreshold.getMinValue())); dryParamThreshold.setUpdateBy(SecurityUtils.getUsername()); dryParamThreshold.setUpdateTime(DateUtils.getNowDate()); - // 重新加载缓存 - autoCollectService.loadRuleCache(); + // 更新数据 + int result = dryParamThresholdMapper.updateById(dryParamThreshold); - return dryParamThresholdMapper.updateById(dryParamThreshold); + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(DryEquipmentInfo::getRuleCode, dryParamThreshold.getRuleCode()); + List infoList = infoMapper.selectList(queryWrapper); + if (!infoList.isEmpty()) { + for (DryEquipmentInfo info : infoList) { + info.setRuleName(dryParamThreshold.getRuleName()); + info.setSetTem(dryParamThreshold.getMaxValue()); + infoMapper.updateById(info); + } + } + + // 新增:根据变更情况同步缓存 + if (result > 0) { + if (enabledStatusChanged || thresholdChanged) { + // 启停状态或阈值变更,刷新所有缓存并推送 + cacheSyncService.notifyCacheUpdateAndPush("ALL"); + } else { + // 其他信息变更,只刷新规则缓存并推送 + cacheSyncService.notifyCacheUpdateAndPush("RULE"); + } + } + + return result; } /** - * 批量删除参数阈值 + * 批量删除参数阈值(按照单独删除的完整逻辑逐个处理) + * 每个规则ID都执行完整的级联置空和关联删除流程 * * @param ids 需要删除的参数阈值主键 - * @return 结果 + * @return 成功删除的记录数 */ @Override @Transactional(rollbackFor = Exception.class) @@ -152,32 +199,83 @@ public class DryParamThresholdServiceImpl implements IDryParamThresholdService if (ids == null || ids.length == 0) { return 0; } - List idList = Arrays.asList(ids); - // 2. 根据规则ID批量查询DryParamThreshold,获取对应的ruleCode列表 - LambdaQueryWrapper thresholdQueryWrapper = new LambdaQueryWrapper<>(); - thresholdQueryWrapper.in(DryParamThreshold::getId, idList) - .select(DryParamThreshold::getRuleCode); - List thresholdList = dryParamThresholdMapper.selectList(thresholdQueryWrapper); + int totalDeleteCount = 0; - // 3. 提取ruleCode列表 - List ruleCodeList = thresholdList.stream() - .map(DryParamThreshold::getRuleCode) - .filter(ruleCode -> ruleCode != null && !ruleCode.isEmpty()) - .distinct() - .collect(Collectors.toList()); + // 记录所有被删除的规则编码,用于设备缓存更新 + List deletedRuleCodes = new java.util.ArrayList<>(); - // 4. 级联删除DryEquipmentParamRelation中匹配ruleCode的所有数据 - if (!CollectionUtils.isEmpty(ruleCodeList)) { - LambdaQueryWrapper relationQueryWrapper = new LambdaQueryWrapper<>(); - relationQueryWrapper.in(DryEquipmentParamRelation::getRuleCode, ruleCodeList); - relationMapper.delete(relationQueryWrapper); + // 2. 遍历每个ID,按照单独删除的逻辑处理 + for (Long id : ids) { + if (id == null) { + continue; + } + + // 3. 根据ID查询对应的DryParamThreshold,获取ruleCode + LambdaQueryWrapper thresholdQueryWrapper = new LambdaQueryWrapper<>(); + thresholdQueryWrapper.eq(DryParamThreshold::getId, id) + .select(DryParamThreshold::getRuleCode); + DryParamThreshold threshold = dryParamThresholdMapper.selectOne(thresholdQueryWrapper); + + if (threshold == null) { + continue; + } + + String ruleCode = threshold.getRuleCode(); + + // 记录被删除的规则编码 + if (StringUtils.hasText(ruleCode)) { + deletedRuleCodes.add(ruleCode); + } + + // 4. 如果存在ruleCode,则处理该规则的级联删除和置空逻辑 + if (StringUtils.hasText(ruleCode)) { + // 4.1 查询relation表中该ruleCode绑定的所有equipmentCode + LambdaQueryWrapper relationQueryWrapper = new LambdaQueryWrapper<>(); + relationQueryWrapper.eq(DryEquipmentParamRelation::getRuleCode, ruleCode) + .select(DryEquipmentParamRelation::getEquipmentCode); + List equipmentCodeList = relationMapper.selectObjs(relationQueryWrapper) + .stream() + .filter(Objects::nonNull) + .map(Object::toString) + .distinct() + .collect(Collectors.toList()); + + // 4.2 批量置空这些equipmentCode对应的ruleCode(DryEquipmentInfo表) + if (!CollectionUtils.isEmpty(equipmentCodeList)) { + LambdaUpdateWrapper infoUpdateWrapper = new LambdaUpdateWrapper<>(); + infoUpdateWrapper.in(DryEquipmentInfo::getEquipmentCode, equipmentCodeList) + .set(DryEquipmentInfo::getRuleCode, null) + .set(DryEquipmentInfo::getRuleName, null) + .set(DryEquipmentInfo::getSetTem, "0"); + infoMapper.update(null, infoUpdateWrapper); + } + + // 4.3 级联删除DryEquipmentParamRelation中该ruleCode的所有关联数据 + LambdaQueryWrapper deleteWrapper = new LambdaQueryWrapper<>(); + deleteWrapper.eq(DryEquipmentParamRelation::getRuleCode, ruleCode); + relationMapper.delete(deleteWrapper); + } + + // 5. 删除DryParamThreshold主表数据 + int deleteCount = dryParamThresholdMapper.deleteById(id); + if (deleteCount > 0) { + totalDeleteCount++; + } } - // 5. 删除DryParamThreshold表中指定ID的规则数据 - int deleteCount = dryParamThresholdMapper.deleteByIds(idList); + // 6. 处理完成后刷新缓存并推送 + if (totalDeleteCount > 0) { + // 如果有设备关联的规则被删除,需要刷新所有缓存 + if (!deletedRuleCodes.isEmpty()) { + cacheSyncService.notifyCacheUpdateAndPush("ALL"); + } else { + // 只刷新规则缓存 + cacheSyncService.notifyCacheUpdateAndPush("RULE"); + } + } - return deleteCount; + return totalDeleteCount; } /** @@ -202,6 +300,8 @@ public class DryParamThresholdServiceImpl implements IDryParamThresholdService } String ruleCode = threshold.getRuleCode(); + boolean hasEquipmentRelation = false; + // 3. 核心逻辑:处理设备关联的ruleCode置空 if (StringUtils.hasText(ruleCode)) { // 3.1 查询relation表中该ruleCode绑定的所有equipmentCode @@ -218,10 +318,12 @@ public class DryParamThresholdServiceImpl implements IDryParamThresholdService // 3.2 批量置空这些equipmentCode对应的ruleCode(DryEquipmentInfo表) if (!equipmentCodeList.isEmpty()) { + hasEquipmentRelation = true; LambdaUpdateWrapper infoUpdateWrapper = new LambdaUpdateWrapper<>(); infoUpdateWrapper.in(DryEquipmentInfo::getEquipmentCode, equipmentCodeList) // 匹配所有关联设备 .set(DryEquipmentInfo::getRuleCode, null) // 将ruleCode置为null - .set(DryEquipmentInfo::getRuleName, null); + .set(DryEquipmentInfo::getRuleName, null) + .set(DryEquipmentInfo::getSetTem, "0"); int updateCount = infoMapper.update(null, infoUpdateWrapper); } @@ -234,7 +336,16 @@ public class DryParamThresholdServiceImpl implements IDryParamThresholdService // 4. 删除DryParamThreshold主表数据 int mainDeleteCount = dryParamThresholdMapper.deleteById(id); - autoCollectService.loadRuleCache(); + // 5. 刷新缓存并推送 + if (mainDeleteCount > 0) { + if (hasEquipmentRelation) { + // 如果有关联设备,刷新所有缓存 + cacheSyncService.notifyCacheUpdateAndPush("ALL"); + } else { + // 只刷新规则缓存 + cacheSyncService.notifyCacheUpdateAndPush("RULE"); + } + } return mainDeleteCount; } @@ -325,7 +436,7 @@ public class DryParamThresholdServiceImpl implements IDryParamThresholdService return ""; } - // 配置拼音格式:无音调(如“干”→“gan”,而非“gan1”) + // 配置拼音格式:无音调(如"干"→"gan",而非"gan1") HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat(); format.setToneType(HanyuPinyinToneType.WITHOUT_TONE); @@ -337,7 +448,7 @@ public class DryParamThresholdServiceImpl implements IDryParamThresholdService // 获取该汉字的所有拼音(多音字取第一个) String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(c, format); if (pinyinArray != null && pinyinArray.length > 0) { - pinyin.append(pinyinArray[0]); // 取第一个拼音(如“行”→“xing”) + pinyin.append(pinyinArray[0]); // 取第一个拼音(如"行"→"xing") } else { pinyin.append("unknown"); // 生僻字兜底 } @@ -355,4 +466,4 @@ public class DryParamThresholdServiceImpl implements IDryParamThresholdService return pinyin.toString(); } -} +} \ No newline at end of file diff --git a/shgx-framework/src/main/java/com/shgx/framework/config/ResourcesConfig.java b/shgx-framework/src/main/java/com/shgx/framework/config/ResourcesConfig.java index 910dc80..e8cb9ad 100644 --- a/shgx-framework/src/main/java/com/shgx/framework/config/ResourcesConfig.java +++ b/shgx-framework/src/main/java/com/shgx/framework/config/ResourcesConfig.java @@ -55,14 +55,12 @@ public class ResourcesConfig implements WebMvcConfigurer public CorsFilter corsFilter() { CorsConfiguration config = new CorsConfiguration(); - config.addAllowedOrigin("*"); // 允许所有来源 // 设置访问源地址 config.addAllowedOriginPattern("*"); // 设置访问源请求头 config.addAllowedHeader("*"); // 设置访问源请求方法 config.addAllowedMethod("*"); - config.setAllowCredentials(false); // 有效期 1800秒 config.setMaxAge(1800L); // 添加映射路径,拦截一切请求 diff --git a/shgx-framework/src/main/java/com/shgx/framework/config/SecurityConfig.java b/shgx-framework/src/main/java/com/shgx/framework/config/SecurityConfig.java index a50b20c..fab224d 100644 --- a/shgx-framework/src/main/java/com/shgx/framework/config/SecurityConfig.java +++ b/shgx-framework/src/main/java/com/shgx/framework/config/SecurityConfig.java @@ -97,7 +97,6 @@ public class SecurityConfig protected SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception { return httpSecurity - .cors().and() // CSRF禁用,因为不使用session .csrf(csrf -> csrf.disable()) // 禁用HTTP响应标头 @@ -113,8 +112,7 @@ public class SecurityConfig permitAllUrl.getUrls().forEach(url -> requests.antMatchers(url).permitAll()); // 对于登录login 注册register 验证码captchaImage 允许匿名访问 requests.antMatchers("/login", "/register", "/captchaImage").permitAll() - .antMatchers("/dry/screen/closeAlarm").permitAll() - // 静态资源,可匿名访问 + // 静态资源,可匿名访问 .antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll() .antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll() // 除上面外的所有请求全部需要鉴权认证 diff --git a/shgx-framework/src/main/java/com/shgx/framework/security/filter/JwtAuthenticationTokenFilter.java b/shgx-framework/src/main/java/com/shgx/framework/security/filter/JwtAuthenticationTokenFilter.java index f850138..9963db0 100644 --- a/shgx-framework/src/main/java/com/shgx/framework/security/filter/JwtAuthenticationTokenFilter.java +++ b/shgx-framework/src/main/java/com/shgx/framework/security/filter/JwtAuthenticationTokenFilter.java @@ -31,14 +31,6 @@ public class JwtAuthenticationTokenFilter extends OncePerRequestFilter protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { - String requestURI = request.getRequestURI(); - - // 如果是需要放行的接口,直接跳过Token验证 - if ("/dry/screen/closeAlarm".equals(requestURI)) { - chain.doFilter(request, response); - return; - } - LoginUser loginUser = tokenService.getLoginUser(request); if (StringUtils.isNotNull(loginUser) && StringUtils.isNull(SecurityUtils.getAuthentication())) { @@ -49,4 +41,4 @@ public class JwtAuthenticationTokenFilter extends OncePerRequestFilter } chain.doFilter(request, response); } -} \ No newline at end of file +}