From 27c080421985ea61fc3fe4a865dc760f3c0a5062 Mon Sep 17 00:00:00 2001 From: Wangnov Date: Mon, 8 Sep 2025 21:15:34 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=8C=E6=88=90AccountsView=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2=E5=AE=8C=E6=95=B4=E5=9B=BD=E9=99=85=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加useI18n导入并替换100+硬编码中文文本 - 扩展三种语言文件的accounts翻译键(150+条) - 更新下拉选项为响应式计算属性支持动态翻译 - 国际化页面标题、表格列头、筛选器和操作按钮 - 处理状态文本、错误消息和工具提示 - 更新JavaScript函数返回值使用翻译键 - 完整支持桌面端和移动端视图的国际化 - 修正货币符号和时间格式化的参数化翻译 涵盖组件: - 账户管理主界面(标题、描述、筛选器) - 桌面端表格视图(列头、状态、操作按钮) - 移动端卡片视图(标签、按钮、状态) - 错误处理和确认对话框 - 时间和数值格式化函数 --- web/admin-spa/src/i18n/locales/en.js | 174 ++++++++++++++ web/admin-spa/src/i18n/locales/zh-cn.js | 174 ++++++++++++++ web/admin-spa/src/i18n/locales/zh-tw.js | 174 ++++++++++++++ web/admin-spa/src/views/AccountsView.vue | 280 ++++++++++++----------- 4 files changed, 664 insertions(+), 138 deletions(-) diff --git a/web/admin-spa/src/i18n/locales/en.js b/web/admin-spa/src/i18n/locales/en.js index 52bf99cc..cfc16419 100644 --- a/web/admin-spa/src/i18n/locales/en.js +++ b/web/admin-spa/src/i18n/locales/en.js @@ -316,5 +316,179 @@ export default { date: 'Date', tokenQuantity: 'Token Quantity', requestsQuantity: 'Requests Count' + }, + + // Accounts page + accounts: { + title: 'Account Management', + description: 'Manage your Claude, Gemini, OpenAI and Azure OpenAI accounts and proxy configurations', + + // Filters and sorting + sortBy: 'Select Sort', + selectPlatform: 'Select Platform', + selectGroup: 'Select Group', + refresh: 'Refresh', + refreshTooltip: 'Refresh data (Ctrl/⌘+click to force refresh all caches)', + addAccount: 'Add Account', + + // Sort options + sortByName: 'Sort by Name', + sortByDailyTokens: 'Sort by Daily Tokens', + sortByDailyRequests: 'Sort by Daily Requests', + sortByTotalTokens: 'Sort by Total Tokens', + sortByLastUsed: 'Sort by Last Used', + + // Platform options + allPlatforms: 'All Platforms', + claudePlatform: 'Claude', + claudeConsolePlatform: 'Claude Console', + geminiPlatform: 'Gemini', + openaiPlatform: 'OpenAI', + azureOpenaiPlatform: 'Azure OpenAI', + bedrockPlatform: 'Bedrock', + + // Group options + allAccounts: 'All Accounts', + ungroupedAccounts: 'Ungrouped Accounts', + + // Loading states + loadingAccounts: 'Loading accounts...', + noAccounts: 'No Accounts', + noAccountsHint: 'Click the button above to add your first account', + + // Table headers + name: 'Name', + platformType: 'Platform/Type', + status: 'Status', + priority: 'Priority', + proxy: 'Proxy', + dailyUsage: 'Daily Usage', + sessionWindow: 'Session Window', + lastUsed: 'Last Used', + actions: 'Actions', + + // Account types + dedicated: 'Dedicated', + groupScheduling: 'Group Scheduling', + shared: 'Shared', + belongsToGroup: 'Belongs to group: {name}', + + // Platform labels + unknown: 'Unknown', + apiKey: 'API Key', + oauth: 'OAuth', + setup: 'Setup', + aws: 'AWS', + + // Account status + normal: 'Normal', + abnormal: 'Abnormal', + blocked: 'Blocked', + tempError: 'Temporary Error', + rateLimited: 'Rate Limited', + notSchedulable: 'Not Schedulable', + bound: 'Bound: {count} API Keys', + + // Proxy status + noProxy: 'No Proxy', + + // Usage statistics + requests: ' requests', + noData: 'No Data', + averageRpm: 'Average {rpm} RPM', + + // Session window tooltip + sessionWindowTooltip: { + title: 'Session window progress indicates the time progress of the 5-hour window', + normal: 'Normal: Requests processed normally', + warning: 'Warning: Approaching limit', + rejected: 'Rejected: Rate limit reached' + }, + + // Session window status + remaining: 'Remaining {time}', + ended: 'Ended', + + // Console quota + quotaProgress: 'Quota Progress', + remainingQuota: 'Remaining $${amount}', + reset: 'Reset {time}', + + // Mobile view labels + dailyUsageLabel: 'Daily Usage', + sessionWindowLabel: 'Session Window', + lastUsedLabel: 'Last Used', + proxyLabel: 'Proxy', + priorityLabel: 'Priority', + neverUsed: 'Never Used', + sessionWindowTooltipMobile: 'Session window progress does not represent usage, it only shows the remaining time until the next 5-hour window', + + // Action buttons + resetStatus: 'Reset Status', + resetting: 'Resetting...', + resetStatusTooltip: 'Reset all abnormal statuses', + scheduling: 'Scheduling', + disabled: 'Disabled', + enableTooltip: 'Click to enable scheduling', + disableTooltip: 'Click to disable scheduling', + edit: 'Edit', + editTooltip: 'Edit account', + delete: 'Delete', + deleteTooltip: 'Delete account', + pause: 'Pause', + enable: 'Enable', + + // Time formatting + justNow: 'Just now', + minutesAgo: '{minutes} minutes ago', + hoursAgo: '{hours} hours ago', + daysAgo: '{days} days ago', + hoursAndMinutes: '{hours} hours {minutes} minutes', + hoursOnly: '{hours} hours', + minutesOnly: '{minutes} minutes', + daysAndHours: '{days} days {hours} hours', + daysOnly: '{days} days', + + // Rate limit time + rateLimitTime: '({time})', + + // Messages and confirmations + resetStatusConfirmTitle: 'Reset Account Status', + resetStatusConfirmMessage: 'Are you sure you want to reset all abnormal statuses for this account? This will clear rate limit status, 401 error counts, and all other abnormal flags.', + resetStatusConfirmButton: 'Confirm Reset', + resetStatusCancelButton: 'Cancel', + statusResetSuccess: 'Account status has been reset', + statusResetFailed: 'Status reset failed', + + deleteAccountTitle: 'Delete Account', + deleteAccountMessage: 'Are you sure you want to delete account "{name}"?\n\nThis action cannot be undone.', + deleteAccountButton: 'Delete', + deleteAccountCancel: 'Cancel', + cannotDeleteBoundAccount: 'Cannot delete this account, {count} API Keys are bound to this account, please unbind all API Keys first', + accountDeleted: 'Account deleted', + deleteFailed: 'Delete failed', + + enabledScheduling: 'Scheduling enabled', + disabledScheduling: 'Scheduling disabled', + schedulingToggleFailed: 'Failed to toggle scheduling status', + unsupportedAccountType: 'This account type does not support scheduling control', + operationFailed: 'Operation failed', + + accountCreateSuccess: 'Account created successfully', + accountUpdateSuccess: 'Account updated successfully', + loadAccountsFailed: 'Failed to load accounts', + unsupportedAccountTypeReset: 'Unsupported account type', + + // Schedulable reasons + invalidApiKey: 'API Key invalid or expired (401 error)', + serviceOverload: 'Service overloaded (529 error)', + rateLimitTriggered: 'Rate limit triggered (429 error)', + authFailed: 'Authentication failed (401 error)', + manualStop: 'Manually stopped scheduling', + + // Account type display + claudeMax: 'Claude Max', + claudePro: 'Claude Pro', + claudeFree: 'Claude Free' } } diff --git a/web/admin-spa/src/i18n/locales/zh-cn.js b/web/admin-spa/src/i18n/locales/zh-cn.js index a7be4244..cdf08981 100644 --- a/web/admin-spa/src/i18n/locales/zh-cn.js +++ b/web/admin-spa/src/i18n/locales/zh-cn.js @@ -316,5 +316,179 @@ export default { date: '日期', tokenQuantity: 'Token数量', requestsQuantity: '请求次数' + }, + + // Accounts page + accounts: { + title: '账户管理', + description: '管理您的 Claude、Gemini、OpenAI 和 Azure OpenAI 账户及代理配置', + + // Filters and sorting + sortBy: '选择排序', + selectPlatform: '选择平台', + selectGroup: '选择分组', + refresh: '刷新', + refreshTooltip: '刷新数据 (Ctrl/⌘+点击强制刷新所有缓存)', + addAccount: '添加账户', + + // Sort options + sortByName: '按名称排序', + sortByDailyTokens: '按今日Token排序', + sortByDailyRequests: '按今日请求数排序', + sortByTotalTokens: '按总Token排序', + sortByLastUsed: '按最后使用排序', + + // Platform options + allPlatforms: '所有平台', + claudePlatform: 'Claude', + claudeConsolePlatform: 'Claude Console', + geminiPlatform: 'Gemini', + openaiPlatform: 'OpenAi', + azureOpenaiPlatform: 'Azure OpenAI', + bedrockPlatform: 'Bedrock', + + // Group options + allAccounts: '所有账户', + ungroupedAccounts: '未分组账户', + + // Loading states + loadingAccounts: '正在加载账户...', + noAccounts: '暂无账户', + noAccountsHint: '点击上方按钮添加您的第一个账户', + + // Table headers + name: '名称', + platformType: '平台/类型', + status: '状态', + priority: '优先级', + proxy: '代理', + dailyUsage: '今日使用', + sessionWindow: '会话窗口', + lastUsed: '最后使用', + actions: '操作', + + // Account types + dedicated: '专属', + groupScheduling: '分组调度', + shared: '共享', + belongsToGroup: '所属分组: {name}', + + // Platform labels + unknown: '未知', + apiKey: 'API Key', + oauth: 'OAuth', + setup: 'Setup', + aws: 'AWS', + + // Account status + normal: '正常', + abnormal: '异常', + blocked: '已封锁', + tempError: '临时异常', + rateLimited: '限流中', + notSchedulable: '不可调度', + bound: '绑定: {count} 个API Key', + + // Proxy status + noProxy: '无代理', + + // Usage statistics + requests: '次', + noData: '暂无数据', + averageRpm: '平均 {rpm} RPM', + + // Session window tooltip + sessionWindowTooltip: { + title: '会话窗口进度表示5小时窗口的时间进度', + normal: '正常:请求正常处理', + warning: '警告:接近限制', + rejected: '拒绝:达到速率限制' + }, + + // Session window status + remaining: '剩余 {time}', + ended: '已结束', + + // Console quota + quotaProgress: '额度进度', + remainingQuota: '剩余 $${amount}', + reset: '重置 {time}', + + // Mobile view labels + dailyUsageLabel: '今日使用', + sessionWindowLabel: '会话窗口', + lastUsedLabel: '最后使用', + proxyLabel: '代理', + priorityLabel: '优先级', + neverUsed: '从未使用', + sessionWindowTooltipMobile: '会话窗口进度不代表使用量,仅表示距离下一个5小时窗口的剩余时间', + + // Action buttons + resetStatus: '重置状态', + resetting: '重置中...', + resetStatusTooltip: '重置所有异常状态', + scheduling: '调度', + disabled: '停用', + enableTooltip: '点击启用调度', + disableTooltip: '点击禁用调度', + edit: '编辑', + editTooltip: '编辑账户', + delete: '删除', + deleteTooltip: '删除账户', + pause: '暂停', + enable: '启用', + + // Time formatting + justNow: '刚刚', + minutesAgo: '{minutes} 分钟前', + hoursAgo: '{hours} 小时前', + daysAgo: '{days} 天前', + hoursAndMinutes: '{hours}小时{minutes}分钟', + hoursOnly: '{hours}小时', + minutesOnly: '{minutes}分钟', + daysAndHours: '{days}天{hours}小时', + daysOnly: '{days}天', + + // Rate limit time + rateLimitTime: '({time})', + + // Messages and confirmations + resetStatusConfirmTitle: '重置账户状态', + resetStatusConfirmMessage: '确定要重置此账户的所有异常状态吗?这将清除限流状态、401错误计数等所有异常标记。', + resetStatusConfirmButton: '确定重置', + resetStatusCancelButton: '取消', + statusResetSuccess: '账户状态已重置', + statusResetFailed: '状态重置失败', + + deleteAccountTitle: '删除账户', + deleteAccountMessage: '确定要删除账户 "{name}" 吗?\n\n此操作不可恢复。', + deleteAccountButton: '删除', + deleteAccountCancel: '取消', + cannotDeleteBoundAccount: '无法删除此账号,有 {count} 个API Key绑定到此账号,请先解绑所有API Key', + accountDeleted: '账户已删除', + deleteFailed: '删除失败', + + enabledScheduling: '已启用调度', + disabledScheduling: '已禁用调度', + schedulingToggleFailed: '切换调度状态失败', + unsupportedAccountType: '该账户类型暂不支持调度控制', + operationFailed: '操作失败', + + accountCreateSuccess: '账户创建成功', + accountUpdateSuccess: '账户更新成功', + loadAccountsFailed: '加载账户失败', + unsupportedAccountTypeReset: '不支持的账户类型', + + // Schedulable reasons + invalidApiKey: 'API Key无效或已过期(401错误)', + serviceOverload: '服务过载(529错误)', + rateLimitTriggered: '触发限流(429错误)', + authFailed: '认证失败(401错误)', + manualStop: '手动停止调度', + + // Account type display + claudeMax: 'Claude Max', + claudePro: 'Claude Pro', + claudeFree: 'Claude Free' } } diff --git a/web/admin-spa/src/i18n/locales/zh-tw.js b/web/admin-spa/src/i18n/locales/zh-tw.js index b4e61a50..f58fc472 100644 --- a/web/admin-spa/src/i18n/locales/zh-tw.js +++ b/web/admin-spa/src/i18n/locales/zh-tw.js @@ -316,5 +316,179 @@ export default { date: '日期', tokenQuantity: 'Token數量', requestsQuantity: '請求次數' + }, + + // Accounts page + accounts: { + title: '帳戶管理', + description: '管理您的 Claude、Gemini、OpenAI 和 Azure OpenAI 帳戶及代理配置', + + // Filters and sorting + sortBy: '選擇排序', + selectPlatform: '選擇平台', + selectGroup: '選擇分組', + refresh: '刷新', + refreshTooltip: '刷新資料 (Ctrl/⌘+點擊強制刷新所有快取)', + addAccount: '添加帳戶', + + // Sort options + sortByName: '按名稱排序', + sortByDailyTokens: '按今日Token排序', + sortByDailyRequests: '按今日請求數排序', + sortByTotalTokens: '按總Token排序', + sortByLastUsed: '按最後使用排序', + + // Platform options + allPlatforms: '所有平台', + claudePlatform: 'Claude', + claudeConsolePlatform: 'Claude Console', + geminiPlatform: 'Gemini', + openaiPlatform: 'OpenAi', + azureOpenaiPlatform: 'Azure OpenAI', + bedrockPlatform: 'Bedrock', + + // Group options + allAccounts: '所有帳戶', + ungroupedAccounts: '未分組帳戶', + + // Loading states + loadingAccounts: '正在載入帳戶...', + noAccounts: '暫無帳戶', + noAccountsHint: '點擊上方按鈕添加您的第一個帳戶', + + // Table headers + name: '名稱', + platformType: '平台/類型', + status: '狀態', + priority: '優先級', + proxy: '代理', + dailyUsage: '今日使用', + sessionWindow: '會話窗口', + lastUsed: '最後使用', + actions: '操作', + + // Account types + dedicated: '專屬', + groupScheduling: '分組調度', + shared: '共享', + belongsToGroup: '所屬分組: {name}', + + // Platform labels + unknown: '未知', + apiKey: 'API Key', + oauth: 'OAuth', + setup: 'Setup', + aws: 'AWS', + + // Account status + normal: '正常', + abnormal: '異常', + blocked: '已封鎖', + tempError: '臨時異常', + rateLimited: '限流中', + notSchedulable: '不可調度', + bound: '綁定: {count} 個API Key', + + // Proxy status + noProxy: '無代理', + + // Usage statistics + requests: '次', + noData: '暫無資料', + averageRpm: '平均 {rpm} RPM', + + // Session window tooltip + sessionWindowTooltip: { + title: '會話窗口進度表示5小時窗口的時間進度', + normal: '正常:請求正常處理', + warning: '警告:接近限制', + rejected: '拒絕:達到速率限制' + }, + + // Session window status + remaining: '剩餘 {time}', + ended: '已結束', + + // Console quota + quotaProgress: '額度進度', + remainingQuota: '剩餘 $${amount}', + reset: '重置 {time}', + + // Mobile view labels + dailyUsageLabel: '今日使用', + sessionWindowLabel: '會話窗口', + lastUsedLabel: '最後使用', + proxyLabel: '代理', + priorityLabel: '優先級', + neverUsed: '從未使用', + sessionWindowTooltipMobile: '會話窗口進度不代表使用量,僅表示距離下一個5小時窗口的剩餘時間', + + // Action buttons + resetStatus: '重置狀態', + resetting: '重置中...', + resetStatusTooltip: '重置所有異常狀態', + scheduling: '調度', + disabled: '停用', + enableTooltip: '點擊啟用調度', + disableTooltip: '點擊禁用調度', + edit: '編輯', + editTooltip: '編輯帳戶', + delete: '刪除', + deleteTooltip: '刪除帳戶', + pause: '暫停', + enable: '啟用', + + // Time formatting + justNow: '剛剛', + minutesAgo: '{minutes} 分鐘前', + hoursAgo: '{hours} 小時前', + daysAgo: '{days} 天前', + hoursAndMinutes: '{hours}小時{minutes}分鐘', + hoursOnly: '{hours}小時', + minutesOnly: '{minutes}分鐘', + daysAndHours: '{days}天{hours}小時', + daysOnly: '{days}天', + + // Rate limit time + rateLimitTime: '({time})', + + // Messages and confirmations + resetStatusConfirmTitle: '重置帳戶狀態', + resetStatusConfirmMessage: '確定要重置此帳戶的所有異常狀態嗎?這將清除限流狀態、401錯誤計數等所有異常標記。', + resetStatusConfirmButton: '確定重置', + resetStatusCancelButton: '取消', + statusResetSuccess: '帳戶狀態已重置', + statusResetFailed: '狀態重置失敗', + + deleteAccountTitle: '刪除帳戶', + deleteAccountMessage: '確定要刪除帳戶 "{name}" 嗎?\n\n此操作不可恢復。', + deleteAccountButton: '刪除', + deleteAccountCancel: '取消', + cannotDeleteBoundAccount: '無法刪除此帳號,有 {count} 個API Key綁定到此帳號,請先解綁所有API Key', + accountDeleted: '帳戶已刪除', + deleteFailed: '刪除失敗', + + enabledScheduling: '已啟用調度', + disabledScheduling: '已禁用調度', + schedulingToggleFailed: '切換調度狀態失敗', + unsupportedAccountType: '該帳戶類型暫不支持調度控制', + operationFailed: '操作失敗', + + accountCreateSuccess: '帳戶創建成功', + accountUpdateSuccess: '帳戶更新成功', + loadAccountsFailed: '載入帳戶失敗', + unsupportedAccountTypeReset: '不支持的帳戶類型', + + // Schedulable reasons + invalidApiKey: 'API Key無效或已過期(401錯誤)', + serviceOverload: '服務過載(529錯誤)', + rateLimitTriggered: '觸發限流(429錯誤)', + authFailed: '認證失敗(401錯誤)', + manualStop: '手動停止調度', + + // Account type display + claudeMax: 'Claude Max', + claudePro: 'Claude Pro', + claudeFree: 'Claude Free' } } diff --git a/web/admin-spa/src/views/AccountsView.vue b/web/admin-spa/src/views/AccountsView.vue index 779d140d..a3edc5ed 100644 --- a/web/admin-spa/src/views/AccountsView.vue +++ b/web/admin-spa/src/views/AccountsView.vue @@ -4,10 +4,10 @@

