feat: 继续完成AccountForm组件国际化的核心模块

- 完成手动Token输入部分国际化,支持Claude/Gemini/OpenAI三个平台
- 完成编辑模式所有特定功能的国际化:账户信息、类型、分组管理
- 完成Claude高级功能国际化:订阅类型、自动停止调度、统一User-Agent、客户端标识
- 完成Gemini Project ID配置的国际化支持
- 新增150+翻译键,涵盖三种语言(简中/繁中/英文)
- 保持响应式特性和暗黑模式兼容性

技术改进:
- 采用结构化翻译键命名策略 (accountForm.module.item)
- 解决重复字符串精确匹配问题
- 使用上下文信息区分相似文本的不同用法
- 优化用户交互文本:占位符、提示、按钮等

进度:AccountForm组件(3730行)已完成约70%的国际化工作
This commit is contained in:
Wangnov
2025-09-09 14:49:53 +08:00
parent e80c49c1ce
commit 2e09896d0b
4 changed files with 254 additions and 68 deletions

View File

@@ -916,7 +916,7 @@
>
<i v-if="!clearingCache" class="fas fa-trash-alt mr-1"></i>
<div v-else class="loading-spinner mr-1"></div>
{{ clearingCache ? '清除中...' : '清除缓存' }}
{{ clearingCache ? t('accountForm.clearing') : t('accountForm.clearCache') }}
</button>
</div>
</div>
@@ -1001,11 +1001,11 @@
class="form-input w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 dark:placeholder-gray-400"
max="100"
min="1"
placeholder="数字越小优先级越高默认50"
:placeholder="t('accountForm.priorityPlaceholder')"
type="number"
/>
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">
数字越小优先级越高建议范围1-100
{{ t('accountForm.priorityDescription') }}
</p>
</div>
@@ -1026,51 +1026,48 @@
</div>
<div>
<h5 class="mb-2 font-semibold text-blue-900 dark:text-blue-300">
手动输入 Token
{{ t('accountForm.manualTokenInput') }}
</h5>
<p
v-if="form.platform === 'claude'"
class="mb-2 text-sm text-blue-800 dark:text-blue-300"
>
请输入有效的 Claude Access Token。如果您有 Refresh
Token建议也一并填写以支持自动刷新。
{{ t('accountForm.manualTokenClaudeDescription') }}
</p>
<p
v-else-if="form.platform === 'gemini'"
class="mb-2 text-sm text-blue-800 dark:text-blue-300"
>
请输入有效的 Gemini Access Token。如果您有 Refresh
Token建议也一并填写以支持自动刷新。
{{ t('accountForm.manualTokenGeminiDescription') }}
</p>
<p
v-else-if="form.platform === 'openai'"
class="mb-2 text-sm text-blue-800 dark:text-blue-300"
>
请输入有效的 OpenAI Access Token。如果您有 Refresh
Token建议也一并填写以支持自动刷新。
{{ t('accountForm.manualTokenOpenAIDescription') }}
</p>
<div
class="mb-2 mt-2 rounded-lg border border-blue-300 bg-white/80 p-3 dark:border-blue-600 dark:bg-gray-800/80"
>
<p class="mb-1 text-sm font-medium text-blue-900 dark:text-blue-300">
<i class="fas fa-folder-open mr-1" />
获取 Access Token 的方法:
{{ t('accountForm.getAccessTokenMethod') }}
</p>
<p
v-if="form.platform === 'claude'"
class="text-xs text-blue-800 dark:text-blue-300"
>
请从已登录 Claude Code 的机器上获取
{{ t('accountForm.claudeCredentialsPath') }}
<code class="rounded bg-blue-100 px-1 py-0.5 font-mono dark:bg-blue-900/50"
>~/.claude/.credentials.json</code
>
文件中的凭证, 请勿使用 Claude 官网 API Keys 页面的密钥。
{{ t('accountForm.claudeCredentialsWarning') }}
</p>
<p
v-else-if="form.platform === 'gemini'"
class="text-xs text-blue-800 dark:text-blue-300"
>
请从已登录 Gemini CLI 的机器上获取
{{ t('accountForm.geminiCredentialsPath') }}
<code class="rounded bg-blue-100 px-1 py-0.5 font-mono dark:bg-blue-900/50"
>~/.config/gemini/credentials.json</code
>
@@ -1080,41 +1077,40 @@
v-else-if="form.platform === 'openai'"
class="text-xs text-blue-800 dark:text-blue-300"
>
请从已登录 OpenAI 账户的机器上获取认证凭证, 或通过 OAuth 授权流程获取 Access
Token。
{{ t('accountForm.openaiCredentialsPath') }}
</p>
</div>
<p class="text-xs text-blue-600 dark:text-blue-400">
💡 如果未填写 Refresh TokenToken 过期后需要手动更新。
{{ t('accountForm.refreshTokenWarning') }}
</p>
</div>
</div>
<div v-if="form.platform === 'openai'">
<label class="mb-3 block text-sm font-semibold text-gray-700 dark:text-gray-300"
>Access Token (可选)</label
>{{ t('accountForm.accessTokenOptional') }}</label
>
<textarea
v-model="form.accessToken"
class="form-input w-full resize-none border-gray-300 font-mono text-xs dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 dark:placeholder-gray-400"
placeholder="可选:如果不填写,系统会自动通过 Refresh Token 获取..."
:placeholder="t('accountForm.accessTokenOptionalPlaceholder')"
rows="4"
/>
<p class="mt-2 text-xs text-gray-500 dark:text-gray-400">
<i class="fas fa-info-circle mr-1" />
Access Token 可选填。如果不提供,系统会通过 Refresh Token 自动获取。
{{ t('accountForm.accessTokenOptionalInfo') }}
</p>
</div>
<div v-else>
<label class="mb-3 block text-sm font-semibold text-gray-700 dark:text-gray-300"
>Access Token *</label
>{{ t('accountForm.accessTokenRequired') }}</label
>
<textarea
v-model="form.accessToken"
class="form-input w-full resize-none border-gray-300 font-mono text-xs dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 dark:placeholder-gray-400"
:class="{ 'border-red-500': errors.accessToken }"
placeholder="请输入 Access Token..."
:placeholder="t('accountForm.accessTokenRequiredPlaceholder')"
required
rows="4"
/>
@@ -1125,13 +1121,13 @@
<div v-if="form.platform === 'openai'">
<label class="mb-3 block text-sm font-semibold text-gray-700 dark:text-gray-300"
>Refresh Token *</label
>{{ t('accountForm.refreshTokenRequired') }}</label
>
<textarea
v-model="form.refreshToken"
class="form-input w-full resize-none border-gray-300 font-mono text-xs dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 dark:placeholder-gray-400"
:class="{ 'border-red-500': errors.refreshToken }"
placeholder="请输入 Refresh Token(必填)..."
:placeholder="t('accountForm.refreshTokenRequiredPlaceholder')"
required
rows="4"
/>
@@ -1140,18 +1136,18 @@
</p>
<p class="mt-2 text-xs text-gray-500 dark:text-gray-400">
<i class="fas fa-info-circle mr-1" />
系统将使用 Refresh Token 自动获取 Access Token 和用户信息
{{ t('accountForm.refreshTokenRequiredInfo') }}
</p>
</div>
<div v-else>
<label class="mb-3 block text-sm font-semibold text-gray-700 dark:text-gray-300"
>Refresh Token (可选)</label
>{{ t('accountForm.refreshTokenOptional') }}</label
>
<textarea
v-model="form.refreshToken"
class="form-input w-full resize-none border-gray-300 font-mono text-xs dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 dark:placeholder-gray-400"
placeholder="请输入 Refresh Token..."
:placeholder="t('accountForm.refreshTokenOptionalPlaceholder')"
rows="4"
/>
</div>
@@ -1382,12 +1378,12 @@
<!-- 基本信息 -->
<div>
<label class="mb-3 block text-sm font-semibold text-gray-700 dark:text-gray-300"
>账户名称</label
>{{ t('accountForm.accountNameEdit') }}</label
>
<input
v-model="form.name"
class="form-input w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 dark:placeholder-gray-400"
placeholder="为账户设置一个易识别的名称"
:placeholder="t('accountForm.accountNameEditPlaceholder')"
required
type="text"
/>
@@ -1395,19 +1391,19 @@
<div>
<label class="mb-3 block text-sm font-semibold text-gray-700 dark:text-gray-300"
>描述 (可选)</label
>{{ t('accountForm.descriptionOptionalEdit') }}</label
>
<textarea
v-model="form.description"
class="form-input w-full resize-none border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 dark:placeholder-gray-400"
placeholder="账户用途说明..."
:placeholder="t('accountForm.descriptionOptionalEditPlaceholder')"
rows="3"
/>
</div>
<div>
<label class="mb-3 block text-sm font-semibold text-gray-700 dark:text-gray-300"
>账户类型</label
>{{ t('accountForm.accountTypeEdit') }}</label
>
<div class="flex gap-4">
<label class="flex cursor-pointer items-center">
@@ -1417,7 +1413,7 @@
type="radio"
value="shared"
/>
<span class="text-sm text-gray-700 dark:text-gray-300">共享账户</span>
<span class="text-sm text-gray-700 dark:text-gray-300">{{ t('accountForm.sharedAccount') }}</span>
</label>
<label class="flex cursor-pointer items-center">
<input
@@ -1426,7 +1422,7 @@
type="radio"
value="dedicated"
/>
<span class="text-sm text-gray-700 dark:text-gray-300">专属账户</span>
<span class="text-sm text-gray-700 dark:text-gray-300">{{ t('accountForm.dedicatedAccount') }}</span>
</label>
<label class="flex cursor-pointer items-center">
<input
@@ -1435,19 +1431,18 @@
type="radio"
value="group"
/>
<span class="text-sm text-gray-700 dark:text-gray-300">分组调度</span>
<span class="text-sm text-gray-700 dark:text-gray-300">{{ t('accountForm.groupScheduling') }}</span>
</label>
</div>
<p class="mt-2 text-xs text-gray-500 dark:text-gray-400">
共享账户供所有API Key使用专属账户仅供特定API
Key使用分组调度加入分组供分组内调度
{{ t('accountForm.accountTypeDescription') }}
</p>
</div>
<!-- 分组选择器 -->
<div v-if="form.accountType === 'group'">
<label class="mb-3 block text-sm font-semibold text-gray-700 dark:text-gray-300"
>选择分组 *</label
>{{ t('accountForm.selectGroupRequired') }}</label
>
<div class="flex gap-2">
<div class="flex-1">
@@ -1459,7 +1454,7 @@
v-if="filteredGroups.length === 0"
class="text-sm text-gray-500 dark:text-gray-400"
>
暂无可用分组
{{ t('accountForm.noAvailableGroups') }}
</div>
<label
v-for="group in filteredGroups"
@@ -1473,7 +1468,7 @@
:value="group.id"
/>
<span class="text-sm text-gray-700 dark:text-gray-200">
{{ group.name }} ({{ group.memberCount || 0 }} 个成员)
{{ group.name }} ({{ group.memberCount || 0 }}{{ t('accountForm.membersCount') }})
</span>
</label>
<!-- 新建分组选项 -->
@@ -1484,7 +1479,7 @@
@click="handleNewGroup"
>
<i class="fas fa-plus" />
新建分组
{{ t('accountForm.createNewGroup') }}
</button>
</div>
</div>
@@ -1502,23 +1497,23 @@
<!-- Gemini 项目 ID 字段 -->
<div v-if="form.platform === 'gemini'">
<label class="mb-3 block text-sm font-semibold text-gray-700 dark:text-gray-300"
>项目 ID (可选)</label
>{{ t('accountForm.projectIdOptional') }}</label
>
<input
v-model="form.projectId"
class="form-input w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 dark:placeholder-gray-400"
placeholder="例如verdant-wares-464411-k9"
:placeholder="t('accountForm.projectIdPlaceholder')"
type="text"
/>
<p class="mt-2 text-xs text-gray-500 dark:text-gray-400">
Google Cloud/Workspace 账号可能需要提供项目 ID
{{ t('accountForm.projectIdDescription') }}
</p>
</div>
<!-- Claude 订阅类型选择(编辑模式) -->
<div v-if="form.platform === 'claude'">
<label class="mb-3 block text-sm font-semibold text-gray-700 dark:text-gray-300"
>订阅类型</label
>{{ t('accountForm.subscriptionType') }}</label
>
<div class="flex gap-4">
<label class="flex cursor-pointer items-center">
@@ -1528,7 +1523,7 @@
type="radio"
value="claude_max"
/>
<span class="text-sm text-gray-700 dark:text-gray-300">Claude Max</span>
<span class="text-sm text-gray-700 dark:text-gray-300">{{ t('accountForm.claudeMaxSubscription') }}</span>
</label>
<label class="flex cursor-pointer items-center">
<input
@@ -1537,12 +1532,12 @@
type="radio"
value="claude_pro"
/>
<span class="text-sm text-gray-700 dark:text-gray-300">Claude Pro</span>
<span class="text-sm text-gray-700 dark:text-gray-300">{{ t('accountForm.claudeProSubscription') }}</span>
</label>
</div>
<p class="mt-2 text-xs text-gray-500 dark:text-gray-400">
<i class="fas fa-info-circle mr-1" />
Pro 账号不支持 Claude Opus 4 模型
{{ t('accountForm.claudeProLimitation') }}
</p>
</div>
@@ -1556,10 +1551,10 @@
/>
<div class="ml-3">
<span class="text-sm font-medium text-gray-700 dark:text-gray-300">
5小时使用量接近限制时自动停止调度
{{ t('accountForm.autoStopOnWarning') }}
</span>
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">
当系统检测到账户接近5小时使用限制时自动暂停调度该账户。进入新的时间窗口后会自动恢复调度。
{{ t('accountForm.autoStopOnWarningDescription') }}
</p>
</div>
</label>
@@ -1575,15 +1570,15 @@
/>
<div class="ml-3">
<span class="text-sm font-medium text-gray-700 dark:text-gray-300">
使用统一 Claude Code 版本
{{ t('accountForm.useUnifiedUserAgent') }}
</span>
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">
开启后将使用从真实 Claude Code 客户端捕获的统一 User-Agent,提高兼容性
{{ t('accountForm.useUnifiedUserAgentDescription') }}
</p>
<div v-if="unifiedUserAgent" class="mt-1">
<div class="flex items-center justify-between">
<p class="text-xs text-green-600 dark:text-green-400">
💡 当前统一版本:{{ unifiedUserAgent }}
💡 {{ t('accountForm.currentUnifiedVersion') }}{{ unifiedUserAgent }}
</p>
<button
class="ml-2 text-xs text-red-500 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300"
@@ -1593,17 +1588,16 @@
>
<i v-if="!clearingCache" class="fas fa-trash-alt mr-1"></i>
<div v-else class="loading-spinner mr-1"></div>
{{ clearingCache ? '清除中...' : '清除缓存' }}
{{ clearingCache ? t('accountForm.clearing') : t('accountForm.clearCache') }}
</button>
</div>
</div>
<div v-else class="mt-1">
<p class="text-xs text-gray-500 dark:text-gray-400">
等待从 Claude Code 客户端捕获 User-Agent
{{ t('accountForm.waitingForCapture') }}
</p>
<p class="mt-1 text-xs text-gray-400 dark:text-gray-500">
💡 提示:如果长时间未能捕获,请确认有 Claude Code 客户端正在使用此账户,
或联系开发者检查 User-Agent 格式是否发生变化
{{ t('accountForm.captureHint') }}
</p>
</div>
</div>
@@ -1621,10 +1615,10 @@
/>
<div class="ml-3 flex-1">
<span class="text-sm font-medium text-gray-700 dark:text-gray-300">
使用统一的客户端标识
{{ t('accountForm.useUnifiedClientId') }}
</span>
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">
开启后将使用固定的客户端标识,使所有请求看起来来自同一个客户端,减少特征
{{ t('accountForm.useUnifiedClientIdDescription') }}
</p>
<div v-if="form.useUnifiedClientId" class="mt-3">
<div
@@ -1632,7 +1626,7 @@
>
<div class="mb-2 flex items-center justify-between">
<span class="text-xs font-medium text-gray-600 dark:text-gray-400"
>客户端标识 ID</span
>{{ t('accountForm.clientIdLabel') }}</span
>
<button
class="rounded-md bg-blue-100 px-2.5 py-1 text-xs font-medium text-blue-700 transition-colors hover:bg-blue-200 dark:bg-blue-900/30 dark:text-blue-400 dark:hover:bg-blue-900/50"
@@ -1640,7 +1634,7 @@
@click="regenerateClientId"
>
<i class="fas fa-sync-alt mr-1" />
重新生成
{{ t('accountForm.regenerateClientId') }}
</button>
</div>
<div class="flex items-center gap-2">
@@ -1660,7 +1654,7 @@
</div>
<p class="mt-2 text-xs text-gray-500 dark:text-gray-400">
<i class="fas fa-info-circle mr-1 text-blue-500" />
此ID将替换请求中的user_id客户端部分保留session部分用于粘性会话
{{ t('accountForm.clientIdDescription') }}
</p>
</div>
</div>
@@ -1671,18 +1665,18 @@
<!-- 所有平台的优先级设置(编辑模式) -->
<div>
<label class="mb-3 block text-sm font-semibold text-gray-700 dark:text-gray-300"
>调度优先级 (1-100)</label
>{{ t('accountForm.prioritySchedulingTitle') }}</label
>
<input
v-model.number="form.priority"
class="form-input w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 dark:placeholder-gray-400"
max="100"
min="1"
placeholder="数字越小优先级越高"
:placeholder="t('accountForm.priorityEditPlaceholder')"
type="number"
/>
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">
数字越小优先级越高建议范围1-100
{{ t('accountForm.priorityDescription') }}
</p>
</div>

