You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

556 lines
9.9 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# API 文档
本文档详细介绍 Flash Send 的 Tauri 命令 API 和事件系统。
## Tauri 命令
所有命令通过 `@tauri-apps/api/core``invoke` 函数调用。
### 设备发现
#### start_discovery
启动设备发现服务,开始广播本机信息并监听其他设备。
```typescript
invoke('start_discovery')
```
**返回**: `Promise<void>`
---
#### stop_discovery
停止设备发现服务。
```typescript
invoke('stop_discovery')
```
**返回**: `Promise<void>`
---
#### get_online_devices
获取当前在线的设备列表。
```typescript
invoke<DeviceInfo[]>('get_online_devices')
```
**返回**: `Promise<DeviceInfo[]>`
```typescript
interface DeviceInfo {
deviceId: string // 设备唯一标识
deviceName: string // 设备名称
ip: string // IP 地址
wsPort: number // WebSocket 端口
httpPort: number // HTTP 端口
lastSeen: number // 最后在线时间戳
}
```
---
#### get_local_device
获取本机设备信息。
```typescript
invoke<DeviceInfo>('get_local_device')
```
**返回**: `Promise<DeviceInfo>`
---
### 聊天通信
#### start_ws_server
启动 WebSocket 服务端,接收其他设备的连接。
```typescript
invoke('start_ws_server')
```
**返回**: `Promise<void>`
---
#### connect_to_device
连接到指定设备的 WebSocket 服务。
```typescript
invoke('connect_to_device', { deviceId: string })
```
**参数**:
| 参数 | 类型 | 说明 |
|------|------|------|
| deviceId | string | 目标设备 ID |
**返回**: `Promise<void>`
---
#### send_chat_message
发送聊天消息。
```typescript
invoke<ChatMessage>('send_chat_message', {
deviceId: string,
content: string,
messageType?: string
})
```
**参数**:
| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| deviceId | string | - | 目标设备 ID |
| content | string | - | 消息内容 |
| messageType | string | 'text' | 消息类型text/image/file |
**返回**: `Promise<ChatMessage>`
```typescript
interface ChatMessage {
id: string
fromDevice: string
toDevice: string
content: string
messageType: 'text' | 'image' | 'file' | 'system'
timestamp: number
isRead: boolean
}
```
---
#### get_chat_history
获取与指定设备的聊天历史。
```typescript
invoke<ChatMessage[]>('get_chat_history', {
deviceId: string,
limit?: number,
offset?: number
})
```
**参数**:
| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| deviceId | string | - | 目标设备 ID |
| limit | number | 50 | 返回条数限制 |
| offset | number | 0 | 偏移量 |
**返回**: `Promise<ChatMessage[]>`
---
#### delete_chat_history
删除与指定设备的聊天历史。
```typescript
invoke('delete_chat_history', { deviceId: string })
```
**参数**:
| 参数 | 类型 | 说明 |
|------|------|------|
| deviceId | string | 目标设备 ID |
**返回**: `Promise<void>`
---
### 文件传输
#### start_http_server
启动 HTTPS 文件服务,接收文件上传。
```typescript
invoke('start_http_server')
```
**返回**: `Promise<void>`
---
#### select_file
打开文件选择对话框。
```typescript
invoke<FileMetadata | null>('select_file')
```
**返回**: `Promise<FileMetadata | null>`
```typescript
interface FileMetadata {
name: string // 文件名
path: string // 文件完整路径
size: number // 文件大小(字节)
mimeType?: string // MIME 类型
}
```
---
#### send_file
发送文件到指定设备。
```typescript
invoke<FileTransfer>('send_file', {
deviceId: string,
fileId: string,
filePath: string
})
```
**参数**:
| 参数 | 类型 | 说明 |
|------|------|------|
| deviceId | string | 目标设备 ID |
| fileId | string | 文件传输 IDUUID |
| filePath | string | 本地文件路径 |
**返回**: `Promise<FileTransfer>`
```typescript
interface FileTransfer {
fileId: string
name: string
size: number
progress: number // 0.0 - 1.0
status: TransferStatus
mimeType?: string
fromDevice: string
toDevice: string
localPath?: string
createdAt: number
completedAt?: number
transferredBytes: number
}
type TransferStatus = 'pending' | 'transferring' | 'completed' | 'failed' | 'cancelled'
```
---
#### cancel_transfer
取消文件传输。
```typescript
invoke('cancel_transfer', { fileId: string })
```
**参数**:
| 参数 | 类型 | 说明 |
|------|------|------|
| fileId | string | 传输 ID |
**返回**: `Promise<void>`
---
#### get_transfer_history
获取与指定设备的文件传输历史。
```typescript
invoke<FileTransfer[]>('get_transfer_history', {
deviceId: string,
limit?: number
})
```
**参数**:
| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| deviceId | string | - | 目标设备 ID |
| limit | number | 50 | 返回条数限制 |
**返回**: `Promise<FileTransfer[]>`
---
#### open_file_location
在系统文件管理器中打开文件所在位置。
```typescript
invoke('open_file_location', { path: string })
```
**参数**:
| 参数 | 类型 | 说明 |
|------|------|------|
| path | string | 文件路径 |
**返回**: `Promise<void>`
**平台行为**:
- **Windows**: `explorer /select, <path>`
- **macOS**: `open -R <path>`
- **Linux**: `xdg-open <dir>`
---
### 配置管理
#### get_app_config
获取应用配置。
```typescript
invoke<AppConfig>('get_app_config')
```
**返回**: `Promise<AppConfig>`
```typescript
interface AppConfig {
deviceId: string // 本机设备 ID
deviceName: string // 设备名称
downloadDir: string // 下载目录
wsPort: number // WebSocket 端口
httpPort: number // HTTP 端口
}
```
---
#### update_device_name
更新设备名称。
```typescript
invoke('update_device_name', { name: string })
```
**参数**:
| 参数 | 类型 | 说明 |
|------|------|------|
| name | string | 新的设备名称 |
**返回**: `Promise<void>`
---
#### update_download_dir
更新文件下载目录。
```typescript
invoke('update_download_dir', { path: string })
```
**参数**:
| 参数 | 类型 | 说明 |
|------|------|------|
| path | string | 新的下载目录路径 |
**返回**: `Promise<void>`
---
## 事件系统
通过 `@tauri-apps/api/event``listen` 函数监听后端事件。
### device:found
发现新设备时触发。
```typescript
import { listen } from '@tauri-apps/api/event'
listen<DeviceInfo>('device:found', (event) => {
console.log('发现设备:', event.payload)
})
```
**Payload**: `DeviceInfo`
---
### device:lost
设备离线时触发。
```typescript
listen<string>('device:lost', (event) => {
console.log('设备离线:', event.payload) // device_id
})
```
**Payload**: `string` (device_id)
---
### chat:message
收到聊天消息时触发。
```typescript
listen<ChatMessage>('chat:message', (event) => {
console.log('收到消息:', event.payload)
})
```
**Payload**: `ChatMessage`
---
### file:progress
文件传输进度更新时触发。
```typescript
listen<TransferProgressEvent>('file:progress', (event) => {
console.log('传输进度:', event.payload)
})
```
**Payload**: `TransferProgressEvent`
```typescript
interface TransferProgressEvent {
fileId: string // 传输 ID
progress: number // 进度 0.0 - 1.0
transferredBytes: number // 已传输字节数
totalBytes: number // 总字节数
status: TransferStatus // 传输状态
fileName?: string // 文件名(接收方)
localPath?: string // 本地路径(接收方)
}
```
---
## 错误处理
所有命令在出错时会抛出 `CommandError`
```typescript
interface CommandError {
code: string // 错误代码
message: string // 错误信息
}
```
**常见错误代码**:
| 代码 | 说明 |
|------|------|
| `DB_ERROR` | 数据库操作错误 |
| `IO_ERROR` | 文件 IO 错误 |
| `WS_ERROR` | WebSocket 错误 |
| `DEVICE_NOT_FOUND` | 设备不存在 |
| `NOT_CONNECTED` | 未建立连接 |
| `TRANSFER_ERROR` | 传输错误 |
**使用示例**
```typescript
try {
await invoke('send_chat_message', { deviceId, content })
} catch (error) {
const err = error as CommandError
if (err.code === 'NOT_CONNECTED') {
// 尝试重新连接
await invoke('connect_to_device', { deviceId })
}
}
```
---
## 完整示例
### 设备发现与聊天
```typescript
import { invoke } from '@tauri-apps/api/core'
import { listen } from '@tauri-apps/api/event'
// 1. 监听设备发现事件
const unlistenDevice = await listen<DeviceInfo>('device:found', (event) => {
console.log('发现设备:', event.payload.deviceName)
})
// 2. 监听消息事件
const unlistenMessage = await listen<ChatMessage>('chat:message', (event) => {
console.log('收到消息:', event.payload.content)
})
// 3. 启动服务
await invoke('start_ws_server')
await invoke('start_discovery')
// 4. 获取在线设备
const devices = await invoke<DeviceInfo[]>('get_online_devices')
// 5. 连接设备并发送消息
if (devices.length > 0) {
const device = devices[0]
await invoke('connect_to_device', { deviceId: device.deviceId })
await invoke('send_chat_message', {
deviceId: device.deviceId,
content: 'Hello!'
})
}
// 清理
unlistenDevice()
unlistenMessage()
await invoke('stop_discovery')
```
### 文件传输
```typescript
import { invoke } from '@tauri-apps/api/core'
import { listen } from '@tauri-apps/api/event'
// 1. 监听传输进度
const unlisten = await listen<TransferProgressEvent>('file:progress', (event) => {
const { fileId, progress, status } = event.payload
console.log(`${fileId}: ${(progress * 100).toFixed(1)}% - ${status}`)
})
// 2. 启动文件服务
await invoke('start_http_server')
// 3. 选择文件
const file = await invoke<FileMetadata | null>('select_file')
if (!file) return
// 4. 发送文件
const fileId = crypto.randomUUID()
const transfer = await invoke<FileTransfer>('send_file', {
deviceId: targetDeviceId,
fileId,
filePath: file.path
})
console.log('开始传输:', transfer.name)
// 清理
unlisten()
```