yeg
2026-09-29 b78295e8da96c3e5e76befeef9582ce5273dbb74
ruoyi-admin/src/main/java/com/battery/business/runtime/RedisBtsSimulatorStateStore.java
@@ -12,6 +12,8 @@
import com.alibaba.fastjson2.JSONObject;
import com.battery.device.simulator.BtsSimulatorStateStore;
import com.battery.device.simulator.BtsSimulatorStateStore.BtsDeviceProfile;
import com.battery.device.simulator.BtsSimulatorStateStore.ChannelConfiguration;
import com.battery.device.simulator.BtsSimulatorStateStore.SimulatorPlanStep;
import com.battery.device.api.model.DeviceWorkStatus;
/** 将开发模拟器完整状态写入 Redis,主状态不设置普通 TTL。 */
@@ -30,6 +32,7 @@
        this.redisTemplate = redisTemplate;
    }
    /** 读取模拟器主状态,不存在时原子写入默认拓扑;并发初始化时以 Redis 中先写入的那份为准。 */
    @Override
    public SimulatorState loadOrInitialize(SimulatorState defaultState)
    {
@@ -42,12 +45,14 @@
        return restoreState(stored);
    }
    /** 整体覆盖模拟器主状态;该键不设普通 TTL。 */
    @Override
    public void save(SimulatorState state)
    {
        redisTemplate.opsForValue().set(STATE_KEY, JSON.toJSONString(state));
    }
    /** 读取短期保留的最近请求;键不存在时返回空列表。 */
    @Override
    public List<RecentRequest> loadRecentRequests()
    {
@@ -56,6 +61,7 @@
        return List.copyOf(JSON.parseArray(stored.toString(), RecentRequest.class));
    }
    /** 覆盖保存最近请求,整键按小时级 TTL 自动过期。 */
    @Override
    public void saveRecentRequests(List<RecentRequest> requests)
    {
@@ -63,6 +69,7 @@
                RECENT_REQUESTS_TTL_HOURS, TimeUnit.HOURS);
    }
    /** 人工重置:删除最近请求并写回默认主状态。 */
    @Override
    public void reset(SimulatorState defaultState)
    {
@@ -185,8 +192,27 @@
        JSONObject object = jsonObject(value);
        String workStatus = object.getString("workStatus");
        if (workStatus == null) throw new IllegalStateException("Missing BTS simulator state field: workStatus");
        JSONObject configuration = object.getJSONObject("configuration");
        return new ChannelState(requiredInteger(object, "channelId"), object.getBooleanValue("online"),
                DeviceWorkStatus.valueOf(workStatus), object.getObject("configuration", ChannelConfiguration.class));
                DeviceWorkStatus.valueOf(workStatus), channelConfiguration(configuration));
    }
    /** Redis 通用反序列化会把泛型 steps 恢复为 JSONObject,不能让 record 构造器直接强转。 */
    private ChannelConfiguration channelConfiguration(JSONObject object)
    {
        if (object == null) return null;
        JSONArray configuredSteps = requiredArray(object, "steps");
        List<SimulatorPlanStep> steps = new ArrayList<>();
        configuredSteps.forEach(item -> {
            JSONObject step = jsonObject(item);
            steps.add(new SimulatorPlanStep(step.getString("name"), step.getString("stepType"),
                    step.getDoubleValue("durationSeconds"), step.getDoubleValue("voltageV")));
        });
        return new ChannelConfiguration(requiredDecimal(object, "currentA"), requiredDecimal(object, "voltageV"),
                requiredDecimal(object, "capacityAh"), requiredDecimal(object, "energyWh"),
                requiredInteger(object, "cycleNo"), requiredInteger(object, "stepNo"),
                requiredInteger(object, "plannedCycleCount"), object.getLongValue("totalTimeSeconds"),
                object.getLongValue("relativeTimeSeconds"), steps);
    }
    private ChannelTombstone channelTombstone(Object value)