From 2e7dbd705fc82e8db74b073e55af938d67d8c19f Mon Sep 17 00:00:00 2001
From: Junjie <fallin.jie@qq.com>
Date: 星期二, 17 三月 2026 09:05:49 +0800
Subject: [PATCH] #
---
src/main/java/com/zy/system/controller/DashboardController.java | 169 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 169 insertions(+), 0 deletions(-)
diff --git a/src/main/java/com/zy/system/controller/DashboardController.java b/src/main/java/com/zy/system/controller/DashboardController.java
index fa97e4d..de5cdc9 100644
--- a/src/main/java/com/zy/system/controller/DashboardController.java
+++ b/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("姝e父", 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("姝e父", 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;
}
--
Gitblit v1.9.1