diff --git a/.claude/settings.local.json b/.claude/settings.local.json new file mode 100644 index 0000000..c4ad5e2 --- /dev/null +++ b/.claude/settings.local.json @@ -0,0 +1,11 @@ +{ + "permissions": { + "allow": [ + "Bash(flutter doctor:*)", + "Bash(flutter devices:*)", + "Bash(flutter pub get:*)", + "Bash(pod install)", + "Bash(flutter run:*)" + ] + } +} diff --git a/docs/API_SPECIFICATION.md b/docs/API_SPECIFICATION.md new file mode 100644 index 0000000..2705c6e --- /dev/null +++ b/docs/API_SPECIFICATION.md @@ -0,0 +1,1202 @@ +# Airhub 后台接口规范文档 + +> 版本: 1.0.0 +> 更新日期: 2025-02-09 +> 基于 PRD HTML 原型与 airhub_app Flutter 代码分析整理 + +--- + +## 目录 + +- [概述](#概述) +- [通用规范](#通用规范) +- [接口列表](#接口列表) + - [1. 用户认证](#1-用户认证) + - [2. 用户信息](#2-用户信息) + - [3. 设备管理](#3-设备管理) + - [4. 角色记忆](#4-角色记忆) + - [5. 故事模块](#5-故事模块) + - [6. 音乐模块](#6-音乐模块) + - [7. 通知模块](#7-通知模块) + - [8. 系统接口](#8-系统接口) +- [数据模型](#数据模型) +- [开发优先级](#开发优先级) +- [附录:代码对照表](#附录代码对照表) + +--- + +## 概述 + +本文档定义了 Airhub 智能硬件控制中心 APP 所需的全部后台接口。接口设计基于以下来源: + +1. **PRD HTML 原型文件** - 根目录下的 `.html` 文件 +2. **airhub_app Flutter 代码** - `airhub_app/lib/` 目录 +3. **已实现的接口调用** - `music-creation.html` 中的实际 API 调用 + +### 技术栈建议 + +- 后端框架: Node.js (Express/Fastify) 或 Python (FastAPI) +- 数据库: PostgreSQL / MySQL +- 缓存: Redis +- 对象存储: 阿里云 OSS +- 实时通信: SSE (Server-Sent Events) + +--- + +## 通用规范 + +### 基础 URL + +``` +开发环境: http://localhost:3000/api +生产环境: https://api.airhub.com/v1 +``` + +### 请求头 + +```http +Content-Type: application/json +Authorization: Bearer {access_token} +X-Device-Id: {device_uuid} +X-App-Version: 1.0.0 +``` + +### 响应格式 + +**成功响应** +```json +{ + "code": 0, + "message": "success", + "data": { ... } +} +``` + +**错误响应** +```json +{ + "code": 40001, + "message": "参数错误", + "data": null +} +``` + +### 错误码定义 + +| 错误码 | 说明 | +|--------|------| +| 0 | 成功 | +| 40001 | 参数错误 | +| 40101 | 未授权 (Token 无效) | +| 40102 | Token 过期 | +| 40301 | 无权限 | +| 40401 | 资源不存在 | +| 50001 | 服务器内部错误 | + +--- + +## 接口列表 + +### 1. 用户认证 + +#### 1.1 发送验证码 + +```http +POST /api/auth/send-code +``` + +**请求参数** +```json +{ + "phone": "13800138000" +} +``` + +**响应** +```json +{ + "code": 0, + "message": "验证码已发送", + "data": { + "expire_in": 60 + } +} +``` + +**说明**: 验证码 60 秒内有效,同一手机号 60 秒内只能发送一次 + +--- + +#### 1.2 验证码登录 + +```http +POST /api/auth/login +``` + +**请求参数** +```json +{ + "phone": "13800138000", + "code": "123456" +} +``` + +**响应** +```json +{ + "code": 0, + "message": "登录成功", + "data": { + "access_token": "eyJhbGciOiJIUzI1NiIs...", + "refresh_token": "eyJhbGciOiJIUzI1NiIs...", + "expire_in": 604800, + "user": { + "id": "u_12345678", + "phone": "138****8000", + "nickname": "用户8000", + "avatar_url": null + } + } +} +``` + +**Flutter 代码对应**: `AuthRemoteDataSource.loginWithPhone()` + +--- + +#### 1.3 一键登录 + +```http +POST /api/auth/one-click-login +``` + +**请求参数** +```json +{ + "access_token": "运营商SDK返回的token" +} +``` + +**响应**: 同验证码登录 + +**说明**: 使用运营商 SDK (如阿里云号码认证) 获取本机号码 + +**Flutter 代码对应**: `AuthRemoteDataSource.oneClickLogin()` + +--- + +#### 1.4 刷新 Token + +```http +POST /api/auth/refresh-token +``` + +**请求参数** +```json +{ + "refresh_token": "eyJhbGciOiJIUzI1NiIs..." +} +``` + +**响应** +```json +{ + "code": 0, + "data": { + "access_token": "新的access_token", + "expire_in": 604800 + } +} +``` + +--- + +#### 1.5 退出登录 + +```http +POST /api/auth/logout +``` + +**请求头**: 需要 Authorization + +**响应** +```json +{ + "code": 0, + "message": "已退出登录" +} +``` + +**Flutter 代码对应**: `AuthRepository.logout()` + +--- + +#### 1.6 账号注销 + +```http +DELETE /api/auth/account +``` + +**请求头**: 需要 Authorization + +**响应** +```json +{ + "code": 0, + "message": "账号注销申请已提交,将在7个工作日内处理" +} +``` + +**PRD 来源**: `settings.html` - 账号注销功能 + +--- + +### 2. 用户信息 + +#### 2.1 获取用户资料 + +```http +GET /api/user/profile +``` + +**响应** +```json +{ + "code": 0, + "data": { + "id": "u_12345678", + "phone": "138****8000", + "nickname": "土豆", + "avatar_url": "https://oss.airhub.com/avatars/xxx.jpg", + "gender": "男", + "birthday": "1994-12-09", + "created_at": "2025-01-15T10:30:00Z" + } +} +``` + +**Flutter 代码对应**: `profile_page.dart` - 用户卡片显示 + +--- + +#### 2.2 更新用户资料 + +```http +PUT /api/user/profile +``` + +**请求参数** +```json +{ + "nickname": "新昵称", + "gender": "女", + "birthday": "1995-06-15" +} +``` + +**响应** +```json +{ + "code": 0, + "message": "保存成功" +} +``` + +**Flutter 代码对应**: `profile_info_page.dart` - 保存按钮 + +--- + +#### 2.3 上传头像 + +```http +POST /api/user/avatar +Content-Type: multipart/form-data +``` + +**请求参数** +``` +file: (binary) +``` + +**响应** +```json +{ + "code": 0, + "data": { + "avatar_url": "https://oss.airhub.com/avatars/xxx.jpg" + } +} +``` + +**Flutter 代码对应**: `profile_info_page.dart` - `_pickImage()` + +--- + +### 3. 设备管理 + +#### 3.1 获取设备列表 + +```http +GET /api/devices +``` + +**响应** +```json +{ + "code": 0, + "data": { + "devices": [ + { + "id": "dev_001", + "name": "毛绒机芯", + "model": "Airhub_5G", + "status": "online", + "battery": 85, + "firmware_version": "2.1.3", + "is_ai": true, + "icon": "Capybara.png" + }, + { + "id": "dev_002", + "name": "电子吧唧 AI", + "model": "Badge_AI", + "status": "offline", + "battery": 0, + "is_ai": true + } + ] + } +} +``` + +**设备状态枚举**: +- `online` - 在线 +- `offline` - 离线 +- `pairing` - 配对中 +- `updating` - 固件更新中 + +**Flutter 代码对应**: `product_selection_page.dart` + +--- + +#### 3.2 获取设备详情 + +```http +GET /api/devices/{device_id} +``` + +**响应** +```json +{ + "code": 0, + "data": { + "id": "dev_001", + "name": "毛绒机芯", + "model": "Airhub_5G", + "status": "online", + "battery": 85, + "firmware_version": "2.1.3", + "mac_address": "AA:BB:CC:DD:EE:FF", + "settings": { + "nickname": "小毛球", + "user_name": "土豆", + "volume": 60, + "brightness": 85, + "allow_interrupt": true, + "privacy_mode": true + }, + "wifi_list": [ + { + "ssid": "Home_WiFi", + "is_connected": true + } + ], + "bound_memory_id": "mem_001" + } +} +``` + +**Flutter 代码对应**: `device_control_page.dart` - 设置页面 + +--- + +#### 3.3 更新设备设置 + +```http +PUT /api/devices/{device_id} +``` + +**请求参数** +```json +{ + "nickname": "新昵称", + "user_name": "主人称呼", + "volume": 70, + "brightness": 90, + "allow_interrupt": false, + "privacy_mode": true +} +``` + +**响应** +```json +{ + "code": 0, + "message": "设置已保存" +} +``` + +**PRD 来源**: `device-control.html` - 设备设置面板 + +--- + +#### 3.4 绑定设备 + +```http +POST /api/devices/{device_id}/bind +``` + +**请求参数** +```json +{ + "mac_address": "AA:BB:CC:DD:EE:FF", + "wifi_ssid": "Home_WiFi", + "wifi_password": "password123" +} +``` + +**响应** +```json +{ + "code": 0, + "message": "设备绑定成功", + "data": { + "device_id": "dev_001", + "memory_id": "mem_001" + } +} +``` + +**PRD 来源**: `bluetooth.html`, `wifi-config.html` + +--- + +#### 3.5 解绑设备 + +```http +DELETE /api/devices/{device_id}/unbind +``` + +**响应** +```json +{ + "code": 0, + "message": "设备已解绑", + "data": { + "memory_id": "mem_001", + "memory_name": "Cloud_Mem_01" + } +} +``` + +**说明**: 解绑后角色记忆自动保存到云端 + +**PRD 来源**: `device-control.html` - 解绑设备弹窗 + +--- + +#### 3.6 配置设备 WiFi + +```http +POST /api/devices/{device_id}/wifi +``` + +**请求参数** +```json +{ + "ssid": "New_WiFi", + "password": "password123" +} +``` + +**响应** +```json +{ + "code": 0, + "message": "WiFi 配置成功" +} +``` + +**PRD 来源**: `wifi-config.html` + +--- + +### 4. 角色记忆 + +#### 4.1 获取角色记忆列表 + +```http +GET /api/agents +``` + +**响应** +```json +{ + "code": 0, + "data": { + "agents": [ + { + "id": "mem_001", + "name": "Airhub_Mem_01", + "icon": "🧠", + "nickname": "小毛球", + "bound_device": { + "id": "dev_001", + "name": "Airhub_5G" + }, + "status": "bound", + "created_at": "2025-01-15" + }, + { + "id": "mem_002", + "name": "Airhub_Mem_02", + "icon": "🐾", + "nickname": "豆豆", + "bound_device": null, + "status": "unbound", + "created_at": "2024-08-22" + } + ] + } +} +``` + +**角色记忆状态**: +- `bound` - 已绑定设备 +- `unbound` - 未绑定 (可注入) + +**Flutter 代码对应**: `agent_manage_page.dart` + +--- + +#### 4.2 解绑角色记忆 + +```http +POST /api/agents/{agent_id}/unbind +``` + +**响应** +```json +{ + "code": 0, + "message": "已解绑角色记忆,数据已保留在云端" +} +``` + +--- + +#### 4.3 注入角色记忆 + +```http +POST /api/agents/{agent_id}/inject +``` + +**请求参数** +```json +{ + "device_id": "dev_002" +} +``` + +**响应** +```json +{ + "code": 0, + "message": "角色记忆注入成功" +} +``` + +**PRD 来源**: `agent-manage.html` - 注入设备按钮 + +--- + +### 5. 故事模块 + +#### 5.1 获取故事列表 + +```http +GET /api/stories +``` + +**查询参数** +``` +shelf_id: 1 # 书架 ID,可选 +page: 1 # 页码 +page_size: 20 # 每页数量 +``` + +**响应** +```json +{ + "code": 0, + "data": { + "stories": [ + { + "id": "story_001", + "title": "卡皮巴拉的奇幻漂流", + "cover_url": "https://oss.airhub.com/covers/xxx.jpg", + "content": "在一条蜿蜒的小河边...", + "has_video": true, + "video_url": "https://oss.airhub.com/videos/xxx.mp4", + "created_at": "2025-01-20T15:30:00Z" + } + ], + "total": 5, + "page": 1, + "page_size": 20 + } +} +``` + +**Flutter 代码对应**: `device_control_page.dart` - `_mockStories` + +--- + +#### 5.2 获取故事详情 + +```http +GET /api/stories/{story_id} +``` + +**响应** +```json +{ + "code": 0, + "data": { + "id": "story_001", + "title": "卡皮巴拉的奇幻漂流", + "cover_url": "https://oss.airhub.com/covers/xxx.jpg", + "content": "完整故事内容...", + "has_video": true, + "video_url": "https://oss.airhub.com/videos/xxx.mp4", + "created_at": "2025-01-20T15:30:00Z" + } +} +``` + +**Flutter 代码对应**: `story_detail_page.dart` + +--- + +#### 5.3 生成故事 (SSE 流式) + +```http +POST /api/stories/generate +Accept: text/event-stream +``` + +**请求参数** +```json +{ + "mode": "random", + "prompt": "关于卡皮巴拉的冒险故事", + "theme": "adventure" +} +``` + +**生成模式**: +- `random` - 随机生成 +- `keyword` - 关键词生成 +- `theme` - 主题生成 + +**SSE 响应流** +``` +data: {"stage": "generating", "progress": 10, "message": "正在构思故事大纲..."} + +data: {"stage": "generating", "progress": 50, "message": "正在撰写故事内容..."} + +data: {"stage": "done", "progress": 100, "story": {...}} +``` + +**Flutter 代码对应**: `story_loading_page.dart` + +--- + +#### 5.4 保存故事 + +```http +POST /api/stories/{story_id}/save +``` + +**请求参数** +```json +{ + "shelf_id": 1 +} +``` + +**响应** +```json +{ + "code": 0, + "message": "故事已保存到书架" +} +``` + +**PRD 来源**: `story-detail.html` - 保存故事按钮 + +--- + +#### 5.5 生成动态绘本 (SSE 流式) + +```http +POST /api/stories/{story_id}/video +Accept: text/event-stream +``` + +**SSE 响应流** +``` +data: {"stage": "processing", "progress": 20, "message": "正在生成插画..."} + +data: {"stage": "processing", "progress": 60, "message": "正在合成视频..."} + +data: {"stage": "done", "progress": 100, "video_url": "https://..."} +``` + +**说明**: 生成动态绘本消耗 10 SP (积分) + +**Flutter 代码对应**: `story_detail_page.dart` - `runGenerationProcess()` + +--- + +#### 5.6 解锁新书架 + +```http +POST /api/stories/shelves/unlock +``` + +**请求参数** +```json +{ + "cost_points": 500 +} +``` + +**响应** +```json +{ + "code": 0, + "message": "解锁成功", + "data": { + "shelf_id": 2, + "remaining_points": 1500 + } +} +``` + +**Flutter 代码对应**: `device_control_page.dart` - `_showUnlockDialog()` + +--- + +### 6. 音乐模块 + +> ⚠️ **重要**: 此模块在 `music-creation.html` 中已有实际 API 调用实现 + +#### 6.1 生成音乐 (SSE 流式) + +```http +POST /api/create_music +Accept: text/event-stream +``` + +**请求参数** +```json +{ + "text": "水豚在雨中等公交,心情却很平静", + "mood": "chill" +} +``` + +**心情类型**: +- `chill` - Chill Lofi (慵懒·治愈) +- `happy` - Happy Funk (活力·奔跑) +- `sleep` - Deep Sleep (白噪音·助眠) +- `focus` - Focus Flow (心流·专注) +- `mystery` - 盲盒惊喜 (AI随机) +- `custom` - 自由创作 + +**SSE 响应流** +``` +data: {"stage": "connecting", "progress": 5, "message": "🎼 正在连接 AI..."} + +data: {"stage": "lyrics", "progress": 20, "message": "🎵 正在生成歌词..."} + +data: {"stage": "music", "progress": 30, "message": "🎹 正在作曲..."} + +data: {"stage": "done", "progress": 100, "file_path": "/music/xxx.mp3", "metadata": {"lyrics": "歌词内容..."}} +``` + +**错误响应** +``` +data: {"stage": "error", "message": "生成失败,请重试"} +``` + +**HTML 代码位置**: `music-creation.html:1730` + +**Flutter 代码对应**: `music_creation_page.dart` - `_mockGenerate()` + +--- + +#### 6.2 获取播放列表 + +```http +GET /api/playlist +``` + +**响应** +```json +{ + "code": 0, + "data": { + "playlist": [ + { + "id": 1, + "title": "卡皮巴拉蹦蹦蹦", + "lyrics": "卡皮巴拉\n啦啦啦啦...", + "audio_url": "/music/卡皮巴拉蹦蹦蹦.mp3", + "cover_url": "Capybara.png", + "mood": "happy", + "duration": 204, + "created_at": "2025-01-15T10:00:00Z" + } + ] + } +} +``` + +**HTML 代码位置**: `music-creation.html:2006` + +**Flutter 代码对应**: `music_creation_page.dart` - `_playlist` + +--- + +#### 6.3 删除播放列表项 + +```http +DELETE /api/playlist/{track_id} +``` + +**响应** +```json +{ + "code": 0, + "message": "已从播放列表移除" +} +``` + +--- + +#### 6.4 收藏音乐 + +```http +POST /api/playlist/{track_id}/favorite +``` + +**响应** +```json +{ + "code": 0, + "message": "已收藏" +} +``` + +--- + +### 7. 通知模块 + +#### 7.1 获取通知列表 + +```http +GET /api/notifications +``` + +**查询参数** +``` +type: all # all, system, activity, device +page: 1 +page_size: 20 +``` + +**响应** +```json +{ + "code": 0, + "data": { + "notifications": [ + { + "id": "notif_001", + "type": "system", + "title": "系统更新", + "description": "Airhub V1.2.0 版本更新已准备就绪", + "content": "

