#
Junjie
昨天 2e7dbd705fc82e8db74b073e55af938d67d8c19f
src/main/java/com/zy/system/controller/DashboardController.java
@@ -25,6 +25,7 @@
import com.zy.core.thread.StationThread;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@@ -59,12 +60,24 @@
    private LlmCallLogService llmCallLogService;
    @Autowired
    private AiChatSessionMapper aiChatSessionMapper;
    @Autowired
    private DevicePingFileStorageService devicePingFileStorageService;
    @Value("${devicePingStorage.intervalMs:1000}")
    private int devicePingIntervalMs;
    @Value("${devicePingStorage.timeoutMs:800}")
    private int devicePingTimeoutMs;
    @Value("${devicePingStorage.probeCount:3}")
    private int devicePingProbeCount;
    @Value("${devicePingStorage.packetSize:-1}")
    private int devicePingPacketSize;
    @GetMapping("/summary/auth")
    @ManagerAuth(memo = "系统仪表盘统计")
    public R summary() {
        Map<String, Object> tasks = buildTaskStats();
        Map<String, Object> devices = buildDeviceStats();
        Map<String, Object> network = buildNetworkStats();
        Map<String, Object> ai = buildAiStats();
        Map<String, Object> overview = new LinkedHashMap<>();
@@ -82,6 +95,7 @@
        result.put("overview", overview);
        result.put("tasks", tasks);
        result.put("devices", devices);
        result.put("network", network);
        result.put("ai", ai);
        return R.ok(result);
    }
