mirror of
https://github.com/router-for-me/Cli-Proxy-API-Management-Center.git
synced 2026-02-03 03:10:50 +08:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8f71b0d811 | ||
|
|
edb723c12b | ||
|
|
295befe42b | ||
|
|
a07faddeff | ||
|
|
5be40092f7 | ||
|
|
d422606f99 | ||
|
|
8b07159c35 |
76
i18n.js
76
i18n.js
@@ -46,6 +46,8 @@ const i18n = {
|
||||
'common.custom_headers_add': '添加请求头',
|
||||
'common.custom_headers_key_placeholder': 'Header 名称,例如 X-Custom-Header',
|
||||
'common.custom_headers_value_placeholder': 'Header 值',
|
||||
'common.model_name_placeholder': '模型名称,例如 claude-3-5-sonnet-20241022',
|
||||
'common.model_alias_placeholder': '模型别名 (可选)',
|
||||
|
||||
// 页面标题
|
||||
'title.main': 'CLI Proxy API Management Center',
|
||||
@@ -139,14 +141,13 @@ const i18n = {
|
||||
'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_add_modal_key_label': 'API密钥',
|
||||
'ai_providers.gemini_add_modal_key_placeholder': '输入 Gemini API 密钥',
|
||||
'ai_providers.gemini_add_modal_key_hint': '逐条输入密钥,可同时指定可选 Base URL。',
|
||||
'ai_providers.gemini_keys_add_btn': '添加密钥',
|
||||
'ai_providers.gemini_base_url_placeholder': '可选 Base URL,如 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 配置',
|
||||
@@ -184,6 +185,10 @@ const i18n = {
|
||||
'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.claude_models_label': '自定义模型 (可选):',
|
||||
'ai_providers.claude_models_hint': '为空表示使用全部模型;可填写 name[, alias] 以限制或重命名模型。',
|
||||
'ai_providers.claude_models_add_btn': '添加模型',
|
||||
'ai_providers.claude_models_count': '模型数量',
|
||||
|
||||
'ai_providers.openai_title': 'OpenAI 兼容提供商',
|
||||
'ai_providers.openai_add_button': '添加提供商',
|
||||
@@ -194,10 +199,12 @@ const i18n = {
|
||||
'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_keys_label': 'API密钥',
|
||||
'ai_providers.openai_edit_modal_keys_label': 'API密钥',
|
||||
'ai_providers.openai_keys_hint': '每个密钥可搭配一个可选代理地址,更便于管理。',
|
||||
'ai_providers.openai_keys_add_btn': '添加密钥',
|
||||
'ai_providers.openai_key_placeholder': '输入 sk- 开头的密钥',
|
||||
'ai_providers.openai_proxy_placeholder': '可选代理 URL (如 socks5://...)',
|
||||
'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',
|
||||
@@ -206,8 +213,7 @@ const i18n = {
|
||||
'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_keys_label': 'API密钥',
|
||||
'ai_providers.openai_edit_modal_models_label': '模型列表 (name[, alias] 每行一个):',
|
||||
'ai_providers.openai_delete_confirm': '确定要删除这个OpenAI提供商吗?',
|
||||
'ai_providers.openai_keys_count': '密钥数量',
|
||||
@@ -222,6 +228,8 @@ const i18n = {
|
||||
'auth_files.delete_all_button': '删除全部',
|
||||
'auth_files.empty_title': '暂无认证文件',
|
||||
'auth_files.empty_desc': '点击上方按钮上传第一个文件',
|
||||
'auth_files.search_empty_title': '没有匹配的配置文件',
|
||||
'auth_files.search_empty_desc': '请调整筛选条件或清空搜索关键字再试一次。',
|
||||
'auth_files.file_size': '大小',
|
||||
'auth_files.file_modified': '修改时间',
|
||||
'auth_files.download_button': '下载',
|
||||
@@ -238,6 +246,13 @@ const i18n = {
|
||||
'auth_files.delete_filtered_partial': '{type} 认证文件删除完成,成功 {success} 个,失败 {failed} 个',
|
||||
'auth_files.delete_filtered_none': '当前筛选类型 ({type}) 下没有可删除的认证文件',
|
||||
'auth_files.files_count': '个文件',
|
||||
'auth_files.pagination_prev': '上一页',
|
||||
'auth_files.pagination_next': '下一页',
|
||||
'auth_files.pagination_info': '第 {current} / {total} 页 · 共 {count} 个文件',
|
||||
'auth_files.search_label': '搜索配置文件',
|
||||
'auth_files.search_placeholder': '输入名称、类型或提供方关键字',
|
||||
'auth_files.page_size_label': '单页数量',
|
||||
'auth_files.page_size_unit': '个/页',
|
||||
'auth_files.filter_all': '全部',
|
||||
'auth_files.filter_qwen': 'Qwen',
|
||||
'auth_files.filter_gemini': 'Gemini',
|
||||
@@ -533,6 +548,8 @@ const i18n = {
|
||||
'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',
|
||||
'common.model_name_placeholder': 'Model name, e.g. claude-3-5-sonnet-20241022',
|
||||
'common.model_alias_placeholder': 'Model alias (optional)',
|
||||
|
||||
// Page titles
|
||||
'title.main': 'CLI Proxy API Management Center',
|
||||
@@ -627,13 +644,12 @@ const i18n = {
|
||||
'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_add_modal_key_placeholder': 'Enter Gemini API key',
|
||||
'ai_providers.gemini_add_modal_key_hint': 'Add keys one by one and optionally specify a Base URL.',
|
||||
'ai_providers.gemini_keys_add_btn': 'Add Key',
|
||||
'ai_providers.gemini_base_url_placeholder': 'Optional Base URL, 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',
|
||||
@@ -671,6 +687,10 @@ const i18n = {
|
||||
'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.claude_models_label': 'Custom Models (Optional):',
|
||||
'ai_providers.claude_models_hint': 'Leave empty to allow all models, or add name[, alias] entries to limit/alias them.',
|
||||
'ai_providers.claude_models_add_btn': 'Add Model',
|
||||
'ai_providers.claude_models_count': 'Models Count',
|
||||
|
||||
'ai_providers.openai_title': 'OpenAI Compatible Providers',
|
||||
'ai_providers.openai_add_button': 'Add Provider',
|
||||
@@ -681,10 +701,12 @@ const i18n = {
|
||||
'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_keys_label': 'API Keys',
|
||||
'ai_providers.openai_edit_modal_keys_label': 'API Keys',
|
||||
'ai_providers.openai_keys_hint': 'Add each key separately with an optional proxy URL to keep things organized.',
|
||||
'ai_providers.openai_keys_add_btn': 'Add Key',
|
||||
'ai_providers.openai_key_placeholder': 'sk-... key',
|
||||
'ai_providers.openai_proxy_placeholder': 'Optional proxy URL (e.g. socks5://...)',
|
||||
'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',
|
||||
@@ -693,8 +715,7 @@ const i18n = {
|
||||
'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_keys_label': 'API Keys',
|
||||
'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',
|
||||
@@ -709,6 +730,8 @@ const i18n = {
|
||||
'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.search_empty_title': 'No matching files',
|
||||
'auth_files.search_empty_desc': 'Try changing the filters or clearing the search box.',
|
||||
'auth_files.file_size': 'Size',
|
||||
'auth_files.file_modified': 'Modified',
|
||||
'auth_files.download_button': 'Download',
|
||||
@@ -725,6 +748,13 @@ const i18n = {
|
||||
'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.pagination_prev': 'Previous',
|
||||
'auth_files.pagination_next': 'Next',
|
||||
'auth_files.pagination_info': 'Page {current} / {total} · {count} files',
|
||||
'auth_files.search_label': 'Search configs',
|
||||
'auth_files.search_placeholder': 'Filter by name, type, or provider',
|
||||
'auth_files.page_size_label': 'Per page',
|
||||
'auth_files.page_size_unit': 'items',
|
||||
'auth_files.filter_all': 'All',
|
||||
'auth_files.filter_qwen': 'Qwen',
|
||||
'auth_files.filter_gemini': 'Gemini',
|
||||
|
||||
32
index.html
32
index.html
@@ -519,7 +519,39 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<div class="auth-file-toolbar">
|
||||
<div class="auth-file-search-group">
|
||||
<label for="auth-files-search-input"
|
||||
data-i18n="auth_files.search_label">搜索配置文件</label>
|
||||
<div class="auth-file-search">
|
||||
<i class="fas fa-search"></i>
|
||||
<input type="text" id="auth-files-search-input"
|
||||
data-i18n-placeholder="auth_files.search_placeholder"
|
||||
placeholder="搜索文件名或类型">
|
||||
</div>
|
||||
</div>
|
||||
<div class="auth-file-page-size">
|
||||
<label for="auth-files-page-size-input"
|
||||
data-i18n="auth_files.page_size_label">单页数量</label>
|
||||
<div class="page-size-input">
|
||||
<input type="number" id="auth-files-page-size-input" min="3" max="60"
|
||||
step="1">
|
||||
<span data-i18n="auth_files.page_size_unit">个/页</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="auth-files-list" class="file-list file-grid"></div>
|
||||
<div id="auth-files-pagination" class="pagination-controls" style="display: none;">
|
||||
<button class="btn btn-secondary pagination-btn" data-action="prev">
|
||||
<i class="fas fa-chevron-left"></i>
|
||||
<span data-i18n="auth_files.pagination_prev">上一页</span>
|
||||
</button>
|
||||
<div id="auth-files-pagination-info" class="pagination-info">-</div>
|
||||
<button class="btn btn-secondary pagination-btn" data-action="next">
|
||||
<span data-i18n="auth_files.pagination_next">下一页</span>
|
||||
<i class="fas fa-chevron-right"></i>
|
||||
</button>
|
||||
</div>
|
||||
<input type="file" id="auth-file-input" accept=".json" style="display: none;">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
164
styles.css
164
styles.css
@@ -1248,6 +1248,21 @@ body {
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.btn-small.btn-warning {
|
||||
background: #ff9800;
|
||||
color: #fff;
|
||||
border-color: #ff9800;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.btn-small.btn-warning:disabled,
|
||||
.btn-small.btn-warning[disabled] {
|
||||
background: #fb8c00;
|
||||
border-color: #fb8c00;
|
||||
color: #fff;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.btn-small i {
|
||||
font-size: 13px;
|
||||
}
|
||||
@@ -1552,6 +1567,33 @@ input:checked+.slider:before {
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.pagination-controls {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 12px;
|
||||
margin-top: 20px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.pagination-btn {
|
||||
gap: 6px;
|
||||
min-width: 120px;
|
||||
justify-content: center;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.pagination-btn:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.pagination-info {
|
||||
font-size: 0.95rem;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
/* 响应式:中等屏幕2列 */
|
||||
@media (max-width: 1400px) {
|
||||
.file-grid {
|
||||
@@ -1588,6 +1630,93 @@ input:checked+.slider:before {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* 认证文件工具栏 */
|
||||
.auth-file-toolbar {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 18px;
|
||||
align-items: flex-end;
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
.auth-file-search-group {
|
||||
flex: 1;
|
||||
min-width: 240px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.auth-file-search-group label,
|
||||
.auth-file-page-size label {
|
||||
font-weight: 600;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.auth-file-search {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border: 1px solid var(--border-primary);
|
||||
border-radius: 10px;
|
||||
padding: 0 12px;
|
||||
background: var(--bg-secondary);
|
||||
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.03);
|
||||
}
|
||||
|
||||
[data-theme="dark"] .auth-file-search {
|
||||
background: var(--bg-tertiary);
|
||||
box-shadow: inset 0 1px 1px rgba(255, 255, 255, 0.04);
|
||||
}
|
||||
|
||||
.auth-file-search i {
|
||||
color: var(--text-tertiary);
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.auth-file-search input {
|
||||
border: none;
|
||||
background: transparent;
|
||||
color: var(--text-primary);
|
||||
width: 100%;
|
||||
padding: 10px 0;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.auth-file-search input:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.auth-file-page-size {
|
||||
min-width: 180px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.page-size-input {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
border: 1px solid var(--border-primary);
|
||||
border-radius: 10px;
|
||||
padding: 8px 12px;
|
||||
background: var(--bg-quaternary);
|
||||
}
|
||||
|
||||
.page-size-input input {
|
||||
width: 80px;
|
||||
padding: 6px 8px;
|
||||
border: 1px solid var(--border-secondary);
|
||||
border-radius: 6px;
|
||||
background: var(--bg-primary);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.page-size-input span {
|
||||
font-size: 0.9rem;
|
||||
color: var(--text-tertiary);
|
||||
}
|
||||
|
||||
/* 认证文件筛选按钮 */
|
||||
.auth-file-filter {
|
||||
display: flex;
|
||||
@@ -2811,6 +2940,7 @@ input:checked+.slider:before {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.model-input-row .input-group {
|
||||
@@ -2831,10 +2961,44 @@ input:checked+.slider:before {
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.api-key-input-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.api-key-input-group {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.api-key-input-group .api-key-value-input {
|
||||
flex: 2;
|
||||
}
|
||||
|
||||
.api-key-input-group .api-key-proxy-input {
|
||||
flex: 1;
|
||||
min-width: 180px;
|
||||
}
|
||||
|
||||
.api-key-input-group .api-key-remove-btn {
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.api-key-input-list + .btn,
|
||||
.model-input-list + .btn,
|
||||
.header-input-list + .btn {
|
||||
margin-top: 4px;
|
||||
align-self: flex-start;
|
||||
}
|
||||
|
||||
.header-input-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.header-input-row .header-input-group {
|
||||
|
||||
Reference in New Issue
Block a user