From 6c38637d89f346a660618558451f2dd7286dc7a5 Mon Sep 17 00:00:00 2001
From: yeg <1347747024@qq.com>
Date: 星期一, 31 八月 2026 22:51:54 +0800
Subject: [PATCH] 补齐检测柜模拟器完整 Excel 数据生命周期

---
 ruoyi-admin/src/main/java/com/ruoyi/config/RedisBtsSimulatorStateStore.java |   64 +++++++++++++++++++++++++++++++-
 1 files changed, 62 insertions(+), 2 deletions(-)

diff --git a/ruoyi-admin/src/main/java/com/ruoyi/config/RedisBtsSimulatorStateStore.java b/ruoyi-admin/src/main/java/com/ruoyi/config/RedisBtsSimulatorStateStore.java
index cae53ec..c78da1d 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/config/RedisBtsSimulatorStateStore.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/config/RedisBtsSimulatorStateStore.java
@@ -17,6 +17,7 @@
 import com.ruoyi.device.simulator.BtsSimulatorStateStore.BtsDeviceProfile;
 import com.ruoyi.device.simulator.BtsSimulatorStateStore.BtsHistoryBatch;
 import com.ruoyi.device.simulator.BtsSimulatorStateStore.BtsHistoryRecord;
+import com.ruoyi.device.simulator.BtsSimulatorStateStore.BtsPlaybackState;
 import com.ruoyi.device.model.DeviceWorkStatus;
 
 /** 将开发模拟器完整状态写入 Redis,主状态不设置普通 TTL。 */
@@ -27,8 +28,10 @@
     static final String RECENT_REQUESTS_KEY = "dev:bts-simulator:recent-requests:v1";
     static final String HISTORY_KEYS_KEY = "dev:bts-simulator:collector-history-keys:v1";
     static final String HISTORY_KEY_PREFIX = "dev:bts-simulator:collector-history:v1:";
-    static final String BTS_HISTORY_KEYS_KEY = "dev:bts-simulator:bts-history-keys:v1";
-    static final String BTS_HISTORY_KEY_PREFIX = "dev:bts-simulator:bts-history:v1:";
+    // Ticket21 fixture 变更后切换独立 key 版本,避免把旧的 3 循环演示历史恢复到新时间轴。
+    static final String BTS_HISTORY_KEYS_KEY = "dev:bts-simulator:bts-history-keys:v2";
+    static final String BTS_HISTORY_KEY_PREFIX = "dev:bts-simulator:bts-history:v2:";
+    static final String BTS_PLAYBACK_KEY_PREFIX = "dev:bts-simulator:bts-playback:v2:";
     private static final long RECENT_REQUESTS_TTL_HOURS = 1;
 
     private final RedisTemplate<Object, Object> redisTemplate;
@@ -210,6 +213,60 @@
     }
 
     @Override
+    public BtsPlaybackState loadBtsPlaybackState(String historyKey)
+    {
+        Object value = redisTemplate.opsForValue().get(BTS_PLAYBACK_KEY_PREFIX + historyKey);
+        return value == null ? null : JSON.parseObject(value.toString(), BtsPlaybackState.class);
+    }
+
+    @Override
+    public void saveBtsPlaybackState(String historyKey, BtsPlaybackState playback)
+    {
+        redisTemplate.opsForValue().set(BTS_PLAYBACK_KEY_PREFIX + historyKey, JSON.toJSONString(playback));
+    }
+
+    @Override
+    public void deleteBtsPlaybackState(String historyKey)
+    {
+        redisTemplate.delete(BTS_PLAYBACK_KEY_PREFIX + historyKey);
+    }
+
+    @Override
+    public void deleteBtsHistory(String historyKey)
+    {
+        String key = BTS_HISTORY_KEY_PREFIX + historyKey;
+        redisTemplate.delete(key);
+        redisTemplate.opsForSet().remove(BTS_HISTORY_KEYS_KEY, key);
+    }
+
+    @Override
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    public void saveBtsPlaybackAndAppendHistory(String historyKey, BtsPlaybackState playback,
+            List<BtsHistoryRecord> records)
+    {
+        List<Object> results = redisTemplate.execute(new SessionCallback<List<Object>>()
+        {
+            @Override
+            public <K, V> List<Object> execute(RedisOperations<K, V> operations)
+            {
+                RedisOperations<Object, Object> typed = (RedisOperations) operations;
+                typed.multi();
+                String key = BTS_HISTORY_KEY_PREFIX + historyKey;
+                if (!records.isEmpty())
+                {
+                    typed.opsForList().rightPushAll(key, new ArrayList<>(records.stream()
+                            .map(JSON::toJSONString).toList()));
+                    typed.opsForList().trim(key, -MAX_HISTORY_RECORDS, -1);
+                    typed.opsForSet().add(BTS_HISTORY_KEYS_KEY, key);
+                }
+                typed.opsForValue().set(BTS_PLAYBACK_KEY_PREFIX + historyKey, JSON.toJSONString(playback));
+                return typed.exec();
+            }
+        });
+        if (results == null) throw new IllegalStateException("BTS simulator playback transaction failed in Redis");
+    }
+
+    @Override
     @SuppressWarnings({ "rawtypes", "unchecked" })
     public void saveAndDeleteCollectorHistory(SimulatorState state, String collectorCode)
     {
@@ -255,6 +312,9 @@
         Set<Object> btsHistoryKeys = redisTemplate.opsForSet().members(BTS_HISTORY_KEYS_KEY);
         if (btsHistoryKeys != null && !btsHistoryKeys.isEmpty()) redisTemplate.delete(btsHistoryKeys);
         redisTemplate.delete(BTS_HISTORY_KEYS_KEY);
+        // 播放状态按通道独立保存,重置演示时必须一并清理。
+        Set<Object> playbackKeys = redisTemplate.keys(BTS_PLAYBACK_KEY_PREFIX + "*");
+        if (playbackKeys != null && !playbackKeys.isEmpty()) redisTemplate.delete(playbackKeys);
         redisTemplate.delete(RECENT_REQUESTS_KEY);
         save(defaultState);
     }

--
Gitblit v1.7.1