From 210663040bf65ee00b5f86545fdc31bd0356fddf Mon Sep 17 00:00:00 2001
From: yeg <1347747024@qq.com>
Date: 星期四, 27 八月 2026 16:31:53 +0800
Subject: [PATCH] feat(device): persist simulator discovery in redis

---
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TCollectorServiceImpl.java |   59 +++++++++++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 53 insertions(+), 6 deletions(-)

diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TCollectorServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TCollectorServiceImpl.java
index a4b5ad7..25be25c 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TCollectorServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TCollectorServiceImpl.java
@@ -3,8 +3,10 @@
 import java.net.InetAddress;
 import java.util.Date;
 import java.util.List;
+import java.util.Set;
 import java.util.regex.Pattern;
-import org.springframework.beans.factory.annotation.Autowired;
+import java.time.Instant;
+import java.util.Map;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import com.ruoyi.common.exception.ServiceException;
@@ -12,6 +14,8 @@
 import com.ruoyi.system.domain.TCollector;
 import com.ruoyi.system.mapper.TCollectorMapper;
 import com.ruoyi.system.service.ITCollectorService;
+import com.ruoyi.device.discovery.DeviceDiscoveryCandidateStore;
+import com.ruoyi.device.discovery.DeviceDiscoveryCandidateStore.CollectorCandidate;
 
 /**
  * 采集器 Service 实现。
@@ -24,14 +28,21 @@
     private static final String ENABLED = "0";
     private static final String DISABLED = "1";
     private static final String OFFLINE = "0";
+    private static final String ONLINE = "1";
     private static final String IDLE = "0";
     private static final String TESTING = "1";
     private static final Pattern IPV4_PATTERN = Pattern.compile(
             "^(25[0-5]|2[0-4]\\d|1?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|1?\\d?\\d)){3}$");
     private static final Pattern MAC_PATTERN = Pattern.compile("^[0-9A-F]{2}(:[0-9A-F]{2}){5}$");
 
-    @Autowired
-    private TCollectorMapper collectorMapper;
+    private final TCollectorMapper collectorMapper;
+    private final DeviceDiscoveryCandidateStore candidateStore;
+
+    public TCollectorServiceImpl(TCollectorMapper collectorMapper, DeviceDiscoveryCandidateStore candidateStore)
+    {
+        this.collectorMapper = collectorMapper;
+        this.candidateStore = candidateStore;
+    }
 
     /**
      * 查询未删除采集器,不存在时抛出业务异常。
@@ -48,7 +59,7 @@
         {
             throw new ServiceException("采集器不存在");
         }
-        return collector;
+        return applyRealtimeState(collector, candidatesByCode());
     }
 
     /**
@@ -64,18 +75,34 @@
         collector.setDevice(trimToNull(collector.getDevice()));
         collector.setBeginCreateTime(trimToNull(collector.getBeginCreateTime()));
         collector.setEndCreateTime(trimToNull(collector.getEndCreateTime()));
-        validateOptionalStatus(collector.getOnlineStatus(), "在线状态");
+        String requestedOnlineStatus = collector.getOnlineStatus();
+        validateOptionalStatus(requestedOnlineStatus, "在线状态");
+        collector.setOnlineStatus(null);
         validateOptionalStatus(collector.getTestStatus(), "测试状态");
         validateOptionalStatus(collector.getStatus(), "状态");
-        return collectorMapper.selectCollectorList(collector);
+        Map<String, CollectorCandidate> candidates = candidatesByCode();
+        return collectorMapper.selectCollectorList(collector).stream()
+                .map(item -> applyRealtimeState(item, candidates))
+                .filter(item -> StringUtils.isEmpty(requestedOnlineStatus)
+                        || requestedOnlineStatus.equals(item.getOnlineStatus()))
+                .toList();
     }
 
     /**
      * 新增采集器并初始化运行状态。
      */
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public int insertCollector(TCollector collector)
     {
+        if (collector == null) throw new ServiceException("采集器信息不能为空");
+        collector.setCollectorCode(trimToNull(collector.getCollectorCode()));
+        CollectorCandidate candidate = candidateStore.findCollector(collector.getCollectorCode(), Instant.now())
+                .filter(CollectorCandidate::online)
+                .orElseThrow(() -> new ServiceException("请先选择在线的发现候选设备"));
+        collector.setIpAddress(candidate.ip());
+        collector.setMacAddress(candidate.mac());
+        collector.setChannelCount(candidate.channelCount());
         validateCollector(collector, false);
         collector.setOnlineStatus(OFFLINE);
         collector.setTestStatus(IDLE);
@@ -132,6 +159,13 @@
         }
         collector.setUpdateTime(new Date());
         return collectorMapper.updateCollectorStatus(collector);
+    }
+
+    /** 查询全部未删除采集器的设备编码,供发现候选排除已登记设备。 */
+    @Override
+    public Set<String> selectRegisteredCollectorCodes()
+    {
+        return Set.copyOf(collectorMapper.selectRegisteredCollectorCodes());
     }
 
     /**
@@ -309,4 +343,17 @@
     {
         return StringUtils.isEmpty(StringUtils.trim(value)) ? null : StringUtils.trim(value);
     }
+
+    private Map<String, CollectorCandidate> candidatesByCode()
+    {
+        return candidateStore.snapshot(Instant.now()).collectors().stream()
+                .collect(java.util.stream.Collectors.toMap(CollectorCandidate::deviceCode, item -> item));
+    }
+
+    private TCollector applyRealtimeState(TCollector collector, Map<String, CollectorCandidate> candidates)
+    {
+        CollectorCandidate candidate = candidates.get(collector.getCollectorCode());
+        collector.setOnlineStatus(candidate != null && candidate.online() ? ONLINE : OFFLINE);
+        return collector;
+    }
 }

--
Gitblit v1.7.1