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
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6308074c11 | ||
|
|
aa852025a5 | ||
|
|
6928cfed28 | ||
|
|
8f71b0d811 | ||
|
|
edb723c12b |
66
i18n.js
66
i18n.js
@@ -141,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 配置',
|
||||
@@ -200,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',
|
||||
@@ -212,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': '密钥数量',
|
||||
@@ -228,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': '下载',
|
||||
@@ -247,6 +249,10 @@ const i18n = {
|
||||
'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',
|
||||
@@ -368,6 +374,10 @@ const i18n = {
|
||||
'usage_stats.by_hour': '按小时',
|
||||
'usage_stats.by_day': '按天',
|
||||
'usage_stats.refresh': '刷新',
|
||||
'usage_stats.chart_line_label_1': '曲线 1',
|
||||
'usage_stats.chart_line_label_2': '曲线 2',
|
||||
'usage_stats.chart_line_label_3': '曲线 3',
|
||||
'usage_stats.chart_line_hidden': '不显示',
|
||||
'usage_stats.no_data': '暂无数据',
|
||||
'usage_stats.loading_error': '加载失败',
|
||||
'usage_stats.api_endpoint': 'API端点',
|
||||
@@ -638,13 +648,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',
|
||||
@@ -696,10 +705,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',
|
||||
@@ -708,8 +719,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',
|
||||
@@ -724,6 +734,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',
|
||||
@@ -743,6 +755,10 @@ const i18n = {
|
||||
'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',
|
||||
@@ -863,6 +879,10 @@ const i18n = {
|
||||
'usage_stats.by_hour': 'By Hour',
|
||||
'usage_stats.by_day': 'By Day',
|
||||
'usage_stats.refresh': 'Refresh',
|
||||
'usage_stats.chart_line_label_1': 'Line 1',
|
||||
'usage_stats.chart_line_label_2': 'Line 2',
|
||||
'usage_stats.chart_line_label_3': 'Line 3',
|
||||
'usage_stats.chart_line_hidden': 'Hide',
|
||||
'usage_stats.no_data': 'No Data Available',
|
||||
'usage_stats.loading_error': 'Loading Failed',
|
||||
'usage_stats.api_endpoint': 'API Endpoint',
|
||||
|
||||
43
index.html
43
index.html
@@ -519,6 +519,27 @@
|
||||
</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">
|
||||
@@ -804,6 +825,28 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 图表曲线选择 -->
|
||||
<div class="usage-filter-bar">
|
||||
<div class="usage-filter-group">
|
||||
<label for="chart-line-select-0" data-i18n="usage_stats.chart_line_label_1">曲线 1</label>
|
||||
<select id="chart-line-select-0" class="model-filter-select chart-line-select" data-line-index="0" disabled>
|
||||
<option value="none" data-i18n="usage_stats.chart_line_hidden">不显示</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="usage-filter-group">
|
||||
<label for="chart-line-select-1" data-i18n="usage_stats.chart_line_label_2">曲线 2</label>
|
||||
<select id="chart-line-select-1" class="model-filter-select chart-line-select" data-line-index="1" disabled>
|
||||
<option value="none" data-i18n="usage_stats.chart_line_hidden">不显示</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="usage-filter-group">
|
||||
<label for="chart-line-select-2" data-i18n="usage_stats.chart_line_label_3">曲线 3</label>
|
||||
<select id="chart-line-select-2" class="model-filter-select chart-line-select" data-line-index="2" disabled>
|
||||
<option value="none" data-i18n="usage_stats.chart_line_hidden">不显示</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 图表区域 -->
|
||||
<div class="charts-container">
|
||||
<!-- 请求趋势图 -->
|
||||
|
||||
158
styles.css
158
styles.css
@@ -1630,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;
|
||||
@@ -2616,6 +2703,42 @@ input:checked+.slider:before {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.usage-filter-bar {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
gap: 16px;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.usage-filter-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
min-width: 220px;
|
||||
}
|
||||
|
||||
.usage-filter-group label {
|
||||
font-weight: 600;
|
||||
color: var(--text-secondary);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.model-filter-select {
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 10px;
|
||||
padding: 10px 14px;
|
||||
background: var(--bg-primary);
|
||||
color: var(--text-primary);
|
||||
min-height: 40px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.model-filter-select:disabled {
|
||||
opacity: 0.7;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
background: var(--card-bg);
|
||||
border: 1px solid var(--border-color);
|
||||
@@ -2853,6 +2976,7 @@ input:checked+.slider:before {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.model-input-row .input-group {
|
||||
@@ -2873,10 +2997,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