feat: 完成 AccountForm.vue 组件的国际化文本替换

- 将多个文本替换为 i18n 语言包中的键,以提升多语言支持和一致性。
- 更新了模型支持描述、用户代理描述、凭证文件描述等文本内容。
- 通过引入 i18n 键,增强了用户界面的可读性和可维护性。
This commit is contained in:
Wangnov
2025-09-11 20:45:27 +08:00
parent 5ea3623736
commit 99d72516ae
6 changed files with 235 additions and 91 deletions

View File

@@ -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')

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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 () => {
// 加载所有数据

View File

@@ -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>