Compare commits

...

46 Commits

Author SHA1 Message Date
Supra4E8C
5be40092f7 feat(app.js, i18n): add custom model management for Claude API
- Introduced UI elements for adding and managing custom models in the CLIProxyManager, including model name and alias inputs.
- Enhanced the display of model counts and badges in the provider item view.
- Updated internationalization strings to support new model management features in both English and Chinese.
2025-11-13 17:52:13 +08:00
Luis Pater
d422606f99 feat(app.js, styles.css): add main flag for Gemini CLI auth files, update styles and filtering logic 2025-11-13 09:22:14 +08:00
Supra4E8C
8b07159c35 refactor(app.js): improve API key handling and display logic
- Enhanced the masking and display of API keys to ensure proper handling of null or undefined values.
- Updated the HTML rendering logic to use normalized and escaped key values for better security and consistency.
- Improved the handling of key arguments in button actions to prevent potential issues with special characters.
- Refactored the file name handling in the UI to ensure proper escaping and display of file names.
2025-11-12 12:04:58 +08:00
Supra4E8C
5b1be05eb9 feat(index.html): add Vertex AI credential import UI
- Implemented the UI for importing Vertex AI credentials, including file selection and input fields for location and JSON key.
- Enhanced internationalization support with appropriate labels and hints in both English and Chinese.
- Removed the previous implementation of the Vertex AI credential import section to streamline the code.
2025-11-11 18:28:56 +08:00
Supra4E8C
a4fd672458 feat(app.js, i18n, index.html, styles): implement Vertex AI credential import feature
- 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.
2025-11-11 18:19:35 +08:00
Supra4E8C
6f1c7b168d feat(app.js, i18n, index.html): add request logging and WebSocket authentication settings
- Introduced toggles for enabling request logging and WebSocket authentication in the UI.
- Implemented methods to load and update the respective settings in the CLIProxyManager.
- Updated internationalization strings to support new features in both English and Chinese.
2025-11-11 12:32:56 +08:00
Luis Pater
1d7408cb25 feat(app.js, i18n): enhance auth file management with filtering and update related UI messages 2025-11-11 11:50:12 +08:00
Supra4E8C
3468fd8373 feat(app.js, styles): enhance connection state handling and update editor dimensions
- Added a new property to track the last connection state in CLIProxyManager.
- Updated the config editor availability logic to reflect changes in connection state.
- Increased minimum height for various editor components in styles to improve usability.
- Introduced responsive styles for smaller screens to ensure proper display of editor elements.
2025-11-10 18:07:31 +08:00
Supra4E8C
4f15c3f5c5 feat(app.js, i18n): enforce required base URL for Codex API configuration
- Updated the Codex API configuration modals to mark the Base URL field as required.
- Added validation to ensure the Base URL is provided before submission, with appropriate error notifications.
- Updated internationalization strings to reflect the change in the Base URL label from "Optional" to "Required" in both English and Chinese.
2025-11-10 12:16:46 +08:00
hkfires
72cd117aab fix(logs): exclude all /v0/management/ API entries from viewer 2025-11-10 10:40:28 +08:00
hkfires
5d62cd91f2 perf(cli): prefetch /usage, derive keyStats, reuse across renders 2025-11-10 10:32:57 +08:00
Supra4E8C
6837100dec feat(app.js, i18n, styles): implement custom headers functionality in API key management
- Added the ability to input custom HTTP headers for API keys in the CLIProxyManager.
- Introduced new methods for adding, populating, collecting, and applying custom headers.
- Updated the UI to include input fields for custom headers in the modals for adding and editing API keys.
- Enhanced internationalization strings to support custom headers in both English and Chinese.
- Added corresponding styles for the new header input fields and badges in the UI.
2025-11-09 18:27:29 +08:00
Supra4E8C
8542041981 feat(app.js, i18n): support batch addition of Gemini API keys with enhanced UI
- Updated the Gemini API key modal to allow input of multiple keys, each on a new line.
- Added a hint for users on how to input multiple keys and updated the corresponding internationalization strings.
- Enhanced the key addition logic to handle success, skipped, and failed counts, providing detailed feedback to users.
- Improved error handling and notifications for batch operations.
2025-11-09 18:06:56 +08:00
Supra4E8C
35ceab0dae feat(app.js, i18n): enhance Gemini API key management with base URL support
- Updated the CLIProxyManager to handle both API keys and optional base URLs for Gemini.
- Added new input fields in the modal for base URL entry during key addition and editing.
- Updated internationalization strings to include labels and placeholders for the base URL in both English and Chinese.
- Improved key normalization and rendering logic to accommodate the new structure.
2025-11-09 17:51:38 +08:00
Supra4E8C
d3fe186df7 refactor(app.js): remove modal click event listener to streamline modal behavior 2025-11-09 17:20:02 +08:00
Supra4E8C
5aff22a20b fix(ui): update modal styles for better responsiveness and overflow handling 2025-11-09 17:17:49 +08:00
hkfires
aa1dedc932 feat(ui): mark runtime-only auth files and disable actions 2025-11-07 22:02:29 +08:00
hkfires
61e75eee97 feat(auth-files): add AI Studio and Gemini CLI with filename masking 2025-11-07 21:46:46 +08:00
hkfires
3a2d96725f fix(ui): align file-item footer and adjust badge spacing 2025-11-06 14:23:07 +08:00
Supra4E8C
8283e99909 fix(app.js):尝试修复codex配置异常丢失数据的问题 2025-11-05 18:06:22 +08:00
hkfires
181cba6886 feat(logs): limit lines, incremental updates, and highlighting 2025-11-03 18:44:50 +08:00
hkfires
aa729914c5 fix(ui): position API Keys/Providers action buttons; prevent overlap 2025-11-03 16:31:29 +08:00
hkfires
f98f31f2ed fix(i18n, ui): correct syntax error in generateDynamicTypeLabel method
- Move generateDynamicTypeLabel method from inside updateAuthFileFilterButtons to proper class method location
- Fix JavaScript syntax error that prevented app from loading
- Preserve all internationalization functionality from 257260b

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-03 16:05:51 +08:00
hkfires
1e79f918e2 fix(ui): harden key list rendering and config handling 2025-10-31 16:24:43 +08:00
Supra4E8C
257260b1d2 feat(i18n, ui): enhance file type filtering with internationalization support
- Updated the file type display logic to utilize i18n for dynamic translations.
- Refactored filter button definitions to include data attributes for improved localization.
- Added new translation keys for various file types and filter options in both English and Chinese.
- Implemented a method to refresh button texts upon language change, ensuring consistent UI updates.
2025-10-26 17:46:57 +08:00
Supra4E8C
8372906820 为筛选按钮容器 .auth-file-filter 改用事件委托,并在重新渲染时移除旧监听器,避免多次绑定导致回调重复执行。 2025-10-26 17:33:06 +08:00
Supra4E8C
5feea2e345 Merge pull request #10 from coulsontl/new_ui
feat(ui): 添加类型筛选和详细信息视图来优化认证文件管理,并优化布局结构
2025-10-26 17:23:09 +08:00
coulsontl
825ad53c2c refactor(ui): streamline auth file actions with event delegation
- Updated the auth file action buttons to use data attributes for improved event handling.
- Implemented event delegation for button actions (show details, download, delete) to enhance performance and maintainability.
- Added a hidden class in CSS to manage file item visibility more effectively.
- Refactored modal button actions to utilize event delegation for better code organization.
2025-10-26 17:09:33 +08:00
coulsontl
3e9413172c feat(ui): enhance auth file management with type filtering and detailed view
- Implemented file type collection and dynamic filter button updates based on available file types.
- Added a detailed view for auth files, displaying JSON content in a modal with copy functionality.
- Improved UI layout for file items and added responsive design for better usability.
2025-10-26 16:43:06 +08:00
Supra4E8C
89099b58ff update README 2025-10-26 14:56:54 +08:00
Supra4E8C
7509a1eddc 更新补全i18n国际化文本 2025-10-26 14:54:07 +08:00
hkfires
e92784f951 feat(ui): add auth file success/failure stats; expand list height 2025-10-21 21:59:08 +08:00
hkfires
d26695da76 feat(ui,keys): granular masking, stats match, legacy format
- Make maskApiKey progressive for short keys to reduce exposure
- When aggregating usage, fall back to masked key to match stored stats
- Support legacy provider config `api-keys` by mapping to `api-key-entries`
- Add scrolling for provider lists >5 and reset styles when empty
- Improves privacy, fixes mismatched stats display, and preserves compatibility
2025-10-21 21:08:09 +08:00
Supra4E8C
8964030ade 尝试修复bug 2025-10-21 12:31:22 +08:00
hkfires
0b9abdf9b1 fix(logs): auto-scroll to latest on full reload 2025-10-20 14:57:15 +08:00
hkfires
a208a484ff feat(config-ui): add YAML config editor with save/reload support 2025-10-19 22:40:08 +08:00
Supra4E8C
369cf52346 0.1.7 2025-10-18 17:04:29 +08:00
hkfires
dcfffc716b feat(ui): add in-app log viewer and file logging controls
- Add Logs section with refresh, download, and clear actions
- Implement auto-refresh toggle and incremental loading via timestamp
- Add “logging to file” setting; integrate with config and /logging-to-file API
- Auto-load logs when opening Logs; hide nav when logging disabled
- Escape HTML when rendering logs for safety
- Update i18n with strings for logs and settings
- Ignore CLAUDE.md and AGENTS.md in .gitignore