更新说明:

", + "is_read": false, + "created_at": "2025-02-09T10:30:00Z" + }, + { + "id": "notif_002", + "type": "activity", + "title": "新春活动", + "description": "领取您的新春限定水豚皮肤", + "image_url": "https://...", + "is_read": true, + "created_at": "2025-02-08T09:00:00Z" + } + ], + "unread_count": 1 + } +} +``` + +**通知类型**: +- `system` - 系统通知 +- `activity` - 活动通知 +- `device` - 设备通知 + +**Flutter 代码对应**: `notification_page.dart` + +--- + +#### 7.2 标记通知已读 + +```http +PUT /api/notifications/{notification_id}/read +``` + +**响应** +```json +{ + "code": 0, + "message": "已标记为已读" +} +``` + +--- + +#### 7.3 标记全部已读 + +```http +PUT /api/notifications/read-all +``` + +**响应** +```json +{ + "code": 0, + "message": "全部标记为已读" +} +``` + +--- + +### 8. 系统接口 + +#### 8.1 提交意见反馈 + +```http +POST /api/feedback +``` + +**请求参数** +```json +{ + "content": "希望增加深色模式功能", + "contact": "user@email.com" +} +``` + +**响应** +```json +{ + "code": 0, + "message": "感谢您的反馈!" +} +``` + +**Flutter 代码对应**: `feedback_dialog.dart` + +--- + +#### 8.2 检查版本更新 + +```http +GET /api/version/check +``` + +**查询参数** +``` +platform: ios # ios, android +current_version: 1.0.0 +``` + +**响应** +```json +{ + "code": 0, + "data": { + "latest_version": "1.2.0", + "current_version": "1.0.0", + "update_required": false, + "force_update": false, + "update_url": "https://apps.apple.com/...", + "release_notes": "1. 新增喂养指南\n2. 优化连接稳定性" + } +} +``` + +**Flutter 代码对应**: `settings_page.dart` - 检查更新 + +--- + +## 数据模型 + +### User (用户) + +```typescript +interface User { + id: string; + phone: string; // 脱敏显示 + nickname: string; + avatar_url: string | null; + gender: '男' | '女' | null; + birthday: string | null; // YYYY-MM-DD + created_at: string; +} +``` + +### Device (设备) + +```typescript +interface Device { + id: string; + name: string; + model: string; + status: 'online' | 'offline' | 'pairing' | 'updating'; + battery: number; // 0-100 + firmware_version: string; + mac_address: string; + is_ai: boolean; + settings: DeviceSettings; + bound_memory_id: string | null; +} + +interface DeviceSettings { + nickname: string; // 设备昵称 + user_name: string; // 用户称呼 + volume: number; // 0-100 + brightness: number; // 0-100 + allow_interrupt: boolean; + privacy_mode: boolean; +} +``` + +### Agent (角色记忆) + +```typescript +interface Agent { + id: string; + name: string; // Airhub_Mem_01 + icon: string; // Emoji + nickname: string; // 小毛球 + bound_device: Device | null; + status: 'bound' | 'unbound'; + created_at: string; +} +``` + +### Story (故事) + +```typescript +interface Story { + id: string; + title: string; + cover_url: string; + content: string; + has_video: boolean; + video_url: string | null; + shelf_id: number; + created_at: string; +} +``` + +### Track (音乐) + +```typescript +interface Track { + id: number; + title: string; + lyrics: string; + audio_url: string; + cover_url: string; + mood: 'chill' | 'happy' | 'sleep' | 'focus' | 'mystery' | 'custom'; + duration: number; // 秒 + created_at: string; +} +``` + +### Notification (通知) + +```typescript +interface Notification { + id: string; + type: 'system' | 'activity' | 'device'; + title: string; + description: string; + content: string | null; // HTML 内容 + image_url: string | null; + is_read: boolean; + created_at: string; +} +``` + +--- + +## 开发优先级 + +| 优先级 | 模块 | 说明 | 依赖 | +|--------|------|------|------| +| **P0** | 用户认证 | 登录/注册是基础功能 | 运营商 SDK | +| **P0** | 设备管理 | 核心业务:设备绑定、配网 | 蓝牙 SDK | +| **P1** | 音乐模块 | 已有 HTML 实现,需对接 MiniMax API | MiniMax API | +| **P1** | 故事模块 | 核心功能:AI 生成故事 | LLM API | +| **P2** | 角色记忆 | 差异化功能 | 设备管理 | +| **P2** | 用户信息 | 个人中心相关 | 用户认证 | +| **P3** | 通知模块 | 辅助功能 | 推送 SDK | +| **P3** | 系统接口 | 反馈、版本检查 | - | + +--- + +## 附录:代码对照表 + +| 接口 | PRD HTML 文件 | Flutter 代码 | +|------|---------------|--------------| +| 登录 | `login.html` | `auth_remote_data_source.dart` | +| 用户资料 | `profile.html`, `profile-info.html` | `profile_page.dart`, `profile_info_page.dart` | +| 设备管理 | `products.html`, `device-control.html` | `product_selection_page.dart`, `device_control_page.dart` | +| 配网 | `bluetooth.html`, `wifi-config.html` | `bluetooth_page.dart`, `wifi_config_page.dart` | +| 角色记忆 | `agent-manage.html` | `agent_manage_page.dart` | +| 故事 | `story-detail.html`, `story-loading.html` | `story_detail_page.dart`, `story_loading_page.dart` | +| 音乐 | `music-creation.html` | `music_creation_page.dart` | +| 通知 | `notifications.html` | `notification_page.dart` | +| 设置 | `settings.html` | `settings_page.dart` | + +--- + +## 更新日志 + +| 版本 | 日期 | 说明 | +|------|------|------| +| 1.0.0 | 2025-02-09 | 初版,基于 PRD 和 Flutter 代码分析 | + +--- + +*本文档由 Claude Code 自动生成,如有问题请联系开发团队。*