From 2a87a4d82aace6fe3434d4c598ad663e50a11e45 Mon Sep 17 00:00:00 2001 From: Test Date: Sun, 14 Dec 2025 17:19:51 +0800 Subject: [PATCH] feat: Add 404 judgment; Virtual authentication files also support obtaining model lists; Chinese support for virtual authentication file i18n; --- src/i18n/locales/zh-CN.json | 7 ++- src/pages/AuthFilesPage.module.scss | 27 +++++++++ src/pages/AuthFilesPage.tsx | 87 ++++++++++++++++++++++------- 3 files changed, 99 insertions(+), 22 deletions(-) diff --git a/src/i18n/locales/zh-CN.json b/src/i18n/locales/zh-CN.json index 4399877..186bec2 100644 --- a/src/i18n/locales/zh-CN.json +++ b/src/i18n/locales/zh-CN.json @@ -316,11 +316,16 @@ "type_vertex": "Vertex", "type_empty": "空文件", "type_unknown": "其他", + "type_virtual": "虚拟认证文件", "models_button": "模型", "models_title": "支持的模型", "models_loading": "正在加载模型列表...", "models_empty": "该凭证暂无可用模型", - "models_empty_desc": "该认证凭证可能尚未被服务器加载或没有绑定任何模型" + "models_empty_desc": "该认证凭证可能尚未被服务器加载或没有绑定任何模型", + "models_unsupported": "当前版本不支持此功能", + "models_unsupported_desc": "请更新 CLI Proxy API 到最新版本后重试", + "models_excluded_badge": "已排除", + "models_excluded_hint": "此模型已被 OAuth 排除" }, "vertex_import": { "title": "Vertex AI 凭证导入", diff --git a/src/pages/AuthFilesPage.module.scss b/src/pages/AuthFilesPage.module.scss index 83681d7..3d0e106 100644 --- a/src/pages/AuthFilesPage.module.scss +++ b/src/pages/AuthFilesPage.module.scss @@ -260,6 +260,8 @@ padding: 4px 10px; border-radius: $radius-sm; font-style: italic; + display: inline-flex; + align-items: center; } // 分页 @@ -446,3 +448,28 @@ margin-left: auto; } +.modelItemExcluded { + opacity: 0.6; + background-color: var(--bg-tertiary); + border-style: dashed; + + .modelId { + text-decoration: line-through; + color: var(--text-tertiary); + } + + &:hover { + border-color: var(--danger-color); + } +} + +.modelExcludedBadge { + font-size: 10px; + color: var(--danger-color); + background-color: rgba(239, 68, 68, 0.1); + padding: 2px 6px; + border-radius: 8px; + border: 1px solid var(--danger-color); + flex-shrink: 0; +} + diff --git a/src/pages/AuthFilesPage.tsx b/src/pages/AuthFilesPage.tsx index b4e5b97..a135a5e 100644 --- a/src/pages/AuthFilesPage.tsx +++ b/src/pages/AuthFilesPage.tsx @@ -145,6 +145,8 @@ export function AuthFilesPage() { const [modelsLoading, setModelsLoading] = useState(false); const [modelsList, setModelsList] = useState<{ id: string; display_name?: string; type?: string }[]>([]); const [modelsFileName, setModelsFileName] = useState(''); + const [modelsFileType, setModelsFileType] = useState(''); + const [modelsError, setModelsError] = useState<'unsupported' | null>(null); // OAuth 排除模型相关 const [excluded, setExcluded] = useState>({}); @@ -415,20 +417,40 @@ export function AuthFilesPage() { // 显示模型列表 const showModels = async (item: AuthFileItem) => { setModelsFileName(item.name); + setModelsFileType(item.type || ''); setModelsList([]); + setModelsError(null); setModelsModalOpen(true); setModelsLoading(true); try { const models = await authFilesApi.getModelsForAuthFile(item.name); setModelsList(models); } catch (err) { + // 检测是否是 API 不支持的错误 (404 或特定错误消息) const errorMessage = err instanceof Error ? err.message : ''; - showNotification(`${t('notification.load_failed')}: ${errorMessage}`, 'error'); + if (errorMessage.includes('404') || errorMessage.includes('not found') || errorMessage.includes('Not Found')) { + setModelsError('unsupported'); + } else { + showNotification(`${t('notification.load_failed')}: ${errorMessage}`, 'error'); + } } finally { setModelsLoading(false); } }; + // 检查模型是否被 OAuth 排除 + const isModelExcluded = (modelId: string, providerType: string): boolean => { + const excludedModels = excluded[providerType] || []; + return excludedModels.some(pattern => { + if (pattern.includes('*')) { + // 支持通配符匹配 + const regex = new RegExp('^' + pattern.replace(/\*/g, '.*') + '$', 'i'); + return regex.test(modelId); + } + return pattern.toLowerCase() === modelId.toLowerCase(); + }); + }; + // 获取类型标签显示文本 const getTypeLabel = (type: string): string => { const key = `auth_files.filter_${type}`; @@ -561,7 +583,19 @@ export function AuthFilesPage() {
{isRuntimeOnly ? ( - {t('auth_files.type_virtual') || '虚拟认证文件'} + <> +
{t('auth_files.type_virtual') || '虚拟认证文件'}
+ + ) : ( <>