package com.ruoyi.config; import java.time.Duration; import java.time.Instant; import java.util.List; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Profile; import com.battery.device.simulator.BtsDevelopmentSimulator; import com.battery.device.discovery.DeviceDiscoveryCandidateStore; import com.battery.device.discovery.DeviceDiscoveryCandidateStore.CollectorCandidate; import com.ruoyi.system.mapper.TCollectorMapper; /** 将模拟采集器的发现写入 Redis,并同步已登记采集器的实时在线事实。 */ @Component @Profile("dev-simulator") public class DevelopmentCollectorStatusSynchronizer { private final BtsDevelopmentSimulator simulator; private final DeviceDiscoveryCandidateStore candidateStore; private final TCollectorMapper collectorMapper; @Autowired public DevelopmentCollectorStatusSynchronizer(BtsDevelopmentSimulator simulator, DeviceDiscoveryCandidateStore candidateStore, TCollectorMapper collectorMapper) { this.simulator = simulator; this.candidateStore = candidateStore; this.collectorMapper = collectorMapper; } /** 保留单元测试及独立模拟器装配使用的旧构造入口。 */ /** 完整替换 dev-sim 采集器快照,删除配置后候选立即消失。 */ @Scheduled(fixedDelay = BtsDevelopmentSimulator.POLL_INTERVAL_MS) public synchronized void synchronizeOnlineStatus() { Instant observedAt = Instant.now(); var simulatorState = simulator.snapshot(); List candidates = simulatorState.collectors().stream() .map(item -> new CollectorCandidate(BtsDevelopmentSimulator.ADAPTER_CODE, item.deviceCode(), item.ip(), item.mac(), item.name(), item.manufacturer(), item.model(), item.channelCount(), item.online(), observedAt, observedAt.plus(Duration.ofSeconds(30)))) .toList(); candidateStore.replaceCollectors(BtsDevelopmentSimulator.ADAPTER_CODE, candidates); candidates.forEach(candidate -> collectorMapper.updateRegisteredObservation(candidate.deviceCode(), candidate.online() ? "ONLINE" : "OFFLINE")); } }