From a5487f4ce3594611eaffed5ed14bb2ec6b88adf0 Mon Sep 17 00:00:00 2001
From: yeg <1347747024@qq.com>
Date: 星期六, 05 九月 2026 11:05:24 +0800
Subject: [PATCH] 整理Ticket08验收后注释

---
 battery-device-api/src/main/java/com/battery/device/api/TestDataObservationAdapter.java    |    5 +++++
 ruoyi-admin/src/main/resources/db/migration-final/V3__test_data_persistence.sql            |    2 ++
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TestDataReceptionServiceImpl.java |    2 ++
 3 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/battery-device-api/src/main/java/com/battery/device/api/TestDataObservationAdapter.java b/battery-device-api/src/main/java/com/battery/device/api/TestDataObservationAdapter.java
index 849ad5a..cee3010 100644
--- a/battery-device-api/src/main/java/com/battery/device/api/TestDataObservationAdapter.java
+++ b/battery-device-api/src/main/java/com/battery/device/api/TestDataObservationAdapter.java
@@ -9,14 +9,19 @@
 /** 供业务持久化使用的厂商无关测试数据观测扩展。 */
 public interface TestDataObservationAdapter extends DeviceObservationAdapter
 {
+    /** 返回指定检测柜通道最近一次实时观测;没有成功观测时返回空值。 */
     CabinetRealtime latestCabinet(ChannelIdentity channel);
 
+    /** 返回采集器独立实时快照;不得通过历史下载补采。 */
     CollectorRealtime latestCollector(long collectorId);
 
+    /** 返回设备直接提供的工步统计,不从实时采样推导。 */
     List<StepRecord> stepRecords(ChannelIdentity channel);
 
+    /** 返回设备直接提供的循环统计,不补齐设备未返回的记录。 */
     List<CycleRecord> cycleRecords(ChannelIdentity channel);
 
+    /** 返回适配器定义的实时持久化槽位间隔。 */
     long persistenceIntervalMillis(ChannelIdentity channel);
 
     record CabinetRealtime(long sequenceId, Instant deviceTime, double currentA, double voltageV,
diff --git a/ruoyi-admin/src/main/resources/db/migration-final/V3__test_data_persistence.sql b/ruoyi-admin/src/main/resources/db/migration-final/V3__test_data_persistence.sql
index 9170246..e45ea75 100644
--- a/ruoyi-admin/src/main/resources/db/migration-final/V3__test_data_persistence.sql
+++ b/ruoyi-admin/src/main/resources/db/migration-final/V3__test_data_persistence.sql
@@ -1,3 +1,4 @@
+-- Ticket08:补齐三类测试事实的绑定、接收时间、来源编号和幂等键;原始事实只追加不覆盖。
 ALTER TABLE t_test_realtime_record
     ADD COLUMN source_identity VARCHAR(256) NULL AFTER adapter_code,
     ADD COLUMN source_record_id VARCHAR(128) NULL AFTER source_identity;
@@ -35,6 +36,7 @@
     MODIFY COLUMN dedupe_key VARCHAR(512) NOT NULL,
     MODIFY COLUMN server_received_at_utc DATETIME(3) NOT NULL,
     DROP INDEX uk_step_identity,
+    -- 前缀索引控制 InnoDB 索引长度,同时保留来源身份和幂等键的稳定区分。
     ADD UNIQUE KEY uk_step_dedupe (test_battery_id, source_identity(128), dedupe_key(128)),
     ADD KEY idx_step_binding_time (binding_id, server_received_at_utc);
 
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TestDataReceptionServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TestDataReceptionServiceImpl.java
index 7aa0abf..8edeefb 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TestDataReceptionServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TestDataReceptionServiceImpl.java
@@ -100,6 +100,7 @@
 
     private void saveRealtime(TTest test, TTestBattery battery)
     {
+        // 柜端和采集器端分别判断成功;同一槽位只写一行,失败来源的身份、时间和指标保持为空。
         if (adapter == null) return;
         TTestChannelBinding binding = battery.getBinding(); if (binding == null || binding.getDevid() == null || binding.getChlid() == null) return;
         Instant now = clock.instant(); long interval = persistenceInterval(binding); String key = test.getTestId() + ":" + battery.getTestBatteryId();
@@ -141,6 +142,7 @@
 
     private void saveDeviceAggregates(TTest test, TTestBattery battery)
     {
+        // 工步、循环只接受设备直接返回的统计记录,并以来源编号或明确的时间组合执行幂等。
         if (adapter == null) return; TTestChannelBinding binding = battery.getBinding(); if (binding == null || binding.getDevid() == null || binding.getChlid() == null) return;
         ChannelIdentity channel = new ChannelIdentity(binding.getAdapterCode(), binding.getDevtype(), binding.getDevid(), binding.getSubdevid(), binding.getChlid());
         List<StepRecord> steps; List<CycleRecord> cycles; try { steps = adapter.stepRecords(channel); cycles = adapter.cycleRecords(channel); } catch (RuntimeException ex) { return; }

--
Gitblit v1.7.1