mirror of
https://github.com/Wei-Shaw/claude-relay-service.git
synced 2026-01-22 16:43:35 +00:00
feat: 完成 AccountForm.vue 组件的国际化文本替换
- 将多个文本替换为 i18n 语言包中的键,以提升多语言支持和一致性。 - 更新了模型支持描述、用户代理描述、凭证文件描述等文本内容。 - 通过引入 i18n 键,增强了用户界面的可读性和可维护性。
This commit is contained in:
@@ -806,7 +806,7 @@
|
||||
</button>
|
||||
</div>
|
||||
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">
|
||||
留空表示支持所有模型。如果指定模型,请求中的模型不在列表内将不会调度到此账号
|
||||
{{ t('accountForm.modelSupportDescription') }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -821,7 +821,7 @@
|
||||
type="text"
|
||||
/>
|
||||
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">
|
||||
留空时将自动使用客户端的 User-Agent,仅在需要固定特定 UA 时填写
|
||||
{{ t('accountForm.userAgentDescription') }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -995,7 +995,7 @@
|
||||
@click="regenerateClientId"
|
||||
>
|
||||
<i class="fas fa-sync-alt mr-1" />
|
||||
重新生成
|
||||
{{ t('accountForm.regenerateButton') }}
|
||||
</button>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
@@ -1103,7 +1103,7 @@
|
||||
<code class="rounded bg-blue-100 px-1 py-0.5 font-mono dark:bg-blue-900/50"
|
||||
>~/.config/gemini/credentials.json</code
|
||||
>
|
||||
文件中的凭证。
|
||||
{{ t('accountForm.credentialsFileDescription') }}
|
||||
</p>
|
||||
<p
|
||||
v-else-if="form.platform === 'openai'"
|
||||
@@ -1267,7 +1267,7 @@
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<p class="mb-2 font-medium text-blue-900 dark:text-blue-200">
|
||||
点击下方按钮生成授权链接
|
||||
{{ t('accountForm.clickToGenerateAuthLink') }}
|
||||
</p>
|
||||
<button
|
||||
v-if="!setupTokenAuthUrl"
|
||||
@@ -1326,10 +1326,10 @@
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<p class="mb-2 font-medium text-blue-900 dark:text-blue-200">
|
||||
在浏览器中打开链接并完成授权
|
||||
{{ t('accountForm.openLinkInBrowser') }}
|
||||
</p>
|
||||
<p class="mb-2 text-sm text-blue-700 dark:text-blue-300">
|
||||
请在新标签页中打开授权链接,登录您的 Claude 账户并授权 Claude Code。
|
||||
{{ t('accountForm.openAuthLinkDescription') }}
|
||||
</p>
|
||||
<div
|
||||
class="rounded border border-yellow-300 bg-yellow-50 p-3 dark:border-yellow-700 dark:bg-yellow-900/30"
|
||||
@@ -1337,7 +1337,7 @@
|
||||
<p class="text-xs text-yellow-800 dark:text-yellow-300">
|
||||
<i class="fas fa-exclamation-triangle mr-1" />
|
||||
<strong>{{ t('accountForm.attentionLabel') }}</strong
|
||||
>如果您设置了代理,请确保浏览器也使用相同的代理访问授权页面。
|
||||
>{{ t('accountForm.proxyWarning') }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1356,10 +1356,10 @@
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<p class="mb-2 font-medium text-blue-900 dark:text-blue-200">
|
||||
输入 Authorization Code
|
||||
{{ t('accountForm.enterAuthorizationCode') }}
|
||||
</p>
|
||||
<p class="mb-3 text-sm text-blue-700 dark:text-blue-300">
|
||||
授权完成后,从返回页面复制 Authorization Code,并粘贴到下方输入框:
|
||||
{{ t('accountForm.copyAuthCodeDescription') }}
|
||||
</p>
|
||||
<div class="space-y-3">
|
||||
<div>
|
||||
@@ -1377,7 +1377,7 @@
|
||||
</div>
|
||||
<p class="mt-2 text-xs text-gray-500 dark:text-gray-400">
|
||||
<i class="fas fa-info-circle mr-1" />
|
||||
请粘贴从Claude Code授权页面复制的Authorization Code
|
||||
{{ t('accountForm.authCodeInputHint') }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1761,7 +1761,7 @@
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label class="mb-3 block text-sm font-semibold text-gray-700 dark:text-gray-300">
|
||||
每日额度限制 ($)
|
||||
{{ t('accountForm.dailyQuotaLimitLabel') }}
|
||||
</label>
|
||||
<input
|
||||
v-model.number="form.dailyQuota"
|
||||
@@ -1772,13 +1772,13 @@
|
||||
type="number"
|
||||
/>
|
||||
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">
|
||||
设置每日使用额度,0 表示不限制
|
||||
{{ t('accountForm.dailyQuotaDescription') }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="mb-3 block text-sm font-semibold text-gray-700 dark:text-gray-300">
|
||||
额度重置时间
|
||||
{{ t('accountForm.quotaResetTimeLabel') }}
|
||||
</label>
|
||||
<input
|
||||
v-model="form.quotaResetTime"
|
||||
@@ -1786,7 +1786,9 @@
|
||||
placeholder="00:00"
|
||||
type="time"
|
||||
/>
|
||||
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">每日自动重置额度的时间</p>
|
||||
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">
|
||||
{{ t('accountForm.quotaResetTimeDescription') }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1797,7 +1799,7 @@
|
||||
>
|
||||
<div class="mb-2 flex items-center justify-between">
|
||||
<span class="text-sm font-semibold text-gray-700 dark:text-gray-300">
|
||||
今日使用情况
|
||||
{{ t('accountForm.todayUsageLabel') }}
|
||||
</span>
|
||||
<span class="text-sm text-gray-500 dark:text-gray-400">
|
||||
${{ calculateCurrentUsage().toFixed(4) }} / ${{ form.dailyQuota.toFixed(2) }}
|
||||
@@ -1818,22 +1820,26 @@
|
||||
</div>
|
||||
<div class="mt-2 flex items-center justify-between text-xs">
|
||||
<span class="text-gray-500 dark:text-gray-400">
|
||||
剩余: ${{ Math.max(0, form.dailyQuota - calculateCurrentUsage()).toFixed(2) }}
|
||||
{{
|
||||
t('accountForm.remainingQuota', {
|
||||
amount: Math.max(0, form.dailyQuota - calculateCurrentUsage()).toFixed(2)
|
||||
})
|
||||
}}
|
||||
</span>
|
||||
<span class="text-gray-500 dark:text-gray-400">
|
||||
{{ usagePercentage.toFixed(1) }}% 已使用
|
||||
{{ t('accountForm.usedPercentage', { percentage: usagePercentage.toFixed(1) }) }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="mb-3 block text-sm font-semibold text-gray-700"
|
||||
>模型映射表 (可选)</label
|
||||
>
|
||||
<label class="mb-3 block text-sm font-semibold text-gray-700">{{
|
||||
t('accountForm.modelMappingTableLabel')
|
||||
}}</label>
|
||||
<div class="mb-3 rounded-lg bg-blue-50 p-3">
|
||||
<p class="text-xs text-blue-700">
|
||||
<i class="fas fa-info-circle mr-1" />
|
||||
留空表示支持所有模型且不修改请求。配置映射后,左侧模型会被识别为支持的模型,右侧是实际发送的模型。
|
||||
{{ t('accountForm.modelMappingTableDescription') }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -1911,14 +1917,14 @@
|
||||
</button>
|
||||
</div>
|
||||
<p class="mt-1 text-xs text-gray-500">
|
||||
留空表示支持所有模型。如果指定模型,请求中的模型不在列表内将不会调度到此账号
|
||||
{{ t('accountForm.modelSupportDescription') }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="mb-3 block text-sm font-semibold text-gray-700"
|
||||
>自定义 User-Agent (可选)</label
|
||||
>
|
||||
<label class="mb-3 block text-sm font-semibold text-gray-700">{{
|
||||
t('accountForm.customUserAgentLabel')
|
||||
}}</label>
|
||||
<input
|
||||
v-model="form.userAgent"
|
||||
class="form-input w-full"
|
||||
@@ -1926,7 +1932,7 @@
|
||||
type="text"
|
||||
/>
|
||||
<p class="mt-1 text-xs text-gray-500">
|
||||
留空时将自动使用客户端的 User-Agent,仅在需要固定特定 UA 时填写
|
||||
{{ t('accountForm.userAgentDescription') }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -1946,21 +1952,23 @@
|
||||
}}</span>
|
||||
</label>
|
||||
<p class="mt-1 text-xs text-gray-500">
|
||||
启用后,当账号返回429错误时将暂停调度一段时间
|
||||
{{ t('accountForm.rateLimitDescription') }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div v-if="form.enableRateLimit">
|
||||
<label class="mb-3 block text-sm font-semibold text-gray-700"
|
||||
>限流时间 (分钟)</label
|
||||
>
|
||||
<label class="mb-3 block text-sm font-semibold text-gray-700">{{
|
||||
t('accountForm.rateLimitDurationLabel')
|
||||
}}</label>
|
||||
<input
|
||||
v-model.number="form.rateLimitDuration"
|
||||
class="form-input w-full"
|
||||
min="1"
|
||||
type="number"
|
||||
/>
|
||||
<p class="mt-1 text-xs text-gray-500">账号被限流后暂停调度的时间(分钟)</p>
|
||||
<p class="mt-1 text-xs text-gray-500">
|
||||
{{ t('accountForm.rateLimitDurationDescription') }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -2011,14 +2019,14 @@
|
||||
<div class="flex items-start gap-2">
|
||||
<i class="fas fa-info-circle mt-0.5 text-blue-600" />
|
||||
<div class="text-xs text-blue-700">
|
||||
<p class="mb-1 font-medium">常用 AWS 区域参考:</p>
|
||||
<p class="mb-1 font-medium">{{ t('accountForm.awsRegionReferenceTitle') }}</p>
|
||||
<div class="grid grid-cols-2 gap-1 text-xs">
|
||||
<span>• us-east-1 (美国东部)</span>
|
||||
<span>• us-west-2 (美国西部)</span>
|
||||
<span>• eu-west-1 (欧洲爱尔兰)</span>
|
||||
<span>• ap-southeast-1 (新加坡)</span>
|
||||
<span>• ap-northeast-1 (东京)</span>
|
||||
<span>• eu-central-1 (法兰克福)</span>
|
||||
<span>{{ t('accountForm.awsRegionUsEast1') }}</span>
|
||||
<span>{{ t('accountForm.awsRegionUsWest2') }}</span>
|
||||
<span>{{ t('accountForm.awsRegionEuWest1') }}</span>
|
||||
<span>{{ t('accountForm.awsRegionApSoutheast1') }}</span>
|
||||
<span>{{ t('accountForm.awsRegionApNortheast1') }}</span>
|
||||
<span>{{ t('accountForm.awsRegionEuCentral1') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -2083,21 +2091,23 @@
|
||||
}}</span>
|
||||
</label>
|
||||
<p class="mt-1 text-xs text-gray-500">
|
||||
启用后,当账号返回429错误时将暂停调度一段时间
|
||||
{{ t('accountForm.rateLimitDescription') }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div v-if="form.enableRateLimit">
|
||||
<label class="mb-3 block text-sm font-semibold text-gray-700"
|
||||
>限流时间 (分钟)</label
|
||||
>
|
||||
<label class="mb-3 block text-sm font-semibold text-gray-700">{{
|
||||
t('accountForm.rateLimitDurationLabel')
|
||||
}}</label>
|
||||
<input
|
||||
v-model.number="form.rateLimitDuration"
|
||||
class="form-input w-full"
|
||||
min="1"
|
||||
type="number"
|
||||
/>
|
||||
<p class="mt-1 text-xs text-gray-500">账号被限流后暂停调度的时间(分钟)</p>
|
||||
<p class="mt-1 text-xs text-gray-500">
|
||||
{{ t('accountForm.rateLimitDurationDescription') }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -2199,7 +2209,9 @@
|
||||
<span class="text-sm text-gray-700 dark:text-gray-300">{{ model }}</span>
|
||||
</label>
|
||||
</div>
|
||||
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">选择此部署支持的模型类型</p>
|
||||
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">
|
||||
{{ t('accountForm.azureModelTypeDescription') }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2223,9 +2235,11 @@
|
||||
{{ t('accountForm.updateTokenLabel') }}
|
||||
</h5>
|
||||
<p class="mb-2 text-sm text-amber-800 dark:text-amber-300">
|
||||
可以更新 Access Token 和 Refresh Token。为了安全起见,不会显示当前的 Token 值。
|
||||
{{ t('accountForm.tokenUpdateDescription') }}
|
||||
</p>
|
||||
<p class="text-xs text-amber-600 dark:text-amber-400">
|
||||
{{ t('accountForm.tokenUpdateHint') }}
|
||||
</p>
|
||||
<p class="text-xs text-amber-600 dark:text-amber-400">💡 留空表示不更新该字段。</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2265,7 +2279,7 @@
|
||||
type="button"
|
||||
@click="$emit('close')"
|
||||
>
|
||||
取消
|
||||
{{ t('accountForm.cancelButton') }}
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-primary flex-1 px-6 py-3 font-semibold"
|
||||
@@ -2504,7 +2518,7 @@ const usagePercentage = computed(() => {
|
||||
return (currentUsage / form.value.dailyQuota) * 100
|
||||
})
|
||||
|
||||
// 加载账户今日使用情况
|
||||
// 加载账户{{ t('accountForm.todayUsageLabel') }}
|
||||
const loadAccountUsage = async () => {
|
||||
if (!isEdit.value || !props.account?.id) return
|
||||
|
||||
@@ -2603,7 +2617,7 @@ const generateSetupTokenAuthUrl = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
// 重新生成Setup Token授权URL
|
||||
// {{ t('accountForm.regenerateButton') }}Setup Token授权URL
|
||||
const regenerateSetupTokenAuthUrl = () => {
|
||||
setupTokenAuthUrl.value = ''
|
||||
setupTokenAuthCode.value = ''
|
||||
@@ -3771,7 +3785,7 @@ const generateClientId = () => {
|
||||
return Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('')
|
||||
}
|
||||
|
||||
// 重新生成客户端标识
|
||||
// {{ t('accountForm.regenerateButton') }}客户端标识
|
||||
const regenerateClientId = () => {
|
||||
form.value.unifiedClientId = generateClientId()
|
||||
showToast(t('accountForm.newClientIdGenerated'), 'success')
|
||||
|
||||
@@ -155,7 +155,11 @@ export default {
|
||||
minutesAgo: '{minutes} minutes ago',
|
||||
hoursAgo: '{hours} hours ago',
|
||||
daysAgo: '{days} days ago'
|
||||
}
|
||||
},
|
||||
|
||||
// API Keys page buttons
|
||||
model: 'Model',
|
||||
stats: 'Stats'
|
||||
},
|
||||
language: {
|
||||
zh: '简体中文',
|
||||
@@ -2815,7 +2819,41 @@ export default {
|
||||
|
||||
// Claude subscription type display
|
||||
claudeMaxDisplay: 'Claude Max',
|
||||
claudeProDisplay: 'Claude Pro'
|
||||
claudeProDisplay: 'Claude Pro',
|
||||
|
||||
// Missing translation keys for AccountForm
|
||||
modelSupportDescription:
|
||||
'Leave empty to support all models. If models are specified, requests with models not in the list will not be scheduled to this account',
|
||||
regenerateButton: 'Regenerate',
|
||||
cancelButton: 'Cancel',
|
||||
credentialsFileDescription: 'credentials from file.',
|
||||
authCodeInputHint:
|
||||
'Please paste the Authorization Code copied from Claude Code authorization page',
|
||||
dailyQuotaLimitLabel: 'Daily Quota Limit ($)',
|
||||
todayUsageLabel: "Today's Usage",
|
||||
remainingQuota: 'Remaining: ${amount}',
|
||||
usedPercentage: '{percentage}% Used',
|
||||
modelMappingTableLabel: 'Model Mapping Table (Optional)',
|
||||
modelMappingTableDescription:
|
||||
'Leave empty to support all models without modifying requests. After configuration, left models will be recognized as supported models, right models are actually sent.',
|
||||
customUserAgentLabel: 'Custom User-Agent (Optional)',
|
||||
rateLimitDurationLabel: 'Rate Limit Duration (Minutes)',
|
||||
awsRegionReferenceTitle: 'Common AWS Regions Reference:',
|
||||
azureModelTypeDescription: 'Select model types supported by this deployment',
|
||||
tokenUpdateDescription:
|
||||
'You can update Access Token and Refresh Token. For security reasons, current Token values will not be displayed.',
|
||||
tokenUpdateHint: '💡 Leave empty to keep current value unchanged.',
|
||||
|
||||
// Setup Token Flow Translations
|
||||
clickToGenerateAuthLink: 'Click to generate authorization link',
|
||||
openLinkInBrowser: 'Open link in browser and complete authorization',
|
||||
openAuthLinkDescription:
|
||||
'Please open the authorization link in a new tab, log in to your Claude account and authorize.',
|
||||
proxyWarning:
|
||||
'Note: If you have configured a proxy, please ensure your browser also uses the same proxy to access the authorization page.',
|
||||
enterAuthorizationCode: 'Enter Authorization Code',
|
||||
copyAuthCodeDescription:
|
||||
'After authorization is complete, copy the Authorization Code from the return page and paste it into the input box below:'
|
||||
},
|
||||
|
||||
// OAuth Flow Component
|
||||
|
||||
@@ -155,7 +155,11 @@ export default {
|
||||
minutesAgo: '{minutes}分钟前',
|
||||
hoursAgo: '{hours}小时前',
|
||||
daysAgo: '{days}天前'
|
||||
}
|
||||
},
|
||||
|
||||
// API Keys 页面按钮
|
||||
model: '模型',
|
||||
stats: '统计'
|
||||
},
|
||||
language: {
|
||||
zh: '简体中文',
|
||||
@@ -1982,6 +1986,9 @@ export default {
|
||||
webhookUrlRequired: '*',
|
||||
webhookUrlPlaceholder: 'https://...',
|
||||
editModeWarning: '编辑模式下不能更改平台类型',
|
||||
cannotChangePlatformType: '编辑模式下不能更改平台类型',
|
||||
serverUrl: '服务器地址',
|
||||
requiredField: '必填项',
|
||||
|
||||
// Bark 特有设置
|
||||
deviceKey: '设备密钥 (Device Key)',
|
||||
@@ -2742,7 +2749,37 @@ export default {
|
||||
|
||||
// Claude 订阅类型显示
|
||||
claudeMaxDisplay: 'Claude Max',
|
||||
claudeProDisplay: 'Claude Pro'
|
||||
claudeProDisplay: 'Claude Pro',
|
||||
|
||||
// 新增缺失的翻译键
|
||||
modelSupportDescription:
|
||||
'留空表示支持所有模型。如果指定模型,请求中的模型不在列表内将不会调度到此账号',
|
||||
regenerateButton: '重新生成',
|
||||
cancelButton: '取消',
|
||||
credentialsFileDescription: '文件中的凭证。',
|
||||
authCodeInputHint: '请粘贴从Claude Code授权页面复制的Authorization Code',
|
||||
dailyQuotaLimitLabel: '每日额度限制 ($)',
|
||||
todayUsageLabel: '今日使用情况',
|
||||
remainingQuota: '剩余: ${amount}',
|
||||
usedPercentage: '{percentage}% 已使用',
|
||||
modelMappingTableLabel: '模型映射表 (可选)',
|
||||
modelMappingTableDescription:
|
||||
'留空表示支持所有模型且不修改请求。配置映射后,左侧模型会被识别为支持的模型,右侧是实际发送的模型。',
|
||||
customUserAgentLabel: '自定义 User-Agent (可选)',
|
||||
rateLimitDurationLabel: '限流时间 (分钟)',
|
||||
awsRegionReferenceTitle: '常用 AWS 区域参考:',
|
||||
azureModelTypeDescription: '选择此部署支持的模型类型',
|
||||
tokenUpdateDescription:
|
||||
'可以更新 Access Token 和 Refresh Token。为了安全起见,不会显示当前的 Token 值。',
|
||||
tokenUpdateHint: '💡 留空表示不更新该字段。',
|
||||
|
||||
// Setup Token 流程翻译
|
||||
clickToGenerateAuthLink: '点击生成授权链接',
|
||||
openLinkInBrowser: '在浏览器中打开链接并完成授权',
|
||||
openAuthLinkDescription: '请在新标签页中打开授权链接,登录您的 Claude 账户并授权。',
|
||||
proxyWarning: '注意:如果您配置了代理,请确保浏览器也使用相同的代理访问授权页面。',
|
||||
enterAuthorizationCode: '输入授权码',
|
||||
copyAuthCodeDescription: '授权完成后,从返回页面复制 Authorization Code,并粘贴到下方输入框:'
|
||||
},
|
||||
|
||||
// OAuth Flow Component
|
||||
|
||||
@@ -155,7 +155,11 @@ export default {
|
||||
minutesAgo: '{minutes}分鐘前',
|
||||
hoursAgo: '{hours}小時前',
|
||||
daysAgo: '{days}天前'
|
||||
}
|
||||
},
|
||||
|
||||
// API Keys 頁面按鈕
|
||||
model: '模型',
|
||||
stats: '統計'
|
||||
},
|
||||
language: {
|
||||
zh: '簡體中文',
|
||||
@@ -2747,7 +2751,37 @@ export default {
|
||||
|
||||
// Claude 訂閱類型顯示
|
||||
claudeMaxDisplay: 'Claude Max',
|
||||
claudeProDisplay: 'Claude Pro'
|
||||
claudeProDisplay: 'Claude Pro',
|
||||
|
||||
// 新增缺失的翻譯鍵
|
||||
modelSupportDescription:
|
||||
'留空表示支援所有模型。如果指定模型,請求中的模型不在列表內將不會調度到此帳戶',
|
||||
regenerateButton: '重新產生',
|
||||
cancelButton: '取消',
|
||||
credentialsFileDescription: '檔案中的憑證。',
|
||||
authCodeInputHint: '請貼上從 Claude Code 授權頁面複製的 Authorization Code',
|
||||
dailyQuotaLimitLabel: '每日額度限制 ($)',
|
||||
todayUsageLabel: '今日使用情況',
|
||||
remainingQuota: '剩餘: ${amount}',
|
||||
usedPercentage: '{percentage}% 已使用',
|
||||
modelMappingTableLabel: '模型映射表 (可選)',
|
||||
modelMappingTableDescription:
|
||||
'留空表示支援所有模型且不修改請求。配置映射後,左側模型會被識別為支援的模型,右側是實際發送的模型。',
|
||||
customUserAgentLabel: '自定義 User-Agent (可選)',
|
||||
rateLimitDurationLabel: '限流時間 (分鐘)',
|
||||
awsRegionReferenceTitle: '常用 AWS 區域參考:',
|
||||
azureModelTypeDescription: '選擇此部署支援的模型類型',
|
||||
tokenUpdateDescription:
|
||||
'可以更新 Access Token 和 Refresh Token。為了安全起見,不會顯示當前的 Token 值。',
|
||||
tokenUpdateHint: '💡 留空表示不更新該欄位。',
|
||||
|
||||
// Setup Token 流程翻譯
|
||||
clickToGenerateAuthLink: '點擊產生授權連結',
|
||||
openLinkInBrowser: '在瀏覽器中開啟連結並完成授權',
|
||||
openAuthLinkDescription: '請在新分頁中開啟授權連結,登錄您的 Claude 帳戶並授權。',
|
||||
proxyWarning: '注意:如果您配置了代理,請確保瀏覽器也使用相同的代理訪問授權頁面。',
|
||||
enterAuthorizationCode: '輸入授權碼',
|
||||
copyAuthCodeDescription: '授權完成後,從返回頁面複製 Authorization Code,並貼上到下方輸入框:'
|
||||
},
|
||||
|
||||
// OAuth Flow Component
|
||||
|
||||
@@ -663,7 +663,7 @@ import Chart from 'chart.js/auto'
|
||||
|
||||
const dashboardStore = useDashboardStore()
|
||||
const themeStore = useThemeStore()
|
||||
const { t } = useI18n()
|
||||
const { t, locale } = useI18n()
|
||||
const { isDarkMode } = storeToRefs(themeStore)
|
||||
|
||||
const {
|
||||
@@ -1337,6 +1337,15 @@ watch(isDarkMode, () => {
|
||||
})
|
||||
})
|
||||
|
||||
// 监听语言变化,重新创建图表
|
||||
watch(locale, () => {
|
||||
nextTick(() => {
|
||||
createModelUsageChart()
|
||||
createUsageTrendChart()
|
||||
createApiKeysUsageTrendChart()
|
||||
})
|
||||
})
|
||||
|
||||
// 初始化
|
||||
onMounted(async () => {
|
||||
// 加载所有数据
|
||||
|
||||
@@ -467,13 +467,15 @@
|
||||
class="mb-6 rounded-lg bg-white/80 p-6 shadow-lg backdrop-blur-sm dark:bg-gray-800/80"
|
||||
>
|
||||
<div class="mb-4 flex items-center justify-between">
|
||||
<h2 class="text-lg font-semibold text-gray-800 dark:text-gray-200">通知平台</h2>
|
||||
<h2 class="text-lg font-semibold text-gray-800 dark:text-gray-200">
|
||||
{{ t('settings.notificationPlatforms') }}
|
||||
</h2>
|
||||
<button
|
||||
class="rounded-lg bg-blue-600 px-4 py-2 text-sm font-medium text-white transition-colors hover:bg-blue-700"
|
||||
@click="showAddPlatformModal = true"
|
||||
>
|
||||
<i class="fas fa-plus mr-2"></i>
|
||||
添加平台
|
||||
{{ t('settings.addPlatform') }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -510,7 +512,7 @@
|
||||
class="flex items-center text-gray-600 dark:text-gray-400"
|
||||
>
|
||||
<i class="fas fa-shield-alt mr-2"></i>
|
||||
<span>已启用签名验证</span>
|
||||
<span>{{ t('settings.enableSignature') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -556,17 +558,19 @@
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="py-8 text-center text-gray-500 dark:text-gray-400">
|
||||
暂无配置的通知平台,请点击"添加平台"按钮添加
|
||||
{{ t('settings.noPlatforms') }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 高级设置 -->
|
||||
<div class="rounded-lg bg-white/80 p-6 shadow-lg backdrop-blur-sm dark:bg-gray-800/80">
|
||||
<h2 class="mb-4 text-lg font-semibold text-gray-800 dark:text-gray-200">高级设置</h2>
|
||||
<h2 class="mb-4 text-lg font-semibold text-gray-800 dark:text-gray-200">
|
||||
{{ t('settings.advancedSettings') }}
|
||||
</h2>
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-3">
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300">
|
||||
最大重试次数
|
||||
{{ t('settings.maxRetries') }}
|
||||
</label>
|
||||
<input
|
||||
v-model.number="webhookConfig.retrySettings.maxRetries"
|
||||
@@ -579,7 +583,7 @@
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300">
|
||||
重试延迟 (毫秒)
|
||||
{{ t('settings.retryDelay') }}
|
||||
</label>
|
||||
<input
|
||||
v-model.number="webhookConfig.retrySettings.retryDelay"
|
||||
@@ -593,7 +597,7 @@
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300">
|
||||
超时时间 (毫秒)
|
||||
{{ t('settings.timeout') }}
|
||||
</label>
|
||||
<input
|
||||
v-model.number="webhookConfig.retrySettings.timeout"
|
||||
@@ -615,7 +619,7 @@
|
||||
@click="sendTestNotification"
|
||||
>
|
||||
<i class="fas fa-paper-plane mr-2"></i>
|
||||
发送测试通知
|
||||
{{ t('settings.sendTestNotification') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -646,10 +650,12 @@
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="text-xl font-semibold text-gray-900 dark:text-white">
|
||||
{{ editingPlatform ? '编辑' : '添加' }}通知平台
|
||||
{{
|
||||
editingPlatform ? t('settings.editPlatformModal') : t('settings.addPlatformModal')
|
||||
}}
|
||||
</h3>
|
||||
<p class="mt-0.5 text-sm text-gray-600 dark:text-gray-400">
|
||||
配置{{ editingPlatform ? '并更新' : '新的' }}Webhook通知渠道
|
||||
{{ t('settings.configurePlatform') }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -671,7 +677,7 @@
|
||||
class="mb-2 flex items-center text-sm font-medium text-gray-700 dark:text-gray-300"
|
||||
>
|
||||
<i class="fas fa-layer-group mr-2 text-gray-400"></i>
|
||||
平台类型
|
||||
{{ t('settings.platformType') }}
|
||||
</label>
|
||||
<div class="relative">
|
||||
<select
|
||||
@@ -679,13 +685,13 @@
|
||||
class="w-full appearance-none rounded-xl border border-gray-300 bg-white px-4 py-3 pr-10 text-gray-900 shadow-sm transition-all focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-500/20 dark:border-gray-600 dark:bg-gray-700 dark:text-white"
|
||||
:disabled="editingPlatform"
|
||||
>
|
||||
<option value="wechat_work">🟢 企业微信</option>
|
||||
<option value="dingtalk">🔵 钉钉</option>
|
||||
<option value="feishu">🟦 飞书</option>
|
||||
<option value="slack">🟣 Slack</option>
|
||||
<option value="discord">🟪 Discord</option>
|
||||
<option value="bark">🔔 Bark</option>
|
||||
<option value="custom">⚙️ 自定义</option>
|
||||
<option value="wechat_work">🟢 {{ t('settings.platforms.wechatWork') }}</option>
|
||||
<option value="dingtalk">🔵 {{ t('settings.platforms.dingtalk') }}</option>
|
||||
<option value="feishu">🟦 {{ t('settings.platforms.feishu') }}</option>
|
||||
<option value="slack">🟣 {{ t('settings.platforms.slack') }}</option>
|
||||
<option value="discord">🟪 {{ t('settings.platforms.discord') }}</option>
|
||||
<option value="bark">🔔 {{ t('settings.platforms.bark') }}</option>
|
||||
<option value="custom">⚙️ {{ t('settings.platforms.custom') }}</option>
|
||||
</select>
|
||||
<div class="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3">
|
||||
<i class="fas fa-chevron-down text-gray-400"></i>
|
||||
@@ -693,7 +699,7 @@
|
||||
</div>
|
||||
<p v-if="editingPlatform" class="mt-1 text-xs text-amber-600 dark:text-amber-400">
|
||||
<i class="fas fa-info-circle mr-1"></i>
|
||||
编辑模式下不能更改平台类型
|
||||
{{ t('settings.cannotChangePlatformType') }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -703,13 +709,13 @@
|
||||
class="mb-2 flex items-center text-sm font-medium text-gray-700 dark:text-gray-300"
|
||||
>
|
||||
<i class="fas fa-tag mr-2 text-gray-400"></i>
|
||||
名称
|
||||
<span class="ml-2 text-xs text-gray-500">(可选)</span>
|
||||
{{ t('settings.platformName') }}
|
||||
<span class="ml-2 text-xs text-gray-500">{{ t('settings.optional') }}</span>
|
||||
</label>
|
||||
<input
|
||||
v-model="platformForm.name"
|
||||
class="w-full rounded-xl border border-gray-300 bg-white px-4 py-3 text-gray-900 shadow-sm transition-all placeholder:text-gray-400 focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-500/20 dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:placeholder:text-gray-500"
|
||||
placeholder="例如:运维群通知、开发测试群"
|
||||
:placeholder="t('settings.platformNamePlaceholder')"
|
||||
type="text"
|
||||
/>
|
||||
</div>
|
||||
@@ -720,7 +726,7 @@
|
||||
class="mb-2 flex items-center text-sm font-medium text-gray-700 dark:text-gray-300"
|
||||
>
|
||||
<i class="fas fa-link mr-2 text-gray-400"></i>
|
||||
Webhook URL
|
||||
{{ t('settings.webhookUrl') }}
|
||||
<span class="ml-1 text-xs text-red-500">*</span>
|
||||
</label>
|
||||
<div class="relative">
|
||||
@@ -762,7 +768,7 @@
|
||||
class="mb-2 flex items-center text-sm font-medium text-gray-700 dark:text-gray-300"
|
||||
>
|
||||
<i class="fas fa-key mr-2 text-gray-400"></i>
|
||||
设备密钥 (Device Key)
|
||||
{{ t('settings.deviceKey') }}
|
||||
<span class="ml-1 text-xs text-red-500">*</span>
|
||||
</label>
|
||||
<input
|
||||
@@ -783,8 +789,8 @@
|
||||
class="mb-2 flex items-center text-sm font-medium text-gray-700 dark:text-gray-300"
|
||||
>
|
||||
<i class="fas fa-server mr-2 text-gray-400"></i>
|
||||
服务器地址
|
||||
<span class="ml-2 text-xs text-gray-500">(可选)</span>
|
||||
{{ t('settings.serverUrl') }}
|
||||
<span class="ml-2 text-xs text-gray-500">{{ t('settings.optional') }}</span>
|
||||
</label>
|
||||
<input
|
||||
v-model="platformForm.serverUrl"
|
||||
@@ -800,7 +806,7 @@
|
||||
class="mb-2 flex items-center text-sm font-medium text-gray-700 dark:text-gray-300"
|
||||
>
|
||||
<i class="fas fa-flag mr-2 text-gray-400"></i>
|
||||
通知级别
|
||||
{{ t('settings.notificationLevel') }}
|
||||
</label>
|
||||
<select
|
||||
v-model="platformForm.level"
|
||||
@@ -820,7 +826,7 @@
|
||||
class="mb-2 flex items-center text-sm font-medium text-gray-700 dark:text-gray-300"
|
||||
>
|
||||
<i class="fas fa-volume-up mr-2 text-gray-400"></i>
|
||||
通知声音
|
||||
{{ t('settings.notificationSound') }}
|
||||
</label>
|
||||
<select
|
||||
v-model="platformForm.sound"
|
||||
@@ -926,7 +932,7 @@
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="text-xs text-gray-500 dark:text-gray-400">
|
||||
<i class="fas fa-asterisk mr-1 text-red-500"></i>
|
||||
必填项
|
||||
{{ t('settings.requiredField') }}
|
||||
</div>
|
||||
<div class="flex space-x-3">
|
||||
<button
|
||||
@@ -934,7 +940,7 @@
|
||||
@click="closePlatformModal"
|
||||
>
|
||||
<i class="fas fa-times mr-2 transition-transform group-hover:scale-110"></i>
|
||||
取消
|
||||
{{ t('common.cancel') }}
|
||||
</button>
|
||||
<button
|
||||
class="group flex items-center rounded-xl border border-blue-200 bg-blue-50 px-4 py-2.5 text-sm font-medium text-blue-700 shadow-sm transition-all hover:bg-blue-100 hover:shadow-md dark:border-blue-800 dark:bg-blue-900/50 dark:text-blue-300 dark:hover:bg-blue-900/70"
|
||||
@@ -947,7 +953,7 @@
|
||||
testingConnection ? 'fas fa-spinner fa-spin' : 'fas fa-vial group-hover:scale-110'
|
||||
"
|
||||
></i>
|
||||
{{ testingConnection ? '测试中...' : '测试连接' }}
|
||||
{{ testingConnection ? t('settings.testing') : t('settings.testConnection') }}
|
||||
</button>
|
||||
<button
|
||||
class="group flex items-center rounded-xl bg-gradient-to-r from-blue-600 to-indigo-600 px-5 py-2.5 text-sm font-medium text-white shadow-md transition-all hover:from-blue-700 hover:to-indigo-700 hover:shadow-lg disabled:cursor-not-allowed disabled:from-gray-400 disabled:to-gray-500"
|
||||
@@ -960,7 +966,13 @@
|
||||
savingPlatform ? 'fas fa-spinner fa-spin' : 'fas fa-save group-hover:scale-110'
|
||||
"
|
||||
></i>
|
||||
{{ savingPlatform ? '保存中...' : editingPlatform ? '保存修改' : '添加平台' }}
|
||||
{{
|
||||
savingPlatform
|
||||
? t('settings.saving')
|
||||
: editingPlatform
|
||||
? t('settings.saveChanges')
|
||||
: t('settings.addPlatform')
|
||||
}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user