Why: Enable users to monitor and manage logs within the app, reduce overhead with incremental updates, and avoid committing local agent docs.
2025-10-16 12:03:15 +08:00
hkfires
7de5280824 feat(build): auto-inject release version into HTML output 2025-10-15 16:49:53 +08:00
hkfires
86d60aad77 增加使用统计开关 2025-10-13 15:56:26 +08:00
Supra4E8C
020fccc032 1 2025-10-11 15:51:51 +08:00
Supra4E8C
c162ab3a54 删除gemini web tokens 2025-10-11 15:02:57 +08:00
Supra4E8C
85d12e15d8 Merge pull request #4 from tombii/main
Add missing English translations.
2025-10-11 14:51:40 +08:00
tombii
ebffb49f52 Add missing English translations. 2025-10-08 22:08:36 +02:00
Supra4E8C
316c1ffc0d Update README_CN.md 2025-10-06 16:02:15 +08:00
Supra4E8C
b3e54e7f14 Update README.md 2025-10-06 16:01:56 +08:00
10 changed files with 5225 additions and 1266 deletions

View File

@@ -27,6 +27,8 @@ jobs:
- name: Build all-in-one HTML
run: npm run build
env:
VERSION: ${{ github.ref_name }}
- name: Prepare release assets
run: |

