From f9f33e7b5c1aa665b67434e83da37b0d7dbc08f4 Mon Sep 17 00:00:00 2001 From: ianshaw Date: Thu, 25 Dec 2025 23:52:55 -0800 Subject: [PATCH] =?UTF-8?q?feat(frontend):=20UI=20=E6=98=BE=E7=A4=BA=20AI?= =?UTF-8?q?=20Studio=20OAuth=20=E9=85=8D=E7=BD=AE=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CreateAccountModal: - 检测 AI Studio OAuth 是否可用(服务器配置了自定义 OAuth 客户端) - 未配置时禁用 AI Studio 选项并显示提示 - 添加悬停提示说明配置要求 ReAuthAccountModal: - 同步 AI Studio OAuth 可用性检测逻辑 - 未配置时自动回退到 Code Assist --- .../components/account/CreateAccountModal.vue | 105 ++++++++++++++---- .../components/account/ReAuthAccountModal.vue | 36 +++++- 2 files changed, 115 insertions(+), 26 deletions(-) diff --git a/frontend/src/components/account/CreateAccountModal.vue b/frontend/src/components/account/CreateAccountModal.vue index de0f45af..b3ef4fd5 100644 --- a/frontend/src/components/account/CreateAccountModal.vue +++ b/frontend/src/components/account/CreateAccountModal.vue @@ -387,7 +387,7 @@
+ +
+ {{ t('admin.accounts.oauth.gemini.aiStudioNotConfiguredTip') }}
-
- AI Studio - {{ t('admin.accounts.oauth.gemini.noProjectIdNeeded') }} - {{ t('admin.accounts.oauth.gemini.noProjectIdNeededDesc') }} -
- +
@@ -1134,6 +1165,7 @@ const selectedErrorCodes = ref([]) const customErrorCodeInput = ref(null) const interceptWarmupRequests = ref(false) const geminiOAuthType = ref<'code_assist' | 'ai_studio'>('code_assist') +const geminiAIStudioOAuthEnabled = ref(false) // Common models for whitelist - Anthropic const anthropicModels = [ @@ -1385,6 +1417,31 @@ watch( } ) +// Gemini AI Studio OAuth availability (requires operator-configured OAuth client) +watch( + [() => props.show, () => form.platform, accountCategory], + async ([show, platform, category]) => { + if (!show || platform !== 'gemini' || category !== 'oauth-based') { + geminiAIStudioOAuthEnabled.value = false + return + } + const caps = await geminiOAuth.getCapabilities() + geminiAIStudioOAuthEnabled.value = !!caps?.ai_studio_oauth_enabled + if (!geminiAIStudioOAuthEnabled.value && geminiOAuthType.value === 'ai_studio') { + geminiOAuthType.value = 'code_assist' + } + }, + { immediate: true } +) + +const handleSelectGeminiOAuthType = (oauthType: 'code_assist' | 'ai_studio') => { + if (oauthType === 'ai_studio' && !geminiAIStudioOAuthEnabled.value) { + appStore.showError(t('admin.accounts.oauth.gemini.aiStudioNotConfigured')) + return + } + geminiOAuthType.value = oauthType +} + // Model mapping helpers const addModelMapping = () => { modelMappings.value.push({ from: '', to: '' }) diff --git a/frontend/src/components/account/ReAuthAccountModal.vue b/frontend/src/components/account/ReAuthAccountModal.vue index a4f172c4..f3395869 100644 --- a/frontend/src/components/account/ReAuthAccountModal.vue +++ b/frontend/src/components/account/ReAuthAccountModal.vue @@ -85,7 +85,7 @@
@@ -283,6 +297,7 @@ const oauthFlowRef = ref(null) // State const addMethod = ref('oauth') const geminiOAuthType = ref<'code_assist' | 'ai_studio'>('code_assist') +const geminiAIStudioOAuthEnabled = ref(false) // Computed - check if this is an OpenAI account const isOpenAI = computed(() => props.account?.platform === 'openai') @@ -348,6 +363,14 @@ watch( const creds = (props.account.credentials || {}) as Record geminiOAuthType.value = creds.oauth_type === 'ai_studio' ? 'ai_studio' : 'code_assist' } + if (isGemini.value) { + geminiOAuth.getCapabilities().then((caps) => { + geminiAIStudioOAuthEnabled.value = !!caps?.ai_studio_oauth_enabled + if (!geminiAIStudioOAuthEnabled.value && geminiOAuthType.value === 'ai_studio') { + geminiOAuthType.value = 'code_assist' + } + }) + } } else { resetState() } @@ -358,12 +381,21 @@ watch( const resetState = () => { addMethod.value = 'oauth' geminiOAuthType.value = 'code_assist' + geminiAIStudioOAuthEnabled.value = false claudeOAuth.resetState() openaiOAuth.resetState() geminiOAuth.resetState() oauthFlowRef.value?.reset() } +const handleSelectGeminiOAuthType = (oauthType: 'code_assist' | 'ai_studio') => { + if (oauthType === 'ai_studio' && !geminiAIStudioOAuthEnabled.value) { + appStore.showError(t('admin.accounts.oauth.gemini.aiStudioNotConfigured')) + return + } + geminiOAuthType.value = oauthType +} + const handleClose = () => { emit('close') }