From 147428971be43eed90a79f3849f15000d3855390 Mon Sep 17 00:00:00 2001
From: yeg <1347747024@qq.com>
Date: 星期一, 28 九月 2026 15:15:22 +0800
Subject: [PATCH] 实现新威 7.6 直连取数与逐行接收

---
 ruoyi-admin/src/test/java/com/battery/business/service/impl/DeviceDiscoveryPersistenceServiceTest.java |   36 ++++++++++++++++++++++++++++++++++++
 1 files changed, 36 insertions(+), 0 deletions(-)

diff --git a/ruoyi-admin/src/test/java/com/battery/business/service/impl/DeviceDiscoveryPersistenceServiceTest.java b/ruoyi-admin/src/test/java/com/battery/business/service/impl/DeviceDiscoveryPersistenceServiceTest.java
index dda94d2..a68bc03 100644
--- a/ruoyi-admin/src/test/java/com/battery/business/service/impl/DeviceDiscoveryPersistenceServiceTest.java
+++ b/ruoyi-admin/src/test/java/com/battery/business/service/impl/DeviceDiscoveryPersistenceServiceTest.java
@@ -76,4 +76,40 @@
         assertEquals(1, candidateStore.snapshot(java.time.Instant.now()).cabinets().size());
         verify(adapter).discoverChannels();
     }
+
+    /**
+     * 直连厂商存储的来源:通道登记是长期事实,候选不按时间过期,
+     * 每条候选附带最近一次采样行的设备时间,供操作员判断哪几台真的在产出数据。
+     */
+    @Test
+    void vendorSourceCandidatesCarryLastDataTimeAndDoNotExpireByTime()
+    {
+        InMemoryDeviceDiscoveryCandidateStore candidateStore = new InMemoryDeviceDiscoveryCandidateStore();
+        TDetectionCabinetMapper cabinetMapper = Mockito.mock(TDetectionCabinetMapper.class);
+        TTestMapper testMapper = Mockito.mock(TTestMapper.class);
+        DeviceAdapterRegistry registry = Mockito.mock(DeviceAdapterRegistry.class);
+        DeviceAdapter adapter = Mockito.mock(DeviceAdapter.class);
+        ChannelIdentity identity = new ChannelIdentity("neware76", 21, 36, 1, 2);
+        java.time.Instant lastDataAt = java.time.Instant.parse("2026-09-28T01:54:56Z");
+        when(testMapper.hasReceivingTestForAdapter("neware76")).thenReturn(0);
+        when(adapter.discoverChannels()).thenReturn(List.of(new DetectedChannel(identity, "26.1.2.3", true,
+                com.battery.device.api.model.DetectedDeviceMetadata.empty(), lastDataAt)));
+        when(registry.execute(eq("neware76"), any())).thenAnswer(invocation -> {
+            @SuppressWarnings("unchecked")
+            Function<DeviceAdapter, Object> operation = (Function<DeviceAdapter, Object>) invocation.getArgument(1);
+            return operation.apply(adapter);
+        });
+
+        DeviceDiscoveryPersistenceService service = new DeviceDiscoveryPersistenceService(candidateStore,
+                cabinetMapper, testMapper);
+        service.discoverForReception(registry, new DeviceDiscoveryPersistenceService.DiscoverySource(
+                "neware76", 8L, "新威 7.6 那台", 60000, true));
+
+        var candidate = candidateStore.snapshot(java.time.Instant.now()).cabinets().get(0);
+        assertEquals(lastDataAt, candidate.lastDataAt());
+        assertEquals(lastDataAt, candidate.channels().get(0).lastDataAt());
+        // 一年后仍然是候选:候选只按"已登记且未删除"排除,不按时间过期。
+        assertEquals(1, candidateStore.snapshot(java.time.Instant.now().plusSeconds(365L * 24 * 3600))
+                .cabinets().size());
+    }
 }

--
Gitblit v1.7.1