mirror of
https://github.com/router-for-me/Cli-Proxy-API-Management-Center.git
synced 2026-02-02 19:00:49 +08:00
- Added functionality for importing Vertex AI credentials, including file selection and upload handling in the CLIProxyManager. - Updated UI components in index.html to support the new Vertex AI credential import feature. - Enhanced internationalization strings to provide appropriate labels and messages for the Vertex AI import functionality in both English and Chinese. - Introduced new styles for the Vertex AI credential import section to ensure a consistent user experience.
1082 lines
63 KiB
JavaScript
1082 lines
63 KiB
JavaScript
// 国际化语言包
|
||
const i18n = {
|
||
// 语言配置
|
||
currentLanguage: 'zh-CN',
|
||
fallbackLanguage: 'zh-CN',
|
||
|
||
// 语言包
|
||
translations: {
|
||
'zh-CN': {
|
||
// 通用
|
||
'common.login': '登录',
|
||
'common.logout': '登出',
|
||
'common.cancel': '取消',
|
||
'common.confirm': '确认',
|
||
'common.save': '保存',
|
||
'common.delete': '删除',
|
||
'common.edit': '编辑',
|
||
'common.add': '添加',
|
||
'common.update': '更新',
|
||
'common.refresh': '刷新',
|
||
'common.close': '关闭',
|
||
'common.success': '成功',
|
||
'common.error': '错误',
|
||
'common.info': '信息',
|
||
'common.warning': '警告',
|
||
'common.loading': '加载中...',
|
||
'common.connecting': '连接中...',
|
||
'common.connected': '已连接',
|
||
'common.disconnected': '未连接',
|
||
'common.connecting_status': '连接中',
|
||
'common.connected_status': '已连接',
|
||
'common.disconnected_status': '未连接',
|
||
'common.yes': '是',
|
||
'common.no': '否',
|
||
'common.optional': '可选',
|
||
'common.required': '必填',
|
||
'common.api_key': '密钥',
|
||
'common.base_url': '地址',
|
||
'common.proxy_url': '代理',
|
||
'common.alias': '别名',
|
||
'common.failure': '失败',
|
||
'common.unknown_error': '未知错误',
|
||
'common.copy': '复制',
|
||
'common.custom_headers_label': '自定义请求头',
|
||
'common.custom_headers_hint': '可选,设置需要附带到请求中的 HTTP 头,名称和值均不能为空。',
|
||
'common.custom_headers_add': '添加请求头',
|
||
'common.custom_headers_key_placeholder': 'Header 名称,例如 X-Custom-Header',
|
||
'common.custom_headers_value_placeholder': 'Header 值',
|
||
|
||
// 页面标题
|
||
'title.main': 'CLI Proxy API Management Center',
|
||
'title.login': 'CLI Proxy API Management Center',
|
||
|
||
// 自动登录
|
||
'auto_login.title': '正在自动登录...',
|
||
'auto_login.message': '正在使用本地保存的连接信息尝试连接服务器',
|
||
|
||
// 登录页面
|
||
'login.subtitle': '请输入连接信息以访问管理界面',
|
||
'login.connection_title': '连接地址',
|
||
'login.connection_current': '当前地址',
|
||
'login.connection_auto_hint': '系统将自动使用当前访问地址进行连接',
|
||
'login.custom_connection_label': '自定义连接地址:',
|
||
'login.custom_connection_placeholder': '例如: https://example.com:8317',
|
||
'login.custom_connection_hint': '默认使用当前访问地址,若需要可手动输入其他地址。',
|
||
'login.use_current_address': '使用当前地址',
|
||
'login.management_key_label': '管理密钥:',
|
||
'login.management_key_placeholder': '请输入管理密钥',
|
||
'login.connect_button': '连接',
|
||
'login.submit_button': '登录',
|
||
'login.submitting': '连接中...',
|
||
'login.error_title': '登录失败',
|
||
'login.error_required': '请填写完整的连接信息',
|
||
'login.error_invalid': '连接失败,请检查地址和密钥',
|
||
|
||
// 头部导航
|
||
'header.check_connection': '检查连接',
|
||
'header.refresh_all': '刷新全部',
|
||
'header.logout': '登出',
|
||
|
||
// 连接信息
|
||
'connection.title': '连接信息',
|
||
'connection.server_address': '服务器地址:',
|
||
'connection.management_key': '管理密钥:',
|
||
'connection.status': '连接状态:',
|
||
|
||
// 侧边栏导航
|
||
'nav.basic_settings': '基础设置',
|
||
'nav.api_keys': 'API 密钥',
|
||
'nav.ai_providers': 'AI 提供商',
|
||
'nav.auth_files': '认证文件',
|
||
'nav.usage_stats': '使用统计',
|
||
'nav.config_management': '配置管理',
|
||
'nav.logs': '日志查看',
|
||
'nav.system_info': '系统信息',
|
||
|
||
// 基础设置
|
||
'basic_settings.title': '基础设置',
|
||
'basic_settings.debug_title': '调试模式',
|
||
'basic_settings.debug_enable': '启用调试模式',
|
||
'basic_settings.proxy_title': '代理设置',
|
||
'basic_settings.proxy_url_label': '代理 URL:',
|
||
'basic_settings.proxy_url_placeholder': '例如: socks5://user:pass@127.0.0.1:1080/',
|
||
'basic_settings.proxy_update': '更新',
|
||
'basic_settings.proxy_clear': '清空',
|
||
'basic_settings.retry_title': '请求重试',
|
||
'basic_settings.retry_count_label': '重试次数:',
|
||
'basic_settings.retry_update': '更新',
|
||
'basic_settings.quota_title': '配额超出行为',
|
||
'basic_settings.quota_switch_project': '自动切换项目',
|
||
'basic_settings.quota_switch_preview': '切换到预览模型',
|
||
'basic_settings.usage_statistics_title': '使用统计',
|
||
'basic_settings.usage_statistics_enable': '启用使用统计',
|
||
'basic_settings.logging_title': '日志记录',
|
||
'basic_settings.logging_to_file_enable': '启用日志记录到文件',
|
||
'basic_settings.request_log_enable': '启用请求日志',
|
||
'basic_settings.ws_auth_title': 'WebSocket 鉴权',
|
||
'basic_settings.ws_auth_enable': '启用 /ws/* 鉴权',
|
||
|
||
// API 密钥管理
|
||
'api_keys.title': 'API 密钥管理',
|
||
'api_keys.proxy_auth_title': '代理服务认证密钥',
|
||
'api_keys.add_button': '添加密钥',
|
||
'api_keys.empty_title': '暂无API密钥',
|
||
'api_keys.empty_desc': '点击上方按钮添加第一个密钥',
|
||
'api_keys.item_title': 'API密钥',
|
||
'api_keys.add_modal_title': '添加API密钥',
|
||
'api_keys.add_modal_key_label': 'API密钥:',
|
||
'api_keys.add_modal_key_placeholder': '请输入API密钥',
|
||
'api_keys.edit_modal_title': '编辑API密钥',
|
||
'api_keys.edit_modal_key_label': 'API密钥:',
|
||
'api_keys.delete_confirm': '确定要删除这个API密钥吗?',
|
||
|
||
// AI 提供商
|
||
'ai_providers.title': 'AI 提供商配置',
|
||
'ai_providers.gemini_title': 'Gemini API 密钥',
|
||
'ai_providers.gemini_add_button': '添加密钥',
|
||
'ai_providers.gemini_empty_title': '暂无Gemini密钥',
|
||
'ai_providers.gemini_empty_desc': '点击上方按钮添加第一个密钥',
|
||
'ai_providers.gemini_item_title': 'Gemini密钥',
|
||
'ai_providers.gemini_add_modal_title': '添加Gemini API密钥',
|
||
'ai_providers.gemini_add_modal_key_label': 'API密钥列表:',
|
||
'ai_providers.gemini_add_modal_key_placeholder': '请输入Gemini API密钥(每行一个)',
|
||
'ai_providers.gemini_add_modal_key_hint': '可一次粘贴多个密钥,每行一个。',
|
||
'ai_providers.gemini_add_modal_url_label': 'Base URL (可选):',
|
||
'ai_providers.gemini_add_modal_url_placeholder': '例如: https://generativelanguage.googleapis.com',
|
||
'ai_providers.gemini_edit_modal_title': '编辑Gemini API密钥',
|
||
'ai_providers.gemini_edit_modal_key_label': 'API密钥:',
|
||
'ai_providers.gemini_edit_modal_url_label': 'Base URL (可选):',
|
||
'ai_providers.gemini_delete_confirm': '确定要删除这个Gemini密钥吗?',
|
||
|
||
'ai_providers.codex_title': 'Codex API 配置',
|
||
'ai_providers.codex_add_button': '添加配置',
|
||
'ai_providers.codex_empty_title': '暂无Codex配置',
|
||
'ai_providers.codex_empty_desc': '点击上方按钮添加第一个配置',
|
||
'ai_providers.codex_item_title': 'Codex配置',
|
||
'ai_providers.codex_add_modal_title': '添加Codex API配置',
|
||
'ai_providers.codex_add_modal_key_label': 'API密钥:',
|
||
'ai_providers.codex_add_modal_key_placeholder': '请输入Codex API密钥',
|
||
'ai_providers.codex_add_modal_url_label': 'Base URL (必填):',
|
||
'ai_providers.codex_add_modal_url_placeholder': '例如: https://api.example.com',
|
||
'ai_providers.codex_add_modal_proxy_label': '代理 URL (可选):',
|
||
'ai_providers.codex_add_modal_proxy_placeholder': '例如: socks5://proxy.example.com:1080',
|
||
'ai_providers.codex_edit_modal_title': '编辑Codex API配置',
|
||
'ai_providers.codex_edit_modal_key_label': 'API密钥:',
|
||
'ai_providers.codex_edit_modal_url_label': 'Base URL (必填):',
|
||
'ai_providers.codex_edit_modal_proxy_label': '代理 URL (可选):',
|
||
'ai_providers.codex_delete_confirm': '确定要删除这个Codex配置吗?',
|
||
|
||
'ai_providers.claude_title': 'Claude API 配置',
|
||
'ai_providers.claude_add_button': '添加配置',
|
||
'ai_providers.claude_empty_title': '暂无Claude配置',
|
||
'ai_providers.claude_empty_desc': '点击上方按钮添加第一个配置',
|
||
'ai_providers.claude_item_title': 'Claude配置',
|
||
'ai_providers.claude_add_modal_title': '添加Claude API配置',
|
||
'ai_providers.claude_add_modal_key_label': 'API密钥:',
|
||
'ai_providers.claude_add_modal_key_placeholder': '请输入Claude API密钥',
|
||
'ai_providers.claude_add_modal_url_label': 'Base URL (可选):',
|
||
'ai_providers.claude_add_modal_url_placeholder': '例如: https://api.anthropic.com',
|
||
'ai_providers.claude_add_modal_proxy_label': '代理 URL (可选):',
|
||
'ai_providers.claude_add_modal_proxy_placeholder': '例如: socks5://proxy.example.com:1080',
|
||
'ai_providers.claude_edit_modal_title': '编辑Claude API配置',
|
||
'ai_providers.claude_edit_modal_key_label': 'API密钥:',
|
||
'ai_providers.claude_edit_modal_url_label': 'Base URL (可选):',
|
||
'ai_providers.claude_edit_modal_proxy_label': '代理 URL (可选):',
|
||
'ai_providers.claude_delete_confirm': '确定要删除这个Claude配置吗?',
|
||
|
||
'ai_providers.openai_title': 'OpenAI 兼容提供商',
|
||
'ai_providers.openai_add_button': '添加提供商',
|
||
'ai_providers.openai_empty_title': '暂无OpenAI兼容提供商',
|
||
'ai_providers.openai_empty_desc': '点击上方按钮添加第一个提供商',
|
||
'ai_providers.openai_add_modal_title': '添加OpenAI兼容提供商',
|
||
'ai_providers.openai_add_modal_name_label': '提供商名称:',
|
||
'ai_providers.openai_add_modal_name_placeholder': '例如: openrouter',
|
||
'ai_providers.openai_add_modal_url_label': 'Base URL:',
|
||
'ai_providers.openai_add_modal_url_placeholder': '例如: https://openrouter.ai/api/v1',
|
||
'ai_providers.openai_add_modal_keys_label': 'API密钥 (每行一个):',
|
||
'ai_providers.openai_add_modal_keys_placeholder': 'sk-key1\nsk-key2',
|
||
'ai_providers.openai_add_modal_keys_proxy_label': '代理 URL (按行对应,可选):',
|
||
'ai_providers.openai_add_modal_keys_proxy_placeholder': 'socks5://proxy.example.com:1080\n',
|
||
'ai_providers.openai_add_modal_models_label': '模型列表 (name[, alias] 每行一个):',
|
||
'ai_providers.openai_models_hint': '示例:gpt-4o-mini 或 moonshotai/kimi-k2:free, kimi-k2',
|
||
'ai_providers.openai_model_name_placeholder': '模型名称,如 moonshotai/kimi-k2:free',
|
||
'ai_providers.openai_model_alias_placeholder': '模型别名 (可选)',
|
||
'ai_providers.openai_models_add_btn': '添加模型',
|
||
'ai_providers.openai_edit_modal_title': '编辑OpenAI兼容提供商',
|
||
'ai_providers.openai_edit_modal_name_label': '提供商名称:',
|
||
'ai_providers.openai_edit_modal_url_label': 'Base URL:',
|
||
'ai_providers.openai_edit_modal_keys_label': 'API密钥 (每行一个):',
|
||
'ai_providers.openai_edit_modal_keys_proxy_label': '代理 URL (按行对应,可选):',
|
||
'ai_providers.openai_edit_modal_models_label': '模型列表 (name[, alias] 每行一个):',
|
||
'ai_providers.openai_delete_confirm': '确定要删除这个OpenAI提供商吗?',
|
||
'ai_providers.openai_keys_count': '密钥数量',
|
||
'ai_providers.openai_models_count': '模型数量',
|
||
|
||
|
||
// 认证文件管理
|
||
'auth_files.title': '认证文件管理',
|
||
'auth_files.title_section': '认证文件',
|
||
'auth_files.description': '这里集中管理 CLI Proxy 支持的所有 JSON 认证文件(如 Qwen、Gemini、Vertex 等),上传后即可在运行时启用相应的 AI 服务。',
|
||
'auth_files.upload_button': '上传文件',
|
||
'auth_files.delete_all_button': '删除全部',
|
||
'auth_files.empty_title': '暂无认证文件',
|
||
'auth_files.empty_desc': '点击上方按钮上传第一个文件',
|
||
'auth_files.file_size': '大小',
|
||
'auth_files.file_modified': '修改时间',
|
||
'auth_files.download_button': '下载',
|
||
'auth_files.delete_button': '删除',
|
||
'auth_files.delete_confirm': '确定要删除文件',
|
||
'auth_files.delete_all_confirm': '确定要删除所有认证文件吗?此操作不可恢复!',
|
||
'auth_files.delete_filtered_confirm': '确定要删除筛选出的 {type} 认证文件吗?此操作不可恢复!',
|
||
'auth_files.upload_error_json': '只能上传JSON文件',
|
||
'auth_files.upload_success': '文件上传成功',
|
||
'auth_files.download_success': '文件下载成功',
|
||
'auth_files.delete_success': '文件删除成功',
|
||
'auth_files.delete_all_success': '成功删除',
|
||
'auth_files.delete_filtered_success': '成功删除 {count} 个 {type} 认证文件',
|
||
'auth_files.delete_filtered_partial': '{type} 认证文件删除完成,成功 {success} 个,失败 {failed} 个',
|
||
'auth_files.delete_filtered_none': '当前筛选类型 ({type}) 下没有可删除的认证文件',
|
||
'auth_files.files_count': '个文件',
|
||
'auth_files.filter_all': '全部',
|
||
'auth_files.filter_qwen': 'Qwen',
|
||
'auth_files.filter_gemini': 'Gemini',
|
||
'auth_files.filter_gemini-cli': 'GeminiCLI',
|
||
'auth_files.filter_aistudio': 'AIStudio',
|
||
'auth_files.filter_claude': 'Claude',
|
||
'auth_files.filter_codex': 'Codex',
|
||
'auth_files.filter_iflow': 'iFlow',
|
||
'auth_files.filter_vertex': 'Vertex',
|
||
'auth_files.filter_empty': '空文件',
|
||
'auth_files.filter_unknown': '其他',
|
||
'auth_files.type_qwen': 'Qwen',
|
||
'auth_files.type_gemini': 'Gemini',
|
||
'auth_files.type_gemini-cli': 'GeminiCLI',
|
||
'auth_files.type_aistudio': 'AIStudio',
|
||
'auth_files.type_claude': 'Claude',
|
||
'auth_files.type_codex': 'Codex',
|
||
'auth_files.type_iflow': 'iFlow',
|
||
'auth_files.type_vertex': 'Vertex',
|
||
'auth_files.type_empty': '空文件',
|
||
'auth_files.type_unknown': '其他',
|
||
'vertex_import.title': 'Vertex AI 凭证导入',
|
||
'vertex_import.description': '上传 Google 服务账号 JSON,使用 CLI vertex-import 同步规则写入 auth-dir/vertex-<project>.json。',
|
||
'vertex_import.location_label': '目标区域 (可选)',
|
||
'vertex_import.location_placeholder': 'us-central1',
|
||
'vertex_import.location_hint': '留空表示使用默认区域 us-central1。',
|
||
'vertex_import.file_label': '服务账号密钥 JSON',
|
||
'vertex_import.file_hint': '仅支持 Google Cloud service account key JSON 文件,私钥会自动规范化。',
|
||
'vertex_import.file_placeholder': '尚未选择文件',
|
||
'vertex_import.choose_file': '选择文件',
|
||
'vertex_import.import_button': '导入 Vertex 凭证',
|
||
'vertex_import.file_required': '请先选择 .json 凭证文件',
|
||
'vertex_import.success': 'Vertex 凭证导入成功',
|
||
'vertex_import.result_title': '凭证已保存',
|
||
'vertex_import.result_project': '项目 ID',
|
||
'vertex_import.result_email': '服务账号',
|
||
'vertex_import.result_location': '区域',
|
||
'vertex_import.result_file': '存储文件',
|
||
|
||
|
||
// Codex OAuth
|
||
'auth_login.codex_oauth_title': 'Codex OAuth',
|
||
'auth_login.codex_oauth_button': '开始 Codex 登录',
|
||
'auth_login.codex_oauth_hint': '通过 OAuth 流程登录 Codex 服务,自动获取并保存认证文件。',
|
||
'auth_login.codex_oauth_url_label': '授权链接:',
|
||
'auth_login.codex_open_link': '打开链接',
|
||
'auth_login.codex_copy_link': '复制链接',
|
||
'auth_login.codex_oauth_status_waiting': '等待认证中...',
|
||
'auth_login.codex_oauth_status_success': '认证成功!',
|
||
'auth_login.codex_oauth_status_error': '认证失败:',
|
||
'auth_login.codex_oauth_start_error': '启动 Codex OAuth 失败:',
|
||
'auth_login.codex_oauth_polling_error': '检查认证状态失败:',
|
||
|
||
// Anthropic OAuth
|
||
'auth_login.anthropic_oauth_title': 'Anthropic OAuth',
|
||
'auth_login.anthropic_oauth_button': '开始 Anthropic 登录',
|
||
'auth_login.anthropic_oauth_hint': '通过 OAuth 流程登录 Anthropic (Claude) 服务,自动获取并保存认证文件。',
|
||
'auth_login.anthropic_oauth_url_label': '授权链接:',
|
||
'auth_login.anthropic_open_link': '打开链接',
|
||
'auth_login.anthropic_copy_link': '复制链接',
|
||
'auth_login.anthropic_oauth_status_waiting': '等待认证中...',
|
||
'auth_login.anthropic_oauth_status_success': '认证成功!',
|
||
'auth_login.anthropic_oauth_status_error': '认证失败:',
|
||
'auth_login.anthropic_oauth_start_error': '启动 Anthropic OAuth 失败:',
|
||
'auth_login.anthropic_oauth_polling_error': '检查认证状态失败:',
|
||
|
||
// Gemini CLI OAuth
|
||
'auth_login.gemini_cli_oauth_title': 'Gemini CLI OAuth',
|
||
'auth_login.gemini_cli_oauth_button': '开始 Gemini CLI 登录',
|
||
'auth_login.gemini_cli_oauth_hint': '通过 OAuth 流程登录 Google Gemini CLI 服务,自动获取并保存认证文件。',
|
||
'auth_login.gemini_cli_project_id_label': 'Google Cloud 项目 ID (可选):',
|
||
'auth_login.gemini_cli_project_id_placeholder': '输入 Google Cloud 项目 ID (可选)',
|
||
'auth_login.gemini_cli_project_id_hint': '如果指定了项目 ID,将使用该项目的认证信息。',
|
||
'auth_login.gemini_cli_oauth_url_label': '授权链接:',
|
||
'auth_login.gemini_cli_open_link': '打开链接',
|
||
'auth_login.gemini_cli_copy_link': '复制链接',
|
||
'auth_login.gemini_cli_oauth_status_waiting': '等待认证中...',
|
||
'auth_login.gemini_cli_oauth_status_success': '认证成功!',
|
||
'auth_login.gemini_cli_oauth_status_error': '认证失败:',
|
||
'auth_login.gemini_cli_oauth_start_error': '启动 Gemini CLI OAuth 失败:',
|
||
'auth_login.gemini_cli_oauth_polling_error': '检查认证状态失败:',
|
||
|
||
// Qwen OAuth
|
||
'auth_login.qwen_oauth_title': 'Qwen OAuth',
|
||
'auth_login.qwen_oauth_button': '开始 Qwen 登录',
|
||
'auth_login.qwen_oauth_hint': '通过设备授权流程登录 Qwen 服务,自动获取并保存认证文件。',
|
||
'auth_login.qwen_oauth_url_label': '授权链接:',
|
||
'auth_login.qwen_open_link': '打开链接',
|
||
'auth_login.qwen_copy_link': '复制链接',
|
||
'auth_login.qwen_oauth_status_waiting': '等待认证中...',
|
||
'auth_login.qwen_oauth_status_success': '认证成功!',
|
||
'auth_login.qwen_oauth_status_error': '认证失败:',
|
||
'auth_login.qwen_oauth_start_error': '启动 Qwen OAuth 失败:',
|
||
'auth_login.qwen_oauth_polling_error': '检查认证状态失败:',
|
||
'auth_login.missing_state': '无法获取认证状态参数',
|
||
|
||
// iFlow OAuth
|
||
'auth_login.iflow_oauth_title': 'iFlow OAuth',
|
||
'auth_login.iflow_oauth_button': '开始 iFlow 登录',
|
||
'auth_login.iflow_oauth_hint': '通过 OAuth 流程登录 iFlow 服务,自动获取并保存认证文件。',
|
||
'auth_login.iflow_oauth_url_label': '授权链接:',
|
||
'auth_login.iflow_open_link': '打开链接',
|
||
'auth_login.iflow_copy_link': '复制链接',
|
||
'auth_login.iflow_oauth_status_waiting': '等待认证中...',
|
||
'auth_login.iflow_oauth_status_success': '认证成功!',
|
||
'auth_login.iflow_oauth_status_error': '认证失败:',
|
||
'auth_login.iflow_oauth_start_error': '启动 iFlow OAuth 失败:',
|
||
'auth_login.iflow_oauth_polling_error': '检查认证状态失败:',
|
||
|
||
// 使用统计
|
||
'usage_stats.title': '使用统计',
|
||
'usage_stats.total_requests': '总请求数',
|
||
'usage_stats.success_requests': '成功请求',
|
||
'usage_stats.failed_requests': '失败请求',
|
||
'usage_stats.total_tokens': '总Token数',
|
||
'usage_stats.requests_trend': '请求趋势',
|
||
'usage_stats.tokens_trend': 'Token 使用趋势',
|
||
'usage_stats.api_details': 'API 详细统计',
|
||
'usage_stats.by_hour': '按小时',
|
||
'usage_stats.by_day': '按天',
|
||
'usage_stats.refresh': '刷新',
|
||
'usage_stats.no_data': '暂无数据',
|
||
'usage_stats.loading_error': '加载失败',
|
||
'usage_stats.api_endpoint': 'API端点',
|
||
'usage_stats.requests_count': '请求次数',
|
||
'usage_stats.tokens_count': 'Token数量',
|
||
'usage_stats.models': '模型统计',
|
||
'usage_stats.success_rate': '成功率',
|
||
'stats.success': '成功',
|
||
'stats.failure': '失败',
|
||
|
||
// 日志查看
|
||
'logs.title': '日志查看',
|
||
'logs.refresh_button': '刷新日志',
|
||
'logs.clear_button': '清空日志',
|
||
'logs.download_button': '下载日志',
|
||
'logs.empty_title': '暂无日志记录',
|
||
'logs.empty_desc': '当启用"日志记录到文件"功能后,日志将显示在这里',
|
||
'logs.log_content': '日志内容',
|
||
'logs.loading': '正在加载日志...',
|
||
'logs.load_error': '加载日志失败',
|
||
'logs.clear_confirm': '确定要清空所有日志吗?此操作不可恢复!',
|
||
'logs.clear_success': '日志已清空',
|
||
'logs.download_success': '日志下载成功',
|
||
'logs.auto_refresh': '自动刷新',
|
||
'logs.auto_refresh_enabled': '自动刷新已开启',
|
||
'logs.auto_refresh_disabled': '自动刷新已关闭',
|
||
'logs.lines': '行',
|
||
'logs.removed': '已删除',
|
||
'logs.upgrade_required_title': '需要升级 CLI Proxy API',
|
||
'logs.upgrade_required_desc': '当前服务器版本不支持日志查看功能,请升级到最新版本的 CLI Proxy API 以使用此功能。',
|
||
|
||
// 配置管理
|
||
'config_management.title': '配置管理',
|
||
'config_management.editor_title': '配置文件',
|
||
'config_management.reload': '重新加载',
|
||
'config_management.save': '保存',
|
||
'config_management.description': '查看并编辑服务器上的 config.yaml 配置文件。保存前请确认语法正确。',
|
||
'config_management.status_idle': '等待操作',
|
||
'config_management.status_loading': '加载配置中...',
|
||
'config_management.status_loaded': '配置已加载',
|
||
'config_management.status_dirty': '有未保存的更改',
|
||
'config_management.status_disconnected': '请先连接服务器以加载配置',
|
||
'config_management.status_load_failed': '加载失败',
|
||
'config_management.status_saving': '正在保存配置...',
|
||
'config_management.status_saved': '配置保存完成',
|
||
'config_management.status_save_failed': '保存失败',
|
||
'config_management.save_success': '配置已保存',
|
||
'config_management.error_yaml_not_supported': '服务器未返回 YAML 格式,请确认 /config.yaml 接口可用',
|
||
'config_management.editor_placeholder': 'key: value',
|
||
|
||
// 系统信息
|
||
'system_info.title': '系统信息',
|
||
'system_info.connection_status_title': '连接状态',
|
||
'system_info.api_status_label': 'API 状态:',
|
||
'system_info.config_status_label': '配置状态:',
|
||
'system_info.last_update_label': '最后更新:',
|
||
'system_info.cache_data': '缓存数据',
|
||
'system_info.real_time_data': '实时数据',
|
||
'system_info.not_loaded': '未加载',
|
||
'system_info.seconds_ago': '秒前',
|
||
|
||
// 通知消息
|
||
'notification.debug_updated': '调试设置已更新',
|
||
'notification.proxy_updated': '代理设置已更新',
|
||
'notification.proxy_cleared': '代理设置已清空',
|
||
'notification.retry_updated': '重试设置已更新',
|
||
'notification.quota_switch_project_updated': '项目切换设置已更新',
|
||
'notification.quota_switch_preview_updated': '预览模型切换设置已更新',
|
||
'notification.usage_statistics_updated': '使用统计设置已更新',
|
||
'notification.logging_to_file_updated': '日志记录设置已更新',
|
||
'notification.request_log_updated': '请求日志设置已更新',
|
||
'notification.ws_auth_updated': 'WebSocket 鉴权设置已更新',
|
||
'notification.api_key_added': 'API密钥添加成功',
|
||
'notification.api_key_updated': 'API密钥更新成功',
|
||
'notification.api_key_deleted': 'API密钥删除成功',
|
||
'notification.gemini_key_added': 'Gemini密钥添加成功',
|
||
'notification.gemini_key_updated': 'Gemini密钥更新成功',
|
||
'notification.gemini_key_deleted': 'Gemini密钥删除成功',
|
||
'notification.gemini_multi_input_required': '请先输入至少一个Gemini密钥',
|
||
'notification.gemini_multi_failed': 'Gemini密钥批量添加失败',
|
||
'notification.gemini_multi_summary': 'Gemini批量添加完成:成功 {success},跳过 {skipped},失败 {failed}',
|
||
'notification.codex_config_added': 'Codex配置添加成功',
|
||
'notification.codex_config_updated': 'Codex配置更新成功',
|
||
'notification.codex_config_deleted': 'Codex配置删除成功',
|
||
'notification.codex_base_url_required': '请填写Codex Base URL',
|
||
'notification.claude_config_added': 'Claude配置添加成功',
|
||
'notification.claude_config_updated': 'Claude配置更新成功',
|
||
'notification.claude_config_deleted': 'Claude配置删除成功',
|
||
'notification.field_required': '必填字段不能为空',
|
||
'notification.openai_provider_required': '请填写提供商名称和Base URL',
|
||
'notification.openai_provider_added': 'OpenAI提供商添加成功',
|
||
'notification.openai_provider_updated': 'OpenAI提供商更新成功',
|
||
'notification.openai_provider_deleted': 'OpenAI提供商删除成功',
|
||
'notification.openai_model_name_required': '请填写模型名称',
|
||
'notification.data_refreshed': '数据刷新成功',
|
||
'notification.connection_required': '请先建立连接',
|
||
'notification.refresh_failed': '刷新失败',
|
||
'notification.update_failed': '更新失败',
|
||
'notification.add_failed': '添加失败',
|
||
'notification.delete_failed': '删除失败',
|
||
'notification.upload_failed': '上传失败',
|
||
'notification.download_failed': '下载失败',
|
||
'notification.login_failed': '登录失败',
|
||
'notification.please_enter': '请输入',
|
||
'notification.please_fill': '请填写',
|
||
'notification.provider_name_url': '提供商名称和Base URL',
|
||
'notification.api_key': 'API密钥',
|
||
'notification.gemini_api_key': 'Gemini API密钥',
|
||
'notification.codex_api_key': 'Codex API密钥',
|
||
'notification.claude_api_key': 'Claude API密钥',
|
||
'notification.link_copied': '链接已复制到剪贴板',
|
||
|
||
// 语言切换
|
||
'language.switch': '语言',
|
||
'language.chinese': '中文',
|
||
'language.english': 'English',
|
||
|
||
// 主题切换
|
||
'theme.switch': '主题',
|
||
'theme.light': '亮色',
|
||
'theme.dark': '暗色',
|
||
'theme.switch_to_light': '切换到亮色模式',
|
||
'theme.switch_to_dark': '切换到暗色模式',
|
||
'theme.auto': '跟随系统',
|
||
|
||
// 侧边栏
|
||
'sidebar.toggle_expand': '展开侧边栏',
|
||
'sidebar.toggle_collapse': '收起侧边栏',
|
||
|
||
// 页脚
|
||
'footer.version': '版本',
|
||
'footer.author': '作者'
|
||
},
|
||
|
||
'en-US': {
|
||
// Common
|
||
'common.login': 'Login',
|
||
'common.logout': 'Logout',
|
||
'common.cancel': 'Cancel',
|
||
'common.confirm': 'Confirm',
|
||
'common.save': 'Save',
|
||
'common.delete': 'Delete',
|
||
'common.edit': 'Edit',
|
||
'common.add': 'Add',
|
||
'common.update': 'Update',
|
||
'common.refresh': 'Refresh',
|
||
'common.close': 'Close',
|
||
'common.success': 'Success',
|
||
'common.error': 'Error',
|
||
'common.info': 'Info',
|
||
'common.warning': 'Warning',
|
||
'common.loading': 'Loading...',
|
||
'common.connecting': 'Connecting...',
|
||
'common.connected': 'Connected',
|
||
'common.disconnected': 'Disconnected',
|
||
'common.connecting_status': 'Connecting',
|
||
'common.connected_status': 'Connected',
|
||
'common.disconnected_status': 'Disconnected',
|
||
'common.yes': 'Yes',
|
||
'common.no': 'No',
|
||
'common.optional': 'Optional',
|
||
'common.required': 'Required',
|
||
'common.api_key': 'Key',
|
||
'common.base_url': 'Address',
|
||
'common.proxy_url': 'Proxy',
|
||
'common.alias': 'Alias',
|
||
'common.failure': 'Failure',
|
||
'common.unknown_error': 'Unknown error',
|
||
'common.copy': 'Copy',
|
||
'common.custom_headers_label': 'Custom Headers',
|
||
'common.custom_headers_hint': 'Optional HTTP headers to send with the request. Leave blank to remove.',
|
||
'common.custom_headers_add': 'Add Header',
|
||
'common.custom_headers_key_placeholder': 'Header name, e.g. X-Custom-Header',
|
||
'common.custom_headers_value_placeholder': 'Header value',
|
||
|
||
// Page titles
|
||
'title.main': 'CLI Proxy API Management Center',
|
||
'title.login': 'CLI Proxy API Management Center',
|
||
|
||
// Auto login
|
||
'auto_login.title': 'Auto Login in Progress...',
|
||
'auto_login.message': 'Attempting to connect to server using locally saved connection information',
|
||
|
||
// Login page
|
||
'login.subtitle': 'Please enter connection information to access the management interface',
|
||
'login.connection_title': 'Connection Address',
|
||
'login.connection_current': 'Current URL',
|
||
'login.connection_auto_hint': 'The system will automatically use the current URL for connection',
|
||
'login.custom_connection_label': 'Custom Connection URL:',
|
||
'login.custom_connection_placeholder': 'Eg: https://example.com:8317',
|
||
'login.custom_connection_hint': 'By default the current URL is used. Override it here if needed.',
|
||
'login.use_current_address': 'Use Current URL',
|
||
'login.management_key_label': 'Management Key:',
|
||
'login.management_key_placeholder': 'Enter the management key',
|
||
'login.connect_button': 'Connect',
|
||
'login.submit_button': 'Login',
|
||
'login.submitting': 'Connecting...',
|
||
'login.error_title': 'Login Failed',
|
||
'login.error_required': 'Please fill in complete connection information',
|
||
'login.error_invalid': 'Connection failed, please check address and key',
|
||
|
||
// Header navigation
|
||
'header.check_connection': 'Check Connection',
|
||
'header.refresh_all': 'Refresh All',
|
||
'header.logout': 'Logout',
|
||
|
||
// Connection info
|
||
'connection.title': 'Connection Information',
|
||
'connection.server_address': 'Server Address:',
|
||
'connection.management_key': 'Management Key:',
|
||
'connection.status': 'Connection Status:',
|
||
|
||
// Sidebar navigation
|
||
'nav.basic_settings': 'Basic Settings',
|
||
'nav.api_keys': 'API Keys',
|
||
'nav.ai_providers': 'AI Providers',
|
||
'nav.auth_files': 'Auth Files',
|
||
'nav.usage_stats': 'Usage Statistics',
|
||
'nav.config_management': 'Config Management',
|
||
'nav.logs': 'Logs Viewer',
|
||
'nav.system_info': 'System Info',
|
||
|
||
// Basic settings
|
||
'basic_settings.title': 'Basic Settings',
|
||
'basic_settings.debug_title': 'Debug Mode',
|
||
'basic_settings.debug_enable': 'Enable Debug Mode',
|
||
'basic_settings.proxy_title': 'Proxy Settings',
|
||
'basic_settings.proxy_url_label': 'Proxy URL:',
|
||
'basic_settings.proxy_url_placeholder': 'e.g.: socks5://user:pass@127.0.0.1:1080/',
|
||
'basic_settings.proxy_update': 'Update',
|
||
'basic_settings.proxy_clear': 'Clear',
|
||
'basic_settings.retry_title': 'Request Retry',
|
||
'basic_settings.retry_count_label': 'Retry Count:',
|
||
'basic_settings.retry_update': 'Update',
|
||
'basic_settings.quota_title': 'Quota Exceeded Behavior',
|
||
'basic_settings.quota_switch_project': 'Auto Switch Project',
|
||
'basic_settings.quota_switch_preview': 'Switch to Preview Model',
|
||
'basic_settings.usage_statistics_title': 'Usage Statistics',
|
||
'basic_settings.usage_statistics_enable': 'Enable usage statistics',
|
||
'basic_settings.logging_title': 'Logging',
|
||
'basic_settings.logging_to_file_enable': 'Enable logging to file',
|
||
'basic_settings.request_log_enable': 'Enable request logging',
|
||
'basic_settings.ws_auth_title': 'WebSocket Authentication',
|
||
'basic_settings.ws_auth_enable': 'Require auth for /ws/*',
|
||
|
||
// API Keys management
|
||
'api_keys.title': 'API Keys Management',
|
||
'api_keys.proxy_auth_title': 'Proxy Service Authentication Keys',
|
||
'api_keys.add_button': 'Add Key',
|
||
'api_keys.empty_title': 'No API Keys',
|
||
'api_keys.empty_desc': 'Click the button above to add the first key',
|
||
'api_keys.item_title': 'API Key',
|
||
'api_keys.add_modal_title': 'Add API Key',
|
||
'api_keys.add_modal_key_label': 'API Key:',
|
||
'api_keys.add_modal_key_placeholder': 'Please enter API key',
|
||
'api_keys.edit_modal_title': 'Edit API Key',
|
||
'api_keys.edit_modal_key_label': 'API Key:',
|
||
'api_keys.delete_confirm': 'Are you sure you want to delete this API key?',
|
||
|
||
// AI Providers
|
||
'ai_providers.title': 'AI Providers Configuration',
|
||
'ai_providers.gemini_title': 'Gemini API Keys',
|
||
'ai_providers.gemini_add_button': 'Add Key',
|
||
'ai_providers.gemini_empty_title': 'No Gemini Keys',
|
||
'ai_providers.gemini_empty_desc': 'Click the button above to add the first key',
|
||
'ai_providers.gemini_item_title': 'Gemini Key',
|
||
'ai_providers.gemini_add_modal_title': 'Add Gemini API Key',
|
||
'ai_providers.gemini_add_modal_key_label': 'API Keys:',
|
||
'ai_providers.gemini_add_modal_key_placeholder': 'Enter Gemini API keys (one per line)',
|
||
'ai_providers.gemini_add_modal_key_hint': 'You can paste multiple keys, one per line.',
|
||
'ai_providers.gemini_add_modal_url_label': 'Base URL (optional):',
|
||
'ai_providers.gemini_add_modal_url_placeholder': 'e.g. https://generativelanguage.googleapis.com',
|
||
'ai_providers.gemini_edit_modal_title': 'Edit Gemini API Key',
|
||
'ai_providers.gemini_edit_modal_key_label': 'API Key:',
|
||
'ai_providers.gemini_edit_modal_url_label': 'Base URL (optional):',
|
||
'ai_providers.gemini_delete_confirm': 'Are you sure you want to delete this Gemini key?',
|
||
|
||
'ai_providers.codex_title': 'Codex API Configuration',
|
||
'ai_providers.codex_add_button': 'Add Configuration',
|
||
'ai_providers.codex_empty_title': 'No Codex Configuration',
|
||
'ai_providers.codex_empty_desc': 'Click the button above to add the first configuration',
|
||
'ai_providers.codex_item_title': 'Codex Configuration',
|
||
'ai_providers.codex_add_modal_title': 'Add Codex API Configuration',
|
||
'ai_providers.codex_add_modal_key_label': 'API Key:',
|
||
'ai_providers.codex_add_modal_key_placeholder': 'Please enter Codex API key',
|
||
'ai_providers.codex_add_modal_url_label': 'Base URL (Required):',
|
||
'ai_providers.codex_add_modal_url_placeholder': 'e.g.: https://api.example.com',
|
||
'ai_providers.codex_add_modal_proxy_label': 'Proxy URL (Optional):',
|
||
'ai_providers.codex_add_modal_proxy_placeholder': 'e.g.: socks5://proxy.example.com:1080',
|
||
'ai_providers.codex_edit_modal_title': 'Edit Codex API Configuration',
|
||
'ai_providers.codex_edit_modal_key_label': 'API Key:',
|
||
'ai_providers.codex_edit_modal_url_label': 'Base URL (Required):',
|
||
'ai_providers.codex_edit_modal_proxy_label': 'Proxy URL (Optional):',
|
||
'ai_providers.codex_delete_confirm': 'Are you sure you want to delete this Codex configuration?',
|
||
|
||
'ai_providers.claude_title': 'Claude API Configuration',
|
||
'ai_providers.claude_add_button': 'Add Configuration',
|
||
'ai_providers.claude_empty_title': 'No Claude Configuration',
|
||
'ai_providers.claude_empty_desc': 'Click the button above to add the first configuration',
|
||
'ai_providers.claude_item_title': 'Claude Configuration',
|
||
'ai_providers.claude_add_modal_title': 'Add Claude API Configuration',
|
||
'ai_providers.claude_add_modal_key_label': 'API Key:',
|
||
'ai_providers.claude_add_modal_key_placeholder': 'Please enter Claude API key',
|
||
'ai_providers.claude_add_modal_url_label': 'Base URL (Optional):',
|
||
'ai_providers.claude_add_modal_url_placeholder': 'e.g.: https://api.anthropic.com',
|
||
'ai_providers.claude_add_modal_proxy_label': 'Proxy URL (Optional):',
|
||
'ai_providers.claude_add_modal_proxy_placeholder': 'e.g.: socks5://proxy.example.com:1080',
|
||
'ai_providers.claude_edit_modal_title': 'Edit Claude API Configuration',
|
||
'ai_providers.claude_edit_modal_key_label': 'API Key:',
|
||
'ai_providers.claude_edit_modal_url_label': 'Base URL (Optional):',
|
||
'ai_providers.claude_edit_modal_proxy_label': 'Proxy URL (Optional):',
|
||
'ai_providers.claude_delete_confirm': 'Are you sure you want to delete this Claude configuration?',
|
||
|
||
'ai_providers.openai_title': 'OpenAI Compatible Providers',
|
||
'ai_providers.openai_add_button': 'Add Provider',
|
||
'ai_providers.openai_empty_title': 'No OpenAI Compatible Providers',
|
||
'ai_providers.openai_empty_desc': 'Click the button above to add the first provider',
|
||
'ai_providers.openai_add_modal_title': 'Add OpenAI Compatible Provider',
|
||
'ai_providers.openai_add_modal_name_label': 'Provider Name:',
|
||
'ai_providers.openai_add_modal_name_placeholder': 'e.g.: openrouter',
|
||
'ai_providers.openai_add_modal_url_label': 'Base URL:',
|
||
'ai_providers.openai_add_modal_url_placeholder': 'e.g.: https://openrouter.ai/api/v1',
|
||
'ai_providers.openai_add_modal_keys_label': 'API Keys (one per line):',
|
||
'ai_providers.openai_add_modal_keys_placeholder': 'sk-key1\nsk-key2',
|
||
'ai_providers.openai_add_modal_keys_proxy_label': 'Proxy URL (one per line, optional):',
|
||
'ai_providers.openai_add_modal_keys_proxy_placeholder': 'socks5://proxy.example.com:1080\n',
|
||
'ai_providers.openai_add_modal_models_label': 'Model List (name[, alias] one per line):',
|
||
'ai_providers.openai_models_hint': 'Example: gpt-4o-mini or moonshotai/kimi-k2:free, kimi-k2',
|
||
'ai_providers.openai_model_name_placeholder': 'Model name, e.g. moonshotai/kimi-k2:free',
|
||
'ai_providers.openai_model_alias_placeholder': 'Model alias (optional)',
|
||
'ai_providers.openai_models_add_btn': 'Add Model',
|
||
'ai_providers.openai_edit_modal_title': 'Edit OpenAI Compatible Provider',
|
||
'ai_providers.openai_edit_modal_name_label': 'Provider Name:',
|
||
'ai_providers.openai_edit_modal_url_label': 'Base URL:',
|
||
'ai_providers.openai_edit_modal_keys_label': 'API Keys (one per line):',
|
||
'ai_providers.openai_edit_modal_keys_proxy_label': 'Proxy URL (one per line, optional):',
|
||
'ai_providers.openai_edit_modal_models_label': 'Model List (name[, alias] one per line):',
|
||
'ai_providers.openai_delete_confirm': 'Are you sure you want to delete this OpenAI provider?',
|
||
'ai_providers.openai_keys_count': 'Keys Count',
|
||
'ai_providers.openai_models_count': 'Models Count',
|
||
|
||
|
||
// Auth files management
|
||
'auth_files.title': 'Auth Files Management',
|
||
'auth_files.title_section': 'Auth Files',
|
||
'auth_files.description': 'Manage all CLI Proxy JSON auth files here (e.g. Qwen, Gemini, Vertex). Uploading a credential immediately enables the corresponding AI integration.',
|
||
'auth_files.upload_button': 'Upload File',
|
||
'auth_files.delete_all_button': 'Delete All',
|
||
'auth_files.empty_title': 'No Auth Files',
|
||
'auth_files.empty_desc': 'Click the button above to upload the first file',
|
||
'auth_files.file_size': 'Size',
|
||
'auth_files.file_modified': 'Modified',
|
||
'auth_files.download_button': 'Download',
|
||
'auth_files.delete_button': 'Delete',
|
||
'auth_files.delete_confirm': 'Are you sure you want to delete file',
|
||
'auth_files.delete_all_confirm': 'Are you sure you want to delete all auth files? This operation cannot be undone!',
|
||
'auth_files.delete_filtered_confirm': 'Are you sure you want to delete all {type} auth files? This operation cannot be undone!',
|
||
'auth_files.upload_error_json': 'Only JSON files are allowed',
|
||
'auth_files.upload_success': 'File uploaded successfully',
|
||
'auth_files.download_success': 'File downloaded successfully',
|
||
'auth_files.delete_success': 'File deleted successfully',
|
||
'auth_files.delete_all_success': 'Successfully deleted',
|
||
'auth_files.delete_filtered_success': 'Deleted {count} {type} auth files successfully',
|
||
'auth_files.delete_filtered_partial': '{type} auth files deletion finished: {success} succeeded, {failed} failed',
|
||
'auth_files.delete_filtered_none': 'No deletable auth files under the current filter ({type})',
|
||
'auth_files.files_count': 'files',
|
||
'auth_files.filter_all': 'All',
|
||
'auth_files.filter_qwen': 'Qwen',
|
||
'auth_files.filter_gemini': 'Gemini',
|
||
'auth_files.filter_gemini-cli': 'GeminiCLI',
|
||
'auth_files.filter_aistudio': 'AIStudio',
|
||
'auth_files.filter_claude': 'Claude',
|
||
'auth_files.filter_codex': 'Codex',
|
||
'auth_files.filter_iflow': 'iFlow',
|
||
'auth_files.filter_vertex': 'Vertex',
|
||
'auth_files.filter_empty': 'Empty',
|
||
'auth_files.filter_unknown': 'Other',
|
||
'auth_files.type_qwen': 'Qwen',
|
||
'auth_files.type_gemini': 'Gemini',
|
||
'auth_files.type_gemini-cli': 'GeminiCLI',
|
||
'auth_files.type_aistudio': 'AIStudio',
|
||
'auth_files.type_claude': 'Claude',
|
||
'auth_files.type_codex': 'Codex',
|
||
'auth_files.type_iflow': 'iFlow',
|
||
'auth_files.type_vertex': 'Vertex',
|
||
'auth_files.type_empty': 'Empty',
|
||
'auth_files.type_unknown': 'Other',
|
||
'vertex_import.title': 'Vertex AI Credential Import',
|
||
'vertex_import.description': 'Upload a Google service account JSON to store it as auth-dir/vertex-<project>.json using the same rules as the CLI vertex-import helper.',
|
||
'vertex_import.location_label': 'Region (optional)',
|
||
'vertex_import.location_placeholder': 'us-central1',
|
||
'vertex_import.location_hint': 'Leave empty to use the default region us-central1.',
|
||
'vertex_import.file_label': 'Service account key JSON',
|
||
'vertex_import.file_hint': 'Only Google Cloud service account key JSON files are accepted.',
|
||
'vertex_import.file_placeholder': 'No file selected',
|
||
'vertex_import.choose_file': 'Choose File',
|
||
'vertex_import.import_button': 'Import Vertex Credential',
|
||
'vertex_import.file_required': 'Select a .json credential file first',
|
||
'vertex_import.success': 'Vertex credential imported successfully',
|
||
'vertex_import.result_title': 'Credential saved',
|
||
'vertex_import.result_project': 'Project ID',
|
||
'vertex_import.result_email': 'Service account',
|
||
'vertex_import.result_location': 'Region',
|
||
'vertex_import.result_file': 'Persisted file',
|
||
|
||
// Codex OAuth
|
||
'auth_login.codex_oauth_title': 'Codex OAuth',
|
||
'auth_login.codex_oauth_button': 'Start Codex Login',
|
||
'auth_login.codex_oauth_hint': 'Login to Codex service through OAuth flow, automatically obtain and save authentication files.',
|
||
'auth_login.codex_oauth_url_label': 'Authorization URL:',
|
||
'auth_login.codex_open_link': 'Open Link',
|
||
'auth_login.codex_copy_link': 'Copy Link',
|
||
'auth_login.codex_oauth_status_waiting': 'Waiting for authentication...',
|
||
'auth_login.codex_oauth_status_success': 'Authentication successful!',
|
||
'auth_login.codex_oauth_status_error': 'Authentication failed:',
|
||
'auth_login.codex_oauth_start_error': 'Failed to start Codex OAuth:',
|
||
'auth_login.codex_oauth_polling_error': 'Failed to check authentication status:',
|
||
|
||
// Anthropic OAuth
|
||
'auth_login.anthropic_oauth_title': 'Anthropic OAuth',
|
||
'auth_login.anthropic_oauth_button': 'Start Anthropic Login',
|
||
'auth_login.anthropic_oauth_hint': 'Login to Anthropic (Claude) service through OAuth flow, automatically obtain and save authentication files.',
|
||
'auth_login.anthropic_oauth_url_label': 'Authorization URL:',
|
||
'auth_login.anthropic_open_link': 'Open Link',
|
||
'auth_login.anthropic_copy_link': 'Copy Link',
|
||
'auth_login.anthropic_oauth_status_waiting': 'Waiting for authentication...',
|
||
'auth_login.anthropic_oauth_status_success': 'Authentication successful!',
|
||
'auth_login.anthropic_oauth_status_error': 'Authentication failed:',
|
||
'auth_login.anthropic_oauth_start_error': 'Failed to start Anthropic OAuth:',
|
||
'auth_login.anthropic_oauth_polling_error': 'Failed to check authentication status:',
|
||
|
||
// Gemini CLI OAuth
|
||
'auth_login.gemini_cli_oauth_title': 'Gemini CLI OAuth',
|
||
'auth_login.gemini_cli_oauth_button': 'Start Gemini CLI Login',
|
||
'auth_login.gemini_cli_oauth_hint': 'Login to Google Gemini CLI service through OAuth flow, automatically obtain and save authentication files.',
|
||
'auth_login.gemini_cli_project_id_label': 'Google Cloud Project ID (Optional):',
|
||
'auth_login.gemini_cli_project_id_placeholder': 'Enter Google Cloud Project ID (optional)',
|
||
'auth_login.gemini_cli_project_id_hint': 'If a project ID is specified, authentication information for that project will be used.',
|
||
'auth_login.gemini_cli_oauth_url_label': 'Authorization URL:',
|
||
'auth_login.gemini_cli_open_link': 'Open Link',
|
||
'auth_login.gemini_cli_copy_link': 'Copy Link',
|
||
'auth_login.gemini_cli_oauth_status_waiting': 'Waiting for authentication...',
|
||
'auth_login.gemini_cli_oauth_status_success': 'Authentication successful!',
|
||
'auth_login.gemini_cli_oauth_status_error': 'Authentication failed:',
|
||
'auth_login.gemini_cli_oauth_start_error': 'Failed to start Gemini CLI OAuth:',
|
||
'auth_login.gemini_cli_oauth_polling_error': 'Failed to check authentication status:',
|
||
|
||
// Qwen OAuth
|
||
'auth_login.qwen_oauth_title': 'Qwen OAuth',
|
||
'auth_login.qwen_oauth_button': 'Start Qwen Login',
|
||
'auth_login.qwen_oauth_hint': 'Login to Qwen service through device authorization flow, automatically obtain and save authentication files.',
|
||
'auth_login.qwen_oauth_url_label': 'Authorization URL:',
|
||
'auth_login.qwen_open_link': 'Open Link',
|
||
'auth_login.qwen_copy_link': 'Copy Link',
|
||
'auth_login.qwen_oauth_status_waiting': 'Waiting for authentication...',
|
||
'auth_login.qwen_oauth_status_success': 'Authentication successful!',
|
||
'auth_login.qwen_oauth_status_error': 'Authentication failed:',
|
||
'auth_login.qwen_oauth_start_error': 'Failed to start Qwen OAuth:',
|
||
'auth_login.qwen_oauth_polling_error': 'Failed to check authentication status:',
|
||
'auth_login.missing_state': 'Unable to retrieve authentication state parameter',
|
||
|
||
// iFlow OAuth
|
||
'auth_login.iflow_oauth_title': 'iFlow OAuth',
|
||
'auth_login.iflow_oauth_button': 'Start iFlow Login',
|
||
'auth_login.iflow_oauth_hint': 'Login to iFlow service through OAuth flow, automatically obtain and save authentication files.',
|
||
'auth_login.iflow_oauth_url_label': 'Authorization URL:',
|
||
'auth_login.iflow_open_link': 'Open Link',
|
||
'auth_login.iflow_copy_link': 'Copy Link',
|
||
'auth_login.iflow_oauth_status_waiting': 'Waiting for authentication...',
|
||
'auth_login.iflow_oauth_status_success': 'Authentication successful!',
|
||
'auth_login.iflow_oauth_status_error': 'Authentication failed:',
|
||
'auth_login.iflow_oauth_start_error': 'Failed to start iFlow OAuth:',
|
||
'auth_login.iflow_oauth_polling_error': 'Failed to check authentication status:',
|
||
|
||
// Usage Statistics
|
||
'usage_stats.title': 'Usage Statistics',
|
||
'usage_stats.total_requests': 'Total Requests',
|
||
'usage_stats.success_requests': 'Success Requests',
|
||
'usage_stats.failed_requests': 'Failed Requests',
|
||
'usage_stats.total_tokens': 'Total Tokens',
|
||
'usage_stats.requests_trend': 'Request Trends',
|
||
'usage_stats.tokens_trend': 'Token Usage Trends',
|
||
'usage_stats.api_details': 'API Details',
|
||
'usage_stats.by_hour': 'By Hour',
|
||
'usage_stats.by_day': 'By Day',
|
||
'usage_stats.refresh': 'Refresh',
|
||
'usage_stats.no_data': 'No Data Available',
|
||
'usage_stats.loading_error': 'Loading Failed',
|
||
'usage_stats.api_endpoint': 'API Endpoint',
|
||
'usage_stats.requests_count': 'Request Count',
|
||
'usage_stats.tokens_count': 'Token Count',
|
||
'usage_stats.models': 'Model Statistics',
|
||
'usage_stats.success_rate': 'Success Rate',
|
||
'stats.success': 'Success',
|
||
'stats.failure': 'Failure',
|
||
|
||
// Logs viewer
|
||
'logs.title': 'Logs Viewer',
|
||
'logs.refresh_button': 'Refresh Logs',
|
||
'logs.clear_button': 'Clear Logs',
|
||
'logs.download_button': 'Download Logs',
|
||
'logs.empty_title': 'No Logs Available',
|
||
'logs.empty_desc': 'When "Enable logging to file" is enabled, logs will be displayed here',
|
||
'logs.log_content': 'Log Content',
|
||
'logs.loading': 'Loading logs...',
|
||
'logs.load_error': 'Failed to load logs',
|
||
'logs.clear_confirm': 'Are you sure you want to clear all logs? This action cannot be undone!',
|
||
'logs.clear_success': 'Logs cleared successfully',
|
||
'logs.download_success': 'Logs downloaded successfully',
|
||
'logs.auto_refresh': 'Auto Refresh',
|
||
'logs.auto_refresh_enabled': 'Auto refresh enabled',
|
||
'logs.auto_refresh_disabled': 'Auto refresh disabled',
|
||
'logs.lines': 'lines',
|
||
'logs.removed': 'Removed',
|
||
'logs.upgrade_required_title': 'Please Upgrade CLI Proxy API',
|
||
'logs.upgrade_required_desc': 'The current server version does not support the logs viewing feature. Please upgrade to the latest version of CLI Proxy API to use this feature.',
|
||
|
||
// Config management
|
||
'config_management.title': 'Config Management',
|
||
'config_management.editor_title': 'Configuration File',
|
||
'config_management.reload': 'Reload',
|
||
'config_management.save': 'Save',
|
||
'config_management.description': 'View and edit the server-side config.yaml file. Validate the syntax before saving.',
|
||
'config_management.status_idle': 'Waiting for action',
|
||
'config_management.status_loading': 'Loading configuration...',
|
||
'config_management.status_loaded': 'Configuration loaded',
|
||
'config_management.status_dirty': 'Unsaved changes',
|
||
'config_management.status_disconnected': 'Connect to the server to load the configuration',
|
||
'config_management.status_load_failed': 'Load failed',
|
||
'config_management.status_saving': 'Saving configuration...',
|
||
'config_management.status_saved': 'Configuration saved',
|
||
'config_management.status_save_failed': 'Save failed',
|
||
'config_management.save_success': 'Configuration saved successfully',
|
||
'config_management.error_yaml_not_supported': 'Server did not return YAML. Verify the /config.yaml endpoint is available.',
|
||
'config_management.editor_placeholder': 'key: value',
|
||
|
||
// System info
|
||
'system_info.title': 'System Information',
|
||
'system_info.connection_status_title': 'Connection Status',
|
||
'system_info.api_status_label': 'API Status:',
|
||
'system_info.config_status_label': 'Config Status:',
|
||
'system_info.last_update_label': 'Last Update:',
|
||
'system_info.cache_data': 'Cache Data',
|
||
'system_info.real_time_data': 'Real-time Data',
|
||
'system_info.not_loaded': 'Not Loaded',
|
||
'system_info.seconds_ago': 'seconds ago',
|
||
|
||
// Notification messages
|
||
'notification.debug_updated': 'Debug settings updated',
|
||
'notification.proxy_updated': 'Proxy settings updated',
|
||
'notification.proxy_cleared': 'Proxy settings cleared',
|
||
'notification.retry_updated': 'Retry settings updated',
|
||
'notification.quota_switch_project_updated': 'Project switch settings updated',
|
||
'notification.quota_switch_preview_updated': 'Preview model switch settings updated',
|
||
'notification.usage_statistics_updated': 'Usage statistics settings updated',
|
||
'notification.logging_to_file_updated': 'Logging settings updated',
|
||
'notification.request_log_updated': 'Request logging setting updated',
|
||
'notification.ws_auth_updated': 'WebSocket authentication setting updated',
|
||
'notification.api_key_added': 'API key added successfully',
|
||
'notification.api_key_updated': 'API key updated successfully',
|
||
'notification.api_key_deleted': 'API key deleted successfully',
|
||
'notification.gemini_key_added': 'Gemini key added successfully',
|
||
'notification.gemini_key_updated': 'Gemini key updated successfully',
|
||
'notification.gemini_key_deleted': 'Gemini key deleted successfully',
|
||
'notification.gemini_multi_input_required': 'Please enter at least one Gemini key',
|
||
'notification.gemini_multi_failed': 'Gemini bulk add failed',
|
||
'notification.gemini_multi_summary': 'Gemini bulk add finished: {success} added, {skipped} skipped, {failed} failed',
|
||
'notification.codex_config_added': 'Codex configuration added successfully',
|
||
'notification.codex_config_updated': 'Codex configuration updated successfully',
|
||
'notification.codex_config_deleted': 'Codex configuration deleted successfully',
|
||
'notification.codex_base_url_required': 'Please enter the Codex Base URL',
|
||
'notification.claude_config_added': 'Claude configuration added successfully',
|
||
'notification.claude_config_updated': 'Claude configuration updated successfully',
|
||
'notification.claude_config_deleted': 'Claude configuration deleted successfully',
|
||
'notification.field_required': 'Required fields cannot be empty',
|
||
'notification.openai_provider_required': 'Please fill in provider name and Base URL',
|
||
'notification.openai_provider_added': 'OpenAI provider added successfully',
|
||
'notification.openai_provider_updated': 'OpenAI provider updated successfully',
|
||
'notification.openai_provider_deleted': 'OpenAI provider deleted successfully',
|
||
'notification.openai_model_name_required': 'Model name is required',
|
||
'notification.data_refreshed': 'Data refreshed successfully',
|
||
'notification.connection_required': 'Please establish connection first',
|
||
'notification.refresh_failed': 'Refresh failed',
|
||
'notification.update_failed': 'Update failed',
|
||
'notification.add_failed': 'Add failed',
|
||
'notification.delete_failed': 'Delete failed',
|
||
'notification.upload_failed': 'Upload failed',
|
||
'notification.download_failed': 'Download failed',
|
||
'notification.login_failed': 'Login failed',
|
||
'notification.please_enter': 'Please enter',
|
||
'notification.please_fill': 'Please fill',
|
||
'notification.provider_name_url': 'provider name and Base URL',
|
||
'notification.api_key': 'API key',
|
||
'notification.gemini_api_key': 'Gemini API key',
|
||
'notification.codex_api_key': 'Codex API key',
|
||
'notification.claude_api_key': 'Claude API key',
|
||
'notification.link_copied': 'Link copied to clipboard',
|
||
|
||
// Language switch
|
||
'language.switch': 'Language',
|
||
'language.chinese': '中文',
|
||
'language.english': 'English',
|
||
|
||
// Theme switch
|
||
'theme.switch': 'Theme',
|
||
'theme.light': 'Light',
|
||
'theme.dark': 'Dark',
|
||
'theme.switch_to_light': 'Switch to light mode',
|
||
'theme.switch_to_dark': 'Switch to dark mode',
|
||
'theme.auto': 'Follow system',
|
||
|
||
// Sidebar
|
||
'sidebar.toggle_expand': 'Expand sidebar',
|
||
'sidebar.toggle_collapse': 'Collapse sidebar',
|
||
|
||
// Footer
|
||
'footer.version': 'Version',
|
||
'footer.author': 'Author'
|
||
}
|
||
},
|
||
|
||
// 获取翻译文本
|
||
t(key, params = {}) {
|
||
const translation = this.translations[this.currentLanguage]?.[key] ||
|
||
this.translations[this.fallbackLanguage]?.[key] ||
|
||
key;
|
||
|
||
// 简单的参数替换
|
||
return translation.replace(/\{(\w+)\}/g, (match, param) => {
|
||
return params[param] || match;
|
||
});
|
||
},
|
||
|
||
// 设置语言
|
||
setLanguage(lang) {
|
||
if (this.translations[lang]) {
|
||
this.currentLanguage = lang;
|
||
localStorage.setItem('preferredLanguage', lang);
|
||
this.updatePageLanguage();
|
||
this.updateAllTexts();
|
||
}
|
||
},
|
||
|
||
// 更新页面语言属性
|
||
updatePageLanguage() {
|
||
document.documentElement.lang = this.currentLanguage;
|
||
},
|
||
|
||
// 更新所有文本
|
||
updateAllTexts() {
|
||
// 更新所有带有 data-i18n 属性的元素
|
||
document.querySelectorAll('[data-i18n]').forEach(element => {
|
||
const key = element.getAttribute('data-i18n');
|
||
const text = this.t(key);
|
||
|
||
if (element.tagName === 'INPUT' && (element.type === 'text' || element.type === 'password')) {
|
||
element.placeholder = text;
|
||
} else if (element.tagName === 'TITLE') {
|
||
element.textContent = text;
|
||
} else {
|
||
element.textContent = text;
|
||
}
|
||
});
|
||
|
||
// 更新所有包含 data-i18n-placeholder 的输入框占位符
|
||
document.querySelectorAll('[data-i18n-placeholder]').forEach(element => {
|
||
const key = element.getAttribute('data-i18n-placeholder');
|
||
element.placeholder = this.t(key);
|
||
});
|
||
|
||
// 更新 data-i18n-title
|
||
document.querySelectorAll('[data-i18n-title]').forEach(element => {
|
||
const key = element.getAttribute('data-i18n-title');
|
||
element.title = this.t(key);
|
||
});
|
||
|
||
// 更新 data-i18n-tooltip
|
||
document.querySelectorAll('[data-i18n-tooltip]').forEach(element => {
|
||
const key = element.getAttribute('data-i18n-tooltip');
|
||
element.setAttribute('data-tooltip', this.t(key));
|
||
});
|
||
|
||
// 更新 data-i18n-text(常用于按钮或标签)
|
||
document.querySelectorAll('[data-i18n-text]').forEach(element => {
|
||
const key = element.getAttribute('data-i18n-text');
|
||
element.textContent = this.t(key);
|
||
});
|
||
|
||
// 更新所有带有 data-i18n-html 属性的元素(支持HTML)
|
||
document.querySelectorAll('[data-i18n-html]').forEach(element => {
|
||
const key = element.getAttribute('data-i18n-html');
|
||
const html = this.t(key);
|
||
element.innerHTML = html;
|
||
});
|
||
},
|
||
|
||
// 初始化
|
||
init() {
|
||
// 从本地存储获取用户偏好语言
|
||
const savedLanguage = localStorage.getItem('preferredLanguage');
|
||
if (savedLanguage && this.translations[savedLanguage]) {
|
||
this.currentLanguage = savedLanguage;
|
||
} else {
|
||
// 根据浏览器语言自动选择
|
||
const browserLang = navigator.language || navigator.userLanguage;
|
||
if (browserLang.startsWith('zh')) {
|
||
this.currentLanguage = 'zh-CN';
|
||
} else {
|
||
this.currentLanguage = 'en-US';
|
||
}
|
||
}
|
||
|
||
this.updatePageLanguage();
|
||
this.updateAllTexts();
|
||
}
|
||
};
|
||
|
||
// 全局函数,供HTML调用
|
||
window.t = (key, params) => i18n.t(key, params);
|
||
window.setLanguage = (lang) => i18n.setLanguage(lang);
|