diff --git a/PLUGIN_DEPENDENCY.md b/PLUGIN_DEPENDENCY.md index ec759d5..933d620 100644 --- a/PLUGIN_DEPENDENCY.md +++ b/PLUGIN_DEPENDENCY.md @@ -14,6 +14,8 @@ **示例**: - screen - 屏幕管理(唤醒锁、光标控制) - wifi - WiFi 管理(扫描、连接、热点) +- video - 视频播放(状态机、渲染) +- ble - 蓝牙服务(GATT、配网,**双架构**:既可配置 WiFi,也可独立提供网络功能) ### 依赖插件(Dependent Plugins) **定义**: 依赖其他插件的功能,需要特定插件先启动 @@ -25,7 +27,6 @@ - 通过消息机制与依赖插件通信 **示例**: -- ble - 依赖 wifi(通过 BLE 配置 WiFi) - http - 依赖 video(通过 HTTP API 控制视频播放) --- @@ -33,27 +34,36 @@ ## 依赖关系图 ``` -独立插件层: -┌─────────┐ ┌─────────┐ ┌─────────┐ -│ screen │ │ wifi │ │ video │ -└─────────┘ └─────────┘ └─────────┘ - ↑ ↑ ↑ - │ │ │ - └────────────┴────────────┘ - core +独立插件层(双架构): +┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ +│ screen │ │ wifi │ │ video │ │ ble │ +└─────────┘ └─────────┘ └─────────┘ └─────────┘ + ↑ ↑ ↑ ↑ + │ │ │ │ + │ └────────────┼────────────┘ + │ ↕ │ + │ (双架构通信) │ + │ │ + └─────────────────────────┘ + core 依赖插件层: -┌─────────┐ ┌─────────┐ -│ ble │ │ http │ -│ (依赖 │ │ (依赖 │ -│ wifi) │ │ video) │ -└─────────┘ └─────────┘ - ↑ ↑ - │ │ - └────────────┘ - core +┌─────────┐ +│ http │ +│ (依赖 │ +│ video) │ +└─────────┘ + ↑ + │ + core ``` +**双架构说明**: +- WiFi 和 BLE 是两套独立的网络架构 +- BLE 可以配置 WiFi(通过消息通信) +- BLE 也可以独立提供网络功能(不依赖 WiFi) +- 用户可以选择使用 WiFi 或 BLE 进行网络连接 + --- ## 插件依赖声明 @@ -77,23 +87,29 @@ pub trait Plugin: Send { ### 依赖声明示例 ```rust -impl Plugin for BlePlugin { - fn dependencies(&self) -> Vec<&'static str> { - vec!["wifi"] // BLE 依赖 WiFi 插件 - } -} - impl Plugin for HttpPlugin { fn dependencies(&self) -> Vec<&'static str> { vec!["video"] // HTTP 依赖 Video 插件 } } +impl Plugin for BlePlugin { + fn dependencies(&self) -> Vec<&'static str> { + vec![] // BLE 是独立插件,通过消息与 WiFi 通信 + } +} + impl Plugin for WifiPlugin { fn dependencies(&self) -> Vec<&'static str> { vec![] // WiFi 是独立插件 } } + +impl Plugin for VideoPlugin { + fn dependencies(&self) -> Vec<&'static str> { + vec![] // Video 是独立插件 + } +} ``` --- @@ -118,13 +134,13 @@ impl Plugin for WifiPlugin { ### 示例启动顺序 ``` -Phase 1: 独立插件 +Phase 1: 独立插件(并行启动) - screen.init() → screen.start() - wifi.init() → wifi.start() - video.init() → video.start() + - ble.init() → ble.start() Phase 2: 依赖插件 - - ble.init() → ble.start() (依赖 wifi) - http.init() → http.start() (依赖 video) ``` @@ -144,16 +160,30 @@ Phase 2: 依赖插件 ### 消息路由示例 ```rust -// BLE 请求 WiFi 扫描 -ble_plugin.send(Message::WifiCommand(WifiCommand::Scan)); - -// WiFi 返回扫描结果(Broadcast) -wifi_plugin.send(Message::WifiResult(result)); - -// BLE 接收到 WifiResult 消息 +// 场景1: BLE 配置 WiFi(双架构协作) +ble_plugin.send(Message::WifiCommand(WifiCommand::Connect { ssid, password })); +wifi_plugin.handle_message(Message::WifiCommand(...)); +wifi_plugin.send(Message::WifiResult(result)); // Broadcast ble_plugin.handle_message(Message::WifiResult(result)); + +// 场景2: BLE 独立提供网络功能(不依赖 WiFi) +// 用户通过 BLE 直接与设备通信,不需要 WiFi +ble_plugin.handle_gatt_request(request); +ble_plugin.send_gatt_response(response); + +// 场景3: HTTP 控制 Video(强依赖) +http_plugin.send(Message::PlayerCommand(PlayerCommand::Play)); +video_plugin.handle_message(Message::PlayerCommand(...)); +video_plugin.send(Message::PlayerStatus(status)); // Broadcast ``` +**关键区别**: +- **双架构(WiFi + BLE)**:两套独立的网络方案,可以互相配置,也可以独立工作 + - BLE 可以配置 WiFi(松耦合,通过消息) + - BLE 可以独立提供网络功能(不依赖 WiFi) + - WiFi 可以独立工作(不依赖 BLE) +- **强依赖(HTTP → Video)**:HTTP 必须在 Video 启动后才能工作 + --- ## 当前插件分类 @@ -162,15 +192,23 @@ ble_plugin.handle_message(Message::WifiResult(result)); | 插件 | 功能 | 依赖 | 状态 | |------|------|------|------| | screen | 屏幕管理 | core | ✅ 完成 | -| wifi | WiFi 管理 | core | ✅ 完成 | +| wifi | WiFi 网络 | core | ✅ 完成 | | video | 视频播放 | core | ✅ 完成 | +| ble | 蓝牙网络 | core | ✅ 完成 | + +**双架构说明**: +- **WiFi 架构**:通过 WiFi 连接网络,支持扫描、连接、热点 +- **BLE 架构**:通过蓝牙连接网络,支持 GATT 服务、配网 +- **协作模式**:BLE 可以配置 WiFi(通过消息通信) +- **独立模式**:BLE 和 WiFi 都可以独立提供网络功能 ### 依赖插件 | 插件 | 功能 | 依赖 | 状态 | |------|------|------|------| -| ble | 蓝牙配网 | core + wifi | ✅ 完成 | | http | HTTP API | core + video | ✅ 完成 | +**说明**:HTTP 必须依赖 Video,因为 HTTP API 的核心功能是控制视频播放。 + --- ## 未来插件规划 @@ -214,6 +252,12 @@ ble_plugin.handle_message(Message::WifiResult(result)); - 独立插件可以单独测试 - 依赖插件可以集成测试 +### 5. 双架构原则(新增) +- 支持多套独立架构并存(如 WiFi + BLE) +- 架构之间可以协作(通过消息) +- 架构之间可以独立工作(不强依赖) +- 用户可以选择使用哪套架构 + --- ## 实现任务 diff --git a/TEAM_CHAT.md b/TEAM_CHAT.md index 8377779..d9c221f 100644 --- a/TEAM_CHAT.md +++ b/TEAM_CHAT.md @@ -139,7 +139,8 @@ [当前] 陈逸飞(CEO) → 张婉琳(产品): 任务:梳理 Phase 1/2/3 所有插件的功能和依赖关系 - 阅读 PLUGIN_DEPENDENCY.md -- 确认当前插件分类是否合理 +- **重要更正**:BLE 是独立插件,不依赖 WiFi(通过消息通信) +- 确认当前插件分类:独立插件(screen, wifi, video, ble),依赖插件(http→video) - 规划 Phase 2/3 新插件的依赖关系 - 输出:更新 PRD.md,包含插件依赖说明 - 与架构师王思远、需求分析师李明哲协作 @@ -147,15 +148,17 @@ [当前] 陈逸飞(CEO) → 王思远(架构师): 任务:设计插件依赖机制的技术实现 - 阅读 PLUGIN_DEPENDENCY.md +- **重要更正**:BLE 是独立插件,不依赖 WiFi +- 区分强依赖(http→video)和松耦合(ble↔wifi 通过消息) - 扩展 Plugin trait,添加 dependencies() 方法 - 设计 ServiceManager 依赖检查和拓扑排序算法 -- 设计循环依赖检测机制 - 输出:技术设计文档 TECH_DESIGN_PLUGIN_DEPENDENCY.md - 与产品张婉琳、PM 刘建国协作 [当前] 陈逸飞(CEO) → 刘建国(PM): 任务:组织开发团队梳理现有插件依赖 - 阅读 PLUGIN_DEPENDENCY.md +- **重要更正**:BLE 是独立插件,dependencies() 返回空 - 让开发团队为现有 5个插件添加 dependencies() 实现 - 验证启动顺序和消息通信 - 输出:更新代码,在 TEAM_CHAT.md 记录梳理结果 diff --git a/clients/README.md b/clients/README.md new file mode 100644 index 0000000..7c8fd10 --- /dev/null +++ b/clients/README.md @@ -0,0 +1,191 @@ +# ShowenV2 客户端应用 + +本目录包含 ShowenV2 的外部控制应用,用户可以通过这些客户端远程控制 ShowenV2 设备。 + +## 客户端类型 + +### 1. 移动端应用 +- **iOS App** - `ios/` - 原生 iOS 应用(Swift/SwiftUI) +- **Android App** - `android/` - 原生 Android 应用(Kotlin/Jetpack Compose) +- **Flutter App** - `flutter/` - 跨平台移动应用(iOS + Android) + +### 2. 小程序 +- **微信小程序** - `wechat-miniapp/` - 微信生态 +- **支付宝小程序** - `alipay-miniapp/` - 支付宝生态 +- **抖音小程序** - `douyin-miniapp/` - 抖音生态 + +### 3. Web 应用 +- **Web App** - `web/` - 响应式 Web 应用(React/Vue) +- **桌面应用** - `desktop/` - Electron 桌面应用(Windows/macOS/Linux) + +### 4. 智能设备 +- **智能手表** - `watch/` - Apple Watch / Wear OS +- **智能音箱** - `voice/` - 语音控制集成 +- **智能家居** - `smarthome/` - HomeKit / 米家 / 小度 + +## 通信协议 + +所有客户端通过以下方式与 ShowenV2 设备通信: + +### HTTP API +- **地址**: `http://:8080/api/` +- **协议**: RESTful API +- **格式**: JSON +- **认证**: Token / API Key + +### WebSocket +- **地址**: `ws://:8080/ws` +- **用途**: 实时状态推送 +- **格式**: JSON + +### BLE (蓝牙) +- **协议**: GATT +- **用途**: 近场控制、配网 +- **服务**: 自定义 GATT Service + +## 核心功能 + +### 设备管理 +- 设备发现和配对 +- WiFi 配置 +- 设备状态监控 + +### 播放控制 +- 播放/暂停/停止 +- 上一个/下一个 +- 跳转到指定视频 +- 音量控制 + +### 状态机控制 +- 触发状态切换 +- 场景切换 +- 查看当前状态 + +### 配置管理 +- 查看配置 +- 修改配置 +- 导入/导出配置 + +### 内容管理 +- 浏览视频列表 +- 上传新视频 +- 删除视频 +- 视频预览 + +## 开发计划 + +### Phase 1(当前) +- [ ] Web App - 基础控制界面 +- [ ] HTTP API 文档 + +### Phase 2(3个月) +- [ ] Flutter App - 跨平台移动应用 +- [ ] 微信小程序 - 快速访问 +- [ ] WebSocket 实时推送 + +### Phase 3(6个月) +- [ ] iOS 原生 App +- [ ] Android 原生 App +- [ ] 智能音箱集成 + +### Phase 4(12个月) +- [ ] 智能手表应用 +- [ ] 智能家居集成 +- [ ] 桌面应用 + +## 技术栈 + +### 移动端 +- **iOS**: Swift 5.9+, SwiftUI, Combine +- **Android**: Kotlin 1.9+, Jetpack Compose, Coroutines +- **Flutter**: Flutter 3.x, Dart 3.x + +### Web 端 +- **前端**: React 18+ / Vue 3+, TypeScript +- **状态管理**: Redux / Pinia +- **UI 框架**: Ant Design / Element Plus +- **构建工具**: Vite / Webpack + +### 小程序 +- **微信**: 原生小程序框架 / uni-app +- **支付宝**: 原生小程序框架 +- **抖音**: 原生小程序框架 + +### 桌面端 +- **Electron**: Electron 28+, React/Vue +- **Tauri**: Tauri 1.x, Rust + Web + +## 目录结构 + +``` +clients/ +├── README.md # 本文件 +├── shared/ # 共享代码 +│ ├── api/ # API 客户端库 +│ ├── models/ # 数据模型 +│ └── utils/ # 工具函数 +├── web/ # Web 应用 +│ ├── package.json +│ ├── src/ +│ └── public/ +├── flutter/ # Flutter 应用 +│ ├── pubspec.yaml +│ ├── lib/ +│ └── assets/ +├── ios/ # iOS 应用 +│ ├── ShowenV2.xcodeproj +│ └── ShowenV2/ +├── android/ # Android 应用 +│ ├── build.gradle +│ └── app/ +├── wechat-miniapp/ # 微信小程序 +│ ├── app.json +│ └── pages/ +├── desktop/ # 桌面应用 +│ ├── package.json +│ └── src/ +└── docs/ # 客户端开发文档 + ├── API.md # API 文档 + ├── DESIGN.md # 设计规范 + └── DEVELOPMENT.md # 开发指南 +``` + +## 快速开始 + +### Web App +```bash +cd clients/web +npm install +npm run dev +``` + +### Flutter App +```bash +cd clients/flutter +flutter pub get +flutter run +``` + +### 微信小程序 +```bash +cd clients/wechat-miniapp +# 使用微信开发者工具打开 +``` + +## API 文档 + +详见 `docs/API.md` + +## 设计规范 + +详见 `docs/DESIGN.md` + +## 贡献指南 + +欢迎贡献新的客户端实现!请参考 `docs/DEVELOPMENT.md` + +--- + +**文档版本**: v1.0 +**最后更新**: 2026-03-12 +**负责人**: 赵雨薇 (前端 & 屏幕工程师) diff --git a/clients/docs/API.md b/clients/docs/API.md new file mode 100644 index 0000000..70c4dc0 --- /dev/null +++ b/clients/docs/API.md @@ -0,0 +1,379 @@ +# ShowenV2 HTTP API 文档 + +## 基础信息 + +- **Base URL**: `http://: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://: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 团队 diff --git a/clients/docs/DESIGN.md b/clients/docs/DESIGN.md new file mode 100644 index 0000000..71f499d --- /dev/null +++ b/clients/docs/DESIGN.md @@ -0,0 +1,305 @@ +# ShowenV2 客户端设计规范 + +## 设计理念 + +### 核心价值 +- **简洁直观**: 界面简洁,操作直观,用户一看就懂 +- **响应迅速**: 操作反馈及时,状态更新实时 +- **一致体验**: 跨平台体验一致,学习成本低 +- **科技感**: 体现数字生命窗口的科技属性 + +### 设计原则 +1. **移动优先**: 优先考虑移动端体验 +2. **触控友好**: 按钮大小适合手指点击 +3. **暗色主题**: 默认暗色,适合夜间使用 +4. **动效流畅**: 过渡动画自然流畅 + +--- + +## 视觉设计 + +### 配色方案 + +#### 主色调 +- **主色**: `#6366F1` (Indigo 500) - 科技感蓝紫色 +- **辅助色**: `#8B5CF6` (Violet 500) - 渐变辅助 +- **强调色**: `#EC4899` (Pink 500) - 重要操作 + +#### 功能色 +- **成功**: `#10B981` (Green 500) +- **警告**: `#F59E0B` (Amber 500) +- **错误**: `#EF4444` (Red 500) +- **信息**: `#3B82F6` (Blue 500) + +#### 中性色(暗色主题) +- **背景**: `#0F172A` (Slate 900) +- **卡片**: `#1E293B` (Slate 800) +- **边框**: `#334155` (Slate 700) +- **文字主**: `#F1F5F9` (Slate 100) +- **文字次**: `#94A3B8` (Slate 400) + +### 字体 + +#### 中文 +- **主字体**: 苹方 / 思源黑体 / Noto Sans SC +- **等宽**: Fira Code / JetBrains Mono + +#### 英文 +- **主字体**: Inter / SF Pro / Roboto +- **等宽**: Fira Code / JetBrains Mono + +#### 字号 +- **标题 H1**: 32px / 2rem +- **标题 H2**: 24px / 1.5rem +- **标题 H3**: 20px / 1.25rem +- **正文**: 16px / 1rem +- **辅助**: 14px / 0.875rem +- **说明**: 12px / 0.75rem + +### 圆角 +- **小**: 4px +- **中**: 8px +- **大**: 16px +- **圆形**: 50% + +### 阴影 +- **浅**: `0 1px 3px rgba(0, 0, 0, 0.12)` +- **中**: `0 4px 6px rgba(0, 0, 0, 0.16)` +- **深**: `0 10px 15px rgba(0, 0, 0, 0.20)` + +### 间距 +- **xs**: 4px +- **sm**: 8px +- **md**: 16px +- **lg**: 24px +- **xl**: 32px +- **2xl**: 48px + +--- + +## 组件设计 + +### 按钮 + +#### 主按钮 +``` +背景: 主色渐变 +文字: 白色 +圆角: 8px +高度: 48px (移动端) / 40px (桌面端) +``` + +#### 次按钮 +``` +背景: 透明 +边框: 1px 主色 +文字: 主色 +圆角: 8px +``` + +#### 图标按钮 +``` +大小: 48x48px (移动端) / 40x40px (桌面端) +圆角: 50% +背景: 半透明 +``` + +### 卡片 +``` +背景: 卡片色 +圆角: 16px +内边距: 16px +阴影: 中 +``` + +### 输入框 +``` +背景: 背景色 +边框: 1px 边框色 +圆角: 8px +高度: 48px (移动端) / 40px (桌面端) +内边距: 12px +``` + +### 开关 +``` +宽度: 48px +高度: 28px +圆角: 14px +动画: 0.2s ease +``` + +### 滑块 +``` +轨道高度: 4px +滑块大小: 20x20px +颜色: 主色 +``` + +--- + +## 界面布局 + +### 移动端 + +#### 底部导航 +``` +位置: 固定底部 +高度: 64px +项目: 3-5个 +图标: 24x24px +文字: 12px +``` + +#### 顶部栏 +``` +高度: 56px +标题: 居中 / 居左 +操作: 右侧图标按钮 +``` + +#### 内容区 +``` +内边距: 16px +卡片间距: 16px +``` + +### 桌面端 + +#### 侧边栏 +``` +宽度: 240px +位置: 固定左侧 +可折叠 +``` + +#### 主内容区 +``` +最大宽度: 1200px +居中显示 +内边距: 24px +``` + +--- + +## 交互设计 + +### 点击反馈 +- **按钮**: 按下缩小 0.95,松开恢复 +- **卡片**: 悬停提升阴影 +- **列表项**: 悬停背景变亮 + +### 加载状态 +- **全局加载**: 顶部进度条 +- **局部加载**: 骨架屏 / 加载动画 +- **按钮加载**: 禁用 + 加载图标 + +### 错误提示 +- **Toast**: 3秒自动消失 +- **Modal**: 需要用户确认 +- **Inline**: 表单验证错误 + +### 动画时长 +- **快速**: 0.15s - 小元素出现/消失 +- **标准**: 0.3s - 页面切换、弹窗 +- **慢速**: 0.5s - 大型动画 + +--- + +## 页面设计 + +### 首页 +- 设备状态卡片 +- 快捷操作按钮 +- 当前播放信息 + +### 播放控制 +- 大型播放/暂停按钮 +- 进度条 +- 上一个/下一个 +- 播放列表 + +### 状态机 +- 当前状态显示 +- 触发器列表 +- 场景切换 + +### 设置 +- WiFi 配置 +- 设备信息 +- 关于 + +--- + +## 图标设计 + +### 图标库 +推荐使用: +- **Heroicons** - 简洁现代 +- **Lucide** - 一致性好 +- **Material Icons** - 丰富全面 + +### 图标规范 +- **大小**: 24x24px (默认) +- **线宽**: 2px +- **风格**: 线性 / 填充 +- **颜色**: 继承文字颜色 + +--- + +## 响应式设计 + +### 断点 +- **xs**: < 640px (手机) +- **sm**: 640px - 768px (大屏手机) +- **md**: 768px - 1024px (平板) +- **lg**: 1024px - 1280px (小屏电脑) +- **xl**: > 1280px (大屏电脑) + +### 适配策略 +- **移动端**: 单列布局,底部导航 +- **平板**: 双列布局,侧边栏可选 +- **桌面**: 多列布局,固定侧边栏 + +--- + +## 无障碍设计 + +### 对比度 +- **正常文字**: 至少 4.5:1 +- **大文字**: 至少 3:1 +- **图标**: 至少 3:1 + +### 触控目标 +- **最小尺寸**: 44x44px (iOS) / 48x48px (Android) +- **间距**: 至少 8px + +### 键盘导航 +- 支持 Tab 键切换 +- 支持 Enter/Space 激活 +- 焦点状态明显 + +### 屏幕阅读器 +- 图片添加 alt 文本 +- 按钮添加 aria-label +- 状态变化通知 + +--- + +## 设计资源 + +### Figma 文件 +- 组件库 +- 页面模板 +- 图标集 + +### 设计规范 +- 颜色变量 +- 字体样式 +- 组件样式 + +--- + +**文档版本**: v1.0 +**最后更新**: 2026-03-12 +**设计负责人**: 赵雨薇 (前端 & 屏幕工程师)