5
.gitignore vendored
View File

@@ -20,3 +20,8 @@ package-lock.json
# OS files
.DS_Store
Thumbs.db
CLAUDE.md
.claude
AGENTS.md
.serena

View File

@@ -10,7 +10,7 @@ Example URL:
https://remote.router-for.me/
Minimum required version: ≥ 6.0.0
Recommended version: ≥ 6.0.19
Recommended version: ≥ 6.2.32
Since version 6.0.19, the WebUI has been rolled into the main program. You can access it by going to `/management.html` on the external port after firing up the main project.
@@ -43,7 +43,6 @@ Since version 6.0.19, the WebUI has been rolled into the main program. You can a
- Download existing authentication files
- Delete single or all authentication files
- Display file details
- **Gemini Web Token**: Direct authentication using browser cookies
### Usage Statistics
- **Real-time Analytics**: Track API usage with interactive charts

View File

@@ -8,7 +8,9 @@ https://github.com/router-for-me/CLIProxyAPI
https://remote.router-for.me/
最低可用版本 ≥ 6.0.0
推荐版本 ≥ 6.0.19
推荐版本 ≥ 6.2.32
自6.0.19起WebUI已经集成在主程序中 可以通过主项目开启的外部端口的`/management.html`访问
## 功能特点
@@ -40,7 +42,6 @@ https://remote.router-for.me/
- 下载现有认证文件
- 删除单个或所有认证文件
- 显示文件详细信息
- **Gemini Web Token**: 使用浏览器 Cookie 直接认证
### 使用统计
- **实时分析**: 通过交互式图表跟踪 API 使用情况

