feat: 新增客户端应用目录结构

新增 clients/ 目录:
- 外部控制应用的统一目录
- 支持多种客户端类型:
  - 移动端:iOS, Android, Flutter
  - 小程序:微信、支付宝、抖音
  - Web:响应式 Web 应用、桌面应用
  - 智能设备:手表、音箱、智能家居

目录结构:
- shared/ - 共享代码(API 客户端、数据模型)
- web/ - Web 应用
- flutter/ - Flutter 跨平台应用
- ios/ - iOS 原生应用
- android/ - Android 原生应用
- wechat-miniapp/ - 微信小程序
- desktop/ - Electron 桌面应用
- docs/ - 客户端开发文档

文档:
- clients/README.md - 客户端总览和开发计划
- clients/docs/API.md - HTTP API 完整文档
- clients/docs/DESIGN.md - 设计规范和组件库

更新 PLUGIN_DEPENDENCY.md:
- 明确 WiFi + BLE 双架构模型
- BLE 既可配置 WiFi,也可独立提供网络功能
- 新增双架构设计原则
This commit is contained in:
showen
2026-03-12 06:46:05 +08:00
parent 7aa42cc9af
commit fa692cd873
5 changed files with 959 additions and 37 deletions

379
clients/docs/API.md Normal file
View File

@@ -0,0 +1,379 @@
# ShowenV2 HTTP API 文档
## 基础信息
- **Base URL**: `http://<device-ip>:8080/api`
- **协议**: HTTP/1.1
- **格式**: JSON
- **编码**: UTF-8
## 认证
当前版本暂不需要认证(局域网内使用)。未来版本将支持 Token 认证。
---
## 播放控制 API
### 播放
```http
POST /api/play
```
**响应**:
```json
{
"ok": true,
"action": "play"
}
```
### 暂停
```http
POST /api/pause
```
**响应**:
```json
{
"ok": true,
"action": "pause"
}
```
### 停止
```http
POST /api/stop
```
**响应**:
```json
{
"ok": true,
"action": "stop"
}
```
### 下一个
```http
POST /api/next
```
**响应**:
```json
{
"ok": true,
"action": "next"
}
```
### 上一个
```http
POST /api/previous
```
**响应**:
```json
{
"ok": true,
"action": "previous"
}
```
### 跳转到指定视频
```http
POST /api/goto/:index
```
**参数**:
- `index` (path): 视频索引(从 0 开始)
**响应**:
```json
{
"ok": true,
"action": "goto",
"index": 0
}
```
---
## 状态机控制 API
### 触发状态切换
```http
POST /api/trigger/:name
```
**参数**:
- `name` (path): 触发器名称(如 "happy", "sad", "angry"
**响应**:
```json
{
"ok": true,
"action": "trigger",
"name": "happy"
}
```
### 切换场景
```http
POST /api/scene/:index
```
**参数**:
- `index` (path): 场景索引(从 0 开始)
**响应**:
```json
{
"ok": true,
"action": "scene",
"index": 0
}
```
---
## 状态查询 API
### 获取播放状态
```http
GET /api/status
```
**响应**:
```json
{
"ok": true,
"status": {
"playing": true,
"current_index": 0,
"current_state": "idle",
"current_scene": 0,
"playlist_length": 10
}
}
```
### 获取配置
```http
GET /api/config
```
**响应**:
```json
{
"ok": true,
"config": {
"device_name": "ShowenV2",
"render_width": 1920,
"render_height": 1080,
"scenes": [...]
}
}
```
---
## WiFi 管理 API
### 扫描 WiFi
```http
POST /api/wifi/scan
```
**响应**:
```json
{
"ok": true,
"networks": [
{
"ssid": "MyWiFi",
"signal": -50,
"security": "WPA2"
}
]
}
```
### 连接 WiFi
```http
POST /api/wifi/connect
Content-Type: application/json
{
"ssid": "MyWiFi",
"password": "password123"
}
```
**响应**:
```json
{
"ok": true,
"action": "connect",
"ssid": "MyWiFi"
}
```
### 断开 WiFi
```http
POST /api/wifi/disconnect
```
**响应**:
```json
{
"ok": true,
"action": "disconnect"
}
```
### 开启热点
```http
POST /api/wifi/hotspot/start
```
**响应**:
```json
{
"ok": true,
"action": "hotspot_start"
}
```
### 关闭热点
```http
POST /api/wifi/hotspot/stop
```
**响应**:
```json
{
"ok": true,
"action": "hotspot_stop"
}
```
---
## Web UI
### 访问 Web 控制界面
```http
GET /
```
返回 HTML 控制界面。
---
## WebSocket API
### 连接
```
ws://<device-ip>:8080/ws
```
### 消息格式
```json
{
"type": "status_update",
"data": {
"playing": true,
"current_index": 0
}
}
```
### 消息类型
- `status_update`: 状态更新
- `config_update`: 配置更新
- `error`: 错误消息
---
## 错误响应
所有 API 在出错时返回:
```json
{
"ok": false,
"error": "错误描述"
}
```
**HTTP 状态码**:
- `200 OK`: 成功
- `400 Bad Request`: 请求参数错误
- `404 Not Found`: 资源不存在
- `500 Internal Server Error`: 服务器错误
---
## 示例代码
### JavaScript (Fetch API)
```javascript
// 播放
fetch('http://192.168.1.100:8080/api/play', {
method: 'POST'
})
.then(res => res.json())
.then(data => console.log(data));
// 获取状态
fetch('http://192.168.1.100:8080/api/status')
.then(res => res.json())
.then(data => console.log(data.status));
```
### Python (requests)
```python
import requests
# 播放
response = requests.post('http://192.168.1.100:8080/api/play')
print(response.json())
# 获取状态
response = requests.get('http://192.168.1.100:8080/api/status')
print(response.json()['status'])
```
### Swift (URLSession)
```swift
//
let url = URL(string: "http://192.168.1.100:8080/api/play")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
URLSession.shared.dataTask(with: request) { data, response, error in
//
}.resume()
```
### Kotlin (OkHttp)
```kotlin
// 播放
val client = OkHttpClient()
val request = Request.Builder()
.url("http://192.168.1.100:8080/api/play")
.post(RequestBody.create(null, ByteArray(0)))
.build()
client.newCall(request).enqueue(object : Callback {
override fun onResponse(call: Call, response: Response) {
// 处理响应
}
})
```
---
**文档版本**: v1.0
**最后更新**: 2026-03-12
**维护者**: ShowenV2 团队