zhou zhou
19 小时以前 5e40dee0e0a4e4cff4a1aafca2444f61c39cbf32
rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/AiMcpMountServiceImpl.java
@@ -34,31 +34,39 @@
    private final ObjectMapper objectMapper;
    @Override
    public List<AiMcpMount> listActiveMounts() {
    public List<AiMcpMount> listActiveMounts(Long tenantId) {
        ensureTenantId(tenantId);
        return this.list(new LambdaQueryWrapper<AiMcpMount>()
                .eq(AiMcpMount::getTenantId, tenantId)
                .eq(AiMcpMount::getStatus, StatusType.ENABLE.val)
                .eq(AiMcpMount::getDeleted, 0)
                .orderByAsc(AiMcpMount::getSort)
                .orderByAsc(AiMcpMount::getId));
    }
    @Override
    public void validateBeforeSave(AiMcpMount aiMcpMount) {
    public void validateBeforeSave(AiMcpMount aiMcpMount, Long tenantId) {
        ensureTenantId(tenantId);
        aiMcpMount.setTenantId(tenantId);
        fillDefaults(aiMcpMount);
        ensureRequiredFields(aiMcpMount);
        ensureRequiredFields(aiMcpMount, tenantId);
    }
    @Override
    public void validateBeforeUpdate(AiMcpMount aiMcpMount) {
    public void validateBeforeUpdate(AiMcpMount aiMcpMount, Long tenantId) {
        ensureTenantId(tenantId);
        fillDefaults(aiMcpMount);
        if (aiMcpMount.getId() == null) {
            throw new CoolException("MCP 挂载 ID 不能为空");
        }
        ensureRequiredFields(aiMcpMount);
        AiMcpMount current = requireMount(aiMcpMount.getId(), tenantId);
        aiMcpMount.setTenantId(current.getTenantId());
        ensureRequiredFields(aiMcpMount, tenantId);
    }
    @Override
    public List<AiMcpToolPreviewDto> previewTools(Long mountId, Long userId, Long tenantId) {
        AiMcpMount mount = requireMount(mountId);
        AiMcpMount mount = requireMount(mountId, tenantId);
        try (McpMountRuntimeFactory.McpMountRuntime runtime = mcpMountRuntimeFactory.create(List.of(mount), userId)) {
            List<AiMcpToolPreviewDto> tools = new ArrayList<>();
            for (ToolCallback callback : runtime.getToolCallbacks()) {
@@ -98,7 +106,7 @@
        } catch (Exception e) {
            throw new CoolException("工具输入 JSON 格式错误: " + e.getMessage());
        }
        AiMcpMount mount = requireMount(mountId);
        AiMcpMount mount = requireMount(mountId, tenantId);
        try (McpMountRuntimeFactory.McpMountRuntime runtime = mcpMountRuntimeFactory.create(List.of(mount), userId)) {
            ToolCallback callback = Arrays.stream(runtime.getToolCallbacks())
                    .filter(item -> item != null && item.getToolDefinition() != null)
@@ -132,13 +140,13 @@
        }
    }
    private void ensureRequiredFields(AiMcpMount aiMcpMount) {
    private void ensureRequiredFields(AiMcpMount aiMcpMount, Long tenantId) {
        if (!StringUtils.hasText(aiMcpMount.getName())) {
            throw new CoolException("MCP 挂载名称不能为空");
        }
        if (AiDefaults.MCP_TRANSPORT_BUILTIN.equals(aiMcpMount.getTransportType())) {
            builtinMcpToolRegistry.validateBuiltinCode(aiMcpMount.getBuiltinCode());
            ensureBuiltinConflictFree(aiMcpMount);
            ensureBuiltinConflictFree(aiMcpMount, tenantId);
            return;
        }
        if (AiDefaults.MCP_TRANSPORT_SSE_HTTP.equals(aiMcpMount.getTransportType())) {
@@ -156,18 +164,23 @@
        throw new CoolException("不支持的 MCP 传输类型: " + aiMcpMount.getTransportType());
    }
    private AiMcpMount requireMount(Long mountId) {
    private AiMcpMount requireMount(Long mountId, Long tenantId) {
        ensureTenantId(tenantId);
        if (mountId == null) {
            throw new CoolException("MCP 挂载 ID 不能为空");
        }
        AiMcpMount mount = this.getById(mountId);
        if (mount == null || (mount.getDeleted() != null && mount.getDeleted() == 1)) {
        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) {
    private void ensureBuiltinConflictFree(AiMcpMount aiMcpMount, Long tenantId) {
        if (aiMcpMount.getStatus() == null || aiMcpMount.getStatus() != StatusType.ENABLE.val) {
            return;
        }
@@ -176,8 +189,10 @@
            return;
        }
        LambdaQueryWrapper<AiMcpMount> queryWrapper = new LambdaQueryWrapper<AiMcpMount>()
                .eq(AiMcpMount::getTenantId, tenantId)
                .eq(AiMcpMount::getTransportType, AiDefaults.MCP_TRANSPORT_BUILTIN)
                .eq(AiMcpMount::getStatus, StatusType.ENABLE.val)
                .eq(AiMcpMount::getDeleted, 0)
                .in(AiMcpMount::getBuiltinCode, conflictCodes);
        if (aiMcpMount.getId() != null) {
            queryWrapper.ne(AiMcpMount::getId, aiMcpMount.getId());
@@ -205,4 +220,10 @@
        }
        return codes;
    }
    private void ensureTenantId(Long tenantId) {
        if (tenantId == null) {
            throw new CoolException("当前租户不存在");
        }
    }
}