From 82624affb0251b75b62b35567d3eb260c06efe78 Mon Sep 17 00:00:00 2001
From: zhou zhou <3272660260@qq.com>
Date: 星期一, 23 三月 2026 12:48:07 +0800
Subject: [PATCH] #ai 代码优化

---
 rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/AiMcpMountServiceImpl.java |  284 ++++++++++++++++----------------------------------------
 1 files changed, 80 insertions(+), 204 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 3ef9423..8c96030 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
@@ -1,9 +1,7 @@
 package com.vincent.rsf.server.ai.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.fasterxml.jackson.databind.ObjectMapper;
 import com.vincent.rsf.framework.exception.CoolException;
 import com.vincent.rsf.server.ai.config.AiDefaults;
 import com.vincent.rsf.server.ai.dto.AiMcpConnectivityTestDto;
@@ -12,30 +10,30 @@
 import com.vincent.rsf.server.ai.dto.AiMcpToolTestRequest;
 import com.vincent.rsf.server.ai.entity.AiMcpMount;
 import com.vincent.rsf.server.ai.mapper.AiMcpMountMapper;
+import com.vincent.rsf.server.ai.service.impl.mcp.AiMcpAdminService;
+import com.vincent.rsf.server.ai.store.AiConfigCacheStore;
+import com.vincent.rsf.server.ai.store.AiConversationCacheStore;
+import com.vincent.rsf.server.ai.store.AiMcpCacheStore;
 import com.vincent.rsf.server.ai.service.AiMcpMountService;
 import com.vincent.rsf.server.ai.service.BuiltinMcpToolRegistry;
-import com.vincent.rsf.server.ai.service.McpMountRuntimeFactory;
 import com.vincent.rsf.server.system.enums.StatusType;
 import lombok.RequiredArgsConstructor;
-import org.springframework.ai.chat.model.ToolContext;
-import org.springframework.ai.tool.ToolCallback;
 import org.springframework.stereotype.Service;
 import org.springframework.util.StringUtils;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Date;
 import java.util.List;
-import java.util.Map;
 
 @Service("aiMcpMountService")
 @RequiredArgsConstructor
 public class AiMcpMountServiceImpl extends ServiceImpl<AiMcpMountMapper, AiMcpMount> implements AiMcpMountService {
 
     private final BuiltinMcpToolRegistry builtinMcpToolRegistry;
-    private final McpMountRuntimeFactory mcpMountRuntimeFactory;
-    private final ObjectMapper objectMapper;
+    private final AiMcpAdminService aiMcpAdminService;
+    private final AiMcpCacheStore aiMcpCacheStore;
+    private final AiConfigCacheStore aiConfigCacheStore;
+    private final AiConversationCacheStore aiConversationCacheStore;
 
+    /** 鏌ヨ鏌愪釜绉熸埛涓嬪綋鍓嶅惎鐢ㄧ殑 MCP 鎸傝浇鍒楄〃銆� */
     @Override
     public List<AiMcpMount> listActiveMounts(Long tenantId) {
         ensureTenantId(tenantId);
@@ -47,6 +45,7 @@
                 .orderByAsc(AiMcpMount::getId));
     }
 
+    /** 淇濆瓨鍓嶆牎楠� MCP 鎸傝浇鑽夌锛屽苟琛ュ叏杩愯鏃堕粯璁ゅ�笺�� */
     @Override
     public void validateBeforeSave(AiMcpMount aiMcpMount, Long tenantId) {
         ensureTenantId(tenantId);
@@ -55,6 +54,7 @@
         ensureRequiredFields(aiMcpMount, tenantId);
     }
 
+    /** 鏇存柊鍓嶆牎楠屽苟閿佸畾璁板綍鎵�灞炵鎴凤紝闃叉璺ㄧ鎴蜂慨鏀广�� */
     @Override
     public void validateBeforeUpdate(AiMcpMount aiMcpMount, Long tenantId) {
         ensureTenantId(tenantId);
@@ -62,64 +62,37 @@
         if (aiMcpMount.getId() == null) {
             throw new CoolException("MCP 鎸傝浇 ID 涓嶈兘涓虹┖");
         }
-        AiMcpMount current = requireMount(aiMcpMount.getId(), tenantId);
+        AiMcpMount current = aiMcpAdminService.requireMount(aiMcpMount.getId(), tenantId);
         aiMcpMount.setTenantId(current.getTenantId());
         ensureRequiredFields(aiMcpMount, tenantId);
     }
 
