From 7ab0e426264707fb85ee38d0a9a73caf41899635 Mon Sep 17 00:00:00 2001
From: yeg <1347747024@qq.com>
Date: 星期六, 29 八月 2026 13:11:40 +0800
Subject: [PATCH] 实现采集器独立实时与历史采样模拟

---
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/device/BtsDevelopmentSimulatorController.java |   86 +++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 86 insertions(+), 0 deletions(-)

diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/device/BtsDevelopmentSimulatorController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/device/BtsDevelopmentSimulatorController.java
index 30fc2a7..7563d63 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/device/BtsDevelopmentSimulatorController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/device/BtsDevelopmentSimulatorController.java
@@ -1,5 +1,7 @@
 package com.ruoyi.web.controller.device;
 
+import java.math.BigDecimal;
+import java.util.List;
 import org.springframework.core.io.ClassPathResource;
 import org.springframework.core.io.Resource;
 import org.springframework.http.HttpStatus;
@@ -10,6 +12,7 @@
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.PutMapping;
 import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.server.ResponseStatusException;
 import com.ruoyi.common.annotation.Anonymous;
@@ -17,6 +20,10 @@
 import com.ruoyi.device.bts.BtsDevelopmentSimulator.StateSnapshot;
 import com.ruoyi.device.discovery.DeviceDiscoveryCandidateStore;
 import com.ruoyi.device.model.DeviceWorkStatus;
+import com.ruoyi.device.simulator.BtsSimulatorStateStore.CollectorHistoryFaults;
+import com.ruoyi.device.simulator.BtsSimulatorStateStore.CollectorMetricState;
+import com.ruoyi.device.simulator.DevelopmentCollectorSimulation.CollectorHistoryPage;
+import com.ruoyi.device.simulator.DevelopmentCollectorSimulation.CollectorRealtimeSnapshot;
 
 /** 本机临时 BTS 模拟器控制 API。 */
 @Anonymous
@@ -132,6 +139,72 @@
         }
     }
 
+    /** 配置采集器采样频率和可重复的历史下载故障场景。 */
+    @PutMapping("/dev/bts-simulator/collectors/{collectorId}/sampling")
+    public StateSnapshot configureCollectorSampling(@PathVariable int collectorId,
+            @RequestBody CollectorSamplingCommand command)
+    {
+        try
+        {
+            simulator.configureCollectorSampling(collectorId, command.sampleIntervalMs(),
+                    new CollectorHistoryFaults(command.missingSequences(), command.duplicateSequence(),
+                            command.conflictingSequence(), command.outOfOrder()));
+            return simulator.snapshot();
+        }
+        catch (IllegalArgumentException exception)
+        {
+            throw badRequest(exception);
+        }
+    }
+
+    /** 配置稳定 S 通道的固定和动态测量项。 */
+    @PutMapping("/dev/bts-simulator/collectors/{collectorId}/channels/{channelCode}")
+    public StateSnapshot configureCollectorChannel(@PathVariable int collectorId,
+            @PathVariable String channelCode, @RequestBody CollectorChannelCommand command)
+    {
+        try
+        {
+            List<CollectorMetricState> metrics = command.metrics().stream()
+                    .map(metric -> new CollectorMetricState(metric.metricCode(), metric.value(), metric.unit()))
+                    .toList();
+            simulator.configureCollectorChannel(collectorId, channelCode, metrics);
+            return simulator.snapshot();
+        }
+        catch (IllegalArgumentException | NullPointerException exception)
+        {
+            throw badRequest(new IllegalArgumentException("Invalid collector channel metrics", exception));
+        }
+    }
+
+    /** 查询采集器最新实时快照;离线时保留最后观测并明确返回离线事实。 */
+    @GetMapping("/dev/bts-simulator/collectors/{collectorId}/realtime")
+    public CollectorRealtimeSnapshot collectorRealtime(@PathVariable int collectorId)
+    {
+        try
+        {
+            return simulator.collectorRealtime(collectorId);
+        }
+        catch (IllegalArgumentException exception)
+        {
+            throw badRequest(exception);
+        }
+    }
+
+    /** 按偏移量分页下载采集器模拟历史,每页最多 1000 条。 */
+    @GetMapping("/dev/bts-simulator/collectors/{collectorId}/history")
+    public CollectorHistoryPage collectorHistory(@PathVariable int collectorId,
+            @RequestParam(defaultValue = "0") long offset, @RequestParam(defaultValue = "100") int limit)
+    {
+        try
+        {
+            return simulator.collectorHistory(collectorId, offset, limit);
+        }
+        catch (IllegalArgumentException exception)
+        {
+            throw badRequest(exception);
+        }
+    }
+
     /** 删除指定虚拟采集器。 */
     @DeleteMapping("/dev/bts-simulator/collectors/{collectorId}")
     public StateSnapshot deleteCollector(@PathVariable int collectorId)
@@ -177,4 +250,17 @@
     public record CreateCollectorCommand(String ip, int channelCount) { }
 
     public record CollectorStateCommand(String ip, int channelCount, boolean online) { }
+
+    public record CollectorSamplingCommand(int sampleIntervalMs, List<Long> missingSequences,
+            Long duplicateSequence, Long conflictingSequence, boolean outOfOrder)
+    {
+        public CollectorSamplingCommand
+        {
+            missingSequences = missingSequences == null ? List.of() : List.copyOf(missingSequences);
+        }
+    }
+
+    public record CollectorChannelCommand(List<CollectorMetricCommand> metrics) { }
+
+    public record CollectorMetricCommand(String metricCode, BigDecimal value, String unit) { }
 }

--
Gitblit v1.7.1