- 新增 Flutter 跨平台客户端项目 (clients/flutter/)
- 29 个 Dart 文件: 服务层/状态管理/5个页面/BLE配网
- BLE 蓝牙配网: 扫描设备、写入WiFi凭据、配网状态监听
- HTTP API 客户端: 覆盖全部端点 (播放/场景/WiFi/视频/配置/文件/插件)
- WebSocket 实时通信: 事件流 + 自动重连
- 暗色主题 Material 3 UI, 中文界面
- Android 配置: minSdkVersion 21, BLE/网络权限
- PRD 产品需求文档 + 开发任务看板
- Web UI 添加 APK 下载入口 (routes.rs)
- 下载弹窗 + 二维码 + /download/{filename} 静态文件路由
- BLE 插件增加自动重连循环 (ble/mod.rs)
- BLE 默认设备名修正为 'Showen' (config.rs)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
412 lines
12 KiB
Markdown
412 lines
12 KiB
Markdown
# Showen Flutter App PRD
|
||
|
||
## 1. 文档信息
|
||
|
||
- 产品名称:Showen Flutter App
|
||
- 版本:v0.1
|
||
- 阶段:Phase 2 立项准备
|
||
- 负责人:刘建国(PM)
|
||
- 目标平台:iOS / Android
|
||
- 技术栈:Flutter 3.x + Dart 3.x
|
||
|
||
## 2. 产品背景
|
||
|
||
ShowenV2 当前已具备 HTTP API、WebSocket 推送与 BLE GATT 配网能力,能够支撑移动端从首次接入到日常远程控制的完整链路。现阶段需要为 Flutter 客户端形成统一产品定义与开发拆解,降低多端接入成本,并为 iOS/Android 双平台提供同一套体验与交付节奏。
|
||
|
||
Flutter App 定位为 Showen 设备的移动控制器,重点解决三类问题:
|
||
|
||
1. 首次接入困难:用户不知道设备 IP,必须通过 BLE 近场配网完成入网。
|
||
2. 日常控制分散:播放控制、状态机触发、场景切换、WiFi/视频/配置管理需要统一入口。
|
||
3. 状态反馈滞后:必须通过 WebSocket 获得设备状态、状态机、WiFi 状态的实时变化。
|
||
|
||
## 3. 产品目标
|
||
|
||
### 3.1 业务目标
|
||
|
||
- 建立移动端首次接入闭环:BLE 发现 -> WiFi 配网 -> 获取设备 IP -> HTTP/WebSocket 连接。
|
||
- 建立移动端高频控制闭环:首页快捷控制 + 播放控制 + 状态机触发。
|
||
- 建立移动端设备管理闭环:设备发现、连接、切换、网络设置、配置与视频管理。
|
||
|
||
### 3.2 用户目标
|
||
|
||
- 3 分钟内完成新设备首次配网。
|
||
- 1 次点击完成播放/暂停等高频控制。
|
||
- 2 秒内看到设备状态变化反馈。
|
||
|
||
### 3.3 成功指标
|
||
|
||
- 首次配网成功率 >= 85%。
|
||
- 核心控制接口成功率 >= 99%(局域网正常环境)。
|
||
- WebSocket 断线自动重连成功率 >= 95%。
|
||
- 首页高频操作平均响应感知时间 <= 800ms。
|
||
|
||
## 4. 用户与场景
|
||
|
||
### 4.1 目标用户
|
||
|
||
- 设备主人:日常使用 Showen 设备的普通用户。
|
||
- 调试人员:需要快速完成设备联网、视频切换、配置更新的部署人员。
|
||
- 高级用户:需要手动输入 IP、管理视频和配置的深度用户。
|
||
|
||
### 4.2 核心使用场景
|
||
|
||
1. 新设备首次开机,用户通过 BLE 扫描到名为 `Showen` 的设备并完成 WiFi 配网。
|
||
2. 用户在局域网内通过首页直接查看设备状态并做播放控制。
|
||
3. 用户进入状态机页触发 `trigger` 或切换 `scene`,立即看到状态变化。
|
||
4. 用户进入网络设置页查看 WiFi 状态、扫描网络、切换网络,必要时使用 BLE 近场控制。
|
||
5. 用户进入设置页查看/更新配置,管理视频资源。
|
||
|
||
## 5. 产品范围
|
||
|
||
### 5.1 本期范围(MVP)
|
||
|
||
- BLE 蓝牙配网
|
||
- 设备发现(BLE + 手动输入 IP)
|
||
- HTTP 远程控制
|
||
- WebSocket 实时状态订阅
|
||
- 首页、播放控制页、状态机页、网络设置页、设置页
|
||
- WiFi 管理、视频管理、配置管理
|
||
- 多设备本地记录与快速切换
|
||
|
||
### 5.2 暂不纳入本期
|
||
|
||
- 用户账号体系与云端同步
|
||
- 设备远程广域网访问
|
||
- 推送通知
|
||
- 视频预览/在线播放
|
||
- 固件升级 OTA
|
||
- 平板/桌面专属布局优化
|
||
|
||
## 6. 依赖与约束
|
||
|
||
### 6.1 服务端依赖
|
||
|
||
- HTTP Base URL:`http://<device-ip>:8080/api`
|
||
- WebSocket:`ws://<device-ip>:8080/ws`
|
||
- 当前局域网环境默认无认证
|
||
- 依赖服务端已支持:播放、场景、触发器、配置、视频、WiFi、BLE 状态相关接口
|
||
|
||
### 6.2 BLE GATT 协议
|
||
|
||
- Service UUID:`12345678-1234-5678-1234-56789abcdef0`
|
||
- SSID 特征:`12345678-1234-5678-1234-56789abcdef1`(write)
|
||
- Password 特征:`12345678-1234-5678-1234-56789abcdef2`(write)
|
||
- Command 特征:`12345678-1234-5678-1234-56789abcdef3`(write)
|
||
- Status 特征:`12345678-1234-5678-1234-56789abcdef4`(read/notify)
|
||
|
||
Command 写入格式:
|
||
|
||
- 配网:`connect:ssid:password`
|
||
- 控制:`play` / `pause` / `next` / `prev`
|
||
|
||
Status JSON:
|
||
|
||
```json
|
||
{
|
||
"ok": true,
|
||
"action": "connect",
|
||
"state": "connected",
|
||
"error": null
|
||
}
|
||
```
|
||
|
||
## 7. 信息架构
|
||
|
||
底部导航建议 5 个 Tab:
|
||
|
||
1. 首页
|
||
2. 播放控制
|
||
3. 状态机
|
||
4. 网络设置
|
||
5. 设置
|
||
|
||
全局能力:
|
||
|
||
- 顶部当前设备切换入口
|
||
- 全局连接状态提示
|
||
- 全局 Toast / 错误弹层
|
||
- 全局 WebSocket 重连状态条
|
||
|
||
## 8. 功能需求
|
||
|
||
### 8.1 设备发现与连接
|
||
|
||
#### 目标
|
||
|
||
让用户能够发现附近设备、手动接入已有设备,并在 App 内维护最近连接设备列表。
|
||
|
||
#### 功能点
|
||
|
||
- BLE 扫描发现广播名为 `Showen` 的设备。
|
||
- 支持显示扫描中、扫描失败、未发现设备状态。
|
||
- 支持手动输入设备 IP 直接连接。
|
||
- 支持保存最近使用设备(名称、IP、上次连接时间、连接方式)。
|
||
- 支持切换当前控制设备。
|
||
|
||
#### 验收标准
|
||
|
||
- BLE 扫描 10 秒内可展示发现结果。
|
||
- 手动输入 IP 成功后可自动拉取 `/api/status` 验证设备可达。
|
||
- 最近设备列表支持至少 10 条本地缓存。
|
||
|
||
### 8.2 BLE 蓝牙配网
|
||
|
||
#### 目标
|
||
|
||
在设备未联网或未知 IP 时,让用户通过手机蓝牙完成 WiFi 入网。
|
||
|
||
#### 功能点
|
||
|
||
- 扫描并连接 BLE 设备。
|
||
- 展示手机权限状态(蓝牙、定位)。
|
||
- 输入或选择 WiFi SSID、输入密码。
|
||
- 按协议写入 SSID/Password/Command 特征值。
|
||
- 监听 Status 特征值读取或 notify,显示配网中/成功/失败。
|
||
- 配网成功后提示用户切换到 WiFi 控制模式,并记录返回状态。
|
||
|
||
#### 交互流程
|
||
|
||
1. 用户进入网络设置页 -> 点击 BLE 配网。
|
||
2. App 扫描附近 `Showen` 设备并展示列表。
|
||
3. 用户选择设备,输入 WiFi SSID/密码。
|
||
4. App 写入 GATT 特征并发送 `connect:ssid:password`。
|
||
5. App 监听 `Status` 返回:
|
||
- 成功:提示联网成功,并引导发现/填写设备 IP。
|
||
- 失败:显示错误原因并支持重试。
|
||
|
||
#### 验收标准
|
||
|
||
- BLE 配网流程在弱网/失败情况下有明确错误提示。
|
||
- 配网状态页能展示至少 4 类状态:连接中、发送中、成功、失败。
|
||
- 重试不需要重新进入页面。
|
||
|
||
### 8.3 首页
|
||
|
||
#### 目标
|
||
|
||
作为高频控制入口,快速查看设备状态并执行最常用操作。
|
||
|
||
#### 功能点
|
||
|
||
- 展示设备在线状态、当前 IP、WiFi 状态、WebSocket 状态。
|
||
- 展示播放状态:运行中、暂停中、当前视频、当前索引。
|
||
- 提供快捷按钮:播放、暂停、上一首、下一首。
|
||
- 展示最近一次状态机状态。
|
||
- 展示关键告警:未连接、WiFi 异常、WebSocket 断开。
|
||
|
||
#### 相关接口
|
||
|
||
- `GET /api/status`
|
||
- `GET /api/wifi/status`
|
||
- WebSocket:`status_update`、`state_update`、`wifi_update`
|
||
|
||
### 8.4 播放控制页
|
||
|
||
#### 目标
|
||
|
||
提供完整播放控制和播放列表跳转能力。
|
||
|
||
#### 功能点
|
||
|
||
- 大按钮控制:播放、暂停、上一个、下一个。
|
||
- 播放状态信息:当前视频、总数、当前索引。
|
||
- 播放列表展示与点击跳转。
|
||
- 支持 `goto(index)` 精准切换。
|
||
- 支持下拉刷新播放状态。
|
||
|
||
#### 相关接口
|
||
|
||
- `POST /api/play`
|
||
- `POST /api/pause`
|
||
- `POST /api/next`
|
||
- `POST /api/previous`
|
||
- `POST /api/goto/:index`
|
||
- `GET /api/playlist`
|
||
- `GET /api/status`
|
||
|
||
### 8.5 状态机页
|
||
|
||
#### 目标
|
||
|
||
让用户能够感知当前状态并显式触发状态机行为。
|
||
|
||
#### 功能点
|
||
|
||
- 展示当前状态、最近状态变化时间。
|
||
- 展示可用 `trigger` 列表,支持无值与带值触发。
|
||
- 展示常用 `scene` 列表,支持快速切换。
|
||
- 显示触发结果反馈和状态更新记录。
|
||
|
||
#### 相关接口
|
||
|
||
- `POST /api/trigger/:name`
|
||
- `POST /api/trigger/:name/:value`
|
||
- `POST /api/scene/:name`
|
||
- WebSocket:`state_update`
|
||
|
||
### 8.6 网络设置页
|
||
|
||
#### 目标
|
||
|
||
统一管理 BLE 配网与 WiFi 能力,降低设备联网操作门槛。
|
||
|
||
#### 功能点
|
||
|
||
- BLE 配网入口。
|
||
- 显示当前 WiFi 连接状态、SSID、IP。
|
||
- 扫描可用 WiFi 列表。
|
||
- 选择 WiFi 并通过 HTTP 发起连接。
|
||
- 启动/关闭热点。
|
||
- 显示 BLE 运行状态。
|
||
- 提供 BLE 简单控制命令入口(如 play/pause/next/prev)用于近场调试。
|
||
|
||
#### 相关接口
|
||
|
||
- `GET /api/wifi/status`
|
||
- `GET /api/wifi/scan`
|
||
- `POST /api/wifi/connect`
|
||
- `POST /api/wifi/ap/start`
|
||
- `POST /api/wifi/ap/stop`
|
||
- `GET /api/ble/status`
|
||
- WebSocket:`wifi_update`
|
||
|
||
### 8.7 设置页
|
||
|
||
#### 目标
|
||
|
||
承载低频但必要的管理能力。
|
||
|
||
#### 功能点
|
||
|
||
- 查看完整配置。
|
||
- 编辑并提交配置。
|
||
- 查看视频列表。
|
||
- 上传视频(若移动端能力与后端联调稳定则纳入;否则本期先只读 + 删除)。
|
||
- 删除视频。
|
||
- 展示设备信息、App 版本、接口地址。
|
||
- 关于页与排障说明。
|
||
|
||
#### 相关接口
|
||
|
||
- `GET /api/config`
|
||
- `POST /api/config`
|
||
- `GET /api/videos`
|
||
- `POST /api/videos/upload`
|
||
- `DELETE /api/videos/:filename`
|
||
|
||
## 9. 实时状态设计
|
||
|
||
### 9.1 WebSocket 事件
|
||
|
||
- `status_update`:播放状态更新
|
||
- `state_update`:状态机状态更新
|
||
- `wifi_update`:WiFi 状态更新
|
||
|
||
### 9.2 客户端处理要求
|
||
|
||
- 建立单例 WebSocket 连接。
|
||
- 支持自动重连(退避策略)。
|
||
- 断线期间显示弱提示,不阻塞已缓存页面操作。
|
||
- 收到推送后更新首页、播放控制页、状态机页、网络设置页的对应状态。
|
||
|
||
## 10. 非功能需求
|
||
|
||
### 10.1 性能
|
||
|
||
- 首页首屏可交互时间 <= 2s(已连接设备场景)。
|
||
- 单次控制请求超时默认 5s。
|
||
- BLE 扫描页进入后 1s 内显示扫描中状态。
|
||
|
||
### 10.2 可用性
|
||
|
||
- 所有关键操作必须有加载态、成功态、失败态。
|
||
- 断网、设备离线、接口超时必须有用户可理解提示。
|
||
- 关键页面支持下拉刷新或重试。
|
||
|
||
### 10.3 兼容性
|
||
|
||
- Android 10+
|
||
- iOS 15+
|
||
- 适配主流手机尺寸
|
||
|
||
### 10.4 安全与隐私
|
||
|
||
- WiFi 密码仅在本地临时使用,不长期明文持久化。
|
||
- 本地仅缓存必要设备信息,不缓存敏感配置副本。
|
||
- 预留后续接入 Token/Auth 的网络层扩展点。
|
||
|
||
## 11. 设计要求
|
||
|
||
基于 `clients/docs/DESIGN.md`,Flutter App 延续以下方向:
|
||
|
||
- 默认暗色科技风。
|
||
- 强调状态反馈与动效流畅。
|
||
- 移动优先、触控友好。
|
||
- 大按钮、清晰卡片分组、底部导航稳定。
|
||
|
||
同时补充移动端实现约束:
|
||
|
||
- 首页、播放控制页优先单手操作。
|
||
- 关键按钮点击区域 >= 48x48dp。
|
||
- 状态颜色必须与文案双重表达,避免只靠颜色区分。
|
||
|
||
## 12. 埋点与日志
|
||
|
||
MVP 至少记录以下本地日志事件,用于调试和测试:
|
||
|
||
- BLE 扫描开始/结束/失败
|
||
- BLE 连接成功/失败
|
||
- 配网命令发送结果
|
||
- HTTP 控制请求成功/失败
|
||
- WebSocket 连接/断开/重连
|
||
- 设备切换
|
||
|
||
## 13. 风险与应对
|
||
|
||
### 13.1 技术风险
|
||
|
||
1. BLE notify 行为可能依赖服务端实现完整性。
|
||
- 应对:客户端同时支持 read + notify 两种状态获取模式。
|
||
2. WebSocket 推送事件命名与文档存在潜在偏差。
|
||
- 应对:建立兼容解析层,并在联调阶段冻结事件模型。
|
||
3. `/api/playlist`、配置热重载等能力可能与服务端行为存在细微差异。
|
||
- 应对:MVP 先以“展示 + 控制成功反馈”为主,复杂行为以联调结果修正文档。
|
||
|
||
### 13.2 产品风险
|
||
|
||
1. 首次配网流程过长导致流失。
|
||
- 应对:提供分步引导、权限解释、失败重试。
|
||
2. 设备 IP 获取链路不清晰。
|
||
- 应对:BLE 配网成功后明确提示“请在路由器管理页或设备屏幕查看 IP”,并支持手动输入。
|
||
|
||
## 14. 验收标准
|
||
|
||
### 14.1 功能验收
|
||
|
||
- 能发现并连接 BLE `Showen` 设备。
|
||
- 能完成 WiFi SSID/密码写入与 `connect` 命令发送。
|
||
- 能通过 HTTP 完成播放控制、状态机触发、场景切换、WiFi 管理、视频管理、配置管理。
|
||
- 能通过 BLE 扫描与手动 IP 两种方式建立设备连接。
|
||
- 能通过 WebSocket 实时接收并刷新 `status_update` / `state_update` / `wifi_update`。
|
||
|
||
### 14.2 体验验收
|
||
|
||
- 五个核心页面链路完整,无死路由。
|
||
- 核心控制操作均有反馈。
|
||
- 网络异常和权限异常均有可理解提示。
|
||
|
||
## 15. 里程碑建议
|
||
|
||
- M1:项目脚手架 + 基础架构 + 设备发现
|
||
- M2:BLE 配网 + HTTP 控制闭环
|
||
- M3:WebSocket 实时状态 + 五大页面完成
|
||
- M4:视频/配置管理 + 稳定性优化 + 测试发布
|
||
|
||
## 16. 开发协作说明
|
||
|
||
- 产品文档:`clients/flutter/PRD.md`
|
||
- 开发看板:`clients/flutter/TASKS.md`
|
||
- 团队沟通记录:`.showen/TEAM_CHAT.md`
|
||
|
||
本 PRD 用于 Flutter App 立项、设计、研发与测试的统一输入,后续联调如发现 API 差异,以服务端实际行为校正文档并增量更新版本记录。
|