View File

@@ -1285,6 +1285,70 @@ export default {
// General description text
allModelsIfEmpty: 'Leave blank to support all models. If models specified, requests with models not in list will not be scheduled to this account',
systemDefaultIfEmpty: 'Leave blank to use system default model. Supports inference profile ID or ARN',
noUpdateIfEmpty: 'Leave blank to not update this field'
noUpdateIfEmpty: 'Leave blank to not update this field',
// Manual Token Input Section
manualTokenInput: 'Manual Token Input',
manualTokenClaudeDescription: 'Please enter valid Claude Access Token. If you have Refresh Token, it is recommended to fill both for automatic refresh support.',
manualTokenGeminiDescription: 'Please enter valid Gemini Access Token. If you have Refresh Token, it is recommended to fill both for automatic refresh support.',
manualTokenOpenAIDescription: 'Please enter valid OpenAI Access Token. If you have Refresh Token, it is recommended to fill both for automatic refresh support.',
getAccessTokenMethod: 'Methods to get Access Token:',
claudeCredentialsPath: 'Please get from logged-in Claude Code machine',
geminiCredentialsPath: 'Please get from logged-in Gemini CLI machine',
openaiCredentialsPath: 'Please get authentication credentials from logged-in OpenAI account machine, or obtain Access Token through OAuth authorization flow.',
claudeCredentialsWarning: 'credentials from file, do not use keys from Claude official API Keys page.',
refreshTokenWarning: '💡 If Refresh Token is not filled, Token needs manual update after expiration.',
accessTokenOptional: 'Access Token (Optional)',
accessTokenOptionalPlaceholder: 'Optional: If not filled, system will automatically obtain through Refresh Token...',
accessTokenOptionalInfo: 'Access Token is optional. If not provided, system will automatically obtain through Refresh Token.',
accessTokenRequired: 'Access Token *',
accessTokenRequiredPlaceholder: 'Please enter Access Token...',
refreshTokenRequired: 'Refresh Token *',
refreshTokenRequiredPlaceholder: 'Please enter Refresh Token (required)...',
refreshTokenRequiredInfo: 'System will use Refresh Token to automatically obtain Access Token and user information',
refreshTokenOptional: 'Refresh Token (Optional)',
refreshTokenOptionalPlaceholder: 'Please enter Refresh Token...',
// Priority Settings
priorityPlaceholder: 'Lower number = higher priority, default 50',
priorityDescription: 'Lower number = higher priority, recommended range: 1-100',
prioritySchedulingTitle: 'Scheduling Priority (1-100)',
priorityEditPlaceholder: 'Lower number = higher priority',
// Gemini Project ID
projectIdOptional: 'Project ID (Optional)',
projectIdPlaceholder: 'e.g., verdant-wares-464411-k9',
projectIdDescription: 'Google Cloud/Workspace accounts may require Project ID',
// Claude Subscription Type and Advanced Options
subscriptionType: 'Subscription Type',
claudeMaxSubscription: 'Claude Max',
claudeProSubscription: 'Claude Pro',
claudeProLimitation: 'Pro accounts do not support Claude Opus 4 model',
autoStopOnWarning: 'Auto-stop scheduling when approaching 5-hour limit',
autoStopOnWarningDescription: 'When system detects account approaching 5-hour usage limit, automatically pause scheduling for this account. Will resume automatically when entering new time window.',
useUnifiedUserAgent: 'Use unified Claude Code version',
useUnifiedUserAgentDescription: 'When enabled, will use unified User-Agent captured from real Claude Code client, improving compatibility',
currentUnifiedVersion: 'Current unified version:',
clearCache: 'Clear Cache',
clearing: 'Clearing...',
waitingForCapture: 'Waiting to capture User-Agent from Claude Code client',
captureHint: '💡 Hint: If unable to capture for long time, please confirm Claude Code client is using this account, or contact developer to check if User-Agent format has changed',
useUnifiedClientId: 'Use unified client identifier',
useUnifiedClientIdDescription: 'When enabled, will use fixed client identifier, making all requests appear to come from same client, reducing characteristics',
clientIdLabel: 'Client Identifier ID',
regenerateClientId: 'Regenerate',
clientIdDescription: 'This ID will replace user_id client part in requests, preserving session part for sticky sessions',
// Edit Mode Fields
accountNameEdit: 'Account Name',
accountNameEditPlaceholder: 'Set an identifiable name for the account',
descriptionOptionalEdit: 'Description (Optional)',
descriptionOptionalEditPlaceholder: 'Account usage description...',
accountTypeEdit: 'Account Type',
selectGroupRequired: 'Select Group *',
noAvailableGroups: 'No available groups',
membersCount: ' members',
createNewGroup: 'Create New Group'
}
}

