This commit is contained in:
duanfuxiang 2025-06-12 16:08:05 +08:00
parent 2f34794a3c
commit d16207e3c5
4 changed files with 78 additions and 19 deletions

View File

@ -239,6 +239,31 @@ export default {
searchOrEnterModelName: 'Search or enter model name...',
enterCustomModelName: 'Enter custom model name',
custom: 'Custom: ',
testConnection: {
testApiConnection: 'Test API Connection',
testingConnection: 'Testing connection...',
connectionSuccess: 'Connection test successful',
connectionFailed: 'Connection test failed',
notSupported: 'Testing {provider} API connection is not supported',
invalidApiKey: 'Invalid or missing API key',
invalidBaseUrl: 'Invalid base URL configuration',
requestTimeout: 'Request timeout, please check network connection',
networkError: 'Network connection failed',
unauthorizedError: 'API key authorization failed',
forbiddenError: 'Access denied, please check API key permissions',
rateLimitError: 'Rate limit exceeded, please try again later',
serverError: 'Internal server error',
noDefaultModel: 'No default model available for {provider}',
invalidResponse: 'Invalid response format',
// UI text
showApiKey: 'Show API Key',
hideApiKey: 'Hide API Key',
testConnectionTooltip: 'Test API connection',
testing: 'Testing',
success: 'Success',
failed: 'Failed',
test: 'Test',
},
},
// Model Parameters Section

View File

@ -240,6 +240,31 @@ export default {
searchOrEnterModelName: '搜索或输入模型名称...',
enterCustomModelName: '输入自定义模型名称',
custom: '自定义: ',
testConnection: {
testApiConnection: '测试 API 连接',
testingConnection: '正在测试连接...',
connectionSuccess: '连接测试成功',
connectionFailed: '连接测试失败',
notSupported: '不支持测试 {provider} 的 API 连接',
invalidApiKey: 'API Key 无效或缺失',
invalidBaseUrl: '基础 URL 设置错误',
requestTimeout: '请求超时,请检查网络连接',
networkError: '网络连接失败',
unauthorizedError: 'API Key 授权失败',
forbiddenError: '访问被拒绝,请检查 API Key 权限',
rateLimitError: '请求频率过高,请稍后重试',
serverError: '服务器内部错误',
noDefaultModel: '{provider} 没有可用的默认模型',
invalidResponse: '响应格式无效',
// UI 文本
showApiKey: '显示 API Key',
hideApiKey: '隐藏 API Key',
testConnectionTooltip: '测试 API 连接',
testing: '测试中',
success: '成功',
failed: '失败',
test: '测试',
},
},
// 模型参数部分

View File

