From 56cddf53e7e71afad29885d7fcf773a222b95f6c Mon Sep 17 00:00:00 2001
From: yeg <1347747024@qq.com>
Date: 星期日, 30 八月 2026 19:38:18 +0800
Subject: [PATCH] 修复采集器断线区间重复关闭
---
ruoyi-admin/src/test/java/com/ruoyi/config/FlywayMigrationContractTest.java | 8 ++++++++
ruoyi-admin/src/main/resources/db/migration/V19__collector_disconnect_open_dedupe.sql | 11 +++++++++++
.gitignore | 1 +
ruoyi-admin/src/test/java/com/ruoyi/system/service/impl/CollectorDisconnectRecoveryServiceImplTest.java | 28 ++++++++++++++++++++++++++++
4 files changed, 48 insertions(+), 0 deletions(-)
diff --git a/.gitignore b/.gitignore
index f18146e..47809a8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,5 +13,6 @@
!/ruoyi-admin/src/main/resources/db/migration/V7__complete_device_registration_boundary.sql
!/ruoyi-admin/src/main/resources/db/migration/V8__complete_collector_page_contract.sql
!/ruoyi-admin/src/main/resources/db/migration/V9__move_discovery_candidates_to_redis.sql
+!/ruoyi-admin/src/main/resources/db/migration/V19__collector_disconnect_open_dedupe.sql
/.mvn-review-repository/
/ruoyi-admin/logs/
diff --git a/ruoyi-admin/src/main/resources/db/migration/V19__collector_disconnect_open_dedupe.sql b/ruoyi-admin/src/main/resources/db/migration/V19__collector_disconnect_open_dedupe.sql
new file mode 100644
index 0000000..f138caa
--- /dev/null
+++ b/ruoyi-admin/src/main/resources/db/migration/V19__collector_disconnect_open_dedupe.sql
@@ -0,0 +1,11 @@
+-- Ticket11:唯一约束只覆盖开放中的采集器断线区间,关闭区间保留为历史追加记录。
+ALTER TABLE t_test_collector_exception_interval
+ DROP INDEX uk_collector_exception_open,
+ ADD COLUMN open_dedupe_key VARCHAR(320)
+ GENERATED ALWAYS AS (
+ CASE WHEN interval_status = 'OPEN' THEN
+ CONCAT(test_id, ':', battery_relation_id, ':', collector_id, ':',
+ collector_channel_code, ':', exception_type)
+ ELSE NULL END
+ ) STORED AFTER interval_status,
+ ADD UNIQUE KEY uk_collector_exception_open (open_dedupe_key);
diff --git a/ruoyi-admin/src/test/java/com/ruoyi/config/FlywayMigrationContractTest.java b/ruoyi-admin/src/test/java/com/ruoyi/config/FlywayMigrationContractTest.java
index 5106b4b..0473fd3 100644
--- a/ruoyi-admin/src/test/java/com/ruoyi/config/FlywayMigrationContractTest.java
+++ b/ruoyi-admin/src/test/java/com/ruoyi/config/FlywayMigrationContractTest.java
@@ -135,6 +135,14 @@
assertTrue(v18.contains("uk_collector_exception_open"));
assertFalse(v18.matches("(?s).*\\bDROP\\s+TABLE\\b.*"));
+ String v19 = resource("db/migration/V19__collector_disconnect_open_dedupe.sql");
+ assertTrue(v19.contains("DROP INDEX uk_collector_exception_open"));
+ assertTrue(v19.contains("open_dedupe_key VARCHAR(320)"));
+ assertTrue(v19.contains("interval_status = 'OPEN'"));
+ assertTrue(v19.contains("ELSE NULL"));
+ assertTrue(v19.contains("ADD UNIQUE KEY uk_collector_exception_open (open_dedupe_key)"));
+ assertFalse(v19.matches("(?s).*\\bDROP\\s+TABLE\\b.*"));
+
String testMapper = resource("mapper/system/TTestMapper.xml");
assertTrue(testMapper.contains("selectReceivingChannelsForAdapter"));
assertTrue(testMapper.contains("RECEPTION_RESUMED"));
diff --git a/ruoyi-admin/src/test/java/com/ruoyi/system/service/impl/CollectorDisconnectRecoveryServiceImplTest.java b/ruoyi-admin/src/test/java/com/ruoyi/system/service/impl/CollectorDisconnectRecoveryServiceImplTest.java
index dd11996..1c2c636 100644
--- a/ruoyi-admin/src/test/java/com/ruoyi/system/service/impl/CollectorDisconnectRecoveryServiceImplTest.java
+++ b/ruoyi-admin/src/test/java/com/ruoyi/system/service/impl/CollectorDisconnectRecoveryServiceImplTest.java
@@ -56,6 +56,34 @@
verify(mapper, never()).insertCollectorExceptionInterval(any());
}
+ @Test
+ void allowsAnotherDisconnectCycleAfterPreviousIntervalWasClosed()
+ {
+ TTestCollectorSource source = source(10L, 20L, 8L, "COL-1", "S-01");
+ TTestCollectorExceptionInterval first = openInterval(99L);
+ TTestCollectorExceptionInterval second = openInterval(100L);
+ when(mapper.selectReceivingCollectorSources()).thenReturn(List.of(source));
+ when(mapper.selectOpenCollectorException(10L, 20L, 8L, "S-01"))
+ .thenReturn(null, first, null, second);
+
+ service.reconcile(Set.of(), Instant.parse("2026-08-30T09:00:00Z"));
+ service.reconcile(Set.of("COL-1"), Instant.parse("2026-08-30T09:01:00Z"));
+ service.reconcile(Set.of(), Instant.parse("2026-08-30T09:02:00Z"));
+ service.reconcile(Set.of("COL-1"), Instant.parse("2026-08-30T09:03:00Z"));
+
+ verify(mapper, org.mockito.Mockito.times(2)).insertCollectorExceptionInterval(any());
+ verify(mapper).closeCollectorExceptionInterval(eq(99L), any(), any());
+ verify(mapper).closeCollectorExceptionInterval(eq(100L), any(), any());
+ }
+
+ private TTestCollectorExceptionInterval openInterval(Long intervalId)
+ {
+ TTestCollectorExceptionInterval interval = new TTestCollectorExceptionInterval();
+ interval.setIntervalId(intervalId);
+ interval.setIntervalStatus("OPEN");
+ return interval;
+ }
+
private TTestCollectorSource source(Long testId, Long relationId, Long collectorId,
String collectorCode, String channelCode)
{
--
Gitblit v1.7.1