View File

@@ -1285,6 +1285,70 @@ export default {
// 通用描述文本
allModelsIfEmpty: '留空表示支持所有模型。如果指定模型,请求中的模型不在列表内将不会调度到此账号',
systemDefaultIfEmpty: '留空将使用系统默认模型。支持 inference profile ID 或 ARN',
noUpdateIfEmpty: '留空表示不更新该字段'
noUpdateIfEmpty: '留空表示不更新该字段',
// 手动 Token 输入部分
manualTokenInput: '手动输入 Token',
manualTokenClaudeDescription: '请输入有效的 Claude Access Token。如果您有 Refresh Token建议也一并填写以支持自动刷新。',
manualTokenGeminiDescription: '请输入有效的 Gemini Access Token。如果您有 Refresh Token建议也一并填写以支持自动刷新。',
manualTokenOpenAIDescription: '请输入有效的 OpenAI Access Token。如果您有 Refresh Token建议也一并填写以支持自动刷新。',
getAccessTokenMethod: '获取 Access Token 的方法:',
claudeCredentialsPath: '请从已登录 Claude Code 的机器上获取',
geminiCredentialsPath: '请从已登录 Gemini CLI 的机器上获取',
openaiCredentialsPath: '请从已登录 OpenAI 账户的机器上获取认证凭证,或通过 OAuth 授权流程获取 Access Token。',
claudeCredentialsWarning: '文件中的凭证,请勿使用 Claude 官网 API Keys 页面的密钥。',
refreshTokenWarning: '💡 如果未填写 Refresh TokenToken 过期后需要手动更新。',
accessTokenOptional: 'Access Token (可选)',
accessTokenOptionalPlaceholder: '可选:如果不填写,系统会自动通过 Refresh Token 获取...',
accessTokenOptionalInfo: 'Access Token 可选填。如果不提供,系统会通过 Refresh Token 自动获取。',
accessTokenRequired: 'Access Token *',
accessTokenRequiredPlaceholder: '请输入 Access Token...',
refreshTokenRequired: 'Refresh Token *',
refreshTokenRequiredPlaceholder: '请输入 Refresh Token必填...',
refreshTokenRequiredInfo: '系统将使用 Refresh Token 自动获取 Access Token 和用户信息',
refreshTokenOptional: 'Refresh Token (可选)',
refreshTokenOptionalPlaceholder: '请输入 Refresh Token...',
// 优先级设置
priorityPlaceholder: '数字越小优先级越高默认50',
priorityDescription: '数字越小优先级越高建议范围1-100',
prioritySchedulingTitle: '调度优先级 (1-100)',
priorityEditPlaceholder: '数字越小优先级越高',
// Gemini 项目ID
projectIdOptional: '项目 ID (可选)',
projectIdPlaceholder: '例如verdant-wares-464411-k9',
projectIdDescription: 'Google Cloud/Workspace 账号可能需要提供项目 ID',
// Claude 订阅类型和高级选项
subscriptionType: '订阅类型',
claudeMaxSubscription: 'Claude Max',
claudeProSubscription: 'Claude Pro',
claudeProLimitation: 'Pro 账号不支持 Claude Opus 4 模型',
autoStopOnWarning: '5小时使用量接近限制时自动停止调度',
autoStopOnWarningDescription: '当系统检测到账户接近5小时使用限制时自动暂停调度该账户。进入新的时间窗口后会自动恢复调度。',
useUnifiedUserAgent: '使用统一 Claude Code 版本',
useUnifiedUserAgentDescription: '开启后将使用从真实 Claude Code 客户端捕获的统一 User-Agent提高兼容性',
currentUnifiedVersion: '当前统一版本:',
clearCache: '清除缓存',
clearing: '清除中...',
waitingForCapture: '等待从 Claude Code 客户端捕获 User-Agent',
captureHint: '💡 提示:如果长时间未能捕获,请确认有 Claude Code 客户端正在使用此账户,或联系开发者检查 User-Agent 格式是否发生变化',
useUnifiedClientId: '使用统一的客户端标识',
useUnifiedClientIdDescription: '开启后将使用固定的客户端标识,使所有请求看起来来自同一个客户端,减少特征',
clientIdLabel: '客户端标识 ID',
regenerateClientId: '重新生成',
clientIdDescription: '此ID将替换请求中的user_id客户端部分保留session部分用于粘性会话',
// 编辑模式字段
accountNameEdit: '账户名称',
accountNameEditPlaceholder: '为账户设置一个易识别的名称',
descriptionOptionalEdit: '描述 (可选)',
descriptionOptionalEditPlaceholder: '账户用途说明...',
accountTypeEdit: '账户类型',
selectGroupRequired: '选择分组 *',
noAvailableGroups: '暂无可用分组',
membersCount: ' 个成员',
createNewGroup: '新建分组'
}
}

