785 lines
11 KiB
Markdown
785 lines
11 KiB
Markdown
# API 文档
|
||
|
||
## 目录
|
||
|
||
- [认证接口](#认证接口)
|
||
- [输入控制接口](#输入控制接口)
|
||
- [流媒体接口](#流媒体接口)
|
||
- [文件传输接口](#文件传输接口)
|
||
- [WebSocket 消息类型](#websocket-消息类型)
|
||
|
||
---
|
||
|
||
## 认证接口
|
||
|
||
### POST /login
|
||
|
||
Web 登录接口,用于用户身份认证。
|
||
|
||
**请求体**
|
||
|
||
```json
|
||
{
|
||
"password": "your_password"
|
||
}
|
||
```
|
||
|
||
**参数说明**
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
|------|------|------|------|
|
||
| password | string | 否 | 用户密码(如果服务器未配置密码则不需要) |
|
||
|
||
**响应示例**
|
||
|
||
成功响应(200):
|
||
```json
|
||
{
|
||
"success": true,
|
||
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
|
||
"message": "Authentication disabled"
|
||
}
|
||
```
|
||
|
||
失败响应(400):
|
||
```json
|
||
{
|
||
"success": false,
|
||
"error": "Password is required"
|
||
}
|
||
```
|
||
|
||
失败响应(401):
|
||
```json
|
||
{
|
||
"success": false,
|
||
"error": "Invalid password"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### POST /api/auth/login
|
||
|
||
API 登录接口,功能与 `/login` 相同。
|
||
|
||
**请求体**
|
||
|
||
```json
|
||
{
|
||
"password": "your_password"
|
||
}
|
||
```
|
||
|
||
**响应示例**
|
||
|
||
成功响应(200):
|
||
```json
|
||
{
|
||
"success": true,
|
||
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### POST /api/auth/verify
|
||
|
||
Token 验证接口,用于验证 JWT Token 是否有效。
|
||
|
||
**请求头**
|
||
|
||
```
|
||
Authorization: Bearer <token>
|
||
```
|
||
|
||
**响应示例**
|
||
|
||
成功响应(200):
|
||
```json
|
||
{
|
||
"success": true,
|
||
"valid": true,
|
||
"userId": "default-user"
|
||
}
|
||
```
|
||
|
||
失败响应(401):
|
||
```json
|
||
{
|
||
"success": false,
|
||
"valid": false,
|
||
"error": "No token provided"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 输入控制接口
|
||
|
||
所有输入控制接口需要在请求头中携带有效的 Token:
|
||
|
||
```
|
||
Authorization: Bearer <token>
|
||
```
|
||
|
||
### 鼠标操作
|
||
|
||
#### POST /api/input/mouse/move
|
||
|
||
移动鼠标到指定坐标。
|
||
|
||
**请求体**
|
||
|
||
```json
|
||
{
|
||
"x": 100,
|
||
"y": 200
|
||
}
|
||
```
|
||
|
||
**参数说明**
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
|------|------|------|------|
|
||
| x | number | 是 | 目标 X 坐标 |
|
||
| y | number | 是 | 目标 Y 坐标 |
|
||
|
||
**响应示例**
|
||
|
||
成功响应(200):
|
||
```json
|
||
{
|
||
"success": true
|
||
}
|
||
```
|
||
|
||
失败响应(400):
|
||
```json
|
||
{
|
||
"success": false,
|
||
"error": "Invalid coordinates"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
#### POST /api/input/mouse/down
|
||
|
||
按下鼠标按键。
|
||
|
||
**请求体**
|
||
|
||
```json
|
||
{
|
||
"button": "left"
|
||
}
|
||
```
|
||
|
||
**参数说明**
|
||
|
||
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|
||
|------|------|------|--------|------|
|
||
| button | string | 否 | left | 鼠标按键:`left`、`right`、`middle` |
|
||
|
||
**响应示例**
|
||
|
||
```json
|
||
{
|
||
"success": true
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
#### POST /api/input/mouse/up
|
||
|
||
释放鼠标按键。
|
||
|
||
**请求体**
|
||
|
||
```json
|
||
{
|
||
"button": "left"
|
||
}
|
||
```
|
||
|
||
**参数说明**
|
||
|
||
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|
||
|------|------|------|--------|------|
|
||
| button | string | 否 | left | 鼠标按键:`left`、`right`、`middle` |
|
||
|
||
**响应示例**
|
||
|
||
```json
|
||
{
|
||
"success": true
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
#### POST /api/input/mouse/click
|
||
|
||
点击鼠标按键。
|
||
|
||
**请求体**
|
||
|
||
```json
|
||
{
|
||
"button": "left"
|
||
}
|
||
```
|
||
|
||
**参数说明**
|
||
|
||
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|
||
|------|------|------|--------|------|
|
||
| button | string | 否 | left | 鼠标按键:`left`、`right`、`middle` |
|
||
|
||
**响应示例**
|
||
|
||
```json
|
||
{
|
||
"success": true
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
#### POST /api/input/mouse/wheel
|
||
|
||
鼠标滚轮滚动。
|
||
|
||
**请求体**
|
||
|
||
```json
|
||
{
|
||
"delta": 100
|
||
}
|
||
```
|
||
|
||
**参数说明**
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
|------|------|------|------|
|
||
| delta | number | 是 | 滚动量(正数向上,负数向下) |
|
||
|
||
**响应示例**
|
||
|
||
```json
|
||
{
|
||
"success": true
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 键盘操作
|
||
|
||
#### POST /api/input/keyboard/down
|
||
|
||
按下键盘按键。
|
||
|
||
**请求体**
|
||
|
||
```json
|
||
{
|
||
"key": "a"
|
||
}
|
||
```
|
||
|
||
**参数说明**
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
|------|------|------|------|
|
||
| key | string | 是 | 按键名称(如 `a`、`enter`、`ctrl`、`shift` 等) |
|
||
|
||
**响应示例**
|
||
|
||
```json
|
||
{
|
||
"success": true
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
#### POST /api/input/keyboard/up
|
||
|
||
释放键盘按键。
|
||
|
||
**请求体**
|
||
|
||
```json
|
||
{
|
||
"key": "a"
|
||
}
|
||
```
|
||
|
||
**参数说明**
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
|------|------|------|------|
|
||
| key | string | 是 | 按键名称 |
|
||
|
||
**响应示例**
|
||
|
||
```json
|
||
{
|
||
"success": true
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
#### POST /api/input/keyboard/press
|
||
|
||
按下并释放键盘按键(单击)。
|
||
|
||
**请求体**
|
||
|
||
```json
|
||
{
|
||
"key": "enter"
|
||
}
|
||
```
|
||
|
||
**参数说明**
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
|------|------|------|------|
|
||
| key | string | 是 | 按键名称 |
|
||
|
||
**响应示例**
|
||
|
||
```json
|
||
{
|
||
"success": true
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
#### POST /api/input/keyboard/type
|
||
|
||
输入文本字符串。
|
||
|
||
**请求体**
|
||
|
||
```json
|
||
{
|
||
"text": "Hello World"
|
||
}
|
||
```
|
||
|
||
**参数说明**
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
|------|------|------|------|
|
||
| text | string | 是 | 要输入的文本内容 |
|
||
|
||
**响应示例**
|
||
|
||
```json
|
||
{
|
||
"success": true
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 流媒体接口
|
||
|
||
### GET /api/stream/info
|
||
|
||
获取流媒体信息。
|
||
|
||
**响应示例**
|
||
|
||
```json
|
||
{
|
||
"success": true,
|
||
"stream": {
|
||
"status": "running",
|
||
"resolution": {
|
||
"width": 1920,
|
||
"height": 1080
|
||
},
|
||
"fps": 30,
|
||
"bitrate": 2000,
|
||
"gop": 60,
|
||
"encoder": "libx264"
|
||
}
|
||
}
|
||
```
|
||
|
||
**字段说明**
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| status | string | 流状态:`running` 或 `stopped` |
|
||
| resolution | object | 屏幕分辨率 |
|
||
| fps | number | 帧率 |
|
||
| bitrate | number | 比特率(kbps) |
|
||
| gop | number | GOP 大小 |
|
||
| encoder | string | 编码器名称 |
|
||
|
||
---
|
||
|
||
### POST /api/stream/start
|
||
|
||
启动流媒体。
|
||
|
||
**响应示例**
|
||
|
||
```json
|
||
{
|
||
"success": true,
|
||
"message": "Stream started"
|
||
}
|
||
```
|
||
|
||
已运行时响应:
|
||
```json
|
||
{
|
||
"success": true,
|
||
"message": "Stream is already running"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### POST /api/stream/stop
|
||
|
||
停止流媒体。
|
||
|
||
**响应示例**
|
||
|
||
```json
|
||
{
|
||
"success": true,
|
||
"message": "Stream stopped"
|
||
}
|
||
```
|
||
|
||
未运行时响应:
|
||
```json
|
||
{
|
||
"success": true,
|
||
"message": "Stream is not running"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 文件传输接口
|
||
|
||
### GET /api/files
|
||
|
||
获取文件列表。
|
||
|
||
**响应示例**
|
||
|
||
```json
|
||
{
|
||
"files": [
|
||
{
|
||
"name": "example.txt",
|
||
"size": 1024,
|
||
"modifiedTime": "2024-01-01T12:00:00.000Z"
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### GET /api/files/browse
|
||
|
||
浏览目录内容。
|
||
|
||
**查询参数**
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
|------|------|------|------|
|
||
| path | string | 否 | 目录路径(默认为根目录) |
|
||
|
||
**请求示例**
|
||
|
||
```
|
||
GET /api/files/browse?path=documents
|
||
```
|
||
|
||
**响应示例**
|
||
|
||
```json
|
||
{
|
||
"path": "documents",
|
||
"directories": ["folder1", "folder2"],
|
||
"files": [
|
||
{
|
||
"name": "file1.txt",
|
||
"size": 1024,
|
||
"modifiedTime": "2024-01-01T12:00:00.000Z"
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### POST /api/files/upload/start
|
||
|
||
开始上传会话(分块上传第一步)。
|
||
|
||
**请求体**
|
||
|
||
```json
|
||
{
|
||
"filename": "example.zip",
|
||
"totalChunks": 10,
|
||
"fileSize": 52428800
|
||
}
|
||
```
|
||
|
||
**参数说明**
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
|------|------|------|------|
|
||
| filename | string | 是 | 文件名 |
|
||
| totalChunks | number | 是 | 总分块数 |
|
||
| fileSize | number | 是 | 文件总大小(字节) |
|
||
|
||
**响应示例**
|
||
|
||
```json
|
||
{
|
||
"fileId": "a1b2c3d4e5f6g7h8",
|
||
"chunkSize": 5242880,
|
||
"message": "Upload session started"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### POST /api/files/upload/chunk
|
||
|
||
上传文件分块(分块上传第二步)。
|
||
|
||
**请求体**
|
||
|
||
Content-Type: `multipart/form-data`
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| fileId | string | 上传会话 ID |
|
||
| chunkIndex | number | 分块索引(从 0 开始) |
|
||
| chunk | file | 分块数据 |
|
||
|
||
**响应示例**
|
||
|
||
```json
|
||
{
|
||
"success": true,
|
||
"chunkIndex": 0
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### POST /api/files/upload/merge
|
||
|
||
合并文件分块(分块上传第三步)。
|
||
|
||
**请求体**
|
||
|
||
```json
|
||
{
|
||
"fileId": "a1b2c3d4e5f6g7h8",
|
||
"totalChunks": 10,
|
||
"filename": "example.zip"
|
||
}
|
||
```
|
||
|
||
**参数说明**
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
|------|------|------|------|
|
||
| fileId | string | 是 | 上传会话 ID |
|
||
| totalChunks | number | 是 | 总分块数 |
|
||
| filename | string | 是 | 最终文件名 |
|
||
|
||
**响应示例**
|
||
|
||
```json
|
||
{
|
||
"success": true,
|
||
"filename": "example.zip"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### GET /api/files/:filename
|
||
|
||
下载文件。
|
||
|
||
**路径参数**
|
||
|
||
| 参数 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| filename | string | 文件名 |
|
||
|
||
**请求头**
|
||
|
||
支持 Range 请求,可用于断点续传:
|
||
|
||
```
|
||
Range: bytes=0-1023
|
||
```
|
||
|
||
**响应示例**
|
||
|
||
成功响应(200 或 206):
|
||
- Content-Type: `application/octet-stream`
|
||
- Accept-Ranges: `bytes`
|
||
- Content-Length: 文件大小
|
||
- Content-Range: 范围(仅 206 响应)
|
||
|
||
失败响应(404):
|
||
```json
|
||
{
|
||
"error": "File not found"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### DELETE /api/files/:filename
|
||
|
||
删除文件。
|
||
|
||
**路径参数**
|
||
|
||
| 参数 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| filename | string | 文件名 |
|
||
|
||
**响应示例**
|
||
|
||
成功响应(200):
|
||
```json
|
||
{
|
||
"success": true
|
||
}
|
||
```
|
||
|
||
失败响应(404):
|
||
```json
|
||
{
|
||
"error": "File not found"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## WebSocket 消息类型
|
||
|
||
### 客户端发送的消息类型
|
||
|
||
| 消息类型 | 说明 | 数据格式 |
|
||
|----------|------|----------|
|
||
| `mouseMove` | 鼠标移动 | `{ x: number, y: number }` |
|
||
| `mouseDown` | 鼠标按下 | `{ button: 'left' \| 'right' \| 'middle' }` |
|
||
| `mouseUp` | 鼠标释放 | `{ button: 'left' \| 'right' \| 'middle' }` |
|
||
| `mouseWheel` | 鼠标滚轮 | `{ delta: number }` |
|
||
| `keyDown` | 键盘按下 | `{ key: string }` |
|
||
| `keyUp` | 键盘释放 | `{ key: string }` |
|
||
| `clipboardGet` | 获取剪贴板内容 | 无额外数据 |
|
||
| `clipboardSet` | 设置剪贴板内容 | `{ content: string }` |
|
||
|
||
### 服务端发送的消息类型
|
||
|
||
| 消息类型 | 说明 | 数据格式 |
|
||
|----------|------|----------|
|
||
| `screenInfo` | 屏幕信息 | `{ width: number, height: number }` |
|
||
| `clipboardData` | 剪贴板数据 | `{ content: string }` |
|
||
| `clipboardResult` | 剪贴板操作结果 | `{ success: boolean }` |
|
||
| `clipboardTooLarge` | 剪贴板数据过大 | `{ message: string }` |
|
||
|
||
### 消息格式示例
|
||
|
||
**客户端发送鼠标移动:**
|
||
```json
|
||
{
|
||
"type": "mouseMove",
|
||
"data": {
|
||
"x": 100,
|
||
"y": 200
|
||
}
|
||
}
|
||
```
|
||
|
||
**客户端发送键盘按键:**
|
||
```json
|
||
{
|
||
"type": "keyDown",
|
||
"data": {
|
||
"key": "ctrl"
|
||
}
|
||
}
|
||
```
|
||
|
||
**服务端发送屏幕信息:**
|
||
```json
|
||
{
|
||
"type": "screenInfo",
|
||
"data": {
|
||
"width": 1920,
|
||
"height": 1080
|
||
}
|
||
}
|
||
```
|
||
|
||
**客户端请求剪贴板:**
|
||
```json
|
||
{
|
||
"type": "clipboardGet"
|
||
}
|
||
```
|
||
|
||
**服务端返回剪贴板数据:**
|
||
```json
|
||
{
|
||
"type": "clipboardData",
|
||
"data": {
|
||
"content": "复制的文本内容"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 错误响应格式
|
||
|
||
所有接口在发生错误时返回统一的错误格式:
|
||
|
||
```json
|
||
{
|
||
"success": false,
|
||
"error": "错误描述信息"
|
||
}
|
||
```
|
||
|
||
常见 HTTP 状态码:
|
||
|
||
| 状态码 | 说明 |
|
||
|--------|------|
|
||
| 200 | 请求成功 |
|
||
| 400 | 请求参数错误 |
|
||
| 401 | 未授权(Token 无效或过期) |
|
||
| 404 | 资源不存在 |
|
||
| 500 | 服务器内部错误 |
|