@ -1,5 +1,7 @@
import React, { useEffect, useState } from "react";
import { t } from '../../lang/helpers';
export type DropdownComponentProps = {
name: string;
description?: string;
@ -310,7 +312,7 @@ export const ApiKeyComponent: React.FC<ApiKeyComponentProps> = ({
type="button"
className="infio-api-key-toggle"
onClick={toggleVisibility}
title={isVisible ? "隐藏API Key" : "显示API Key"}
title={isVisible ? t("settings.ModelProvider.testConnection.hideApiKey") : t("settings.ModelProvider.testConnection.showApiKey")}
>
{isVisible ? (
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
@ -332,19 +334,19 @@ export const ApiKeyComponent: React.FC<ApiKeyComponentProps> = ({
className={`infio-api-key-test ${isTestingConnection ? 'testing' : ''} ${testResult ? testResult : ''}`}
onClick={handleTest}
disabled={isTestingConnection || !localValue.trim()}
title="测试API连通性"
title={t("settings.ModelProvider.testConnection.testConnectionTooltip")}
>
{isTestingConnection ? (
<>
<div className="loading-spinner"></div>
<span></span>
<span>{t("settings.ModelProvider.testConnection.testing")}</span>
</>
) : testResult === 'success' ? (
<>
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
<polyline points="20,6 9,17 4,12"></polyline>
</svg>
<span></span>
<span>{t("settings.ModelProvider.testConnection.success")}</span>
</>
) : testResult === 'error' ? (
<>
@ -353,7 +355,7 @@ export const ApiKeyComponent: React.FC<ApiKeyComponentProps> = ({
<line x1="15" y1="9" x2="9" y2="15"></line>
<line x1="9" y1="9" x2="15" y2="15"></line>
</svg>
<span></span>
<span>{t("settings.ModelProvider.testConnection.failed")}</span>
</>
) : (
<>
@ -362,7 +364,7 @@ export const ApiKeyComponent: React.FC<ApiKeyComponentProps> = ({
<path d="M20.2 20.2c2.04-2.03.02-7.36-4.5-11.9-4.54-4.52-9.87-6.54-11.9-4.5-2.04 2.03-.02 7.36 4.5 11.9 4.54 4.52 9.87 6.54 11.9 4.5z"></path>
<path d="M15.7 15.7c4.52-4.54 6.54-9.87 4.5-11.9-2.03-2.04-7.36-.02-11.9 4.5-4.52 4.54-6.54 9.87-4.5 11.9 2.03 2.04 7.36.02 11.9-4.5z"></path>
</svg>
<span></span>
<span>{t("settings.ModelProvider.testConnection.test")}</span>
</>
)}
</button>

View File

@ -181,7 +181,7 @@ const CustomProviderSettings: React.FC<CustomProviderSettingsProps> = ({ plugin,
// 对于Ollama和OpenAICompatible不支持测试API连接
if (provider === ApiProvider.Ollama || provider === ApiProvider.OpenAICompatible) {
throw new Error(`不支持测试 ${provider} 的API连接`);
throw new Error(t("settings.ModelProvider.testConnection.notSupported", { provider }));
}
// 创建LLM管理器实例
@ -193,7 +193,7 @@ const CustomProviderSettings: React.FC<CustomProviderSettingsProps> = ({ plugin,
// 对于没有默认模型的提供商,使用通用的测试模型
if (!testModelId) {
throw new Error(`No default chat model available for ${provider}`);
throw new Error(t("settings.ModelProvider.testConnection.noDefaultModel", { provider }));
}
// 构造测试模型对象
@ -235,7 +235,7 @@ const CustomProviderSettings: React.FC<CustomProviderSettingsProps> = ({ plugin,
// ApiKeyComponent expects no return value on success, just no thrown error
return;
} else {
throw new Error('Invalid response format');
throw new Error(t("settings.ModelProvider.testConnection.invalidResponse"));
}
} catch (apiError) {
clearTimeout(timeoutId);
@ -246,26 +246,33 @@ const CustomProviderSettings: React.FC<CustomProviderSettingsProps> = ({ plugin,
console.error(`${provider} connection test failed:`, error);
// 根据错误类型提供更具体的错误信息
let errorMessage = '连接测试失败';
let errorMessage = t("settings.ModelProvider.testConnection.connectionFailed");
if (error.message?.includes('API key')) {
errorMessage = 'API Key 无效或缺失';
errorMessage = t("settings.ModelProvider.testConnection.invalidApiKey");
} else if (error.message?.includes('base URL') || error.message?.includes('baseURL')) {
errorMessage = '基础URL设置错误';
errorMessage = t("settings.ModelProvider.testConnection.invalidBaseUrl");
} else if (error.message?.includes('timeout') || error.name === 'AbortError') {
errorMessage = '请求超时,请检查网络连接';
errorMessage = t("settings.ModelProvider.testConnection.requestTimeout");
} else if (error.message?.includes('fetch')) {
errorMessage = '网络连接失败';
errorMessage = t("settings.ModelProvider.testConnection.networkError");
} else if (error.message?.includes('401')) {
errorMessage = 'API Key 授权失败';
errorMessage = t("settings.ModelProvider.testConnection.unauthorizedError");
} else if (error.message?.includes('403')) {
errorMessage = '访问被拒绝请检查API Key权限';
errorMessage = t("settings.ModelProvider.testConnection.forbiddenError");
} else if (error.message?.includes('429')) {
errorMessage = '请求频率过高,请稍后重试';
errorMessage = t("settings.ModelProvider.testConnection.rateLimitError");
} else if (error.message?.includes('500')) {
errorMessage = '服务器内部错误';
errorMessage = t("settings.ModelProvider.testConnection.serverError");
} else if (error.message) {
errorMessage = error.message;
// 如果错误消息本身已经是翻译过的(比如不支持的提供商),直接使用
if (error.message.includes(t("settings.ModelProvider.testConnection.notSupported", { provider: '' }).slice(0, 10))) {
errorMessage = error.message;
} else if (error.message.includes(t("settings.ModelProvider.testConnection.noDefaultModel", { provider: '' }).slice(0, 10))) {
errorMessage = error.message;
} else {
errorMessage = error.message;
}
}
alert(errorMessage);
// 必须抛出错误这样ApiKeyComponent才能正确显示失败状态