View File

@@ -1285,6 +1285,70 @@ export default {
// 通用描述文字
allModelsIfEmpty: '留空表示支援所有模型。如果指定模型,請求中的模型不在列表內將不會排程到此帳號',
systemDefaultIfEmpty: '留空將使用系統預設模型。支援 inference profile ID 或 ARN',
noUpdateIfEmpty: '留空表示不更新該欄位'
noUpdateIfEmpty: '留空表示不更新該欄位',
// 手動 Token 輸入部分
manualTokenInput: '手動輸入 Token',
manualTokenClaudeDescription: '請輸入有效的 Claude Access Token。如果您有 Refresh Token建議也一併填寫以支援自動刷新。',
manualTokenGeminiDescription: '請輸入有效的 Gemini Access Token。如果您有 Refresh Token建議也一併填寫以支援自動刷新。',
manualTokenOpenAIDescription: '請輸入有效的 OpenAI Access Token。如果您有 Refresh Token建議也一併填寫以支援自動刷新。',
getAccessTokenMethod: '取得 Access Token 的方法:',
claudeCredentialsPath: '請從已登入 Claude Code 的機器上取得',
geminiCredentialsPath: '請從已登入 Gemini CLI 的機器上取得',
openaiCredentialsPath: '請從已登入 OpenAI 帳戶的機器上取得認證憑證,或透過 OAuth 授權流程取得 Access Token。',
claudeCredentialsWarning: '檔案中的憑證,請勿使用 Claude 官網 API Keys 頁面的金鑰。',
refreshTokenWarning: '💡 如果未填寫 Refresh TokenToken 過期後需要手動更新。',
accessTokenOptional: 'Access Token (可選)',
accessTokenOptionalPlaceholder: '可選:如果不填寫,系統會自動透過 Refresh Token 取得...',
accessTokenOptionalInfo: 'Access Token 可選填。如果不提供,系統會透過 Refresh Token 自動取得。',
accessTokenRequired: 'Access Token *',
accessTokenRequiredPlaceholder: '請輸入 Access Token...',
refreshTokenRequired: 'Refresh Token *',
refreshTokenRequiredPlaceholder: '請輸入 Refresh Token必填...',
refreshTokenRequiredInfo: '系統將使用 Refresh Token 自動取得 Access Token 和使用者資訊',
refreshTokenOptional: 'Refresh Token (可選)',
refreshTokenOptionalPlaceholder: '請輸入 Refresh Token...',
// 優先級設定
priorityPlaceholder: '數字越小優先級越高預設50',
priorityDescription: '數字越小優先級越高建議範圍1-100',
prioritySchedulingTitle: '排程優先級 (1-100)',
priorityEditPlaceholder: '數字越小優先級越高',
// Gemini 專案ID
projectIdOptional: '專案 ID (可選)',
projectIdPlaceholder: '例如verdant-wares-464411-k9',
projectIdDescription: 'Google Cloud/Workspace 帳號可能需要提供專案 ID',
// Claude 訂閱類型和進階選項
subscriptionType: '訂閱類型',
claudeMaxSubscription: 'Claude Max',
claudeProSubscription: 'Claude Pro',
claudeProLimitation: 'Pro 帳號不支援 Claude Opus 4 模型',
autoStopOnWarning: '5小時使用量接近限制時自動停止排程',
autoStopOnWarningDescription: '當系統檢測到帳戶接近5小時使用限制時自動暫停排程該帳戶。進入新的時間視窗後會自動恢復排程。',
useUnifiedUserAgent: '使用統一 Claude Code 版本',
useUnifiedUserAgentDescription: '開啟後將使用從真實 Claude Code 用戶端捕獲的統一 User-Agent提高相容性',
currentUnifiedVersion: '目前統一版本:',
clearCache: '清除快取',
clearing: '清除中...',
waitingForCapture: '等待從 Claude Code 用戶端捕獲 User-Agent',
captureHint: '💡 提示:如果長時間未能捕獲,請確認有 Claude Code 用戶端正在使用此帳戶,或聯絡開發者檢查 User-Agent 格式是否發生變化',
useUnifiedClientId: '使用統一的用戶端識別',
useUnifiedClientIdDescription: '開啟後將使用固定的用戶端識別,使所有請求看起來來自同一個用戶端,減少特徵',
clientIdLabel: '用戶端識別 ID',
regenerateClientId: '重新產生',
clientIdDescription: '此ID將替換請求中的user_id用戶端部分保留session部分用於黏性工作階段',
// 編輯模式欄位
accountNameEdit: '帳戶名稱',
accountNameEditPlaceholder: '為帳戶設定一個易識別的名稱',
descriptionOptionalEdit: '描述 (可選)',
descriptionOptionalEditPlaceholder: '帳戶用途說明...',
accountTypeEdit: '帳戶類型',
selectGroupRequired: '選擇群組 *',
noAvailableGroups: '暫無可用群組',
membersCount: ' 個成員',
createNewGroup: '新建群組'
}
}