2902
app.js

File diff suppressed because it is too large Load Diff

View File

@@ -49,6 +49,35 @@ function escapeForStyle(content) {
return content.replace(/<\/(style)/gi, '<\\/$1');
}
function getVersion() {
// 1. 优先从环境变量获取GitHub Actions 会设置)
if (process.env.VERSION) {
return process.env.VERSION;
}
// 2. 尝试从 git tag 获取
try {
const { execSync } = require('child_process');
const gitTag = execSync('git describe --tags --exact-match 2>/dev/null || git describe --tags 2>/dev/null || echo ""', { encoding: 'utf8' }).trim();
if (gitTag) {
return gitTag;
}
} catch (err) {
console.warn('无法从 git 获取版本号');
}
// 3. 回退到 package.json
try {
const packageJson = JSON.parse(fs.readFileSync(path.join(projectRoot, 'package.json'), 'utf8'));
return 'v' + packageJson.version;
} catch (err) {
console.warn('无法从 package.json 读取版本号');
}
// 4. 最后使用默认值
return 'v0.0.0-dev';
}
function ensureDistDir() {
if (fs.existsSync(distDir)) {
fs.rmSync(distDir, { recursive: true, force: true });
@@ -82,6 +111,11 @@ function build() {
const css = escapeForStyle(readFile(sourceFiles.css));
const i18n = escapeForScript(readFile(sourceFiles.i18n));
const app = escapeForScript(readFile(sourceFiles.app));
// 获取版本号并替换
const version = getVersion();
console.log(`使用版本号: ${version}`);
html = html.replace(/__VERSION__/g, version);
html = html.replace(
'<link rel="stylesheet" href="styles.css">',

1916
i18n.js

File diff suppressed because it is too large Load Diff

View File

@@ -7,7 +7,13 @@
<title data-i18n="title.login">CLI Proxy API Management Center</title>
<link rel="stylesheet" href="styles.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/codemirror.min.css">
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/codemirror.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/mode/yaml/yaml.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/addon/edit/closebrackets.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/addon/comment/comment.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/js-yaml@4.1.0/dist/js-yaml.min.js"></script>
<script src="i18n.js"></script>
</head>
@@ -71,8 +77,7 @@
<div class="form-group">
<label for="login-api-base" data-i18n="login.custom_connection_label">自定义连接地址:</label>
<div class="input-group">
<input type="text" id="login-api-base" data-i18n="login.custom_connection_placeholder"
placeholder="例如: https://example.com:8317">
<input type="text" id="login-api-base" data-i18n-placeholder="login.custom_connection_placeholder">
<button type="button" id="login-reset-api-base"
class="btn btn-secondary connection-reset-btn">
<i class="fas fa-location-arrow"></i>
@@ -85,8 +90,7 @@
<div class="form-group">
<label for="login-management-key" data-i18n="login.management_key_label">管理密钥:</label>
<div class="input-group">
<input type="password" id="login-management-key"
data-i18n="login.management_key_placeholder" placeholder="请输入管理密钥" required>
<input type="password" id="login-management-key" data-i18n-placeholder="login.management_key_placeholder" required>
<button type="button" class="btn btn-secondary toggle-key-visibility">
<i class="fas fa-eye"></i>
</button>
@@ -117,7 +121,7 @@
<button class="mobile-menu-btn" id="mobile-menu-btn">
<i class="fas fa-bars"></i>
</button>
<button class="sidebar-toggle-btn-desktop" id="sidebar-toggle-btn-desktop" title="收起/展开侧边栏">
<button class="sidebar-toggle-btn-desktop" id="sidebar-toggle-btn-desktop" data-i18n-title="sidebar.toggle_collapse">
<i class="fas fa-bars"></i>
</button>
<div class="top-navbar-brand">
@@ -155,23 +159,29 @@
<nav class="sidebar" id="sidebar">
<!-- 导航菜单 -->
<ul class="nav-menu">
<li data-tooltip="基础设置"><a href="#basic-settings" class="nav-item active"
<li data-i18n-tooltip="nav.basic_settings"><a href="#basic-settings" class="nav-item active"
data-section="basic-settings">
<i class="fas fa-sliders-h"></i> <span data-i18n="nav.basic_settings">基础设置</span>
</a></li>
<li data-tooltip="API 密钥"><a href="#api-keys" class="nav-item" data-section="api-keys">
<li data-i18n-tooltip="nav.api_keys"><a href="#api-keys" class="nav-item" data-section="api-keys">
<i class="fas fa-key"></i> <span data-i18n="nav.api_keys">API 密钥</span>
</a></li>
<li data-tooltip="AI 提供商"><a href="#ai-providers" class="nav-item" data-section="ai-providers">
<li data-i18n-tooltip="nav.ai_providers"><a href="#ai-providers" class="nav-item" data-section="ai-providers">
<i class="fas fa-robot"></i> <span data-i18n="nav.ai_providers">AI 提供商</span>
</a></li>
<li data-tooltip="认证文件"><a href="#auth-files" class="nav-item" data-section="auth-files">
<li data-i18n-tooltip="nav.auth_files"><a href="#auth-files" class="nav-item" data-section="auth-files">
<i class="fas fa-file-alt"></i> <span data-i18n="nav.auth_files">认证文件</span>
</a></li>
<li data-tooltip="使用统计"><a href="#usage-stats" class="nav-item" data-section="usage-stats">
<li data-i18n-tooltip="nav.usage_stats"><a href="#usage-stats" class="nav-item" data-section="usage-stats">
<i class="fas fa-chart-line"></i> <span data-i18n="nav.usage_stats">使用统计</span>
</a></li>
<li data-tooltip="系统信息"><a href="#system-info" class="nav-item" data-section="system-info">
<li data-i18n-tooltip="nav.config_management"><a href="#config-management" class="nav-item" data-section="config-management">
<i class="fas fa-cog"></i> <span data-i18n="nav.config_management">配置管理</span>
</a></li>
<li id="logs-nav-item" data-i18n-tooltip="nav.logs" style="display: none;"><a href="#logs" class="nav-item" data-section="logs">
<i class="fas fa-scroll"></i> <span data-i18n="nav.logs">日志查看</span>
</a></li>
<li data-i18n-tooltip="nav.system_info"><a href="#system-info" class="nav-item" data-section="system-info">
<i class="fas fa-info-circle"></i> <span data-i18n="nav.system_info">系统信息</span>
</a></li>
</ul>
@@ -218,9 +228,7 @@
<label for="proxy-url" data-i18n="basic_settings.proxy_url_label">代理
URL:</label>
<div class="input-group">
<input type="text" id="proxy-url"
data-i18n="basic_settings.proxy_url_placeholder"
placeholder="例如: socks5://user:pass@127.0.0.1:1080/">
<input type="text" id="proxy-url" data-i18n-placeholder="basic_settings.proxy_url_placeholder">
<button id="update-proxy" class="btn btn-primary"
data-i18n="basic_settings.proxy_update">更新</button>
<button id="clear-proxy" class="btn btn-danger"
@@ -275,6 +283,68 @@
</div>
</div>
<!-- 使用统计设置 -->
<div class="card">
<div class="card-header">
<h3><i class="fas fa-chart-bar"></i> <span
data-i18n="basic_settings.usage_statistics_title">使用统计</span></h3>
</div>
<div class="card-content">
<div class="toggle-group">
<label class="toggle-switch">
<input type="checkbox" id="usage-statistics-enabled-toggle">
<span class="slider"></span>
</label>
<span class="toggle-label"
data-i18n="basic_settings.usage_statistics_enable">启用使用统计</span>
</div>
</div>
</div>
<!-- 日志记录设置 -->
<div class="card">
<div class="card-header">
<h3><i class="fas fa-file-alt"></i> <span
data-i18n="basic_settings.logging_title">日志记录</span></h3>
</div>
<div class="card-content">
<div class="toggle-group">
<label class="toggle-switch">
<input type="checkbox" id="logging-to-file-toggle">
<span class="slider"></span>
</label>
<span class="toggle-label"
data-i18n="basic_settings.logging_to_file_enable">启用日志记录到文件</span>
</div>
<div class="toggle-group">
<label class="toggle-switch">
<input type="checkbox" id="request-log-toggle">
<span class="slider"></span>
</label>
<span class="toggle-label"
data-i18n="basic_settings.request_log_enable">启用请求日志</span>
</div>
</div>
</div>
<!-- WebSocket 鉴权 -->
<div class="card">
<div class="card-header">
<h3><i class="fas fa-shield-alt"></i> <span
data-i18n="basic_settings.ws_auth_title">WebSocket 鉴权</span></h3>
</div>
<div class="card-content">
<div class="toggle-group">
<label class="toggle-switch">
<input type="checkbox" id="ws-auth-toggle">
<span class="slider"></span>
</label>
<span class="toggle-label"
data-i18n="basic_settings.ws_auth_enable">启用 /ws/* 鉴权</span>
</div>
</div>
</div>
</section>
<!-- API 密钥管理 -->
@@ -358,6 +428,51 @@
<div id="openai-providers-list" class="provider-list"></div>
</div>
</div>
<!-- Vertex AI Credential Import -->
<div class="card" id="vertex-import-card">
<div class="card-header">
<h3><i class="fas fa-cloud-upload-alt"></i> <span data-i18n="vertex_import.title">Vertex AI 凭证导入</span></h3>
</div>
<div class="card-content">
<p class="form-hint" data-i18n="vertex_import.description">
上传 Google 服务账号 JSON 并保存为 vertex-<project>.json。
</p>
<div class="form-group">
<label for="vertex-location" data-i18n="vertex_import.location_label">区域 (可选)</label>
<input type="text" id="vertex-location" data-i18n-placeholder="vertex_import.location_placeholder" value="us-central1">
<p class="form-hint" data-i18n="vertex_import.location_hint">留空则使用默认 us-central1。</p>
</div>
<div class="form-group">
<label data-i18n="vertex_import.file_label">服务账号密钥 JSON</label>
<div class="input-group">
<input type="text" id="vertex-file-display" readonly data-i18n-placeholder="vertex_import.file_placeholder" placeholder="尚未选择文件">
<input type="file" id="vertex-file-input" accept=".json" style="display: none;">
<button type="button" id="vertex-select-file" class="btn btn-secondary">
<i class="fas fa-file-upload"></i> <span data-i18n="vertex_import.choose_file">选择文件</span>
</button>
</div>
<p class="form-hint" data-i18n="vertex_import.file_hint">仅支持 Google Cloud service account JSON。</p>
</div>
<div class="form-actions vertex-import-actions">
<button type="button" id="vertex-import-btn" class="btn btn-primary" disabled>
<i class="fas fa-cloud-upload-alt"></i> <span data-i18n="vertex_import.import_button">导入 Vertex 凭证</span>
</button>
</div>
<div id="vertex-import-result" class="vertex-import-result" style="display: none;">
<div class="vertex-import-result-header">
<i class="fas fa-check-circle"></i>
<span data-i18n="vertex_import.result_title">凭证已保存</span>
</div>
<ul>
<li><span data-i18n="vertex_import.result_project">项目 ID</span>: <code id="vertex-result-project">-</code></li>
<li><span data-i18n="vertex_import.result_email">服务账号</span>: <code id="vertex-result-email">-</code></li>
<li><span data-i18n="vertex_import.result_location">区域</span>: <code id="vertex-result-location">-</code></li>
<li><span data-i18n="vertex_import.result_file">存储文件</span>: <code id="vertex-result-file">-</code></li>
</ul>
</div>
</div>
</div>
</section>
<!-- 认证文件管理 -->
@@ -372,50 +487,26 @@
</div>
</div>
<!-- Gemini Web Token -->
<div class="card">
<div class="card-header">
<h3><i class="fab fa-google"></i> <span
data-i18n="auth_login.gemini_web_title">Gemini Web Token</span></h3>
<button id="gemini-web-token-btn" class="btn btn-primary">
<i class="fas fa-save"></i> <span data-i18n="auth_login.gemini_web_button">保存
Gemini Web Token</span>
</button>
</div>
<div class="card-content">
<p class="form-hint" style="margin-bottom: 20px;"
data-i18n="auth_login.gemini_web_hint">
从浏览器开发者工具中获取 Gemini 网页版的 Cookie 值,用于直接认证访问 Gemini。
</p>
<div class="form-group">
<label for="secure-1psid-input"
data-i18n="auth_login.secure_1psid_label">__Secure-1PSID Cookie:</label>
<input type="text" id="secure-1psid-input"
data-i18n="auth_login.secure_1psid_placeholder"
placeholder="输入 __Secure-1PSID cookie 值">
</div>
<div class="form-group">
<label for="secure-1psidts-input"
data-i18n="auth_login.secure_1psidts_label">__Secure-1PSIDTS Cookie:</label>
<input type="text" id="secure-1psidts-input"
data-i18n="auth_login.secure_1psidts_placeholder"
placeholder="输入 __Secure-1PSIDTS cookie 值">
</div>
<div class="form-group">
<label for="gemini-web-label-input"
data-i18n="auth_login.gemini_web_label_label">Label (Optional):</label>
<input type="text" id="gemini-web-label-input"
data-i18n="auth_login.gemini_web_label_placeholder"
placeholder="输入标签名称 (可选)">
</div>
</div>
</div>
<!-- 认证文件 -->
<div class="card">
<div class="card-header">
<h3><i class="fas fa-file-alt"></i> <span
data-i18n="auth_files.title_section">认证文件</span></h3>
<div class="card-header card-header-with-filter">
<div class="header-left">
<h3><i class="fas fa-file-alt"></i> <span
data-i18n="auth_files.title_section">认证文件</span></h3>
<!-- 类型筛选 -->
<div class="auth-file-filter">
<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>
<button class="filter-btn" data-type="vertex" data-i18n-text="auth_files.filter_vertex">Vertex</button>
<button class="filter-btn" data-type="empty" data-i18n-text="auth_files.filter_empty">Empty</button>
</div>
</div>
<div class="header-actions">
<button id="upload-auth-file" class="btn btn-primary">
<i class="fas fa-upload"></i> <span
@@ -428,7 +519,7 @@
</div>
</div>
<div class="card-content">
<div id="auth-files-list" class="file-list"></div>
<div id="auth-files-list" class="file-list file-grid"></div>
<input type="file" id="auth-file-input" accept=".json" style="display: none;">
</div>
</div>
@@ -452,7 +543,7 @@
<div class="form-group">
<label data-i18n="auth_login.codex_oauth_url_label">授权链接:</label>
<div class="input-group">
<input type="text" id="codex-oauth-url" readonly>
<input type="text" id="codex-oauth-url" readonly>
<button id="codex-open-link" class="btn btn-primary">
<i class="fas fa-external-link-alt"></i> <span
data-i18n="auth_login.codex_open_link">打开链接</span>
@@ -524,11 +615,10 @@
data-i18n="auth_login.gemini_cli_project_id_label">Google Cloud 项目 ID
(可选):</label>
<input type="text" id="gemini-cli-project-id"
data-i18n="auth_login.gemini_cli_project_id_placeholder"
placeholder="输入 Google Cloud 项目 ID (可选)">
<div class="form-hint" data-i18n="auth_login.gemini_cli_project_id_hint">
如果指定了项目 ID将使用该项目的认证信息。
</div>
data-i18n-placeholder="auth_login.gemini_cli_project_id_placeholder">
<div class="form-hint" data-i18n="auth_login.gemini_cli_project_id_hint">
如果指定了项目 ID将使用该项目的认证信息。
</div>
</div>
<div id="gemini-cli-oauth-content" style="display: none;">
<div class="form-group">
@@ -622,6 +712,40 @@
</div>
</section>
<!-- 日志查看 -->
<section id="logs" class="content-section">
<h2 data-i18n="logs.title">日志查看</h2>
<div class="card">
<div class="card-header">
<h3><i class="fas fa-scroll"></i> <span data-i18n="logs.log_content">日志内容</span></h3>
<div class="header-actions">
<div class="toggle-group" style="margin-right: 15px;">
<label class="toggle-switch" style="margin-right: 5px;">
<input type="checkbox" id="logs-auto-refresh-toggle">
<span class="slider"></span>
</label>
<span class="toggle-label" data-i18n="logs.auto_refresh" style="font-size: 0.9em;">自动刷新</span>
</div>
<button id="refresh-logs" class="btn btn-primary">
<i class="fas fa-sync-alt"></i> <span data-i18n="logs.refresh_button">刷新日志</span>
</button>
<button id="download-logs" class="btn btn-secondary">
<i class="fas fa-download"></i> <span data-i18n="logs.download_button">下载日志</span>
</button>
<button id="clear-logs" class="btn btn-danger">
<i class="fas fa-trash"></i> <span data-i18n="logs.clear_button">清空日志</span>
</button>
</div>
</div>
<div class="card-content">
<div id="logs-content" class="logs-container">
<div class="loading-placeholder" data-i18n="logs.loading">正在加载日志...</div>
</div>
</div>
</div>
</section>
<!-- 使用统计 -->
<section id="usage-stats" class="content-section">
<h2 data-i18n="usage_stats.title">使用统计</h2>
@@ -732,6 +856,32 @@
</div>
</section>
<!-- 配置管理 -->
<section id="config-management" class="content-section">
<h2 data-i18n="config_management.title">配置管理</h2>
<div class="card">
<div class="card-header">
<h3><i class="fas fa-file-code"></i> <span data-i18n="config_management.editor_title">配置文件</span></h3>
<div class="editor-actions">
<button id="config-reload-btn" class="btn btn-secondary">
<i class="fas fa-sync-alt"></i> <span data-i18n="config_management.reload">重新加载</span>
</button>
<button id="config-save-btn" class="btn btn-primary">
<i class="fas fa-save"></i> <span data-i18n="config_management.save">保存</span>
</button>
</div>
</div>
<div class="card-content">
<p class="form-hint" data-i18n="config_management.description">查看并编辑服务器上的 config.yaml 配置文件。保存前请确认语法正确。</p>
<div class="yaml-editor-container">
<textarea id="config-editor" class="yaml-editor" spellcheck="false" data-i18n="config_management.editor_placeholder"></textarea>
<div id="config-editor-status" class="editor-status" data-i18n="config_management.status_idle">等待操作</div>
</div>
</div>
</div>
</section>
<!-- 系统信息 -->
<section id="system-info" class="content-section">
<h2 data-i18n="system_info.title">系统信息</h2>
@@ -751,13 +901,6 @@
</div>
<div class="info-value" id="display-api-url">-</div>
</div>
<div class="info-item">
<div class="info-label">
<i class="fas fa-key"></i>
<span data-i18n="connection.management_key">管理密钥:</span>
</div>
<div class="info-value" id="display-management-key">-</div>
</div>
<div class="info-item">
<div class="info-label">
<i class="fas fa-circle"></i>
@@ -806,9 +949,9 @@
<!-- 版本信息 -->
<footer class="version-footer">
<div class="version-info">
<span data-i18n="footer.version">版本</span>: v0.1.0
<span data-i18n="footer.version">版本</span>: __VERSION__
<span class="separator"></span>
<span data-i18n="footer.author">作者</span>: Supra4E8C
<span data-i18n="footer.author">作者</span>: CLI Proxy API Team
</div>
</footer>
</div>
@@ -834,4 +977,4 @@
<script src="app.js"></script>
</body>
</html>
</html>

View File

@@ -26,6 +26,5 @@
"repository": {
"type": "git",
"url": "local"
},
"dependencies": {}
}
}

1332
styles.css

File diff suppressed because it is too large Load Diff