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