feat: 添加获取最近一次设备快照的方法,增强设备状态解析逻辑,更新设备空闲状态配置返回值

This commit is contained in:
yahaozhang
2025-09-16 02:08:08 +08:00
parent b14573bb88
commit 75f116de8f
4 changed files with 69 additions and 2 deletions

View File

@@ -0,0 +1,52 @@
package com.gameplatform.server.controller.admin;
import com.gameplatform.server.device.Detection;
import com.gameplatform.server.device.DeviceStats;
import com.gameplatform.server.model.dto.device.DeviceStatusResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/admin/devices")
@Tag(name = "设备状态", description = "获取所有设备的实时状态")
public class DeviceStatusController {
private static final Logger log = LoggerFactory.getLogger(DeviceStatusController.class);
private final Detection detection;
private final DeviceStats deviceStats;
public DeviceStatusController(Detection detection, DeviceStats deviceStats) {
this.detection = detection;
this.deviceStats = deviceStats;
}
@GetMapping("/status")
@Operation(summary = "获取设备分组状态", description = "返回最近一次分组统计快照(含 categoryToDevices 与计数)。必要时会基于最新快照即时计算一次,不触发脚本刷新。")
public ResponseEntity<DeviceStats.Snapshot> getAllDeviceStatus() {
DeviceStats.Snapshot stats = deviceStats.getLastComputedSnapshot();
if (stats == null) {
// 优先使用检测缓存其次拉取一次带TTL并计算分组
DeviceStatusResponse latest = detection.getLastSnapshot();
if (latest == null) {
latest = detection.listAllDevices();
}
if (latest != null) {
stats = deviceStats.updateWithSnapshot(latest);
}
}
if (stats == null) {
log.warn("getAllDeviceStatus: 未获取到分组统计快照返回204");
return ResponseEntity.noContent().build();
}
return ResponseEntity.ok(stats);
}
}

View File

@@ -103,6 +103,13 @@ public class Detection {
return resp; return resp;
} }
/**
* 获取最近一次缓存的全量设备快照不触发刷新不受TTL约束
*/
public DeviceStatusResponse getLastSnapshot() {
return this.lastSnapshot;
}
/** /**
* 定时任务:全量拉取并交由 DeviceStats 更新内存分类与审计。 * 定时任务:全量拉取并交由 DeviceStats 更新内存分类与审计。
* 默认每 30 秒执行一次可通过配置覆盖detection.poll.cron 或 detection.poll.fixedDelayMs * 默认每 30 秒执行一次可通过配置覆盖detection.poll.cron 或 detection.poll.fixedDelayMs

View File

@@ -9,6 +9,7 @@ import com.gameplatform.server.mapper.agent.LinkTaskMapper;
import com.gameplatform.server.mapper.history.DeviceStatusTransitionMapper; import com.gameplatform.server.mapper.history.DeviceStatusTransitionMapper;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import com.gameplatform.server.service.admin.SystemConfigService;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.*; import java.util.*;
@@ -67,6 +68,7 @@ public class DeviceStats {
private final MemoryMachineCooldownService cooldownService; private final MemoryMachineCooldownService cooldownService;
private final DeviceStatusTransitionMapper transitionMapper; private final DeviceStatusTransitionMapper transitionMapper;
private final DeviceAllocationService deviceAllocationService; private final DeviceAllocationService deviceAllocationService;
private final SystemConfigService systemConfigService;
// 记录上一次统计时每台设备的分类结果,用于检测状态变更 // 记录上一次统计时每台设备的分类结果,用于检测状态变更
private final Map<String, Category> lastStatusByDevice = new ConcurrentHashMap<>(); private final Map<String, Category> lastStatusByDevice = new ConcurrentHashMap<>();
@@ -74,11 +76,13 @@ public class DeviceStats {
public DeviceStats(LinkTaskMapper linkTaskMapper, public DeviceStats(LinkTaskMapper linkTaskMapper,
MemoryMachineCooldownService cooldownService, MemoryMachineCooldownService cooldownService,
DeviceStatusTransitionMapper transitionMapper, DeviceStatusTransitionMapper transitionMapper,
DeviceAllocationService deviceAllocationService) { DeviceAllocationService deviceAllocationService,
SystemConfigService systemConfigService) {
this.linkTaskMapper = linkTaskMapper; this.linkTaskMapper = linkTaskMapper;
this.cooldownService = cooldownService; this.cooldownService = cooldownService;
this.transitionMapper = transitionMapper; this.transitionMapper = transitionMapper;
this.deviceAllocationService = deviceAllocationService; this.deviceAllocationService = deviceAllocationService;
this.systemConfigService = systemConfigService;
} }
/** /**
@@ -112,6 +116,7 @@ public class DeviceStats {
boolean usingTask = hasUsingTask(deviceId); boolean usingTask = hasUsingTask(deviceId);
boolean cooldown = cooldownService.isMachineInCooldown(deviceId); boolean cooldown = cooldownService.isMachineInCooldown(deviceId);
boolean numeric = isNumeric(v); boolean numeric = isNumeric(v);
String configuredIdle = systemConfigService.getDeviceIdleStatus();
// log.debug("设备[{}] 原始脚本值='{}' | LOGGED_IN={} USING={} COOLDOWN={} NUMERIC={}", // log.debug("设备[{}] 原始脚本值='{}' | LOGGED_IN={} USING={} COOLDOWN={} NUMERIC={}",
// deviceId, v, loggedIn, usingTask, cooldown, numeric); // deviceId, v, loggedIn, usingTask, cooldown, numeric);
@@ -128,6 +133,9 @@ public class DeviceStats {
} else if ("已打完".equals(v) || cooldown) { } else if ("已打完".equals(v) || cooldown) {
newCategory = Category.IDLE_COOLDOWN; newCategory = Category.IDLE_COOLDOWN;
reason = "已打完".equals(v) ? "脚本值=已打完" : "处于冷却服务中"; reason = "已打完".equals(v) ? "脚本值=已打完" : "处于冷却服务中";
} else if (v != null && configuredIdle != null && configuredIdle.equals(v)) {
newCategory = Category.IDLE_FREE;
reason = "脚本值=配置的空闲标识";
} else { } else {
newCategory = Category.RUNNING; newCategory = Category.RUNNING;
reason = "默认运行中/未知状态"; reason = "默认运行中/未知状态";

View File

@@ -110,7 +110,7 @@ public class SystemConfigService {
// 获取设备检测相关配置 // 获取设备检测相关配置
public String getDeviceIdleStatus() { public String getDeviceIdleStatus() {
return getConfigValue("device.idle_status", ""); return getConfigValue("device.idle_status", "");
} }
// 获取首次选区后链接过期时间(秒) // 获取首次选区后链接过期时间(秒)