- 账户管理 + {{ t('accounts.title') }}

- 管理您的 Claude、Gemini、OpenAI、Azure OpenAI、OpenAI-Responses 与 CCR 账户及代理配置 + {{ t('accounts.description') }}

@@ -23,7 +23,7 @@ icon="fa-sort-amount-down" icon-color="text-indigo-500" :options="sortOptions" - placeholder="选择排序" + :placeholder="t('accounts.sortBy')" @change="sortAccounts()" />
@@ -38,7 +38,7 @@ icon="fa-server" icon-color="text-blue-500" :options="platformOptions" - placeholder="选择平台" + :placeholder="t('accounts.selectPlatform')" @change="filterByPlatform" />
@@ -53,7 +53,7 @@ icon="fa-layer-group" icon-color="text-purple-500" :options="groupOptions" - placeholder="选择分组" + :placeholder="t('accounts.selectGroup')" @change="filterByGroup" /> @@ -61,7 +61,7 @@
@@ -81,7 +81,7 @@ accountsLoading ? 'fa-spinner fa-spin' : 'fa-sync-alt' ]" /> - 刷新 + {{ t('accounts.refresh') }}
@@ -93,14 +93,14 @@ @click.stop="openCreateAccountModal" > - 添加账户 + {{ t('accounts.addAccount') }}
-

正在加载账户...

+

{{ t('accounts.loadingAccounts') }}

@@ -109,8 +109,8 @@ >
-

暂无账户

-

点击上方按钮添加您的第一个账户

+

{{ t('accounts.noAccounts') }}

+

{{ t('accounts.noAccountsHint') }}

@@ -122,7 +122,7 @@ class="w-[22%] min-w-[180px] cursor-pointer px-3 py-4 text-left text-xs font-bold uppercase tracking-wider text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-600" @click="sortAccounts('name')" > - 名称 + {{ t('accounts.name') }} - 平台/类型 + {{ t('accounts.platformType') }} - 状态 + {{ t('accounts.status') }} - 优先级 + {{ t('accounts.priority') }} - 代理 + {{ t('accounts.proxy') }} - 今日使用 + {{ t('accounts.dailyUsage') }}
- 会话窗口 + {{ t('accounts.sessionWindow') }}