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
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6837100dec | ||
|
|
8542041981 | ||
|
|
35ceab0dae | ||
|
|
d3fe186df7 | ||
|
|
5aff22a20b | ||
|
|
aa1dedc932 | ||
|
|
61e75eee97 | ||
|
|
3a2d96725f | ||
|
|
8283e99909 | ||
|
|
181cba6886 |
40
i18n.js
40
i18n.js
@@ -41,6 +41,11 @@ const i18n = {
|
||||
'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',
|
||||
@@ -131,10 +136,14 @@ 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_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 配置',
|
||||
@@ -225,6 +234,8 @@ const i18n = {
|
||||
'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',
|
||||
@@ -232,6 +243,8 @@ const i18n = {
|
||||
'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',
|
||||
@@ -396,6 +409,9 @@ const i18n = {
|
||||
'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配置删除成功',
|
||||
@@ -483,6 +499,11 @@ const i18n = {
|
||||
'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',
|
||||
@@ -573,10 +594,14 @@ const i18n = {
|
||||
'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 Key:',
|
||||
'ai_providers.gemini_add_modal_key_placeholder': 'Please enter 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',
|
||||
@@ -667,6 +692,8 @@ const i18n = {
|
||||
'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',
|
||||
@@ -674,6 +701,8 @@ const i18n = {
|
||||
'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',
|
||||
@@ -837,6 +866,9 @@ const i18n = {
|
||||
'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',
|
||||
|
||||
@@ -427,6 +427,8 @@
|
||||
<button class="filter-btn active" data-type="all" data-i18n-text="auth_files.filter_all">All</button>
|
||||
<button class="filter-btn" data-type="qwen" data-i18n-text="auth_files.filter_qwen">Qwen</button>
|
||||
<button class="filter-btn" data-type="gemini" data-i18n-text="auth_files.filter_gemini">Gemini</button>
|
||||
<button class="filter-btn" data-type="gemini-cli" data-i18n-text="auth_files.filter_gemini-cli">GeminiCLI</button>
|
||||
<button class="filter-btn" data-type="aistudio" data-i18n-text="auth_files.filter_aistudio">AIStudio</button>
|
||||
<button class="filter-btn" data-type="claude" data-i18n-text="auth_files.filter_claude">Claude</button>
|
||||
<button class="filter-btn" data-type="codex" data-i18n-text="auth_files.filter_codex">Codex</button>
|
||||
<button class="filter-btn" data-type="iflow" data-i18n-text="auth_files.filter_iflow">iFlow</button>
|
||||
|
||||
@@ -26,6 +26,5 @@
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "local"
|
||||
},
|
||||
"dependencies": {}
|
||||
}
|
||||
}
|
||||
|
||||
316
styles.css
316
styles.css
@@ -1683,6 +1683,27 @@ input:checked+.slider:before {
|
||||
border: 1px dashed #666666;
|
||||
}
|
||||
|
||||
/* 虚拟认证文件标记样式 */
|
||||
.virtual-auth-badge {
|
||||
background: linear-gradient(135deg, var(--primary-color) 0%, var(--primary-hover) 100%);
|
||||
color: white;
|
||||
font-size: 13px;
|
||||
padding: 4px 8px;
|
||||
border-radius: 12px;
|
||||
font-weight: 500;
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
box-shadow: 0 2px 4px rgba(59, 130, 246, 0.25);
|
||||
letter-spacing: 0.3px;
|
||||
}
|
||||
|
||||
[data-theme="dark"] .virtual-auth-badge {
|
||||
background: linear-gradient(135deg, var(--primary-color) 0%, var(--primary-hover) 100%);
|
||||
box-shadow: 0 2px 4px rgba(96, 165, 250, 0.25);
|
||||
}
|
||||
|
||||
|
||||
.provider-list {
|
||||
/* 默认不限制高度,动态设置 */
|
||||
min-height: 0;
|
||||
@@ -1751,6 +1772,22 @@ input:checked+.slider:before {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
/* 认证文件项的底部布局优化 - 确保状态标签和操作按钮垂直对齐 */
|
||||
.file-item .item-footer {
|
||||
align-items: center; /* 垂直居中对齐 */
|
||||
gap: 12px; /* 增加状态标签和按钮之间的间距 */
|
||||
}
|
||||
|
||||
.file-item .item-stats {
|
||||
align-items: center; /* 状态徽章垂直居中 */
|
||||
margin: 0; /* 移除默认外边距 */
|
||||
}
|
||||
|
||||
.file-item .item-actions {
|
||||
align-items: center; /* 操作按钮垂直居中 */
|
||||
gap: 6px; /* 按钮之间适当间距 */
|
||||
}
|
||||
|
||||
/* API Keys 和 AI Providers 的按钮组 - 绝对定位到右侧垂直居中 */
|
||||
.key-item .item-actions,
|
||||
.provider-item .item-actions {
|
||||
@@ -2039,9 +2076,13 @@ input:checked+.slider:before {
|
||||
border-radius: 15px;
|
||||
width: 90%;
|
||||
max-width: 550px;
|
||||
max-height: 90vh;
|
||||
box-shadow: var(--shadow-modal);
|
||||
animation: modalSlideIn 0.3s ease;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
@keyframes modalSlideIn {
|
||||
@@ -2082,6 +2123,9 @@ input:checked+.slider:before {
|
||||
|
||||
#modal-body {
|
||||
padding: 35px 30px 30px 30px;
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
/* 模态框标题样式 */
|
||||
@@ -2770,6 +2814,68 @@ input:checked+.slider:before {
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.header-input-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.header-input-row .header-input-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.header-key-input {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.header-value-input {
|
||||
flex: 2;
|
||||
}
|
||||
|
||||
.header-separator {
|
||||
color: var(--text-tertiary);
|
||||
}
|
||||
|
||||
.header-badges-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.header-badge-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.header-badge {
|
||||
background: var(--accent-tertiary);
|
||||
border: 1px solid var(--border-primary);
|
||||
border-radius: 12px;
|
||||
padding: 4px 8px;
|
||||
font-size: 12px;
|
||||
color: var(--text-secondary);
|
||||
display: inline-flex;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.header-badge strong {
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
[data-theme="dark"] .header-badge {
|
||||
background: rgba(59, 130, 246, 0.15);
|
||||
border-color: rgba(59, 130, 246, 0.3);
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
[data-theme="dark"] .header-badge strong {
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
/* Codex OAuth 样式 */
|
||||
#codex-oauth-content {
|
||||
transition: all 0.3s ease;
|
||||
@@ -3280,9 +3386,10 @@ input:checked+.slider:before {
|
||||
border: 1px solid var(--border-primary);
|
||||
border-radius: 6px;
|
||||
padding: 16px;
|
||||
font-size: 12px;
|
||||
font-size: 13px;
|
||||
line-height: 1.6;
|
||||
color: var(--text-secondary);
|
||||
font-weight: 600;
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
max-height: calc(100vh - 480px);
|
||||
@@ -3291,6 +3398,133 @@ input:checked+.slider:before {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.logs-text .log-line {
|
||||
display: block;
|
||||
padding: 2px 0;
|
||||
margin: 0;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.logs-text .log-line + .log-line {
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.logs-text .log-status-tag {
|
||||
display: inline-block;
|
||||
padding: 0 8px;
|
||||
margin-right: 6px;
|
||||
border-radius: 6px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.3px;
|
||||
}
|
||||
|
||||
.logs-text .log-status-tag.log-status-2xx {
|
||||
background: rgba(16, 185, 129, 0.18);
|
||||
color: #047857;
|
||||
}
|
||||
|
||||
.logs-text .log-status-tag.log-status-3xx {
|
||||
background: rgba(6, 182, 212, 0.2);
|
||||
color: #0f766e;
|
||||
}
|
||||
|
||||
.logs-text .log-status-tag.log-status-4xx {
|
||||
background: rgba(251, 191, 36, 0.26);
|
||||
color: #92400e;
|
||||
}
|
||||
|
||||
.logs-text .log-status-tag.log-status-5xx {
|
||||
background: rgba(239, 68, 68, 0.22);
|
||||
color: #b91c1c;
|
||||
}
|
||||
|
||||
.logs-text .log-status-tag.log-status-1xx {
|
||||
background: rgba(165, 180, 252, 0.22);
|
||||
color: #4338ca;
|
||||
}
|
||||
|
||||
/* 日志高亮样式 */
|
||||
|
||||
/* 时间戳高亮 */
|
||||
.logs-text .log-timestamp {
|
||||
color: #8b5cf6;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* 日志级别高亮 */
|
||||
.logs-text .log-level {
|
||||
display: inline-block;
|
||||
padding: 1px 6px;
|
||||
border-radius: 4px;
|
||||
font-weight: 700;
|
||||
font-size: 0.95em;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.logs-text .log-level-error {
|
||||
background: rgba(239, 68, 68, 0.20);
|
||||
color: #dc2626;
|
||||
}
|
||||
|
||||
.logs-text .log-level-warn {
|
||||
background: rgba(251, 191, 36, 0.25);
|
||||
color: #d97706;
|
||||
}
|
||||
|
||||
.logs-text .log-level-info {
|
||||
background: rgba(59, 130, 246, 0.20);
|
||||
color: #2563eb;
|
||||
}
|
||||
|
||||
.logs-text .log-level-debug {
|
||||
background: rgba(107, 114, 128, 0.18);
|
||||
color: #6b7280;
|
||||
}
|
||||
|
||||
/* HTTP 方法高亮 */
|
||||
.logs-text .log-http-method {
|
||||
color: #0891b2;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
/* 路径/URL 高亮 */
|
||||
.logs-text .log-path {
|
||||
color: #059669;
|
||||
text-decoration: underline;
|
||||
text-decoration-style: dotted;
|
||||
text-decoration-color: rgba(5, 150, 105, 0.3);
|
||||
}
|
||||
|
||||
/* IP 地址高亮 */
|
||||
.logs-text .log-ip {
|
||||
color: #7c3aed;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* 关键字高亮 - 成功 */
|
||||
.logs-text .log-keyword-success {
|
||||
color: #059669;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* 关键字高亮 - 错误 */
|
||||
.logs-text .log-keyword-error {
|
||||
color: #dc2626;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* 关键字高亮 - 警告 */
|
||||
.logs-text .log-keyword-warn {
|
||||
color: #ea580c;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* 数字和单位高亮 */
|
||||
.logs-text .log-number-unit {
|
||||
color: #db2777;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.logs-text::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
@@ -3424,10 +3658,89 @@ input:checked+.slider:before {
|
||||
color: var(--text-tertiary);
|
||||
}
|
||||
|
||||
[data-theme="dark"] .logs-text .log-status-tag.log-status-2xx {
|
||||
background: rgba(16, 185, 129, 0.32);
|
||||
color: #6ee7b7;
|
||||
}
|
||||
|
||||
[data-theme="dark"] .logs-text .log-status-tag.log-status-3xx {
|
||||
background: rgba(6, 182, 212, 0.34);
|
||||
color: #5eead4;
|
||||
}
|
||||
|
||||
[data-theme="dark"] .logs-text .log-status-tag.log-status-4xx {
|
||||
background: rgba(251, 191, 36, 0.38);
|
||||
color: #fcd34d;
|
||||
}
|
||||
|
||||
[data-theme="dark"] .logs-text .log-status-tag.log-status-5xx {
|
||||
background: rgba(239, 68, 68, 0.38);
|
||||
color: #fca5a5;
|
||||
}
|
||||
|
||||
[data-theme="dark"] .logs-text .log-status-tag.log-status-1xx {
|
||||
background: rgba(165, 180, 252, 0.38);
|
||||
color: #c7d2fe;
|
||||
}
|
||||
|
||||
[data-theme="dark"] .logs-container {
|
||||
background: rgba(15, 23, 42, 0.3);
|
||||
}
|
||||
|
||||
/* 暗色主题 - 日志高亮样式 */
|
||||
[data-theme="dark"] .logs-text .log-timestamp {
|
||||
color: #c4b5fd;
|
||||
}
|
||||
|
||||
[data-theme="dark"] .logs-text .log-level-error {
|
||||
background: rgba(239, 68, 68, 0.32);
|
||||
color: #fca5a5;
|
||||
}
|
||||
|
||||
[data-theme="dark"] .logs-text .log-level-warn {
|
||||
background: rgba(251, 191, 36, 0.35);
|
||||
color: #fbbf24;
|
||||
}
|
||||
|
||||
[data-theme="dark"] .logs-text .log-level-info {
|
||||
background: rgba(59, 130, 246, 0.32);
|
||||
color: #93c5fd;
|
||||
}
|
||||
|
||||
[data-theme="dark"] .logs-text .log-level-debug {
|
||||
background: rgba(107, 114, 128, 0.28);
|
||||
color: #9ca3af;
|
||||
}
|
||||
|
||||
[data-theme="dark"] .logs-text .log-http-method {
|
||||
color: #22d3ee;
|
||||
}
|
||||
|
||||
[data-theme="dark"] .logs-text .log-path {
|
||||
color: #34d399;
|
||||
text-decoration-color: rgba(52, 211, 153, 0.3);
|
||||
}
|
||||
|
||||
[data-theme="dark"] .logs-text .log-ip {
|
||||
color: #a78bfa;
|
||||
}
|
||||
|
||||
[data-theme="dark"] .logs-text .log-keyword-success {
|
||||
color: #34d399;
|
||||
}
|
||||
|
||||
[data-theme="dark"] .logs-text .log-keyword-error {
|
||||
color: #f87171;
|
||||
}
|
||||
|
||||
[data-theme="dark"] .logs-text .log-keyword-warn {
|
||||
color: #fb923c;
|
||||
}
|
||||
|
||||
[data-theme="dark"] .logs-text .log-number-unit {
|
||||
color: #f472b6;
|
||||
}
|
||||
|
||||
/* ===== AI提供商统计徽章样式 ===== */
|
||||
|
||||
/* 统计信息容器 */
|
||||
@@ -3435,6 +3748,7 @@ input:checked+.slider:before {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
flex-wrap: wrap;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
/* 统计徽章基础样式 */
|
||||
|
||||
Reference in New Issue
Block a user