+    /**
+     * 棰勮褰撳墠鎸傝浇鏈�缁堜細鏆撮湶缁欐ā鍨嬬殑宸ュ叿鐩綍銆�
+     * 瀵瑰唴缃� MCP 浼氶澶栧悎骞舵不鐞嗙洰褰曚俊鎭紝瀵瑰閮� MCP 鍒欎互瀹為檯瑙f瀽缁撴灉涓哄噯銆�
+     */
     @Override
     public List<AiMcpToolPreviewDto> previewTools(Long mountId, Long userId, Long tenantId) {
-        AiMcpMount mount = requireMount(mountId, tenantId);
-        long startedAt = System.currentTimeMillis();
-        try (McpMountRuntimeFactory.McpMountRuntime runtime = mcpMountRuntimeFactory.create(List.of(mount), userId)) {
-            List<AiMcpToolPreviewDto> tools = buildToolPreviewDtos(runtime.getToolCallbacks(),
-                    AiDefaults.MCP_TRANSPORT_BUILTIN.equals(mount.getTransportType())
-                            ? builtinMcpToolRegistry.listBuiltinToolCatalog(mount.getBuiltinCode())
-                            : List.of());
-            if (!runtime.getErrors().isEmpty()) {
-                String message = String.join("锛�", runtime.getErrors());
-                updateHealthStatus(mount.getId(), AiDefaults.MCP_HEALTH_UNHEALTHY, message, System.currentTimeMillis() - startedAt);
-                throw new CoolException(message);
-            }
-            updateHealthStatus(mount.getId(), AiDefaults.MCP_HEALTH_HEALTHY,
-                    "宸ュ叿瑙f瀽鎴愬姛锛屽叡 " + tools.size() + " 涓伐鍏�", System.currentTimeMillis() - startedAt);
-            return tools;
-        } catch (CoolException e) {
-            throw e;
-        } catch (Exception e) {
-            updateHealthStatus(mount.getId(), AiDefaults.MCP_HEALTH_UNHEALTHY,
-                    "宸ュ叿瑙f瀽澶辫触: " + e.getMessage(), System.currentTimeMillis() - startedAt);
-            throw new CoolException("鑾峰彇宸ュ叿鍒楄〃澶辫触: " + e.getMessage());
+        AiMcpMount mount = aiMcpAdminService.requireMount(mountId, tenantId);
+        List<AiMcpToolPreviewDto> cached = aiMcpCacheStore.getToolPreview(tenantId, mountId);
+        if (cached != null) {
+            return cached;
         }
+        List<AiMcpToolPreviewDto> tools = aiMcpAdminService.previewTools(mount, userId);
+        aiMcpCacheStore.cacheToolPreview(tenantId, mountId, tools);
+        return tools;
     }
 
+    /** 瀵瑰凡淇濆瓨鐨勬寕杞藉仛鐪熷疄杩為�氭�ф祴璇曪紝骞舵妸缁撴灉鍥炲啓鍒拌繍琛屾�佸瓧娈点�� */
     @Override
     public AiMcpConnectivityTestDto testConnectivity(Long mountId, Long userId, Long tenantId) {
-        AiMcpMount mount = requireMount(mountId, tenantId);
-        long startedAt = System.currentTimeMillis();
-        try (McpMountRuntimeFactory.McpMountRuntime runtime = mcpMountRuntimeFactory.create(List.of(mount), userId)) {
-            long elapsedMs = System.currentTimeMillis() - startedAt;
-            if (!runtime.getErrors().isEmpty()) {
-                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);
-            }
-            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);
-        } catch (CoolException e) {
-            throw e;
-        } catch (Exception e) {
-            long elapsedMs = System.currentTimeMillis() - startedAt;
-            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);
-        }
+        AiMcpMount mount = aiMcpAdminService.requireMount(mountId, tenantId);
+        AiMcpConnectivityTestDto connectivity = aiMcpAdminService.testConnectivity(mount, userId, true);
+        aiMcpCacheStore.cacheConnectivity(tenantId, mountId, connectivity);
+        return connectivity;
     }
 
+    /** 瀵硅〃鍗曢噷鐨勮崏绋块厤缃仛涓存椂杩為�氭�ф祴璇曪紝涓嶈惤搴撱�� */
     @Override
     public AiMcpConnectivityTestDto testDraftConnectivity(AiMcpMount mount, Long userId, Long tenantId) {
         ensureTenantId(tenantId);
@@ -132,89 +105,55 @@
         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());
-        }
+        return aiMcpAdminService.testConnectivity(mount, userId, false);
+    }
+
+    /**
+     * 鐩存帴鎵ц鏌愪竴涓伐鍏风殑娴嬭瘯璋冪敤銆�
+     * 璇ユ柟娉曚富瑕佹湇鍔′簬绠$悊绔殑鈥滃伐鍏锋祴璇曗�濋潰鏉匡紝涓嶅弬涓庢寮忓璇濋摼璺��
+     */
+    @Override
+    public AiMcpToolTestDto testTool(Long mountId, Long userId, Long tenantId, AiMcpToolTestRequest request) {
+        AiMcpMount mount = aiMcpAdminService.requireMount(mountId, tenantId);
+        return aiMcpAdminService.testTool(mount, userId, tenantId, request);
     }
 
     @Override