@@ -424,6 +438,74 @@
        return result;
    }
    @SuppressWarnings("unchecked")
    private Map<String, Object> buildNetworkStats() {
        Map<String, Object> result = new LinkedHashMap<>();
        Map<String, Object> overview = new LinkedHashMap<>();
        overview.put("totalDevices", 0L);
        overview.put("okDevices", 0L);
        overview.put("unstableDevices", 0L);
        overview.put("offlineDevices", 0L);
        overview.put("noDataDevices", 0L);
        overview.put("attentionDevices", 0L);
        overview.put("avgLatencyMs", null);
        overview.put("maxLatencyMs", null);
        Map<String, Object> samplingConfig = new LinkedHashMap<>();
        samplingConfig.put("intervalMs", devicePingIntervalMs);
        samplingConfig.put("timeoutMs", devicePingTimeoutMs);
        samplingConfig.put("probeCount", devicePingProbeCount);
        samplingConfig.put("packetSize", Math.max(devicePingPacketSize, -1));
        List<Map<String, Object>> statusStats = new ArrayList<>();
        statusStats.add(metric("正常", 0L));
        statusStats.add(metric("波动", 0L));
        statusStats.add(metric("超时/异常", 0L));
        statusStats.add(metric("暂无数据", 0L));
        List<Map<String, Object>> focusDevices = new ArrayList<>();
        try {
            Map<String, Object> overviewResult = devicePingFileStorageService.queryOverview(listPingConfigs());
            Map<String, Object> summary = overviewResult.get("summary") instanceof Map
                    ? (Map<String, Object>) overviewResult.get("summary")
                    : Collections.emptyMap();
            List<Map<String, Object>> devices = overviewResult.get("devices") instanceof List
                    ? (List<Map<String, Object>>) overviewResult.get("devices")
                    : Collections.emptyList();
            long okDevices = toLong(summary.get("okDevices"));
            long unstableDevices = toLong(summary.get("unstableDevices"));
            long offlineDevices = toLong(summary.get("offlineDevices"));
            long noDataDevices = toLong(summary.get("noDataDevices"));
            overview.put("totalDevices", toLong(summary.get("totalDevices")));
            overview.put("okDevices", okDevices);
            overview.put("unstableDevices", unstableDevices);
            overview.put("offlineDevices", offlineDevices);
            overview.put("noDataDevices", noDataDevices);
            overview.put("attentionDevices", unstableDevices + offlineDevices + noDataDevices);
            overview.put("avgLatencyMs", summary.get("avgLatencyMs"));
            overview.put("maxLatencyMs", summary.get("maxLatencyMs"));
            statusStats = new ArrayList<>();
            statusStats.add(metric("正常", okDevices));
            statusStats.add(metric("波动", unstableDevices));
            statusStats.add(metric("超时/异常", offlineDevices));
            statusStats.add(metric("暂无数据", noDataDevices));
            focusDevices = buildNetworkFocusDevices(devices);
        } catch (Exception e) {
            log.warn("dashboard network stats load failed: {}", safeMessage(e));
        }
        result.put("overview", overview);
        result.put("samplingConfig", samplingConfig);
        result.put("statusStats", statusStats);
        result.put("focusDevices", focusDevices);
        return result;
    }
    private List<DeviceConfig> listDeviceConfig(SlaveType type) {
        try {
            return deviceConfigService.list(new QueryWrapper<DeviceConfig>()
@@ -434,6 +516,93 @@
        }
    }
    private List<DeviceConfig> listPingConfigs() {
        try {
            return deviceConfigService.list(new QueryWrapper<DeviceConfig>()
                    .isNotNull("ip")
                    .ne("ip", "")
                    .orderBy(true, true, "device_type", "device_no"));
        } catch (Exception e) {
            log.warn("dashboard ping device config load failed: {}", safeMessage(e));
            return Collections.emptyList();
        }
    }
    private List<Map<String, Object>> buildNetworkFocusDevices(List<Map<String, Object>> devices) {
        if (devices == null || devices.isEmpty()) {
            return Collections.emptyList();
        }
        List<Map<String, Object>> candidates = new ArrayList<>();
        for (Map<String, Object> row : devices) {
            if (resolveNetworkFocusRank(row) < 3) {
                candidates.add(row);
            }
        }
        if (candidates.isEmpty()) {
            return Collections.emptyList();
        }
        candidates.sort((left, right) -> {
            int rankDiff = Integer.compare(resolveNetworkFocusRank(left), resolveNetworkFocusRank(right));
            if (rankDiff != 0) {
                return rankDiff;
            }
            int latencyDiff = Long.compare(toLong(right.get("avgLatencyMs")), toLong(left.get("avgLatencyMs")));
            if (latencyDiff != 0) {
                return latencyDiff;
            }
            return Long.compare(toLong(right.get("latestTime")), toLong(left.get("latestTime")));
        });
        List<Map<String, Object>> result = new ArrayList<>();
        for (Map<String, Object> item : candidates) {
            if (item == null) {
                continue;
            }
            Map<String, Object> focus = new LinkedHashMap<>();
            focus.put("name", toText(item.get("deviceType")) + "-" + toText(item.get("deviceNo")));
            focus.put("ip", toText(item.get("ip")));
            focus.put("statusText", defaultText(toText(item.get("statusText")), "未知"));
            focus.put("statusType", resolveNetworkStatusTagType(toText(item.get("status"))));
            focus.put("avgLatencyMs", item.get("avgLatencyMs"));
            focus.put("latestTimeLabel", defaultText(toText(item.get("latestTimeLabel")), "--"));
            focus.put("message", defaultText(toText(item.get("message")), "暂无额外说明"));
            result.add(focus);
            if (result.size() >= 4) {
                break;
            }
        }
        return result;
    }
    private int resolveNetworkFocusRank(Map<String, Object> row) {
        String status = row == null ? "" : toText(row.get("status"));
        if ("TIMEOUT".equalsIgnoreCase(status) || "ERROR".equalsIgnoreCase(status)) {
            return 0;
        }
        if ("UNSTABLE".equalsIgnoreCase(status)) {
            return 1;
        }
        if ("NO_DATA".equalsIgnoreCase(status)) {
            return 2;
        }
        return 3;
    }
    private String resolveNetworkStatusTagType(String status) {
        if ("TIMEOUT".equalsIgnoreCase(status) || "ERROR".equalsIgnoreCase(status)) {
            return "danger";
        }
        if ("UNSTABLE".equalsIgnoreCase(status)) {
            return "warning";
        }
        if ("OK".equalsIgnoreCase(status)) {
            return "success";
        }
        return "info";
    }
    private boolean isInboundTask(Long wrkSts) {
        return wrkSts != null && wrkSts > 0 && wrkSts < 100;
    }