From 4954d3978cf1967729a5a2d5b90f6baef18974da Mon Sep 17 00:00:00 2001
From: zhou zhou <3272660260@qq.com>
Date: 星期一, 23 三月 2026 09:35:10 +0800
Subject: [PATCH] #ai redis+页面优化
---
rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/AiMcpMountServiceImpl.java | 129 ++++++++++++++++++++++++++++++++++++++----
1 files changed, 115 insertions(+), 14 deletions(-)
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/AiMcpMountServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/AiMcpMountServiceImpl.java
index 87eb622..409c20f 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/AiMcpMountServiceImpl.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/AiMcpMountServiceImpl.java
@@ -35,7 +35,9 @@
private final BuiltinMcpToolRegistry builtinMcpToolRegistry;
private final McpMountRuntimeFactory mcpMountRuntimeFactory;
private final ObjectMapper objectMapper;
+ private final AiRedisSupport aiRedisSupport;
+ /** 鏌ヨ鏌愪釜绉熸埛涓嬪綋鍓嶅惎鐢ㄧ殑 MCP 鎸傝浇鍒楄〃銆� */
@Override
public List<AiMcpMount> listActiveMounts(Long tenantId) {
ensureTenantId(tenantId);
@@ -47,6 +49,7 @@
.orderByAsc(AiMcpMount::getId));
}
+ /** 淇濆瓨鍓嶆牎楠� MCP 鎸傝浇鑽夌锛屽苟琛ュ叏杩愯鏃堕粯璁ゅ�笺�� */
@Override
public void validateBeforeSave(AiMcpMount aiMcpMount, Long tenantId) {
ensureTenantId(tenantId);
@@ -55,6 +58,7 @@
ensureRequiredFields(aiMcpMount, tenantId);
}
+ /** 鏇存柊鍓嶆牎楠屽苟閿佸畾璁板綍鎵�灞炵鎴凤紝闃叉璺ㄧ鎴蜂慨鏀广�� */
@Override
public void validateBeforeUpdate(AiMcpMount aiMcpMount, Long tenantId) {
ensureTenantId(tenantId);
@@ -67,9 +71,18 @@
ensureRequiredFields(aiMcpMount, tenantId);
}
+ /**
+ * 棰勮褰撳墠鎸傝浇鏈�缁堜細鏆撮湶缁欐ā鍨嬬殑宸ュ叿鐩綍銆�
+ * 瀵瑰唴缃� MCP 浼氶澶栧悎骞舵不鐞嗙洰褰曚俊鎭紝瀵瑰閮� MCP 鍒欎互瀹為檯瑙f瀽缁撴灉涓哄噯銆�
+ */
@Override
public List<AiMcpToolPreviewDto> previewTools(Long mountId, Long userId, Long tenantId) {
AiMcpMount mount = requireMount(mountId, tenantId);
+ // 宸ュ叿鐩綍棰勮鍒濆鍖栨垚鏈珮锛屼絾鍙樺寲棰戠巼浣庯紝閫傚悎鍋氱鐞嗙鐭紦瀛樸��
+ List<AiMcpToolPreviewDto> cached = aiRedisSupport.getToolPreview(tenantId, mountId);
+ if (cached != null) {
+ return cached;
+ }
long startedAt = System.currentTimeMillis();
try (McpMountRuntimeFactory.McpMountRuntime runtime = mcpMountRuntimeFactory.create(List.of(mount), userId)) {
List<AiMcpToolPreviewDto> tools = buildToolPreviewDtos(runtime.getToolCallbacks(),
@@ -83,6 +96,7 @@
}
updateHealthStatus(mount.getId(), AiDefaults.MCP_HEALTH_HEALTHY,
"宸ュ叿瑙f瀽鎴愬姛锛屽叡 " + tools.size() + " 涓伐鍏�", System.currentTimeMillis() - startedAt);
+ aiRedisSupport.cacheToolPreview(tenantId, mountId, tools);
return tools;
} catch (CoolException e) {
throw e;
@@ -93,6 +107,7 @@
}
}
+ /** 瀵瑰凡淇濆瓨鐨勬寕杞藉仛鐪熷疄杩為�氭�ф祴璇曪紝骞舵妸缁撴灉鍥炲啓鍒拌繍琛屾�佸瓧娈点�� */
@Override
public AiMcpConnectivityTestDto testConnectivity(Long mountId, Long userId, Long tenantId) {
AiMcpMount mount = requireMount(mountId, tenantId);
@@ -103,12 +118,16 @@
String message = String.join("锛�", runtime.getErrors());
updateHealthStatus(mount.getId(), AiDefaults.MCP_HEALTH_UNHEALTHY, message, elapsedMs);
AiMcpMount latest = requireMount(mount.getId(), tenantId);
- return buildConnectivityDto(latest, message, elapsedMs, runtime.getToolCallbacks().length);
+ AiMcpConnectivityTestDto connectivity = buildConnectivityDto(latest, message, elapsedMs, runtime.getToolCallbacks().length);
+ aiRedisSupport.cacheConnectivity(tenantId, mountId, connectivity);
+ return connectivity;
}
String message = "杩為�氭�ф祴璇曟垚鍔燂紝瑙f瀽鍑� " + runtime.getToolCallbacks().length + " 涓伐鍏�";
updateHealthStatus(mount.getId(), AiDefaults.MCP_HEALTH_HEALTHY, message, elapsedMs);
AiMcpMount latest = requireMount(mount.getId(), tenantId);
- return buildConnectivityDto(latest, message, elapsedMs, runtime.getToolCallbacks().length);
+ AiMcpConnectivityTestDto connectivity = buildConnectivityDto(latest, message, elapsedMs, runtime.getToolCallbacks().length);
+ aiRedisSupport.cacheConnectivity(tenantId, mountId, connectivity);
+ return connectivity;
} catch (CoolException e) {
throw e;
} catch (Exception e) {
@@ -116,10 +135,59 @@
String message = "杩為�氭�ф祴璇曞け璐�: " + e.getMessage();
updateHealthStatus(mount.getId(), AiDefaults.MCP_HEALTH_UNHEALTHY, message, elapsedMs);
AiMcpMount latest = requireMount(mount.getId(), tenantId);
- return buildConnectivityDto(latest, message, elapsedMs, 0);
+ AiMcpConnectivityTestDto connectivity = buildConnectivityDto(latest, message, elapsedMs, 0);
+ aiRedisSupport.cacheConnectivity(tenantId, mountId, connectivity);
+ return connectivity;
}
}
+ /** 瀵硅〃鍗曢噷鐨勮崏绋块厤缃仛涓存椂杩為�氭�ф祴璇曪紝涓嶈惤搴撱�� */
+ @Override
+ public AiMcpConnectivityTestDto testDraftConnectivity(AiMcpMount mount, Long userId, Long tenantId) {
+ ensureTenantId(tenantId);
+ if (userId == null) {
+ throw new CoolException("褰撳墠鐧诲綍鐢ㄦ埛涓嶅瓨鍦�");
+ }
+ if (mount == null) {
+ throw new CoolException("MCP 鎸傝浇鍙傛暟涓嶈兘涓虹┖");
+ }
+ mount.setTenantId(tenantId);
+ fillDefaults(mount);
+ ensureRequiredFields(mount, tenantId);
+ long startedAt = System.currentTimeMillis();
+ try (McpMountRuntimeFactory.McpMountRuntime runtime = mcpMountRuntimeFactory.create(List.of(mount), userId)) {
+ long elapsedMs = System.currentTimeMillis() - startedAt;
+ if (!runtime.getErrors().isEmpty()) {
+ return AiMcpConnectivityTestDto.builder()
+ .mountId(mount.getId())
+ .mountName(mount.getName())
+ .healthStatus(AiDefaults.MCP_HEALTH_UNHEALTHY)
+ .message(String.join("锛�", runtime.getErrors()))
+ .initElapsedMs(elapsedMs)
+ .toolCount(runtime.getToolCallbacks().length)
+ .testedAt(new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()))
+ .build();
+ }
+ return AiMcpConnectivityTestDto.builder()
+ .mountId(mount.getId())
+ .mountName(mount.getName())
+ .healthStatus(AiDefaults.MCP_HEALTH_HEALTHY)
+ .message("鑽夌杩為�氭�ф祴璇曟垚鍔燂紝瑙f瀽鍑� " + runtime.getToolCallbacks().length + " 涓伐鍏�")
+ .initElapsedMs(elapsedMs)
+ .toolCount(runtime.getToolCallbacks().length)
+ .testedAt(new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()))
+ .build();
+ } catch (CoolException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new CoolException("鑽夌杩為�氭�ф祴璇曞け璐�: " + e.getMessage());
+ }
+ }
+
+ /**
+ * 鐩存帴鎵ц鏌愪竴涓伐鍏风殑娴嬭瘯璋冪敤銆�
+ * 璇ユ柟娉曚富瑕佹湇鍔′簬绠$悊绔殑鈥滃伐鍏锋祴璇曗�濋潰鏉匡紝涓嶅弬涓庢寮忓璇濋摼璺��
+ */
@Override
public AiMcpToolTestDto testTool(Long mountId, Long userId, Long tenantId, AiMcpToolTestRequest request) {
if (userId == null) {
@@ -172,7 +240,42 @@
}
}
+ @Override
+ public boolean save(AiMcpMount entity) {
+ boolean saved = super.save(entity);
+ if (saved && entity != null && entity.getTenantId() != null) {
+ aiRedisSupport.evictMcpMountCaches(entity.getTenantId(), entity.getId());
+ }
+ return saved;
+ }
+
+ @Override
+ public boolean updateById(AiMcpMount entity) {
+ boolean updated = super.updateById(entity);
+ if (updated && entity != null && entity.getTenantId() != null) {
+ aiRedisSupport.evictMcpMountCaches(entity.getTenantId(), entity.getId());
+ }
+ return updated;
+ }
+
+ @Override
+ public boolean removeByIds(java.util.Collection<?> list) {
+ java.util.List<java.io.Serializable> ids = list == null ? java.util.List.of() : list.stream()
+ .filter(java.util.Objects::nonNull)
+ .map(item -> (java.io.Serializable) item)
+ .toList();
+ java.util.List<AiMcpMount> records = this.listByIds(ids);
+ boolean removed = super.removeByIds(list);
+ if (removed) {
+ records.stream()
+ .filter(java.util.Objects::nonNull)
+ .forEach(item -> aiRedisSupport.evictMcpMountCaches(item.getTenantId(), item.getId()));
+ }
+ return removed;
+ }
+
private void fillDefaults(AiMcpMount aiMcpMount) {
+ /** 涓烘寕杞借崏绋胯ˉ榻愮粺涓�榛樿鍊硷紝淇濊瘉鍚庣画杩愯鏃朵唬鐮佷笉闇�瑕侀噸澶嶅垽鏂┖鍊笺�� */
if (!StringUtils.hasText(aiMcpMount.getTransportType())) {
aiMcpMount.setTransportType(AiDefaults.MCP_TRANSPORT_SSE_HTTP);
}
@@ -191,6 +294,10 @@
}
private void ensureRequiredFields(AiMcpMount aiMcpMount, Long tenantId) {
+ /**
+ * 鎸� transportType 鏍¢獙鎸傝浇蹇呭~椤广��
+ * 杩欓噷鎶娾�滃瓧娈靛悎娉曟�р�濆拰鈥滆法璁板綍鍐茬獊鈥濅竴璧锋敹鍙o紝閬垮厤鏍¢獙閫昏緫鍒嗘暎鍦� controller 灞傘��
+ */
if (!StringUtils.hasText(aiMcpMount.getName())) {
throw new CoolException("MCP 鎸傝浇鍚嶇О涓嶈兘涓虹┖");
}
@@ -215,6 +322,7 @@
}
private AiMcpMount requireMount(Long mountId, Long tenantId) {
+ /** 鎸夌鎴峰姞杞芥寕杞借褰曪紝涓嶅瓨鍦ㄧ洿鎺ユ姏閿欍�� */
ensureTenantId(tenantId);
if (mountId == null) {
throw new CoolException("MCP 鎸傝浇 ID 涓嶈兘涓虹┖");
@@ -231,6 +339,7 @@
}
private void ensureBuiltinConflictFree(AiMcpMount aiMcpMount, Long tenantId) {
+ /** 鏍¢獙鍚岀鎴蜂笅鏄惁瀛樺湪涓庡綋鍓嶅唴缃紪鐮佷簰鏂ョ殑鍚敤鎸傝浇銆� */
if (aiMcpMount.getStatus() == null || aiMcpMount.getStatus() != StatusType.ENABLE.val) {
return;
}
@@ -256,19 +365,10 @@
}
private List<String> resolveConflictCodes(String builtinCode) {
- List<String> codes = new ArrayList<>();
if (AiDefaults.MCP_BUILTIN_RSF_WMS.equals(builtinCode)) {
- codes.add(AiDefaults.MCP_BUILTIN_RSF_WMS_STOCK);
- codes.add(AiDefaults.MCP_BUILTIN_RSF_WMS_TASK);
- codes.add(AiDefaults.MCP_BUILTIN_RSF_WMS_BASE);
- return codes;
+ return List.of();
}
- if (AiDefaults.MCP_BUILTIN_RSF_WMS_STOCK.equals(builtinCode)
- || AiDefaults.MCP_BUILTIN_RSF_WMS_TASK.equals(builtinCode)
- || AiDefaults.MCP_BUILTIN_RSF_WMS_BASE.equals(builtinCode)) {
- codes.add(AiDefaults.MCP_BUILTIN_RSF_WMS);
- }
- return codes;
+ throw new CoolException("涓嶆敮鎸佺殑鍐呯疆 MCP 缂栫爜: " + builtinCode);
}
private void ensureTenantId(Long tenantId) {
@@ -278,6 +378,7 @@
}
private List<AiMcpToolPreviewDto> buildToolPreviewDtos(ToolCallback[] callbacks, List<AiMcpToolPreviewDto> governedCatalog) {
+ /** 鎶婂簳灞� ToolCallback 鍜屾不鐞嗙洰褰曚俊鎭嫾鎴愬墠绔渶瑕佺殑缁撴瀯鍖栧伐鍏峰崱鐗囨暟鎹�� */
List<AiMcpToolPreviewDto> tools = new ArrayList<>();
Map<String, AiMcpToolPreviewDto> catalogMap = new java.util.LinkedHashMap<>();
for (AiMcpToolPreviewDto item : governedCatalog) {
--
Gitblit v1.9.1