yeg
2026-08-28 9fed155adefdb73dd349ff99a897f2d2da5ea03e
ruoyi-admin/src/main/java/com/ruoyi/config/RedisBtsSimulatorStateStore.java
@@ -1,12 +1,15 @@
package com.ruoyi.config;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.device.simulator.BtsSimulatorStateStore;
import com.ruoyi.device.model.DeviceWorkStatus;
/** 将开发模拟器完整状态写入 Redis,主状态不设置普通 TTL。 */
@Component
@@ -67,12 +70,19 @@
    {
        try
        {
            String json = stored.toString();
            JSONObject root = JSON.parseObject(json);
            // 通用 RedisTemplate 在可执行包中可能将泛型数组恢复为 JSONObject,必须在存储边界逐层重建。
            JSONObject root = jsonObject(stored);
            Integer version = root.getInteger("version");
            if (version == null || version != CURRENT_VERSION)
                throw new IllegalStateException("Unsupported BTS simulator state version: " + version);
            return JSON.parseObject(json, SimulatorState.class);
            List<DeviceState> devices = new ArrayList<>();
            requiredArray(root, "devices").forEach(item -> devices.add(deviceState(item)));
            List<CollectorState> collectors = new ArrayList<>();
            requiredArray(root, "collectors").forEach(item -> collectors.add(collectorState(item)));
            List<ChannelTombstone> tombstones = new ArrayList<>();
            requiredArray(root, "tombstones").forEach(item -> tombstones.add(channelTombstone(item)));
            return new SimulatorState(version, devices, collectors,
                    requiredInteger(root, "nextDeviceId"), requiredInteger(root, "nextCollectorId"), tombstones);
        }
        catch (IllegalStateException exception)
        {
@@ -83,4 +93,65 @@
            throw new IllegalStateException("Invalid BTS simulator state in Redis", exception);
        }
    }
    private JSONObject jsonObject(Object value)
    {
        if (value instanceof JSONObject object) return object;
        if (value instanceof String text)
        {
            Object parsed = JSON.parse(text);
            if (parsed instanceof String nested) parsed = JSON.parse(nested);
            if (parsed instanceof JSONObject object) return object;
            return JSON.parseObject(JSON.toJSONString(parsed));
        }
        return JSON.parseObject(JSON.toJSONString(value));
    }
    private JSONArray requiredArray(JSONObject object, String field)
    {
        JSONArray array = object.getJSONArray(field);
        if (array == null) throw new IllegalStateException("Missing BTS simulator state field: " + field);
        return array;
    }
    private int requiredInteger(JSONObject object, String field)
    {
        Integer value = object.getInteger(field);
        if (value == null) throw new IllegalStateException("Missing BTS simulator state field: " + field);
        return value;
    }
    private DeviceState deviceState(Object value)
    {
        JSONObject object = jsonObject(value);
        List<ChannelState> channels = new ArrayList<>();
        requiredArray(object, "channels").forEach(item -> channels.add(channelState(item)));
        return new DeviceState(requiredInteger(object, "deviceId"), object.getString("ip"),
                object.getBooleanValue("online"), channels);
    }
    private CollectorState collectorState(Object value)
    {
        JSONObject object = jsonObject(value);
        return new CollectorState(requiredInteger(object, "collectorId"), object.getString("deviceCode"),
                object.getString("ip"), object.getString("mac"), object.getString("name"),
                object.getString("manufacturer"), object.getString("model"),
                requiredInteger(object, "channelCount"), object.getBooleanValue("online"));
    }
    private ChannelState channelState(Object value)
    {
        JSONObject object = jsonObject(value);
        String workStatus = object.getString("workStatus");
        if (workStatus == null) throw new IllegalStateException("Missing BTS simulator state field: workStatus");
        return new ChannelState(requiredInteger(object, "channelId"), object.getBooleanValue("online"),
                DeviceWorkStatus.valueOf(workStatus));
    }
    private ChannelTombstone channelTombstone(Object value)
    {
        JSONObject object = jsonObject(value);
        return new ChannelTombstone(requiredInteger(object, "deviceId"), object.getString("ip"),
                requiredInteger(object, "channelId"), requiredInteger(object, "remainingDiscoveries"));
    }
}