feat(gemini): 完善 Gemini OAuth 配额系统和用量显示
主要改动: - 后端:重构 Gemini 配额服务,支持多层级配额策略(GCP Standard/Free, Google One, AI Studio, Code Assist) - 后端:优化 OAuth 服务,增强 tier_id 识别和存储逻辑 - 后端:改进用量统计服务,支持不同平台的配额查询 - 后端:优化限流服务,增加临时解除调度状态管理 - 前端:统一四种授权方式的用量显示格式和徽标样式 - 前端:增强账户配额信息展示,支持多种配额类型 - 前端:改进创建和重新授权模态框的用户体验 - 国际化:完善中英文配额相关文案 - 移除 CHANGELOG.md 文件 测试:所有单元测试通过
This commit is contained in:
@@ -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'
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user