From bcabde8bfb8f16671fa5937e62668f99210e0720 Mon Sep 17 00:00:00 2001
From: Junjie <fallin.jie@qq.com>
Date: 星期四, 30 四月 2026 08:56:45 +0800
Subject: [PATCH] #Agent自动调参
---
src/main/java/com/zy/system/controller/DashboardController.java | 201 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 201 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..989f8c7 100644
--- a/src/main/java/com/zy/system/controller/DashboardController.java
+++ b/src/main/java/com/zy/system/controller/DashboardController.java
@@ -3,10 +3,13 @@
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.core.annotations.ManagerAuth;
import com.core.common.R;
+import com.zy.ai.entity.AiAutoTuneJob;
import com.zy.ai.entity.AiChatSession;
import com.zy.ai.entity.LlmCallLog;
import com.zy.ai.entity.LlmRouteConfig;
+import com.zy.ai.enums.AiPromptScene;
import com.zy.ai.mapper.AiChatSessionMapper;
+import com.zy.ai.service.AiAutoTuneJobService;
import com.zy.ai.service.LlmCallLogService;
import com.zy.ai.service.LlmRouteConfigService;
import com.zy.asrs.entity.*;
@@ -25,6 +28,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;
@@ -58,13 +62,27 @@
@Autowired
private LlmCallLogService llmCallLogService;
@Autowired
+ private AiAutoTuneJobService aiAutoTuneJobService;
+ @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 +100,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);
}
@@ -313,6 +332,9 @@
long completionTokenTotal = 0L;
long askCount = 0L;
long sessionCount = 0L;
+ long autoTunePromptTokenTotal = 0L;
+ long autoTuneCompletionTokenTotal = 0L;
+ long autoTuneTokenTotal = 0L;
try {
List<AiChatSession> sessions = aiChatSessionMapper.selectList(new QueryWrapper<AiChatSession>()
.select("id", "sum_prompt_tokens", "sum_completion_tokens", "sum_total_tokens", "ask_count"));
@@ -327,6 +349,27 @@
}
} catch (Exception e) {
log.warn("dashboard ai session stats load failed: {}", safeMessage(e));
+ }
+
+ try {
+ List<Map<String, Object>> autoTuneRows = aiAutoTuneJobService.listMaps(new QueryWrapper<AiAutoTuneJob>()
+ .select("COALESCE(SUM(prompt_tokens), 0) AS prompt_token_total",
+ "COALESCE(SUM(completion_tokens), 0) AS completion_token_total",
+ "COALESCE(SUM(total_tokens), 0) AS token_total")
+ .eq("prompt_scene_code", AiPromptScene.AUTO_TUNE_DISPATCH.getCode()));
+ Map<String, Object> autoTuneRow = autoTuneRows == null || autoTuneRows.isEmpty()
+ ? Collections.emptyMap()
+ : autoTuneRows.get(0);
+ autoTunePromptTokenTotal = toLong(autoTuneRow.get("prompt_token_total"));
+ autoTuneCompletionTokenTotal = toLong(autoTuneRow.get("completion_token_total"));
+ autoTuneTokenTotal = toLong(autoTuneRow.get("token_total"));
+
+ // Agent 鑷姩璋冨弬涓嶇敓鎴� sys_ai_chat_session锛屼細鍗曠嫭钀藉埌 sys_ai_auto_tune_job銆�
+ promptTokenTotal += autoTunePromptTokenTotal;
+ completionTokenTotal += autoTuneCompletionTokenTotal;
+ tokenTotal += autoTuneTokenTotal;
+ } catch (Exception e) {
+ log.warn("dashboard ai auto tune token stats load failed: {}", safeMessage(e));
}
List<LlmRouteConfig> routes = Collections.emptyList();
@@ -401,6 +444,9 @@
overview.put("tokenTotal", tokenTotal);
overview.put("promptTokenTotal", promptTokenTotal);
overview.put("completionTokenTotal", completionTokenTotal);
+ overview.put("autoTuneTokenTotal", autoTuneTokenTotal);
+ overview.put("autoTunePromptTokenTotal", autoTunePromptTokenTotal);
+ overview.put("autoTuneCompletionTokenTotal", autoTuneCompletionTokenTotal);
overview.put("askCount", askCount);
overview.put("sessionCount", sessionCount);
overview.put("routeTotal", routeTotal);
@@ -424,6 +470,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 +548,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