feat: update README.md README_CN.md

This commit is contained in:
Supra4E8C
2025-12-22 23:20:31 +08:00
parent 94962158ef
commit 561e06503c
2 changed files with 175 additions and 295 deletions

216
README.md
View File

@@ -1,190 +1,130 @@
# CLI Proxy API Management Center
A modern React-based WebUI for managing the CLI Proxy API, completely refactored with a modern tech stack for enhanced maintainability, type safety, and user experience.
A single-file WebUI (React + TypeScript) for operating and troubleshooting the **CLI Proxy API** via its **Management API** (config, credentials, logs, and usage).
[中文文档](README_CN.md)
**Main Project**: https://github.com/router-for-me/CLIProxyAPI
**Example URL**: https://remote.router-for.me/
**Main Project**: https://github.com/router-for-me/CLIProxyAPI
**Example URL**: https://remote.router-for.me/
**Minimum Required Version**: ≥ 6.3.0 (recommended ≥ 6.5.0)
Since version 6.0.19, the WebUI ships with the main program; access it via `/management.html` on the API port once the service is running.
## Features
## What this is (and isnt)
### Core Capabilities
- This repository is the WebUI only. It talks to the CLI Proxy API **Management API** (`/v0/management`) to read/update config, upload credentials, view logs, and inspect usage.
- It is **not** a proxy and does not forward traffic.
- **Login & Authentication**: Auto-detects current address (manual override supported), encrypted auto-login with secure localStorage, session persistence
- **Basic Settings**: Debug mode, proxy URL, request retries with custom config, quota fallback (auto-switch project/preview models), usage statistics toggle, request logging & file logging, WebSocket `/ws/*` authentication
- **API Keys Management**: Manage proxy auth keys with add/edit/delete operations
- **AI Providers**: Configure Gemini/Codex/Claude settings, OpenAI-compatible providers with custom base URLs/headers/proxy/model aliases, Vertex AI credential import from service-account JSON
- **Auth Files & OAuth**: Upload/download/search/paginate JSON credentials; type filters (Qwen/Gemini/GeminiCLI/AIStudio/Claude/Codex/Antigravity/iFlow/Vertex/Empty); bulk delete; OAuth/Device flows for multiple providers
- **Logs Viewer**: Real-time log viewer with auto-refresh, download and clear capabilities (appears when logging-to-file is enabled)
- **Usage Analytics**: Overview cards, hourly/daily toggles, interactive charts with multiple model lines, per-API statistics table
- **Config Management**: In-browser YAML editor for `/config.yaml` with syntax highlighting, reload/save functionality
- **System Information**: Connection status, config cache, server version/build date, UI version in footer
## Quick start
### User Experience
### Option A: Use the WebUI bundled in CLIProxyAPI (recommended)
- **Responsive Design**: Full mobile support with collapsible sidebar
- **Theme System**: Light/dark mode with persistent preference
- **Internationalization**: English and Simplified Chinese (zh-CN) with seamless switching
- **Real-time Feedback**: Toast notifications for all operations
- **Security**: Masked secrets, encrypted local storage
1. Start your CLI Proxy API service.
2. Open: `http://<host>:<api_port>/management.html`
3. Enter your **management key** and connect.
## Tech Stack
The address is auto-detected from the current page URL; manual override is supported.
- **Frontend Framework**: React 19 with TypeScript
- **Build Tool**: Vite 7 with single-file output ([vite-plugin-singlefile](https://github.com/nicknisi/vite-plugin-singlefile))
- **State Management**: [Zustand](https://github.com/pmndrs/zustand) for global stores
- **Routing**: React Router 7 with HashRouter
- **HTTP Client**: Axios with interceptors for auth & error handling
- **Internationalization**: i18next + react-i18next
- **Styling**: SCSS with CSS Modules, CSS Variables for theming
- **Charts**: Chart.js + react-chartjs-2
- **Code Editor**: @uiw/react-codemirror with YAML support
## Getting Started
### Prerequisites
- Node.js 18+ (LTS recommended)
- npm 9+
### Installation
### Option B: Run the dev server
```bash
# Clone the repository
git clone https://github.com/router-for-me/Cli-Proxy-API-Management-Center.git
cd Cli-Proxy-API-Management-Center
# Install dependencies
npm install
npm run dev
```
### Development
Open `http://localhost:5173`, then connect to your CLI Proxy API instance.
### Option C: Build a single HTML file
```bash
npm run dev # Start Vite dev server (default: http://localhost:5173)
npm install
npm run build
```
### Build
- Output: `dist/index.html` (all assets are inlined).
- For CLIProxyAPI bundling, the release workflow renames it to `management.html`.
- To preview locally: `npm run preview`
```bash
npm run build # TypeScript check + Vite production build
```
Tip: opening `dist/index.html` via `file://` may be blocked by browser CORS; serving it (preview/static server) is more reliable.
The build outputs a single `dist/index.html` file with all assets inlined.
## Connecting to the server
### Other Commands
### API address
```bash
npm run preview # Preview production build locally
npm run lint # ESLint with strict mode (--max-warnings 0)
npm run format # Prettier formatting for src/**/*.{ts,tsx,css,scss}
npm run type-check # TypeScript type checking only (tsc --noEmit)
```
You can enter any of the following; the UI will normalize it:
## Usage
- `localhost:8317`
- `http://192.168.1.10:8317`
- `https://example.com:8317`
- `http://example.com:8317/v0/management` (also accepted; the suffix is removed internally)
### Access Methods
### Management key (not the same as API keys)
1. **Integrated with CLI Proxy API (Recommended)**
After starting the CLI Proxy API service, visit `http://your-server:8317/management.html`
The management key is sent with every request as:
2. **Standalone (Built file)**
Open the built `dist/index.html` directly in a browser, or host it on any static file server
- `Authorization: Bearer <MANAGEMENT_KEY>` (default)
3. **Development Server**
Run `npm run dev` and open `http://localhost:5173`
This is different from the proxy `api-keys` you manage inside the UI (those are for client requests to the proxy endpoints).
### Initial Configuration
### Remote management
1. The login page auto-detects the current address; you can modify it if needed
2. Enter your management key
3. Click Connect to authenticate
4. Credentials are encrypted and saved locally for auto-login
If you connect from a non-localhost browser, the server must allow remote management (e.g. `allow-remote-management: true`).
See `api.md` for the full authentication rules, server-side limits, and edge cases.
> **Tip**: The Logs navigation item appears only after enabling "Logging to file" in Basic Settings.
## What you can manage (mapped to the UI pages)
## Project Structure
- **Dashboard**: connection status, server version/build date, quick counts, model availability snapshot.
- **Basic Settings**: debug, proxy URL, request retry, quota fallback (switch project/preview models), usage statistics, request logging, file logging, WebSocket auth.
- **API Keys**: manage proxy `api-keys` (add/edit/delete).
- **AI Providers**:
- Gemini/Codex/Claude key entries (base URL, headers, proxy, model aliases, excluded models, prefix).
- OpenAI-compatible providers (multiple API keys, custom headers, model alias import via `/v1/models`, optional browser-side “chat/completions” test).
- Ampcode integration (upstream URL/key, force mappings, model mapping table).
- **Auth Files**: upload/download/delete JSON credentials, filter/search/pagination, runtime-only indicators, view supported models per credential (when the server supports it), manage OAuth excluded models (supports `*` wildcards).
- **OAuth**: start OAuth/device flows for supported providers, poll status, optionally submit callback `redirect_url`; includes iFlow cookie import.
- **Usage**: requests/tokens charts (hour/day), per-API & per-model breakdown, cached/reasoning token breakdown, RPM/TPM window, optional cost estimation with locally-saved model pricing.
- **Config**: edit `/config.yaml` in-browser with YAML highlighting + search, then save/reload.
- **Logs**: tail logs with incremental polling, auto-refresh, search, hide management traffic, clear logs; download request error log files.
- **System**: quick links + fetch `/v1/models` (grouped view). Requires at least one proxy API key to query models.
```
├── src/
│ ├── components/
│ │ ├── common/ # Shared components (NotificationContainer)
│ │ ├── layout/ # App shell (MainLayout with sidebar)
│ │ └── ui/ # Reusable UI primitives (Button, Input, Modal, etc.)
│ ├── hooks/ # Custom hooks (useApi, useDebounce, usePagination, etc.)
│ ├── i18n/
│ │ ├── locales/ # Translation files (zh-CN.json, en.json)
│ │ └── index.ts # i18next configuration
│ ├── pages/ # Route page components with co-located .module.scss
│ ├── router/ # ProtectedRoute wrapper
│ ├── services/
│ │ ├── api/ # API layer (client.ts singleton, feature modules)
│ │ └── storage/ # Secure storage utilities
│ ├── stores/ # Zustand stores (auth, config, theme, language, notification)
│ ├── styles/ # Global SCSS (variables, mixins, themes, components)
│ ├── types/ # TypeScript type definitions
│ ├── utils/ # Utility functions (constants, format, validation, etc.)
│ ├── App.tsx # Root component with routing
│ └── main.tsx # Entry point
├── dist/ # Build output (single-file bundle)
├── vite.config.ts # Vite configuration
├── tsconfig.json # TypeScript configuration
└── package.json
```
## Build & release notes
### Key Architecture Patterns
- Vite produces a **single HTML** output (`dist/index.html`) with all assets inlined (via `vite-plugin-singlefile`).
- Tagging `vX.Y.Z` triggers `.github/workflows/release.yml` to publish `dist/management.html`.
- The UI version shown in the footer is injected at build time (env `VERSION`, git tag, or `package.json` fallback).
- **Path Alias**: Use `@/` to import from `src/` (configured in vite.config.ts and tsconfig.json)
- **API Client**: Singleton `apiClient` in `src/services/api/client.ts` with auth interceptors
- **State Management**: Zustand stores with localStorage persistence for auth/theme/language
- **Styling**: SCSS variables auto-injected; CSS Modules for component-scoped styles
- **Build Output**: Single-file bundle for easy distribution (all assets inlined)
## Security notes
- The management key is stored in browser `localStorage` using a lightweight obfuscation format (`enc::v1::...`) to avoid plaintext storage; treat it as sensitive.
- Use a dedicated browser profile/device for management. Be cautious when enabling remote management and evaluate its exposure surface.
## Troubleshooting
### Connection Issues
- **Cant connect / 401**: confirm the API address and management key; remote access may require enabling remote management in the server config.
- **Repeated auth failures**: the server may temporarily block remote IPs.
- **Logs page missing**: enable “Logging to file” in Basic Settings; the navigation item is shown only when file logging is enabled.
- **Some features show “unsupported”**: the backend may be too old or the endpoint is disabled/absent (common for model lists per auth file, excluded models, logs).
- **OpenAI provider test fails**: the test runs in the browser and depends on network/CORS of the provider endpoint; a failure here does not always mean the server cannot reach it.
1. Confirm the CLI Proxy API service is running
2. Check if the API address is correct
3. Verify that the management key is valid
4. Ensure your firewall allows the connection
## Development
### Data Not Updating
1. Click the "Refresh All" button in the header
2. Check your network connection
3. Open browser DevTools console for error details
### Logs & Config Editor
- **Logs**: Requires server-side logging-to-file enabled; 404 indicates old server version or logging disabled
- **Config Editor**: Requires `/config.yaml` endpoint; ensure valid YAML syntax before saving
### Usage Statistics
- If charts are empty, enable "Usage statistics" in settings; data resets on server restart
```bash
npm run dev # Vite dev server
npm run build # tsc + Vite build
npm run preview # serve dist locally
npm run lint # ESLint (fails on warnings)
npm run format # Prettier
npm run type-check # tsc --noEmit
```
## Contributing
We welcome Issues and Pull Requests! Please follow these guidelines:
Issues and PRs are welcome. Please include:
1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes with clear messages
4. Push to your branch
5. Open a Pull Request
### Development Guidelines
- Run `npm run lint` and `npm run type-check` before committing
- Follow existing code patterns and naming conventions
- Use TypeScript strict mode
- Write meaningful commit messages
- Reproduction steps (server version + UI version)
- Screenshots for UI changes
- Verification notes (`npm run lint`, `npm run type-check`)
## License
This project is licensed under the MIT License.
MIT

View File

@@ -1,190 +1,130 @@
# CLI Proxy API 管理中心
用于管理 CLI Proxy API 的现代化 React Web 界面,采用全新技术栈重构,提供更好的可维护性、类型安全性和用户体验
用于管理与排障 **CLI Proxy API** 的单文件 WebUIReact + TypeScript通过 **Management API** 完成配置、凭据、日志与统计等运维工作
[English](README.md)
**主项目**: https://github.com/router-for-me/CLIProxyAPI
**示例地址**: https://remote.router-for.me/
**主项目**: https://github.com/router-for-me/CLIProxyAPI
**示例地址**: https://remote.router-for.me/
**最低版本要求**: ≥ 6.3.0(推荐 ≥ 6.5.0
自 6.0.19 版本起WebUI 已集成到主程序中,启动服务后可通过 `/management.html` 访问。
Since version 6.0.19, the WebUI ships with the main program; access it via `/management.html` on the API port once the service is running.
## 功能特点
## 这是什么(以及不是什么)
### 核心功能
- **登录与认证**: 自动检测当前地址(支持手动修改),加密自动登录,会话持久化
- **基础设置**: 调试模式、代理 URL、请求重试配置、配额溢出自动切换项目/预览模型、使用统计开关、请求日志与文件日志、WebSocket `/ws/*` 鉴权
- **API 密钥管理**: 管理代理认证密钥,支持添加/编辑/删除操作
- **AI 提供商**: 配置 Gemini/Codex/ClaudeOpenAI 兼容提供商(自定义 Base URL/Headers/代理/模型别名Vertex AI 服务账号 JSON 导入
- **认证文件与 OAuth**: 上传/下载/搜索/分页 JSON 凭据类型筛选Qwen/Gemini/GeminiCLI/AIStudio/Claude/Codex/Antigravity/iFlow/Vertex/Empty批量删除多提供商 OAuth/设备码流程
- **日志查看**: 实时日志查看,支持自动刷新、下载和清空(启用"写入日志文件"后显示)
- **使用统计**: 概览卡片、小时/天切换、多模型交互式图表、按 API 统计表格
- **配置管理**: 内置 YAML 编辑器,支持 `/config.yaml` 语法高亮、重载/保存
- **系统信息**: 连接状态、配置缓存、服务器版本/构建时间、底栏显示 UI 版本
### 用户体验
- **响应式设计**: 完整移动端支持,可折叠侧边栏
- **主题系统**: 明/暗模式切换,偏好持久化
- **国际化**: 简体中文和英文,无缝切换
- **实时反馈**: 所有操作的消息通知
- **安全性**: 密钥遮蔽、加密本地存储
## 技术栈
- **前端框架**: React 19 + TypeScript
- **构建工具**: Vite 7单文件输出[vite-plugin-singlefile](https://github.com/nicknisi/vite-plugin-singlefile)
- **状态管理**: [Zustand](https://github.com/pmndrs/zustand)
- **路由**: React Router 7 (HashRouter)
- **HTTP 客户端**: Axios带认证和错误处理拦截器
- **国际化**: i18next + react-i18next
- **样式**: SCSS + CSS ModulesCSS 变量主题
- **图表**: Chart.js + react-chartjs-2
- **代码编辑器**: @uiw/react-codemirrorYAML 支持)
- 本仓库只包含 Web 管理界面本身,通过 CLI Proxy API 的 **Management API**`/v0/management`)读取/修改配置、上传凭据、查看日志与使用统计。
-**不是** 代理本体,不参与流量转发。
## 快速开始
### 环境要求
### 方式 A使用 CLIProxyAPI 自带的 WebUI推荐
- Node.js 18+(推荐 LTS 版本)
- npm 9+
1. 启动 CLI Proxy API 服务。
2. 打开:`http://<host>:<api_port>/management.html`
3. 输入 **管理密钥** 并连接。
### 安装
页面会根据当前地址自动推断 API 地址,也支持手动修改。
### 方式 B开发调试
```bash
# 克隆仓库
git clone https://github.com/router-for-me/Cli-Proxy-API-Management-Center.git
cd Cli-Proxy-API-Management-Center
# 安装依赖
npm install
npm run dev
```
### 开发
打开 `http://localhost:5173`,然后连接到你的 CLI Proxy API 实例。
### 方式 C构建单文件 HTML
```bash
npm run dev # 启动 Vite 开发服务器(默认: http://localhost:5173
npm install
npm run build
```
### 构建
- 构建产物:`dist/index.html`(资源已全部内联)。
- 在 CLIProxyAPI 的发布流程里会重命名为 `management.html`
- 本地预览:`npm run preview`
提示:直接用 `file://` 打开 `dist/index.html` 可能遇到浏览器 CORS 限制;更稳妥的方式是用预览/静态服务器打开。
## 连接说明
### API 地址怎么填
以下格式均可WebUI 会自动归一化:
- `localhost:8317`
- `http://192.168.1.10:8317`
- `https://example.com:8317`
- `http://example.com:8317/v0/management`(也可填写,后缀会被自动去除)
### 管理密钥(注意:不是 API Keys
管理密钥会以如下方式随请求发送:
- `Authorization: Bearer <MANAGEMENT_KEY>`(默认)
这与 WebUI 中“API Keys”页面管理的 `api-keys` 不同:后者是代理对外接口(如 OpenAI 兼容接口)给客户端使用的鉴权 key。
### 远程管理
当你从非 localhost 的浏览器访问时,服务端通常需要开启远程管理(例如 `allow-remote-management: true`)。
完整鉴权规则、限制与边界情况请查看 `api.md`
## 功能一览(按页面对应)
- **仪表盘**:连接状态、服务版本/构建时间、关键数量概览、可用模型概览。
- **基础设置**:调试开关、代理 URL、请求重试、配额回退切项目/切预览模型、使用统计、请求日志、文件日志、WebSocket 鉴权。
- **API Keys**:管理代理 `api-keys`(增/改/删)。
- **AI 提供商**
- Gemini/Codex/Claude 配置Base URL、Headers、代理、模型别名、排除模型、Prefix
- OpenAI 兼容提供商(多 Key、Header、自助从 `/v1/models` 拉取并导入模型别名、可选浏览器侧 `chat/completions` 测试)。
- Ampcode 集成(上游地址/密钥、强制映射、模型映射表)。
- **认证文件**:上传/下载/删除 JSON 凭据,筛选/搜索/分页,标记 runtime-only查看单个凭据可用模型依赖后端支持管理 OAuth 排除模型(支持 `*` 通配符)。
- **OAuth**:对支持的提供商发起 OAuth/设备码流程,轮询状态;可选提交回调 `redirect_url`;包含 iFlow Cookie 导入。
- **使用统计**:按小时/天图表、按 API 与按模型统计、缓存/推理 Token 拆分、RPM/TPM 时间窗、可选本地保存的模型价格用于费用估算。
- **配置文件**:浏览器内编辑 `/config.yaml`YAML 高亮 + 搜索),保存/重载。
- **日志**:增量拉取日志、自动刷新、搜索、隐藏管理端流量、清空日志;下载请求错误日志文件。
- **系统信息**:快捷链接 + 拉取 `/v1/models` 并分组展示(需要至少一个代理 API Key 才能查询模型)。
## 构建与发布说明
- 使用 Vite 输出 **单文件 HTML**`dist/index.html`),资源全部内联(`vite-plugin-singlefile`)。
-`vX.Y.Z` 标签会触发 `.github/workflows/release.yml`,发布 `dist/management.html`
- 页脚显示的 UI 版本在构建期注入(优先使用环境变量 `VERSION`,否则使用 git tag / `package.json`)。
## 安全提示
- 管理密钥会存入浏览器 `localStorage`,并使用轻量混淆格式(`enc::v1::...`)避免明文;仍应视为敏感信息。
- 建议使用独立浏览器配置/设备进行管理;开启远程管理时请谨慎评估暴露面。
## 常见问题
- **无法连接 / 401**:确认 API 地址与管理密钥;远程访问可能需要服务端开启远程管理。
- **反复输错密钥**:服务端可能对远程 IP 进行临时封禁。
- **日志页面不显示**:需要在“基础设置”里开启“写入日志文件”,导航项才会出现。
- **功能提示不支持**:多为后端版本较旧或接口未启用/不存在(如:认证文件模型列表、排除模型、日志相关接口)。
- **OpenAI 提供商测试失败**:测试在浏览器侧执行,会受网络与 CORS 影响;这里失败不一定代表服务端不可用。
## 开发命令
```bash
npm run build # TypeScript 检查 + Vite 生产构建
npm run dev # 启动开发服务器
npm run build # tsc + Vite 构建
npm run preview # 本地预览 dist
npm run lint # ESLintwarnings 视为失败)
npm run format # Prettier
npm run type-check # tsc --noEmit
```
构建输出单个 `dist/index.html` 文件,所有资源已内联。
### 其他命令
```bash
npm run preview # 本地预览生产构建
npm run lint # ESLint 严格模式(--max-warnings 0
npm run format # Prettier 格式化 src/**/*.{ts,tsx,css,scss}
npm run type-check # 仅 TypeScript 类型检查tsc --noEmit
```
## 使用方法
### 访问方式
1. **与 CLI Proxy API 集成使用(推荐)**
启动 CLI Proxy API 服务后,访问 `http://您的服务器:8317/management.html`
2. **独立使用(构建后文件)**
直接在浏览器打开构建的 `dist/index.html`,或部署到任意静态文件服务器
3. **开发服务器**
运行 `npm run dev` 后打开 `http://localhost:5173`
### 初始配置
1. 登录页会自动检测当前地址,可根据需要修改
2. 输入管理密钥
3. 点击连接进行认证
4. 凭据会加密保存到本地,下次自动登录
> **提示**: 只有在"基础设置"中启用"写入日志文件"后,才会显示"日志查看"导航项。
## 项目结构
```
├── src/
│ ├── components/
│ │ ├── common/ # 公共组件NotificationContainer
│ │ ├── layout/ # 应用外壳MainLayout 侧边栏布局)
│ │ └── ui/ # 可复用 UI 组件Button、Input、Modal 等)
│ ├── hooks/ # 自定义 HooksuseApi、useDebounce、usePagination 等)
│ ├── i18n/
│ │ ├── locales/ # 翻译文件zh-CN.json、en.json
│ │ └── index.ts # i18next 配置
│ ├── pages/ # 路由页面组件,配套 .module.scss 样式
│ ├── router/ # ProtectedRoute 路由守卫
│ ├── services/
│ │ ├── api/ # API 层client.ts 单例,功能模块)
│ │ └── storage/ # 安全存储工具
│ ├── stores/ # Zustand 状态管理auth、config、theme、language、notification
│ ├── styles/ # 全局 SCSSvariables、mixins、themes、components
│ ├── types/ # TypeScript 类型定义
│ ├── utils/ # 工具函数constants、format、validation 等)
│ ├── App.tsx # 根组件与路由
│ └── main.tsx # 入口文件
├── dist/ # 构建输出(单文件打包)
├── vite.config.ts # Vite 配置
├── tsconfig.json # TypeScript 配置
└── package.json
```
### 核心架构模式
- **路径别名**: 使用 `@/` 导入 `src/` 目录(在 vite.config.ts 和 tsconfig.json 中配置)
- **API 客户端**: `src/services/api/client.ts` 单例,带认证拦截器
- **状态管理**: Zustand storesauth/theme/language 持久化到 localStorage
- **样式**: SCSS 变量自动注入CSS Modules 实现组件作用域样式
- **构建输出**: 单文件打包,便于分发(所有资源内联)
## 故障排除
### 连接问题
1. 确认 CLI Proxy API 服务正在运行
2. 检查 API 地址是否正确
3. 验证管理密钥是否有效
4. 确认防火墙设置允许连接
### 数据不更新
1. 点击顶栏的"刷新全部"按钮
2. 检查网络连接
3. 打开浏览器开发者工具控制台查看错误信息
### 日志与配置编辑
- **日志**: 需要服务端启用写文件日志;返回 404 说明服务器版本过旧或未启用日志
- **配置编辑**: 依赖 `/config.yaml` 接口;保存前请确保 YAML 语法正确
### 使用统计
- 若图表为空,请在设置中启用"使用统计";数据在服务重启后会清空
## 贡献
欢迎提 Issue Pull Request请遵循以下指南
欢迎提 Issue PR。建议附上
1. Fork 本仓库
2. 创建功能分支(`git checkout -b feature/amazing-feature`
3. 提交更改,使用清晰的提交信息
4. 推送到分支
5. 开启 Pull Request
### 开发规范
- 提交前运行 `npm run lint``npm run type-check`
- 遵循现有代码模式和命名规范
- 使用 TypeScript 严格模式
- 编写有意义的提交信息
- 复现步骤(服务端版本 + UI 版本)
- UI 改动截图
- 验证记录(`npm run lint``npm run type-check`
## 许可证
本项目采用 MIT 许可证。
MIT