-    public AiMcpToolTestDto testTool(Long mountId, Long userId, Long tenantId, AiMcpToolTestRequest request) {
-        if (userId == null) {
-            throw new CoolException("褰撳墠鐧诲綍鐢ㄦ埛涓嶅瓨鍦�");
+    public boolean save(AiMcpMount entity) {
+        boolean saved = super.save(entity);
+        if (saved && entity != null && entity.getTenantId() != null) {
+            evictMountRelatedCaches(entity.getTenantId(), entity.getId());
         }
-        if (tenantId == null) {
-            throw new CoolException("褰撳墠绉熸埛涓嶅瓨鍦�");
+        return saved;
+    }
+
+    @Override
+    public boolean updateById(AiMcpMount entity) {
+        boolean updated = super.updateById(entity);
+        if (updated && entity != null && entity.getTenantId() != null) {
+            evictMountRelatedCaches(entity.getTenantId(), entity.getId());
         }
-        if (request == null) {
-            throw new CoolException("宸ュ叿娴嬭瘯鍙傛暟涓嶈兘涓虹┖");
+        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 -> evictMountRelatedCaches(item.getTenantId(), item.getId()));
         }
-        if (!StringUtils.hasText(request.getToolName())) {
-            throw new CoolException("宸ュ叿鍚嶇О涓嶈兘涓虹┖");
-        }
-        if (!StringUtils.hasText(request.getInputJson())) {
-            throw new CoolException("宸ュ叿杈撳叆 JSON 涓嶈兘涓虹┖");
-        }
-        try {
-            objectMapper.readTree(request.getInputJson());
-        } catch (Exception e) {
-            throw new CoolException("宸ュ叿杈撳叆 JSON 鏍煎紡閿欒: " + e.getMessage());
-        }
-        AiMcpMount mount = requireMount(mountId, tenantId);
-        long startedAt = System.currentTimeMillis();
-        try (McpMountRuntimeFactory.McpMountRuntime runtime = mcpMountRuntimeFactory.create(List.of(mount), userId)) {
-            ToolCallback callback = Arrays.stream(runtime.getToolCallbacks())
-                    .filter(item -> item != null && item.getToolDefinition() != null)
-                    .filter(item -> request.getToolName().equals(item.getToolDefinition().name()))
-                    .findFirst()
-                    .orElseThrow(() -> new CoolException("鏈壘鍒拌娴嬭瘯鐨勫伐鍏�: " + request.getToolName()));
-            String output = callback.call(
-                    request.getInputJson(),
-                    new ToolContext(Map.of("userId", userId, "tenantId", tenantId, "mountId", mountId))
-            );
-            updateHealthStatus(mount.getId(), AiDefaults.MCP_HEALTH_HEALTHY,
-                    "宸ュ叿娴嬭瘯鎴愬姛: " + request.getToolName(), System.currentTimeMillis() - startedAt);
-            return AiMcpToolTestDto.builder()
-                    .toolName(request.getToolName())
-                    .inputJson(request.getInputJson())
-                    .output(output)
-                    .build();
-        } catch (CoolException e) {
-            updateHealthStatus(mount.getId(), AiDefaults.MCP_HEALTH_UNHEALTHY,
-                    "宸ュ叿娴嬭瘯澶辫触: " + e.getMessage(), System.currentTimeMillis() - startedAt);
-            throw e;
-        } catch (Exception e) {
-            updateHealthStatus(mount.getId(), AiDefaults.MCP_HEALTH_UNHEALTHY,
-                    "宸ュ叿娴嬭瘯澶辫触: " + e.getMessage(), System.currentTimeMillis() - startedAt);
-            throw new CoolException("宸ュ叿娴嬭瘯澶辫触: " + e.getMessage());
-        }
+        return removed;
     }
 
     private void fillDefaults(AiMcpMount aiMcpMount) {
+        /** 涓烘寕杞借崏绋胯ˉ榻愮粺涓�榛樿鍊硷紝淇濊瘉鍚庣画杩愯鏃朵唬鐮佷笉闇�瑕侀噸澶嶅垽鏂┖鍊笺�� */
         if (!StringUtils.hasText(aiMcpMount.getTransportType())) {
             aiMcpMount.setTransportType(AiDefaults.MCP_TRANSPORT_SSE_HTTP);
         }
@@ -233,6 +172,10 @@
     }
 
     private void ensureRequiredFields(AiMcpMount aiMcpMount, Long tenantId) {
+        /**
+         * 鎸� transportType 鏍¢獙鎸傝浇蹇呭~椤广��
+         * 杩欓噷鎶娾�滃瓧娈靛悎娉曟�р�濆拰鈥滆法璁板綍鍐茬獊鈥濅竴璧锋敹鍙o紝閬垮厤鏍¢獙閫昏緫鍒嗘暎鍦� controller 灞傘��
+         */
         if (!StringUtils.hasText(aiMcpMount.getName())) {
             throw new CoolException("MCP 鎸傝浇鍚嶇О涓嶈兘涓虹┖");
         }
@@ -256,23 +199,8 @@
         throw new CoolException("涓嶆敮鎸佺殑 MCP 浼犺緭绫诲瀷: " + aiMcpMount.getTransportType());
     }
 
-    private AiMcpMount requireMount(Long mountId, Long tenantId) {
-        ensureTenantId(tenantId);
-        if (mountId == null) {
-            throw new CoolException("MCP 鎸傝浇 ID 涓嶈兘涓虹┖");
-        }
-        AiMcpMount mount = this.getOne(new LambdaQueryWrapper<AiMcpMount>()
-                .eq(AiMcpMount::getId, mountId)
-                .eq(AiMcpMount::getTenantId, tenantId)
-                .eq(AiMcpMount::getDeleted, 0)
-                .last("limit 1"));
-        if (mount == null) {
-            throw new CoolException("MCP 鎸傝浇涓嶅瓨鍦�");
-        }
-        return mount;
-    }
-
     private void ensureBuiltinConflictFree(AiMcpMount aiMcpMount, Long tenantId) {
+        /** 鏍¢獙鍚岀鎴蜂笅鏄惁瀛樺湪涓庡綋鍓嶅唴缃紪鐮佷簰鏂ョ殑鍚敤鎸傝浇銆� */
         if (aiMcpMount.getStatus() == null || aiMcpMount.getStatus() != StatusType.ENABLE.val) {
             return;
         }
@@ -298,19 +226,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) {
@@ -319,52 +238,9 @@
         }
     }
 
-    private List<AiMcpToolPreviewDto> buildToolPreviewDtos(ToolCallback[] callbacks, List<AiMcpToolPreviewDto> governedCatalog) {
-        List<AiMcpToolPreviewDto> tools = new ArrayList<>();
-        Map<String, AiMcpToolPreviewDto> catalogMap = new java.util.LinkedHashMap<>();
-        for (AiMcpToolPreviewDto item : governedCatalog) {
-            if (item == null || !StringUtils.hasText(item.getName())) {
-                continue;
-            }
-            catalogMap.put(item.getName(), item);
-        }
-        for (ToolCallback callback : callbacks) {
-            if (callback == null || callback.getToolDefinition() == null) {
-                continue;
-            }
-            AiMcpToolPreviewDto governedItem = catalogMap.get(callback.getToolDefinition().name());
-            tools.add(AiMcpToolPreviewDto.builder()
-                    .name(callback.getToolDefinition().name())
-                    .description(callback.getToolDefinition().description())
-                    .inputSchema(callback.getToolDefinition().inputSchema())
-                    .returnDirect(callback.getToolMetadata() == null ? null : callback.getToolMetadata().returnDirect())
-                    .toolGroup(governedItem == null ? null : governedItem.getToolGroup())
-                    .toolPurpose(governedItem == null ? null : governedItem.getToolPurpose())
-                    .queryBoundary(governedItem == null ? null : governedItem.getQueryBoundary())
-                    .exampleQuestions(governedItem == null ? List.of() : governedItem.getExampleQuestions())
-                    .build());
-        }
-        return tools;
-    }
-
-    private void updateHealthStatus(Long mountId, String healthStatus, String message, Long initElapsedMs) {
-        this.update(new LambdaUpdateWrapper<AiMcpMount>()
-                .eq(AiMcpMount::getId, mountId)
-                .set(AiMcpMount::getHealthStatus, healthStatus)
-                .set(AiMcpMount::getLastTestTime, new Date())
-                .set(AiMcpMount::getLastTestMessage, message)
-                .set(AiMcpMount::getLastInitElapsedMs, initElapsedMs));
-    }
-
-    private AiMcpConnectivityTestDto buildConnectivityDto(AiMcpMount mount, String message, Long initElapsedMs, Integer toolCount) {
-        return AiMcpConnectivityTestDto.builder()
-                .mountId(mount.getId())
-                .mountName(mount.getName())
-                .healthStatus(mount.getHealthStatus())
-                .message(message)
-                .initElapsedMs(initElapsedMs)
-                .toolCount(toolCount)
-                .testedAt(mount.getLastTestTime$())
-                .build();
+    private void evictMountRelatedCaches(Long tenantId, Long mountId) {
+        aiMcpCacheStore.evictMcpMountCaches(tenantId, mountId);
+        aiConfigCacheStore.evictTenantConfigCaches(tenantId);
+        aiConversationCacheStore.evictTenantRuntimeCaches(tenantId);
     }
 }

--
Gitblit v1.9.1