feat(gemini): 完善 Gemini OAuth 配额系统和用量显示

主要改动:
- 后端:重构 Gemini 配额服务,支持多层级配额策略(GCP Standard/Free, Google One, AI Studio, Code Assist)
- 后端:优化 OAuth 服务,增强 tier_id 识别和存储逻辑
- 后端:改进用量统计服务,支持不同平台的配额查询
- 后端:优化限流服务,增加临时解除调度状态管理
- 前端:统一四种授权方式的用量显示格式和徽标样式
- 前端:增强账户配额信息展示,支持多种配额类型
- 前端:改进创建和重新授权模态框的用户体验
- 国际化:完善中英文配额相关文案
- 移除 CHANGELOG.md 文件

测试:所有单元测试通过
This commit is contained in:
IanShaw027
2026-01-04 15:36:00 +08:00
parent cc4cc806ea
commit a185ad1144
21 changed files with 1205 additions and 368 deletions

View File

@@ -65,32 +65,33 @@ const tierLabel = computed(() => {
const creds = props.account.credentials as GeminiCredentials | undefined
if (isCodeAssist.value) {
// GCP Code Assist: 显示 GCP tier
const tierMap: Record<string, string> = {
LEGACY: 'Free',
PRO: 'Pro',
ULTRA: 'Ultra',
'standard-tier': 'Standard',
'pro-tier': 'Pro',
'ultra-tier': 'Ultra'
}
return tierMap[creds?.tier_id || ''] || (creds?.tier_id ? 'GCP' : 'Unknown')
const tier = (creds?.tier_id || '').toString().trim().toLowerCase()
if (tier === 'gcp_enterprise') return 'GCP Enterprise'
if (tier === 'gcp_standard') return 'GCP Standard'
// Backward compatibility
const upper = (creds?.tier_id || '').toString().trim().toUpperCase()
if (upper.includes('ULTRA') || upper.includes('ENTERPRISE')) return 'GCP Enterprise'
if (upper) return `GCP ${upper}`
return 'GCP'
}
if (isGoogleOne.value) {
// Google One: tier 映射
const tierMap: Record<string, string> = {
AI_PREMIUM: 'AI Premium',
GOOGLE_ONE_STANDARD: 'Standard',
GOOGLE_ONE_BASIC: 'Basic',
FREE: 'Free',
GOOGLE_ONE_UNKNOWN: 'Personal',
GOOGLE_ONE_UNLIMITED: 'Unlimited'
}
return tierMap[creds?.tier_id || ''] || 'Personal'
const tier = (creds?.tier_id || '').toString().trim().toLowerCase()
if (tier === 'google_ai_ultra') return 'Google AI Ultra'
if (tier === 'google_ai_pro') return 'Google AI Pro'
if (tier === 'google_one_free') return 'Google One Free'
// Backward compatibility
const upper = (creds?.tier_id || '').toString().trim().toUpperCase()
if (upper === 'AI_PREMIUM') return 'Google AI Pro'
if (upper === 'GOOGLE_ONE_UNLIMITED') return 'Google AI Ultra'
if (upper) return `Google One ${upper}`
return 'Google One'
}
// API Key: 显示 AI Studio
const tier = (creds?.tier_id || '').toString().trim().toLowerCase()
if (tier === 'aistudio_paid') return 'AI Studio Pay-as-you-go'
if (tier === 'aistudio_free') return 'AI Studio Free Tier'
return 'AI Studio'
})
@@ -99,35 +100,31 @@ const tierBadgeClass = computed(() => {
const creds = props.account.credentials as GeminiCredentials | undefined
if (isCodeAssist.value) {
// GCP Code Assist 样式
const tierColorMap: Record<string, string> = {
LEGACY: 'bg-gray-100 text-gray-600 dark:bg-gray-700 dark:text-gray-300',
PRO: 'bg-blue-100 text-blue-600 dark:bg-blue-900/40 dark:text-blue-300',
ULTRA: 'bg-purple-100 text-purple-600 dark:bg-purple-900/40 dark:text-purple-300',
'standard-tier': 'bg-green-100 text-green-600 dark:bg-green-900/40 dark:text-green-300',
'pro-tier': 'bg-blue-100 text-blue-600 dark:bg-blue-900/40 dark:text-blue-300',
'ultra-tier': 'bg-purple-100 text-purple-600 dark:bg-purple-900/40 dark:text-purple-300'
}
return (
tierColorMap[creds?.tier_id || ''] ||
'bg-gray-100 text-gray-600 dark:bg-gray-700 dark:text-gray-300'
)
const tier = (creds?.tier_id || '').toString().trim().toLowerCase()
if (tier === 'gcp_enterprise') return 'bg-purple-100 text-purple-600 dark:bg-purple-900/40 dark:text-purple-300'
if (tier === 'gcp_standard') return 'bg-blue-100 text-blue-600 dark:bg-blue-900/40 dark:text-blue-300'
// Backward compatibility
const upper = (creds?.tier_id || '').toString().trim().toUpperCase()
if (upper.includes('ULTRA') || upper.includes('ENTERPRISE')) return 'bg-purple-100 text-purple-600 dark:bg-purple-900/40 dark:text-purple-300'
return 'bg-blue-100 text-blue-600 dark:bg-blue-900/40 dark:text-blue-300'
}
if (isGoogleOne.value) {
// Google One tier 样式
const tierColorMap: Record<string, string> = {
AI_PREMIUM: 'bg-purple-100 text-purple-600 dark:bg-purple-900/40 dark:text-purple-300',
GOOGLE_ONE_STANDARD: 'bg-blue-100 text-blue-600 dark:bg-blue-900/40 dark:text-blue-300',
GOOGLE_ONE_BASIC: 'bg-green-100 text-green-600 dark:bg-green-900/40 dark:text-green-300',
FREE: 'bg-gray-100 text-gray-600 dark:bg-gray-700 dark:text-gray-300',
GOOGLE_ONE_UNKNOWN: 'bg-gray-100 text-gray-600 dark:bg-gray-700 dark:text-gray-300',
GOOGLE_ONE_UNLIMITED: 'bg-amber-100 text-amber-600 dark:bg-amber-900/40 dark:text-amber-300'
}
return tierColorMap[creds?.tier_id || ''] || 'bg-gray-100 text-gray-600 dark:bg-gray-700 dark:text-gray-300'
const tier = (creds?.tier_id || '').toString().trim().toLowerCase()
if (tier === 'google_ai_ultra') return 'bg-purple-100 text-purple-600 dark:bg-purple-900/40 dark:text-purple-300'
if (tier === 'google_ai_pro') return 'bg-blue-100 text-blue-600 dark:bg-blue-900/40 dark:text-blue-300'
if (tier === 'google_one_free') return 'bg-gray-100 text-gray-600 dark:bg-gray-700 dark:text-gray-300'
// Backward compatibility
const upper = (creds?.tier_id || '').toString().trim().toUpperCase()
if (upper === 'GOOGLE_ONE_UNLIMITED') return 'bg-purple-100 text-purple-600 dark:bg-purple-900/40 dark:text-purple-300'
if (upper === 'AI_PREMIUM') return 'bg-blue-100 text-blue-600 dark:bg-blue-900/40 dark:text-blue-300'
return 'bg-gray-100 text-gray-600 dark:bg-gray-700 dark:text-gray-300'
}
// AI Studio 默认样式:蓝色
const tier = (creds?.tier_id || '').toString().trim().toLowerCase()
if (tier === 'aistudio_paid') return 'bg-blue-100 text-blue-600 dark:bg-blue-900/40 dark:text-blue-300'
if (tier === 'aistudio_free') return 'bg-gray-100 text-gray-600 dark:bg-gray-700 dark:text-gray-300'
return 'bg-blue-100 text-blue-600 dark:bg-blue-900/40 dark:text-blue-300'
})