rtc_prd/阶段总结/session_progress.md
seaislee1209 8f5fb32b37 feat(story,music,server): 豆包故事生成 + 历史数据持久化 + 封面占位
- 接入火山引擎豆包 Chat API 生成儿童故事(SSE 流式进度)
- 新增 /api/stories 接口加载历史故事到书架
- 新增 /api/playlist 接口加载历史歌曲到唱片架
- 书架排序:预设故事在前,AI 生成在后
- AI 生成的故事显示"暂无封面"淡紫渐变占位
- 保存故事时传回真实标题+内容(不再用 mock)
- 修复 Windows GBK 编码导致的中文乱码问题
- 新增 MusicGenerationService 单例管理音乐生成
- 音乐页心情卡片 UI 重做 + 歌词可读性优化
- 添加豆包 API 参考文档和故事创作 prompt

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-09 23:11:58 +08:00

198 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Airhub 开发进度存档 🔖
> **用途**:每次对话结束前 / 做完一个阶段后更新此文件。
> 新对话开始时AI 先读此文件恢复上下文。
>
> **最后更新**2026-02-09 (第八次对话)
---
## 当前阶段HTML → Flutter 迁移 & UI 还原
### 总体目标
将所有 HTML 原型页面 1:1 还原为 Flutter 原生代码,使 App 脱离 WebView 依赖。
### 本次完成的工作第三次对话2026-02-06
#### 1. 全局字体修复(最重要)
- 把全项目所有 `fontFamily: 'Inter'` 替换为正确字体
- PRD 规范:标题用 **Outfit**,正文用 **DM Sans**Logo 用 **Press Start 2P**
- 修改了 `app_theme.dart`:设置 DM Sans 为全局默认字体Outfit 用于 heading styles
- 修改了 `design_tokens.dart`AppTextStyles 全部改为 GoogleFonts 调用
- 修改了 `gradient_button.dart`:按钮文字改 DM Sans
- 修改了所有页面文件(共 15+ 个文件),零 Inter 残留
#### 2. 逐页 UI 对齐 HTML 原版
- **settings_page.dart**:标题字号 18→16Slider 激活色紫色→暖橙 #FFB088
- **bluetooth_page.dart**:标题字号 18→17设备名字号 24→20
- **wifi_config_page.dart**:标题字号 18→17
- **home_page.dart**Mascot 尺寸 280→320px添加 translateX(5%) 偏移
- **device_control_page.dart**Mascot 阴影色紫→粉,导航栏阴影色紫→中性灰
- **login_page.dart**两个版本Logo 字号 26→28
- **product_selection_page.dart**:标题字体改 Outfit
- **glass_dialog.dart**:对话框标题改 Outfit
- **story files**:清除所有 Inter 引用
#### 3. 编译验证通过
-`flutter run -d web-server --web-port=8080` 编译成功
- 浏览器预览所有页面确认正常
### 第四次对话完成的工作2026-02-07
#### 修复音乐播放功能
- **问题**:音乐页面按播放键只有黑胶唱片旋转动画,完全没有接入 just_audio 播放器
- **根因**`music_creation_page.dart` 没有导入 `just_audio`,没有创建 `AudioPlayer``_togglePlay()` 只改 UI 状态不播放音频
- **修复内容**
- 导入 `just_audio` 并创建 `AudioPlayer` 实例
- `initState` 中初始化播放器 + 监听 position/duration/playerState 三条流
- `_togglePlay()` 现在真正调用 `play()` / `pause()`
- `_playTrack()` 加载对应 asset 并播放
- 进度条双向绑定:拖拽时 seek播放时实时更新
- 播完自动切下一首(循环播放列表)
- 错误处理 + 语音气泡提示
- **MP3 文件**9 首歌已在 `assets/www/music/`pubspec.yaml 已声明,播放列表用了前 4 首
### 第五次对话完成的工作2026-02-07
#### UI 规范化 & 按钮/头部统一
- **书架页面优化**:高度、布局、解锁动画丝滑化
- **头部统一**12 个文件统一为标准头部样式40×40按钮、圆角12、arrow_back_ios_new、17px标题
- **主按钮统一**9 个手写按钮改为 GradientButton 组件(光泽+涟漪+DM Sans
- **GradientButton 规范化**默认高度50→48plush字号18→17统一
- **次级按钮规范化**统一高度48、圆角24
- **全局 Toast**SnackBar → iOS 风格 AppToast
- **新增文档**`flutter_style_guide.md`Flutter 专属样式规范)
- **阶段总结**`阶段总结/phase5_ui_standardization.md`
- 详见 `阶段总结/phase5_ui_standardization.md`
#### 故事详情页修复
- loading 页传完整故事内容(不再是占位符)
- 5 个书架故事补全 content 字段(不再显示 null
- "重写"按钮改为跳转 loading 页重新生成
- 内容卡片加圆角和边距,头部 padding 加大
- footer 去掉多余白色底板
- content 兜底逻辑:无内容时自动用默认故事
### 第六次对话完成的工作2026-02-08
#### 故事保存"精灵吸入"动画Genie Suck
- **实现位置**`story_detail_page.dart`
- **动画效果**:点击"保存故事"后,故事卡片执行三段式吸入动画
- Phase 10→15%):卡片轻微放大到 1.05"蓄力"张力感)
- Phase 215%→100%):卡片极速缩小到 0.05、向下移动、模糊 + 淡出
- 缓动曲线cubic-bezier(0.6, -0.28, 0.735, 0.045)(带回弹的快速吸入)
- **底部按钮**:动画开始时 300ms 渐隐 + 禁用点击
- **总时长**0.8s,动画完成后自动 pop('saved') → 触发书架页 bookPop + 粒子效果
- **三段式完整链路**Genie Suck故事页→ bookPop书架页→ sparkle 粒子(书架页)
- **编译验证**web-server 编译通过,无 lint 错误
### 第七次对话完成的工作2026-02-08
#### 音乐页心情卡片 UI 全面重做
- **卡片风格**:回归玻璃拟态,每张卡片均匀铺一层淡主题色(不再用左白右彩的丑渐变)
- **边框优化**:去掉彩色粗描边,默认极淡主题色边框,选中才加深
- **图标简化**:去掉 40x40 色块方框,改为裸图标 + 主题色着色,更干净
- **选中态**:右上角 8px 主题色圆点指示器 + 卡片颜色加深 + 阴影发光
- **标题字号**:从 13px 回到 14px对应 HTML 原版
- **自由创作**:恢复白底玻璃质感,与心情卡片明确区分
- **盲盒惊喜**:换紫色调(#D4A0E8+ 颜色更浓 + 斜扫柔光动画3s 循环)
#### 歌词可读性优化
- 歌词文字不透明度从 0.75 提到 0.92
- 字号从 11px 提到 12px
- 歌词区域加暗色圆形遮罩,解决纹路干扰
#### 选中态交互修复
- 生成完成后自动清除 `_selectedMoodIndex`,不再残留选中状态
### 第八次对话完成的工作2026-02-09
#### 音乐生成 API 全链路接入(第七次对话中完成,此处补记)
- **SSE 实时进度**:点击心情卡片 → 发 POST 到后端 → SSE 流式推送 lyrics/music/saving/done/error 各阶段
- **MusicGenerationService 单例**:生成任务在后台运行,页面切走不中断
- **切回页面恢复**:切回音乐页弹窗通知生成结果,不在其他页面自动播放
- **进度环动画**:环形光晕进度条(匹配 HTML 版视觉)+ 翻面歌词时仍可见
- **进度条防闪烁**:用 `_crawlId` 取消令牌确保同一时间只有一条爬升动画
- **超时友好提示**:气泡显示"网络开小差了,再试一次~"
- **歌词清洗**:前后端双重清理(去 `\n`、去 `[verse]` 等结构标签、去 JSON 引号)
- **歌名修复**:后端优先取 LLM 返回的 `song_title`,歌词增长至 16-24 行
- **对话气泡样式**:文字垂直居中 + 三角尾巴
- **通知页展开 bug 修复**`AnimatedCrossFade``ClipRect + AnimatedSize` 避免文字竖排
#### 启动时加载历史歌曲
- **后端**`/api/playlist` 接口扫描 `Capybara music/` 目录,返回所有 mp3 + 歌词
- **Service 层**`MusicGenerationService.fetchPlaylist()` 拉取列表
- **前端**`initState` 异步调用,将服务器歌曲插入唱片架最前面(去重,不重复加载硬编码的 4 首)
- **当前服务器上有 19 首 AI 生成歌曲 + 4 首原始歌曲,重编译后唱片架不再丢失**
#### 故事生成接入豆包 API
- **后端**`server.py` 新增 `/api/create_story` 接口SSE 流式调用豆包 Chat API
- **模型**Doubao-Seed-1.6-lite`doubao-seed-1-6-lite-250515`),关闭深度思考加快响应
- **Prompt**`prompts/story_director.md`儿童故事创作大师400-600 字JSON 输出
- **前端串联**
- `StoryGeneratorModal` 返回选中素材 Map角色/场景/道具分类)
- `DeviceControlPage` 把素材传给 `StoryLoadingPage`
- `StoryLoadingPage` 调真实 APISSE 实时进度(连接→生成→解析→完成)
- `StoryDetailPage` 无需改动,已支持接收动态故事数据
- **故事保存**:生成的故事文本保存到 `Capybara stories/` 目录
- **错误处理**超时提示、API 异常、空内容兜底,错误时显示"返回重试"按钮
#### 唱片架高度优化
- 限制唱片架弹窗高度为 3.5 行,超出部分滚动查看
- 半行露出作为"还有更多"的视觉提示
#### Windows 编码问题全面修复
- `sys.stdout` / `sys.stderr` 强制 UTF-8Windows 默认 GBK 导致中文乱码)
- Doubao API 请求体手动 `json.dumps + encode("utf-8")`,避免 `requests` 用 GBK 编码
- SSE 流使用 `ensure_ascii=True`,确保前端 `jsonDecode` 100% 正常
- `resp.encoding = "utf-8"` 强制豆包返回流按 UTF-8 解码
- 已清理 4 个编码出错时保存的乱码故事文件
#### 书架加载历史故事
- **后端**`/api/stories` 接口扫描 `Capybara stories/` 返回所有故事标题+内容
- **前端**`initState` 异步拉取,历史故事排在预设故事之后
- **保存联动**:新生成的故事保存后,真实标题+内容即时加入书架(不再用 mock 数据)
- **封面区分**预设故事显示封面图AI 生成的故事显示淡紫渐变"暂无封面"占位
- **乱码过滤**API 层自动跳过无中文标题的异常文件
### 正在做的
- TTS 语音合成待后续接入(用户去开通火山语音服务后再做)
- 故事封面方案待定(付费生成 or 免费生成)
---
## 重复登录页说明
- `lib/features/auth/presentation/pages/login_page.dart` — 路由使用,带 Riverpod 认证
- `lib/pages/login_page.dart` — 完整 UI 实现,作为参考保留
- 后续需要把 pages/ 版本的完整 UI 合并到 auth 版本
---
## 三步走计划
1. ✅ 修已转换页面的 UI 差异(本次完成)
2. 🔄 构建音乐创作页面(进行中)
3. ⬜ 转换剩余 WebView 页面Profile、收藏、帮助等
---
## 开发环境备忘
- **预览方式**`flutter run -d web-server --web-port=PORT`,用 Cursor 内置浏览器看
- **镜像源**:需设 `PUB_HOSTED_URL``FLUTTER_STORAGE_BASE_URL` 为国内源
- **Android 模拟器**已装好VTX 已开,但编译慢,非最终验收不用
- **Flutter web-server 当前运行在端口 8080**
---
## 关键文件索引
| 文件 | 说明 |
|------|------|
| `PRD.md` | 产品需求文档 |
| `design_system.md` | 视觉设计规范 |
| `airhub_app/migration_report.md` | HTML→Flutter 迁移进度 & UI 差异 |
| `music-creation.html` | 音乐创作页面 HTML 原版 |
| `阶段总结/task.md` | "我的"模块任务清单 |
| `阶段总结/phase_summary.md` | 音乐电台功能阶段总结 |
| `阶段总结/session_progress.md` | 👈 **就是本文件,开发进度存档** |