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
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a208a484ff | ||
|
|
369cf52346 | ||
|
|
dcfffc716b | ||
|
|
7de5280824 | ||
|
|
86d60aad77 | ||
|
|
020fccc032 | ||
|
|
c162ab3a54 | ||
|
|
85d12e15d8 | ||
|
|
ebffb49f52 | ||
|
|
316c1ffc0d | ||
|
|
b3e54e7f14 | ||
|
|
fe11bfb48f | ||
|
|
ee0d8f82d7 | ||
|
|
0bbb397df5 | ||
|
|
27948b3d5c | ||
|
|
dff28db227 | ||
|
|
34b16ca886 | ||
|
|
fa86f76289 | ||
|
|
41ca99978f | ||
|
|
6ef674487f | ||
|
|
2be7ced21a | ||
|
|
b61155d215 | ||
|
|
5488d6153d |
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -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: |
|
||||
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -20,3 +20,7 @@ package-lock.json
|
||||
# OS files
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
CLAUDE.md
|
||||
AGENTS.md
|
||||
.serena
|
||||
97
README.md
97
README.md
@@ -10,8 +10,9 @@ Example URL:
|
||||
https://remote.router-for.me/
|
||||
|
||||
Minimum required version: ≥ 6.0.0
|
||||
Recommended version: ≥ 6.0.19
|
||||
Starting from version 6.0.19, the WebUI has been integrated into the main program and is accessible via `/management.html`.
|
||||
Recommended version: ≥ 6.1.3
|
||||
|
||||
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.
|
||||
|
||||
## Features
|
||||
|
||||
@@ -19,13 +20,16 @@ Starting from version 6.0.19, the WebUI has been integrated into the main progra
|
||||
- Supports management key authentication
|
||||
- Configurable API base address
|
||||
- Real-time connection status detection
|
||||
- Auto-login with saved credentials
|
||||
- Language and theme switching
|
||||
|
||||
### Basic Settings
|
||||
- **Debug Mode**: Enable/disable debugging
|
||||
- **Proxy Settings**: Configure proxy server URL
|
||||
- **Request Retries**: Set the number of request retries
|
||||
- **Quota Management**: Configure behavior when the quota is exceeded
|
||||
- **Local Access**: Manage local unauthenticated access
|
||||
- Auto-switch project when quota exceeded
|
||||
- Switch to preview models when quota exceeded
|
||||
|
||||
### API Key Management
|
||||
- **Proxy Service Authentication Key**: Manage API keys for the proxy service
|
||||
@@ -40,13 +44,31 @@ Starting from version 6.0.19, the WebUI has been integrated into the main progra
|
||||
- Delete single or all authentication files
|
||||
- Display file details
|
||||
|
||||
### Usage Statistics
|
||||
- **Real-time Analytics**: Track API usage with interactive charts
|
||||
- **Request Trends**: Visualize request patterns by hour/day
|
||||
- **Token Usage**: Monitor token consumption over time
|
||||
- **API Details**: Detailed statistics for each API endpoint
|
||||
- **Success/Failure Rates**: Track API reliability metrics
|
||||
|
||||
### System Information
|
||||
- **Connection Status**: Real-time connection monitoring
|
||||
- **Configuration Status**: Track configuration loading state
|
||||
- **Server Information**: Display server address and management key
|
||||
- **Last Update**: Show when data was last refreshed
|
||||
|
||||
|
||||
## How to Use
|
||||
|
||||
### 1. Direct Use (Recommended)
|
||||
### 1. Using After CLI Proxy API Program Launch (Recommended)
|
||||
Once the CLI Proxy API program is up and running, you can access the WebUI at `http://your-server-IP:8317/management.html`.
|
||||
|
||||
### 2. Direct Use
|
||||
Simply open the `index.html` file directly in your browser to use it.
|
||||
|
||||
### 2. Use a Local Server
|
||||
### 3. Use a Local Server
|
||||
|
||||
#### Option A: Using Node.js (npm)
|
||||
```bash
|
||||
# Install dependencies
|
||||
npm install
|
||||
@@ -55,10 +77,19 @@ npm install
|
||||
npm start
|
||||
```
|
||||
|
||||
### 3. Configure API Connection
|
||||
#### Option B: Using Python
|
||||
```bash
|
||||
# Python 3.x
|
||||
python -m http.server 8000
|
||||
|
||||
```
|
||||
|
||||
Then open `http://localhost:8000` in your browser.
|
||||
|
||||
### 3. Configure Connection
|
||||
1. Open the management interface.
|
||||
2. On the login screen, enter:
|
||||
- **Remote Address**: `http://localhost:8317` (`/v0/management` will be auto-completed for you)
|
||||
- **Remote Address**: The current version automatically picks up the remote address from where you're connecting. But you can also set your own address if you prefer.
|
||||
- **Management Key**: Your management key
|
||||
3. Click the "Connect" button.
|
||||
4. Once connected successfully, all features will be available.
|
||||
@@ -70,8 +101,16 @@ npm start
|
||||
- **API Keys**: Management of keys for various API services.
|
||||
- **AI Providers**: Configuration for AI service providers.
|
||||
- **Auth Files**: Upload and download management for authentication files.
|
||||
- **Usage Stats**: Real-time analytics and usage statistics with interactive charts.
|
||||
- **System Info**: Connection status and system information.
|
||||
|
||||
### Login Interface
|
||||
- **Auto-connection**: Automatically attempts to connect using saved credentials
|
||||
- **Custom Connection**: Manual configuration of API base address
|
||||
- **Current Address Detection**: Automatically detects and uses current access address
|
||||
- **Language Switching**: Support for multiple languages (English/Chinese)
|
||||
- **Theme Switching**: Light and dark theme support
|
||||
|
||||
## Feature Highlights
|
||||
|
||||
### Modern UI
|
||||
@@ -79,27 +118,45 @@ npm start
|
||||
- Beautiful gradient colors and shadow effects
|
||||
- Smooth animations and transition effects
|
||||
- Intuitive icons and status indicators
|
||||
- Dark/Light theme support with system preference detection
|
||||
- Mobile-friendly sidebar with overlay
|
||||
|
||||
### Real-time Updates
|
||||
- Configuration changes take effect immediately
|
||||
- Real-time status feedback
|
||||
- Automatic data refresh
|
||||
- Live usage statistics with interactive charts
|
||||
- Real-time connection status monitoring
|
||||
|
||||
### Security Features
|
||||
- Masked display for keys
|
||||
- Secure credential storage
|
||||
- Auto-login with encrypted local storage
|
||||
|
||||
### Responsive Design
|
||||
- Perfectly adapts to desktop and mobile devices
|
||||
- Adaptive layout
|
||||
- Adaptive layout with collapsible sidebar
|
||||
- Touch-friendly interactions
|
||||
- Mobile menu with overlay
|
||||
|
||||
### Analytics & Monitoring
|
||||
- Interactive charts powered by Chart.js
|
||||
- Real-time usage statistics
|
||||
- Request trend visualization
|
||||
- Token consumption tracking
|
||||
- API performance metrics
|
||||
|
||||
## Tech Stack
|
||||
|
||||
- **Frontend**: Plain HTML, CSS, JavaScript
|
||||
- **Styling**: CSS3 + Flexbox/Grid
|
||||
- **Frontend**: Plain HTML, CSS, JavaScript (ES6+)
|
||||
- **Styling**: CSS3 + Flexbox/Grid with CSS Variables
|
||||
- **Icons**: Font Awesome 6.4.0
|
||||
- **Charts**: Chart.js for interactive data visualization
|
||||
- **Fonts**: Segoe UI system font
|
||||
- **API**: RESTful API calls
|
||||
- **API**: RESTful API calls with automatic authentication
|
||||
- **Internationalization**: Custom i18n system with English/Chinese support
|
||||
- **Theme System**: CSS custom properties for dynamic theming
|
||||
- **Storage**: LocalStorage for user preferences and credentials
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
@@ -119,12 +176,20 @@ npm start
|
||||
### File Structure
|
||||
```
|
||||
webui/
|
||||
├── index.html # Main page
|
||||
├── styles.css # Stylesheet
|
||||
├── app.js # Application logic
|
||||
├── index.html # Main page with responsive layout
|
||||
├── styles.css # Stylesheet with theme support
|
||||
├── app.js # Application logic and API management
|
||||
├── i18n.js # Internationalization support (EN/CN)
|
||||
├── package.json # Project configuration
|
||||
├── i18n.js # Internationalization support
|
||||
└── README.md # README document
|
||||
├── build.js # Build script for production
|
||||
├── bundle-entry.js # Entry point for bundling
|
||||
├── build-scripts/ # Build utilities
|
||||
│ └── prepare-html.js # HTML preparation script
|
||||
├── logo.jpg # Application logo
|
||||
├── LICENSE # MIT License
|
||||
├── README.md # English documentation
|
||||
├── README_CN.md # Chinese documentation
|
||||
└── BUILD_RELEASE.md # Build and release notes
|
||||
```
|
||||
|
||||
### API Calls
|
||||
|
||||
101
README_CN.md
101
README_CN.md
@@ -1,14 +1,17 @@
|
||||
# Cli-Proxy-API-Management-Center
|
||||
这是一个用于管理 CLI Proxy API 的现代化 Web 界面。
|
||||
|
||||
主项目
|
||||
https://github.com/router-for-me/CLIProxyAPI
|
||||
|
||||
示例网站:
|
||||
https://remote.router-for.me/
|
||||
|
||||
最低可用版本 ≥ 5.0.0
|
||||
推荐版本 ≥ 5.2.6
|
||||
自6.0.19起WebUI已经集成在主程序中 可以通过/management.html访问
|
||||
最低可用版本 ≥ 6.0.0
|
||||
|
||||
推荐版本 ≥ 6.1.3
|
||||
|
||||
自6.0.19起WebUI已经集成在主程序中 可以通过主项目开启的外部端口的`/management.html`访问
|
||||
|
||||
## 功能特点
|
||||
|
||||
@@ -16,13 +19,16 @@ https://remote.router-for.me/
|
||||
- 支持管理密钥认证
|
||||
- 可配置 API 基础地址
|
||||
- 实时连接状态检测
|
||||
- 自动登录保存的凭据
|
||||
- 语言和主题切换
|
||||
|
||||
### 基础设置
|
||||
- **调试模式**: 开启/关闭调试功能
|
||||
- **代理设置**: 配置代理服务器 URL
|
||||
- **请求重试**: 设置请求重试次数
|
||||
- **配额管理**: 配置超出配额时的行为
|
||||
- **本地访问**: 管理本地未认证访问
|
||||
- 超出配额时自动切换项目
|
||||
- 超出配额时切换到预览模型
|
||||
|
||||
### API 密钥管理
|
||||
- **代理服务认证密钥**: 管理用于代理服务的 API 密钥
|
||||
@@ -37,13 +43,31 @@ https://remote.router-for.me/
|
||||
- 删除单个或所有认证文件
|
||||
- 显示文件详细信息
|
||||
|
||||
### 使用统计
|
||||
- **实时分析**: 通过交互式图表跟踪 API 使用情况
|
||||
- **请求趋势**: 按小时/天可视化请求模式
|
||||
- **Token 使用**: 监控 Token 消耗随时间变化
|
||||
- **API 详情**: 每个 API 端点的详细统计
|
||||
- **成功率/失败率**: 跟踪 API 可靠性指标
|
||||
|
||||
### 系统信息
|
||||
- **连接状态**: 实时连接监控
|
||||
- **配置状态**: 跟踪配置加载状态
|
||||
- **服务器信息**: 显示服务器地址和管理密钥
|
||||
- **最后更新**: 显示数据最后刷新时间
|
||||
|
||||
|
||||
## 使用方法
|
||||
|
||||
### 1. 直接使用(推荐)
|
||||
### 1. 在CLI Proxy API程序启动后使用 (推荐)
|
||||
在启动了CLI Proxy API程序后 访问`http://您的服务器IP:8317/management.html`使用
|
||||
|
||||
### 2. 直接使用
|
||||
直接用浏览器打开 `index.html` 文件即可使用。
|
||||
|
||||
### 2. 使用本地服务器
|
||||
### 3. 使用本地服务器
|
||||
|
||||
#### 方法A:使用 Node.js (npm)
|
||||
```bash
|
||||
# 安装依赖
|
||||
npm install
|
||||
@@ -52,10 +76,19 @@ npm install
|
||||
npm start
|
||||
```
|
||||
|
||||
### 3. 配置 API 连接
|
||||
#### 方法B:使用 Python
|
||||
```bash
|
||||
# Python 3.x
|
||||
python -m http.server 8000
|
||||
|
||||
```
|
||||
|
||||
然后在浏览器中打开 `http://localhost:8000`。
|
||||
|
||||
### 3. 配置连接
|
||||
1. 打开管理界面
|
||||
2. 在登录界面上输入:
|
||||
- **远程地址**: `http://localhost:8317`/v0/management将会自动为您补全
|
||||
- **远程地址**: 现版本远程地址将会自动从您的访问地址中获取 当然您也可以自定义
|
||||
- **管理密钥**: 您的管理密钥
|
||||
3. 点击"连接"按钮
|
||||
4. 连接成功后即可使用所有功能
|
||||
@@ -67,8 +100,16 @@ npm start
|
||||
- **API 密钥**: 各种 API 服务的密钥管理
|
||||
- **AI 提供商**: AI 服务提供商配置
|
||||
- **认证文件**: 认证文件的上传下载管理
|
||||
- **使用统计**: 实时分析和使用统计,包含交互式图表
|
||||
- **系统信息**: 连接状态和系统信息
|
||||
|
||||
### 登录界面
|
||||
- **自动连接**: 使用保存的凭据自动尝试连接
|
||||
- **自定义连接**: 手动配置 API 基础地址
|
||||
- **当前地址检测**: 自动检测并使用当前访问地址
|
||||
- **语言切换**: 支持多种语言(英文/中文)
|
||||
- **主题切换**: 支持明暗主题
|
||||
|
||||
## 特性亮点
|
||||
|
||||
### 现代化 UI
|
||||
@@ -76,27 +117,45 @@ npm start
|
||||
- 美观的渐变色彩和阴影效果
|
||||
- 流畅的动画和过渡效果
|
||||
- 直观的图标和状态指示
|
||||
- 明暗主题支持,自动检测系统偏好
|
||||
- 移动端友好的侧边栏和遮罩
|
||||
|
||||
### 实时更新
|
||||
- 配置更改立即生效
|
||||
- 实时状态反馈
|
||||
- 自动数据刷新
|
||||
- 实时使用统计和交互式图表
|
||||
- 实时连接状态监控
|
||||
|
||||
### 安全特性
|
||||
- 密钥遮蔽显示
|
||||
- 安全凭据存储
|
||||
- 加密本地存储自动登录
|
||||
|
||||
### 响应式设计
|
||||
- 完美适配桌面和移动设备
|
||||
- 自适应布局
|
||||
- 自适应布局,可折叠侧边栏
|
||||
- 触摸友好的交互
|
||||
- 移动端菜单和遮罩
|
||||
|
||||
### 分析与监控
|
||||
- Chart.js 驱动的交互式图表
|
||||
- 实时使用统计
|
||||
- 请求趋势可视化
|
||||
- Token 消耗跟踪
|
||||
- API 性能指标
|
||||
|
||||
## 技术栈
|
||||
|
||||
- **前端**: 纯 HTML、CSS、JavaScript
|
||||
- **样式**: CSS3 + Flexbox/Grid
|
||||
- **前端**: 纯 HTML、CSS、JavaScript (ES6+)
|
||||
- **样式**: CSS3 + Flexbox/Grid,支持 CSS 变量
|
||||
- **图标**: Font Awesome 6.4.0
|
||||
- **图表**: Chart.js 交互式数据可视化
|
||||
- **字体**: Segoe UI 系统字体
|
||||
- **API**: RESTful API 调用
|
||||
- **API**: RESTful API 调用,自动认证
|
||||
- **国际化**: 自定义 i18n 系统,支持中英文
|
||||
- **主题系统**: CSS 自定义属性动态主题
|
||||
- **存储**: LocalStorage 用户偏好和凭据存储
|
||||
|
||||
## 故障排除
|
||||
|
||||
@@ -116,12 +175,20 @@ npm start
|
||||
### 文件结构
|
||||
```
|
||||
webui/
|
||||
├── index.html # 主页面
|
||||
├── styles.css # 样式文件
|
||||
├── app.js # 应用逻辑
|
||||
├── index.html # 主页面,响应式布局
|
||||
├── styles.css # 样式文件,支持主题
|
||||
├── app.js # 应用逻辑和 API 管理
|
||||
├── i18n.js # 国际化支持(中英文)
|
||||
├── package.json # 项目配置
|
||||
├── i18n.js # 国际化支持
|
||||
└── README.md # 说明文档
|
||||
├── build.js # 生产环境构建脚本
|
||||
├── bundle-entry.js # 打包入口文件
|
||||
├── build-scripts/ # 构建工具
|
||||
│ └── prepare-html.js # HTML 准备脚本
|
||||
├── logo.jpg # 应用图标
|
||||
├── LICENSE # MIT 许可证
|
||||
├── README.md # 英文文档
|
||||
├── README_CN.md # 中文文档
|
||||
└── BUILD_RELEASE.md # 构建和发布说明
|
||||
```
|
||||
|
||||
### API 调用
|
||||
|
||||
34
build.js
34
build.js
@@ -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 });
|
||||
@@ -83,6 +112,11 @@ function build() {
|
||||
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">',
|
||||
`<style>
|
||||
|
||||
291
i18n.js
291
i18n.js
@@ -36,6 +36,8 @@ const i18n = {
|
||||
'common.required': '必填',
|
||||
'common.api_key': '密钥',
|
||||
'common.base_url': '地址',
|
||||
'common.proxy_url': '代理',
|
||||
'common.alias': '别名',
|
||||
|
||||
// 页面标题
|
||||
'title.main': 'CLI Proxy API Management Center',
|
||||
@@ -80,6 +82,8 @@ const i18n = {
|
||||
'nav.ai_providers': 'AI 提供商',
|
||||
'nav.auth_files': '认证文件',
|
||||
'nav.usage_stats': '使用统计',
|
||||
'nav.config_management': '配置管理',
|
||||
'nav.logs': '日志查看',
|
||||
'nav.system_info': '系统信息',
|
||||
|
||||
// 基础设置
|
||||
@@ -97,6 +101,10 @@ const i18n = {
|
||||
'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': '启用日志记录到文件',
|
||||
|
||||
// API 密钥管理
|
||||
'api_keys.title': 'API 密钥管理',
|
||||
@@ -136,9 +144,12 @@ const i18n = {
|
||||
'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 配置',
|
||||
@@ -151,9 +162,12 @@ const i18n = {
|
||||
'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 兼容提供商',
|
||||
@@ -167,10 +181,19 @@ const i18n = {
|
||||
'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': '模型数量',
|
||||
@@ -197,17 +220,74 @@ const i18n = {
|
||||
'auth_files.delete_all_success': '成功删除',
|
||||
'auth_files.files_count': '个文件',
|
||||
|
||||
// Gemini Web Token
|
||||
'auth_login.gemini_web_title': 'Gemini Web Token',
|
||||
'auth_login.gemini_web_button': '保存 Gemini Web Token',
|
||||
'auth_login.gemini_web_hint': '从浏览器开发者工具中获取 Gemini 网页版的 Cookie 值,用于直接认证访问 Gemini。',
|
||||
'auth_login.secure_1psid_label': '__Secure-1PSID Cookie:',
|
||||
'auth_login.secure_1psid_placeholder': '输入 __Secure-1PSID cookie 值',
|
||||
'auth_login.secure_1psidts_label': '__Secure-1PSIDTS Cookie:',
|
||||
'auth_login.secure_1psidts_placeholder': '输入 __Secure-1PSIDTS cookie 值',
|
||||
'auth_login.gemini_web_label_label': '标签 (可选):',
|
||||
'auth_login.gemini_web_label_placeholder': '输入标签名称 (可选)',
|
||||
'auth_login.gemini_web_saved': 'Gemini Web Token 保存成功',
|
||||
|
||||
// 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': '检查认证状态失败:',
|
||||
|
||||
// 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': '使用统计',
|
||||
@@ -229,6 +309,45 @@ const i18n = {
|
||||
'usage_stats.models': '模型统计',
|
||||
'usage_stats.success_rate': '成功率',
|
||||
|
||||
// 日志查看
|
||||
'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 接口可用',
|
||||
|
||||
// 系统信息
|
||||
'system_info.title': '系统信息',
|
||||
'system_info.connection_status_title': '连接状态',
|
||||
@@ -247,6 +366,8 @@ const i18n = {
|
||||
'notification.retry_updated': '重试设置已更新',
|
||||
'notification.quota_switch_project_updated': '项目切换设置已更新',
|
||||
'notification.quota_switch_preview_updated': '预览模型切换设置已更新',
|
||||
'notification.usage_statistics_updated': '使用统计设置已更新',
|
||||
'notification.logging_to_file_updated': '日志记录设置已更新',
|
||||
'notification.api_key_added': 'API密钥添加成功',
|
||||
'notification.api_key_updated': 'API密钥更新成功',
|
||||
'notification.api_key_deleted': 'API密钥删除成功',
|
||||
@@ -259,9 +380,12 @@ const i18n = {
|
||||
'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': '刷新失败',
|
||||
@@ -327,6 +451,8 @@ const i18n = {
|
||||
'common.required': 'Required',
|
||||
'common.api_key': 'Key',
|
||||
'common.base_url': 'Address',
|
||||
'common.proxy_url': 'Proxy',
|
||||
'common.alias': 'Alias',
|
||||
|
||||
// Page titles
|
||||
'title.main': 'CLI Proxy API Management Center',
|
||||
@@ -371,6 +497,8 @@ const i18n = {
|
||||
'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
|
||||
@@ -388,6 +516,10 @@ const i18n = {
|
||||
'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',
|
||||
|
||||
// API Keys management
|
||||
'api_keys.title': 'API Keys Management',
|
||||
@@ -427,9 +559,12 @@ const i18n = {
|
||||
'ai_providers.codex_add_modal_key_placeholder': 'Please enter Codex API key',
|
||||
'ai_providers.codex_add_modal_url_label': 'Base URL (Optional):',
|
||||
'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 (Optional):',
|
||||
'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',
|
||||
@@ -442,9 +577,12 @@ const i18n = {
|
||||
'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',
|
||||
@@ -458,10 +596,19 @@ const i18n = {
|
||||
'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',
|
||||
@@ -488,17 +635,73 @@ const i18n = {
|
||||
'auth_files.delete_all_success': 'Successfully deleted',
|
||||
'auth_files.files_count': 'files',
|
||||
|
||||
// Gemini Web Token
|
||||
'auth_login.gemini_web_title': 'Gemini Web Token',
|
||||
'auth_login.gemini_web_button': 'Save Gemini Web Token',
|
||||
'auth_login.gemini_web_hint': 'Obtain the Cookie value of the Gemini web version from the browser\'s developer tools, used for direct authentication to access Gemini.',
|
||||
'auth_login.secure_1psid_label': '__Secure-1PSID Cookie:',
|
||||
'auth_login.secure_1psid_placeholder': 'Enter __Secure-1PSID cookie value',
|
||||
'auth_login.secure_1psidts_label': '__Secure-1PSIDTS Cookie:',
|
||||
'auth_login.secure_1psidts_placeholder': 'Enter __Secure-1PSIDTS cookie value',
|
||||
'auth_login.gemini_web_label_label': 'Label (Optional):',
|
||||
'auth_login.gemini_web_label_placeholder': 'Enter label name (optional)',
|
||||
'auth_login.gemini_web_saved': 'Gemini Web Token saved successfully',
|
||||
// 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:',
|
||||
|
||||
// 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',
|
||||
@@ -520,6 +723,45 @@ const i18n = {
|
||||
'usage_stats.models': 'Model Statistics',
|
||||
'usage_stats.success_rate': 'Success Rate',
|
||||
|
||||
// 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.',
|
||||
|
||||
// System info
|
||||
'system_info.title': 'System Information',
|
||||
'system_info.connection_status_title': 'Connection Status',
|
||||
@@ -538,6 +780,8 @@ const i18n = {
|
||||
'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.api_key_added': 'API key added successfully',
|
||||
'notification.api_key_updated': 'API key updated successfully',
|
||||
'notification.api_key_deleted': 'API key deleted successfully',
|
||||
@@ -550,9 +794,12 @@ const i18n = {
|
||||
'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',
|
||||
|
||||
574
index.html
574
index.html
@@ -1,14 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<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>
|
||||
|
||||
<body>
|
||||
<!-- 自动登录加载页面 -->
|
||||
<div id="auto-login-loading" class="login-container" style="display: none;">
|
||||
@@ -69,8 +77,10 @@
|
||||
<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">
|
||||
<button type="button" id="login-reset-api-base" class="btn btn-secondary connection-reset-btn">
|
||||
<input type="text" id="login-api-base" data-i18n="login.custom_connection_placeholder"
|
||||
placeholder="例如: https://example.com:8317">
|
||||
<button type="button" id="login-reset-api-base"
|
||||
class="btn btn-secondary connection-reset-btn">
|
||||
<i class="fas fa-location-arrow"></i>
|
||||
<span data-i18n="login.use_current_address">使用当前地址</span>
|
||||
</button>
|
||||
@@ -81,7 +91,8 @@
|
||||
<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="login.management_key_placeholder" placeholder="请输入管理密钥" required>
|
||||
<button type="button" class="btn btn-secondary toggle-key-visibility">
|
||||
<i class="fas fa-eye"></i>
|
||||
</button>
|
||||
@@ -105,26 +116,31 @@
|
||||
</div>
|
||||
|
||||
<!-- 主页面 -->
|
||||
<div id="main-page" class="container" style="display: none;">
|
||||
<!-- 头部导航 -->
|
||||
<header class="header">
|
||||
<div class="header-content">
|
||||
<h1 class="brand">
|
||||
<img id="site-logo" alt="Logo" style="display:none" />
|
||||
<span class="brand-title" data-i18n="title.main">CLI Proxy API Management Center</span>
|
||||
</h1>
|
||||
<div class="header-actions">
|
||||
<div id="main-page" style="display: none;">
|
||||
<!-- 顶部导航栏 -->
|
||||
<div class="top-navbar">
|
||||
<div class="top-navbar-left">
|
||||
<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="收起/展开侧边栏">
|
||||
<i class="fas fa-bars"></i>
|
||||
</button>
|
||||
<div class="top-navbar-brand">
|
||||
<img id="site-logo" class="top-navbar-brand-logo" alt="Logo" style="display:none" />
|
||||
<span class="top-navbar-brand-text" data-i18n="title.main">CLI Proxy API Management Center</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="top-navbar-actions">
|
||||
<div class="header-controls">
|
||||
<div class="language-switcher">
|
||||
<button id="language-toggle-main" class="btn btn-secondary language-btn">
|
||||
<i class="fas fa-globe"></i>
|
||||
<span data-i18n="language.switch">语言</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="theme-switcher">
|
||||
<button id="theme-toggle-main" class="btn btn-secondary theme-btn">
|
||||
<i class="fas fa-moon"></i>
|
||||
<span data-i18n="theme.switch">主题</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -132,77 +148,54 @@
|
||||
<i class="fas fa-circle"></i> <span data-i18n="header.check_connection">检查连接</span>
|
||||
</button>
|
||||
<button id="refresh-all" class="btn btn-primary">
|
||||
<i class="fas fa-sync-alt"></i> <span data-i18n="header.refresh_all">刷新全部</span>
|
||||
<i class="fas fa-sync-alt"></i>
|
||||
</button>
|
||||
<button id="logout-btn" class="btn btn-danger">
|
||||
<i class="fas fa-sign-out-alt"></i> <span data-i18n="header.logout">登出</span>
|
||||
<i class="fas fa-sign-out-alt"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- 连接信息 -->
|
||||
<section class="auth-section">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h2><i class="fas fa-server"></i> <span data-i18n="connection.title">连接信息</span></h2>
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<div class="connection-info">
|
||||
<div class="info-item">
|
||||
<div class="info-label">
|
||||
<i class="fas fa-globe"></i>
|
||||
<span data-i18n="connection.server_address">服务器地址:</span>
|
||||
</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>
|
||||
<span data-i18n="connection.status">连接状态:</span>
|
||||
</div>
|
||||
<div class="info-value" id="display-connection-status">
|
||||
<span class="status-indicator disconnected" data-i18n="common.disconnected">未连接</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 主要内容区域 -->
|
||||
<main class="main-content">
|
||||
<!-- 侧边栏导航 -->
|
||||
<nav class="sidebar">
|
||||
<div class="layout" id="layout-container">
|
||||
<!-- 侧边栏 -->
|
||||
<nav class="sidebar" id="sidebar">
|
||||
<!-- 导航菜单 -->
|
||||
<ul class="nav-menu">
|
||||
<li><a href="#basic-settings" class="nav-item active" data-section="basic-settings">
|
||||
<li data-tooltip="基础设置"><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><a href="#api-keys" class="nav-item" data-section="api-keys">
|
||||
<li data-tooltip="API 密钥"><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><a href="#ai-providers" class="nav-item" data-section="ai-providers">
|
||||
<li data-tooltip="AI 提供商"><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><a href="#auth-files" class="nav-item" data-section="auth-files">
|
||||
<li data-tooltip="认证文件"><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><a href="#usage-stats" class="nav-item" data-section="usage-stats">
|
||||
<li data-tooltip="使用统计"><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><a href="#system-info" class="nav-item" data-section="system-info">
|
||||
<li data-tooltip="配置管理"><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-tooltip="日志查看" 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-tooltip="系统信息"><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>
|
||||
</nav>
|
||||
|
||||
<!-- 侧边栏遮罩(移动端) -->
|
||||
<div class="sidebar-overlay" id="sidebar-overlay"></div>
|
||||
|
||||
<!-- 主内容包装器 -->
|
||||
<div class="main-wrapper" id="main-wrapper">
|
||||
<!-- 主内容区域 -->
|
||||
<div class="main-content">
|
||||
<!-- 内容区域 -->
|
||||
<div class="content-area">
|
||||
<!-- 基础设置 -->
|
||||
@@ -212,7 +205,8 @@
|
||||
<!-- Debug 设置 -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3><i class="fas fa-bug"></i> <span data-i18n="basic_settings.debug_title">调试模式</span></h3>
|
||||
<h3><i class="fas fa-bug"></i> <span
|
||||
data-i18n="basic_settings.debug_title">调试模式</span></h3>
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<div class="toggle-group">
|
||||
@@ -228,15 +222,21 @@
|
||||
<!-- 代理设置 -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3><i class="fas fa-network-wired"></i> <span data-i18n="basic_settings.proxy_title">代理设置</span></h3>
|
||||
<h3><i class="fas fa-network-wired"></i> <span
|
||||
data-i18n="basic_settings.proxy_title">代理设置</span></h3>
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<div class="form-group">
|
||||
<label for="proxy-url" data-i18n="basic_settings.proxy_url_label">代理 URL:</label>
|
||||
<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/">
|
||||
<button id="update-proxy" class="btn btn-primary" data-i18n="basic_settings.proxy_update">更新</button>
|
||||
<button id="clear-proxy" class="btn btn-danger" data-i18n="basic_settings.proxy_clear">清空</button>
|
||||
<input type="text" id="proxy-url"
|
||||
data-i18n="basic_settings.proxy_url_placeholder"
|
||||
placeholder="例如: socks5://user:pass@127.0.0.1:1080/">
|
||||
<button id="update-proxy" class="btn btn-primary"
|
||||
data-i18n="basic_settings.proxy_update">更新</button>
|
||||
<button id="clear-proxy" class="btn btn-danger"
|
||||
data-i18n="basic_settings.proxy_clear">清空</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -245,14 +245,17 @@
|
||||
<!-- 请求重试设置 -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3><i class="fas fa-redo"></i> <span data-i18n="basic_settings.retry_title">请求重试</span></h3>
|
||||
<h3><i class="fas fa-redo"></i> <span
|
||||
data-i18n="basic_settings.retry_title">请求重试</span></h3>
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<div class="form-group">
|
||||
<label for="request-retry" data-i18n="basic_settings.retry_count_label">重试次数:</label>
|
||||
<label for="request-retry"
|
||||
data-i18n="basic_settings.retry_count_label">重试次数:</label>
|
||||
<div class="input-group">
|
||||
<input type="number" id="request-retry" min="0" max="10" value="3">
|
||||
<button id="update-retry" class="btn btn-primary" data-i18n="basic_settings.retry_update">更新</button>
|
||||
<button id="update-retry" class="btn btn-primary"
|
||||
data-i18n="basic_settings.retry_update">更新</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -261,7 +264,8 @@
|
||||
<!-- 配额超出行为 -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3><i class="fas fa-exclamation-triangle"></i> <span data-i18n="basic_settings.quota_title">配额超出行为</span></h3>
|
||||
<h3><i class="fas fa-exclamation-triangle"></i> <span
|
||||
data-i18n="basic_settings.quota_title">配额超出行为</span></h3>
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<div class="toggle-group">
|
||||
@@ -269,14 +273,52 @@
|
||||
<input type="checkbox" id="switch-project-toggle">
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
<span class="toggle-label" data-i18n="basic_settings.quota_switch_project">自动切换项目</span>
|
||||
<span class="toggle-label"
|
||||
data-i18n="basic_settings.quota_switch_project">自动切换项目</span>
|
||||
</div>
|
||||
<div class="toggle-group">
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" id="switch-preview-model-toggle">
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
<span class="toggle-label" data-i18n="basic_settings.quota_switch_preview">切换到预览模型</span>
|
||||
<span class="toggle-label"
|
||||
data-i18n="basic_settings.quota_switch_preview">切换到预览模型</span>
|
||||
</div>
|
||||
</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>
|
||||
</div>
|
||||
@@ -289,7 +331,8 @@
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3><i class="fas fa-key"></i> <span data-i18n="api_keys.proxy_auth_title">代理服务认证密钥</span></h3>
|
||||
<h3><i class="fas fa-key"></i> <span
|
||||
data-i18n="api_keys.proxy_auth_title">代理服务认证密钥</span></h3>
|
||||
<button id="add-api-key" class="btn btn-primary">
|
||||
<i class="fas fa-plus"></i> <span data-i18n="api_keys.add_button">添加密钥</span>
|
||||
</button>
|
||||
@@ -307,9 +350,11 @@
|
||||
<!-- Gemini API Keys -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3><i class="fab fa-google"></i> <span data-i18n="ai_providers.gemini_title">Gemini API 密钥</span></h3>
|
||||
<h3><i class="fab fa-google"></i> <span data-i18n="ai_providers.gemini_title">Gemini
|
||||
API 密钥</span></h3>
|
||||
<button id="add-gemini-key" class="btn btn-primary">
|
||||
<i class="fas fa-plus"></i> <span data-i18n="ai_providers.gemini_add_button">添加密钥</span>
|
||||
<i class="fas fa-plus"></i> <span
|
||||
data-i18n="ai_providers.gemini_add_button">添加密钥</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="card-content">
|
||||
@@ -320,9 +365,11 @@
|
||||
<!-- Codex API Keys -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3><i class="fas fa-code"></i> <span data-i18n="ai_providers.codex_title">Codex API 配置</span></h3>
|
||||
<h3><i class="fas fa-code"></i> <span data-i18n="ai_providers.codex_title">Codex API
|
||||
配置</span></h3>
|
||||
<button id="add-codex-key" class="btn btn-primary">
|
||||
<i class="fas fa-plus"></i> <span data-i18n="ai_providers.codex_add_button">添加配置</span>
|
||||
<i class="fas fa-plus"></i> <span
|
||||
data-i18n="ai_providers.codex_add_button">添加配置</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="card-content">
|
||||
@@ -333,9 +380,11 @@
|
||||
<!-- Claude API Keys -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3><i class="fas fa-brain"></i> <span data-i18n="ai_providers.claude_title">Claude API 配置</span></h3>
|
||||
<h3><i class="fas fa-brain"></i> <span data-i18n="ai_providers.claude_title">Claude
|
||||
API 配置</span></h3>
|
||||
<button id="add-claude-key" class="btn btn-primary">
|
||||
<i class="fas fa-plus"></i> <span data-i18n="ai_providers.claude_add_button">添加配置</span>
|
||||
<i class="fas fa-plus"></i> <span
|
||||
data-i18n="ai_providers.claude_add_button">添加配置</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="card-content">
|
||||
@@ -346,9 +395,11 @@
|
||||
<!-- OpenAI 兼容提供商 -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3><i class="fas fa-plug"></i> <span data-i18n="ai_providers.openai_title">OpenAI 兼容提供商</span></h3>
|
||||
<h3><i class="fas fa-plug"></i> <span data-i18n="ai_providers.openai_title">OpenAI
|
||||
兼容提供商</span></h3>
|
||||
<button id="add-openai-provider" class="btn btn-primary">
|
||||
<i class="fas fa-plus"></i> <span data-i18n="ai_providers.openai_add_button">添加提供商</span>
|
||||
<i class="fas fa-plus"></i> <span
|
||||
data-i18n="ai_providers.openai_add_button">添加提供商</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="card-content">
|
||||
@@ -369,43 +420,19 @@
|
||||
</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>
|
||||
<h3><i class="fas fa-file-alt"></i> <span
|
||||
data-i18n="auth_files.title_section">认证文件</span></h3>
|
||||
<div class="header-actions">
|
||||
<button id="upload-auth-file" class="btn btn-primary">
|
||||
<i class="fas fa-upload"></i> <span data-i18n="auth_files.upload_button">上传文件</span>
|
||||
<i class="fas fa-upload"></i> <span
|
||||
data-i18n="auth_files.upload_button">上传文件</span>
|
||||
</button>
|
||||
<button id="delete-all-auth-files" class="btn btn-danger">
|
||||
<i class="fas fa-trash"></i> <span data-i18n="auth_files.delete_all_button">删除全部</span>
|
||||
<i class="fas fa-trash"></i> <span
|
||||
data-i18n="auth_files.delete_all_button">删除全部</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -414,6 +441,228 @@
|
||||
<input type="file" id="auth-file-input" accept=".json" style="display: none;">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Codex OAuth -->
|
||||
<div class="card" id="codex-oauth-card">
|
||||
<div class="card-header">
|
||||
<h3><i class="fas fa-code"></i> <span data-i18n="auth_login.codex_oauth_title">Codex
|
||||
OAuth</span></h3>
|
||||
<button id="codex-oauth-btn" class="btn btn-primary">
|
||||
<i class="fas fa-sign-in-alt"></i> <span
|
||||
data-i18n="auth_login.codex_oauth_button">开始 Codex 登录</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<p class="form-hint" style="margin-bottom: 20px;"
|
||||
data-i18n="auth_login.codex_oauth_hint">
|
||||
通过 OAuth 流程登录 Codex 服务,自动获取并保存认证文件。
|
||||
</p>
|
||||
<div id="codex-oauth-content" style="display: none;">
|
||||
<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>
|
||||
<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>
|
||||
</button>
|
||||
<button id="codex-copy-link" class="btn btn-secondary">
|
||||
<i class="fas fa-copy"></i> <span
|
||||
data-i18n="auth_login.codex_copy_link">复制链接</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="codex-oauth-status" class="form-hint" style="margin-top: 10px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Anthropic OAuth -->
|
||||
<div class="card" id="anthropic-oauth-card">
|
||||
<div class="card-header">
|
||||
<h3><i class="fas fa-brain"></i> <span
|
||||
data-i18n="auth_login.anthropic_oauth_title">Anthropic OAuth</span></h3>
|
||||
<button id="anthropic-oauth-btn" class="btn btn-primary">
|
||||
<i class="fas fa-sign-in-alt"></i> <span
|
||||
data-i18n="auth_login.anthropic_oauth_button">开始 Anthropic 登录</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<p class="form-hint" style="margin-bottom: 20px;"
|
||||
data-i18n="auth_login.anthropic_oauth_hint">
|
||||
通过 OAuth 流程登录 Anthropic (Claude) 服务,自动获取并保存认证文件。
|
||||
</p>
|
||||
<div id="anthropic-oauth-content" style="display: none;">
|
||||
<div class="form-group">
|
||||
<label data-i18n="auth_login.anthropic_oauth_url_label">授权链接:</label>
|
||||
<div class="input-group">
|
||||
<input type="text" id="anthropic-oauth-url" readonly>
|
||||
<button id="anthropic-open-link" class="btn btn-primary">
|
||||
<i class="fas fa-external-link-alt"></i> <span
|
||||
data-i18n="auth_login.anthropic_open_link">打开链接</span>
|
||||
</button>
|
||||
<button id="anthropic-copy-link" class="btn btn-secondary">
|
||||
<i class="fas fa-copy"></i> <span
|
||||
data-i18n="auth_login.anthropic_copy_link">复制链接</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="anthropic-oauth-status" class="form-hint" style="margin-top: 10px;">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Gemini CLI OAuth -->
|
||||
<div class="card" id="gemini-cli-oauth-card">
|
||||
<div class="card-header">
|
||||
<h3><i class="fab fa-google"></i> <span
|
||||
data-i18n="auth_login.gemini_cli_oauth_title">Gemini CLI OAuth</span></h3>
|
||||
<button id="gemini-cli-oauth-btn" class="btn btn-primary">
|
||||
<i class="fas fa-sign-in-alt"></i> <span
|
||||
data-i18n="auth_login.gemini_cli_oauth_button">开始 Gemini CLI 登录</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<p class="form-hint" style="margin-bottom: 20px;"
|
||||
data-i18n="auth_login.gemini_cli_oauth_hint">
|
||||
通过 OAuth 流程登录 Google Gemini CLI 服务,自动获取并保存认证文件。
|
||||
</p>
|
||||
<div class="form-group" style="margin-bottom: 20px;">
|
||||
<label for="gemini-cli-project-id"
|
||||
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>
|
||||
</div>
|
||||
<div id="gemini-cli-oauth-content" style="display: none;">
|
||||
<div class="form-group">
|
||||
<label data-i18n="auth_login.gemini_cli_oauth_url_label">授权链接:</label>
|
||||
<div class="input-group">
|
||||
<input type="text" id="gemini-cli-oauth-url" readonly>
|
||||
<button id="gemini-cli-open-link" class="btn btn-primary">
|
||||
<i class="fas fa-external-link-alt"></i> <span
|
||||
data-i18n="auth_login.gemini_cli_open_link">打开链接</span>
|
||||
</button>
|
||||
<button id="gemini-cli-copy-link" class="btn btn-secondary">
|
||||
<i class="fas fa-copy"></i> <span
|
||||
data-i18n="auth_login.gemini_cli_copy_link">复制链接</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="gemini-cli-oauth-status" class="form-hint" style="margin-top: 10px;">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Qwen OAuth -->
|
||||
<div class="card" id="qwen-oauth-card">
|
||||
<div class="card-header">
|
||||
<h3><i class="fas fa-robot"></i> <span data-i18n="auth_login.qwen_oauth_title">Qwen
|
||||
OAuth</span></h3>
|
||||
<button id="qwen-oauth-btn" class="btn btn-primary">
|
||||
<i class="fas fa-sign-in-alt"></i> <span
|
||||
data-i18n="auth_login.qwen_oauth_button">开始 Qwen 登录</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<p class="form-hint" style="margin-bottom: 20px;"
|
||||
data-i18n="auth_login.qwen_oauth_hint">
|
||||
通过设备授权流程登录 Qwen 服务,自动获取并保存认证文件。
|
||||
</p>
|
||||
<div id="qwen-oauth-content" style="display: none;">
|
||||
<div class="form-group">
|
||||
<label data-i18n="auth_login.qwen_oauth_url_label">授权链接:</label>
|
||||
<div class="input-group">
|
||||
<input type="text" id="qwen-oauth-url" readonly>
|
||||
<button id="qwen-open-link" class="btn btn-primary">
|
||||
<i class="fas fa-external-link-alt"></i> <span
|
||||
data-i18n="auth_login.qwen_open_link">打开链接</span>
|
||||
</button>
|
||||
<button id="qwen-copy-link" class="btn btn-secondary">
|
||||
<i class="fas fa-copy"></i> <span
|
||||
data-i18n="auth_login.qwen_copy_link">复制链接</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="qwen-oauth-status" class="form-hint" style="margin-top: 10px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- iFlow OAuth -->
|
||||
<div class="card" id="iflow-oauth-card">
|
||||
<div class="card-header">
|
||||
<h3><i class="fas fa-stream"></i> <span
|
||||
data-i18n="auth_login.iflow_oauth_title">iFlow OAuth</span></h3>
|
||||
<button id="iflow-oauth-btn" class="btn btn-primary">
|
||||
<i class="fas fa-sign-in-alt"></i> <span
|
||||
data-i18n="auth_login.iflow_oauth_button">开始 iFlow 登录</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<p class="form-hint" style="margin-bottom: 20px;"
|
||||
data-i18n="auth_login.iflow_oauth_hint">
|
||||
通过 OAuth 流程登录 iFlow 服务,自动获取并保存认证文件。
|
||||
</p>
|
||||
<div id="iflow-oauth-content" style="display: none;">
|
||||
<div class="form-group">
|
||||
<label data-i18n="auth_login.iflow_oauth_url_label">授权链接:</label>
|
||||
<div class="input-group">
|
||||
<input type="text" id="iflow-oauth-url" readonly>
|
||||
<button id="iflow-open-link" class="btn btn-primary">
|
||||
<i class="fas fa-external-link-alt"></i> <span
|
||||
data-i18n="auth_login.iflow_open_link">打开链接</span>
|
||||
</button>
|
||||
<button id="iflow-copy-link" class="btn btn-secondary">
|
||||
<i class="fas fa-copy"></i> <span
|
||||
data-i18n="auth_login.iflow_copy_link">复制链接</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="iflow-oauth-status" class="form-hint" style="margin-top: 10px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</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>
|
||||
|
||||
<!-- 使用统计 -->
|
||||
@@ -468,12 +717,14 @@
|
||||
<!-- 请求趋势图 -->
|
||||
<div class="card chart-card">
|
||||
<div class="card-header">
|
||||
<h3><i class="fas fa-chart-line"></i> <span data-i18n="usage_stats.requests_trend">请求趋势</span></h3>
|
||||
<h3><i class="fas fa-chart-line"></i> <span
|
||||
data-i18n="usage_stats.requests_trend">请求趋势</span></h3>
|
||||
<div class="chart-controls">
|
||||
<button class="btn btn-small" data-period="hour" id="requests-hour-btn">
|
||||
<span data-i18n="usage_stats.by_hour">按小时</span>
|
||||
</button>
|
||||
<button class="btn btn-small active" data-period="day" id="requests-day-btn">
|
||||
<button class="btn btn-small active" data-period="day"
|
||||
id="requests-day-btn">
|
||||
<span data-i18n="usage_stats.by_day">按天</span>
|
||||
</button>
|
||||
</div>
|
||||
@@ -488,7 +739,8 @@
|
||||
<!-- Token使用趋势图 -->
|
||||
<div class="card chart-card">
|
||||
<div class="card-header">
|
||||
<h3><i class="fas fa-chart-area"></i> <span data-i18n="usage_stats.tokens_trend">Token 使用趋势</span></h3>
|
||||
<h3><i class="fas fa-chart-area"></i> <span
|
||||
data-i18n="usage_stats.tokens_trend">Token 使用趋势</span></h3>
|
||||
<div class="chart-controls">
|
||||
<button class="btn btn-small" data-period="hour" id="tokens-hour-btn">
|
||||
<span data-i18n="usage_stats.by_hour">按小时</span>
|
||||
@@ -509,7 +761,8 @@
|
||||
<!-- API详细统计 -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3><i class="fas fa-list"></i> <span data-i18n="usage_stats.api_details">API 详细统计</span></h3>
|
||||
<h3><i class="fas fa-list"></i> <span data-i18n="usage_stats.api_details">API
|
||||
详细统计</span></h3>
|
||||
<button id="refresh-usage-stats" class="btn btn-primary">
|
||||
<i class="fas fa-sync-alt"></i> <span data-i18n="usage_stats.refresh">刷新</span>
|
||||
</button>
|
||||
@@ -522,26 +775,87 @@
|
||||
</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" placeholder="key: value"></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>
|
||||
|
||||
<!-- 连接信息卡片 -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3><i class="fas fa-info-circle"></i> <span data-i18n="system_info.connection_status_title">连接状态</span></h3>
|
||||
<h3><i class="fas fa-server"></i> <span data-i18n="connection.title">连接信息</span>
|
||||
</h3>
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<div class="connection-info">
|
||||
<div class="info-item">
|
||||
<div class="info-label">
|
||||
<i class="fas fa-globe"></i>
|
||||
<span data-i18n="connection.server_address">服务器地址:</span>
|
||||
</div>
|
||||
<div class="info-value" id="display-api-url">-</div>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<div class="info-label">
|
||||
<i class="fas fa-circle"></i>
|
||||
<span data-i18n="connection.status">连接状态:</span>
|
||||
</div>
|
||||
<div class="info-value" id="display-connection-status">
|
||||
<span class="status-indicator disconnected"
|
||||
data-i18n="common.disconnected">未连接</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3><i class="fas fa-info-circle"></i> <span
|
||||
data-i18n="system_info.connection_status_title">连接状态</span></h3>
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<div id="system-status" class="status-info">
|
||||
<div class="status-item">
|
||||
<span class="status-label" data-i18n="system_info.api_status_label">API 状态:</span>
|
||||
<span id="api-status" class="status-value" data-i18n="common.disconnected">未连接</span>
|
||||
<span class="status-label" data-i18n="system_info.api_status_label">API
|
||||
状态:</span>
|
||||
<span id="api-status" class="status-value"
|
||||
data-i18n="common.disconnected">未连接</span>
|
||||
</div>
|
||||
<div class="status-item">
|
||||
<span class="status-label" data-i18n="system_info.config_status_label">配置状态:</span>
|
||||
<span id="config-status" class="status-value" data-i18n="system_info.not_loaded">未加载</span>
|
||||
<span class="status-label"
|
||||
data-i18n="system_info.config_status_label">配置状态:</span>
|
||||
<span id="config-status" class="status-value"
|
||||
data-i18n="system_info.not_loaded">未加载</span>
|
||||
</div>
|
||||
<div class="status-item">
|
||||
<span class="status-label" data-i18n="system_info.last_update_label">最后更新:</span>
|
||||
<span class="status-label"
|
||||
data-i18n="system_info.last_update_label">最后更新:</span>
|
||||
<span id="last-update" class="status-value">-</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -549,17 +863,22 @@
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</main>
|
||||
<!-- /内容区域 -->
|
||||
|
||||
<!-- 版本信息 -->
|
||||
<footer class="version-footer">
|
||||
<div class="version-info">
|
||||
<span data-i18n="footer.version">版本</span>: v0.0.5
|
||||
<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>
|
||||
<!-- /主内容区域 -->
|
||||
</div>
|
||||
<!-- /主内容包装器 -->
|
||||
</div>
|
||||
<!-- /主页面 -->
|
||||
|
||||
<!-- 模态框 -->
|
||||
<div id="modal" class="modal">
|
||||
@@ -576,4 +895,5 @@
|
||||
|
||||
<script src="app.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
2029
styles.css
2029
styles.css
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user