feat: 任务 3.15 克隆进度展示 — 轮询 Hook + 进度条 + 状态标签 #153

Merged
xiaoxia merged 2 commits from feat/clone-progress-3.15 into develop 2026-07-02 18:27:04 +08:00
Owner

任务 3.15 — 克隆进度展示

变更内容

  • 新增 useCloneProgress hook:processing 状态自动 3s 轮询,全部就绪/失败后停止
  • 新增 voiceClone API 层:VoiceClone 类型定义、CRUD 函数、进度模拟(tickProgress)
  • 重构 MyVoices.tsx:移除本地 mock,使用共享 API 和 hook,支持进度条/状态标签/轮询提示
  • 重构 GeneratePage.tsx 克隆区域:调用 createVoiceClone API,显示进度条和状态标签
  • 新增 CSS 样式:进度条、轮询提示动画、状态变体(processing/failed)

文件清单

文件 操作
api/voiceClone.ts 修改 — VoiceClone 类型、CRUD API、进度模拟
hooks/useCloneProgress.ts 新增 — 轮询 Hook
pages/my-voices/MyVoices.tsx 修改 — 接入共享 API
pages/my-voices/my-voices.css 修改 — 轮询提示样式
pages/generate/GeneratePage.tsx 修改 — 克隆区域重构
pages/generate/generate.css 修改 — 进度条/状态样式
config/navigation.ts 新增 — 导航配置

技术要点

  • 轮询策略:仅在有 processing 条目时启动 setInterval,全部结束时自动清理
  • 进度模拟:每次 API 调用 processing 条目 +5~15%,达到 100 自动转 ready
  • API 字段命名:snake_case(created_at, duration_seconds, sample_url)
## 任务 3.15 — 克隆进度展示 ### 变更内容 - **新增 `useCloneProgress` hook**:processing 状态自动 3s 轮询,全部就绪/失败后停止 - **新增 `voiceClone` API 层**:VoiceClone 类型定义、CRUD 函数、进度模拟(tickProgress) - **重构 `MyVoices.tsx`**:移除本地 mock,使用共享 API 和 hook,支持进度条/状态标签/轮询提示 - **重构 `GeneratePage.tsx` 克隆区域**:调用 `createVoiceClone` API,显示进度条和状态标签 - **新增 CSS 样式**:进度条、轮询提示动画、状态变体(processing/failed) ### 文件清单 | 文件 | 操作 | |------|------| | `api/voiceClone.ts` | 修改 — VoiceClone 类型、CRUD API、进度模拟 | | `hooks/useCloneProgress.ts` | 新增 — 轮询 Hook | | `pages/my-voices/MyVoices.tsx` | 修改 — 接入共享 API | | `pages/my-voices/my-voices.css` | 修改 — 轮询提示样式 | | `pages/generate/GeneratePage.tsx` | 修改 — 克隆区域重构 | | `pages/generate/generate.css` | 修改 — 进度条/状态样式 | | `config/navigation.ts` | 新增 — 导航配置 | ### 技术要点 - 轮询策略:仅在有 processing 条目时启动 setInterval,全部结束时自动清理 - 进度模拟:每次 API 调用 processing 条目 +5~15%,达到 100 自动转 ready - API 字段命名:snake_case(created_at, duration_seconds, sample_url)
xiaoxia force-pushed feat/clone-progress-3.15 from 7604f4e75e to c52be9b036 2026-07-02 18:11:38 +08:00 Compare
Author
Owner

Rebase 冲突已解决,force push 完成。

冲突解决摘要:

  • voiceClone.ts:保留 develop 真实 API + 新增 progress 字段
  • GeneratePage.tsx:保留真实 API imports + VoiceCloneModal,集成 useCloneProgress hook + CLONE_STATUS_CONFIG + 进度条/状态标签 UI
  • MyVoices.tsx:合并 PageHead default import + useCloneProgress/voiceClone API imports

验证: TypeScript npx tsc --noEmit 零错误

@灵应 请合并 PR。

✅ Rebase 冲突已解决,force push 完成。 **冲突解决摘要:** - `voiceClone.ts`:保留 develop 真实 API + 新增 `progress` 字段 - `GeneratePage.tsx`:保留真实 API imports + VoiceCloneModal,集成 `useCloneProgress` hook + CLONE_STATUS_CONFIG + 进度条/状态标签 UI - `MyVoices.tsx`:合并 PageHead default import + useCloneProgress/voiceClone API imports **验证:** TypeScript `npx tsc --noEmit` 零错误 ✅ @灵应 请合并 PR。
Author
Owner

🟡 PR #153 有条件通过(任务 3.15 克隆进度展示)

7 文件 +427/-199,mergeable=True

通过项

  • useCloneProgress Hook 设计良好:3秒轮询、processing 状态自动启停、useRef+cleanup 完整、silent 模式避免 loading 闪烁
  • 集成正确:MyVoices 和 GeneratePage 均正确使用 Hook,addClone/removeClone/updateClone 状态操作无误
  • 使用 apiClient:无裸 fetch
  • TypeScript 类型完整:VoiceClone 新增 progress 字段
  • CSS 规范:V21 设计变量、状态变体样式、动画关键帧完整

问题

级别 位置 问题
P2 voiceClone.ts:98 progress: 0 硬编码,后端 VoiceCloneProfile 无 progress 字段,进度条永远显示 0%,误导用户。建议 progress=0 时显示不确定态(indeterminate 动画 + "处理中..."文本),而非假的 0%
P3 navigation.ts 81行统一导航配置文件混入本 PR,且无任何文件 import 此模块,属于孤立文件。建议移到独立 PR
P3 MyVoices.tsx:176 setTimeout(() => setToasts(...), 3000) 无组件卸载清理
P3 MyVoices.tsx:190 sample_url 缺失时 fallback 到 /mock/audio/clone-${id}.mp3 Mock URL

结论

有条件通过:0P0/0P1/1P2/3P3。修复 P2(进度条空壳)后可合并。P3 不阻塞。

## 🟡 PR #153 有条件通过(任务 3.15 克隆进度展示) 7 文件 +427/-199,mergeable=True ### ✅ 通过项 - **useCloneProgress Hook 设计良好**:3秒轮询、processing 状态自动启停、useRef+cleanup 完整、silent 模式避免 loading 闪烁 - **集成正确**:MyVoices 和 GeneratePage 均正确使用 Hook,addClone/removeClone/updateClone 状态操作无误 - **使用 apiClient**:无裸 fetch - **TypeScript 类型完整**:VoiceClone 新增 progress 字段 - **CSS 规范**:V21 设计变量、状态变体样式、动画关键帧完整 ### 问题 | 级别 | 位置 | 问题 | |------|------|------| | **P2** | `voiceClone.ts:98` | `progress: 0` 硬编码,后端 VoiceCloneProfile 无 progress 字段,进度条永远显示 0%,误导用户。建议 progress=0 时显示不确定态(indeterminate 动画 + "处理中..."文本),而非假的 0% | | **P3** | `navigation.ts` | 81行统一导航配置文件混入本 PR,且无任何文件 import 此模块,属于孤立文件。建议移到独立 PR | | **P3** | `MyVoices.tsx:176` | `setTimeout(() => setToasts(...), 3000)` 无组件卸载清理 | | **P3** | `MyVoices.tsx:190` | `sample_url` 缺失时 fallback 到 `/mock/audio/clone-${id}.mp3` Mock URL | ### 结论 **有条件通过**:0P0/0P1/1P2/3P3。修复 P2(进度条空壳)后可合并。P3 不阻塞。
xiaoxia added 1 commit 2026-07-02 18:22:24 +08:00
fix: progress bar indeterminate animation (P2)
CI/CD Pipeline / Frontend Lint (pull_request) Failing after 162h32m5s
CI/CD Pipeline / Validate Code Quality And Tests (pull_request) Failing after 162h32m11s
8dd0db58b8
- GeneratePage.tsx: processing 状态进度条改为 indeterminate 条纹流动动画
- MyVoices.tsx: 同上,移除硬编码 progress: 0 百分比显示
- generate.css: 添加 @keyframes xx-clone-progress-flow 条纹流动 + pulse 脉冲
- my-voices.css: 添加 @keyframes xx-mv-progress-flow 条纹流动 + pulse 脉冲
- 文本从 '0%' 改为 '处理中…',给用户处理中的视觉反馈

Fixes: P2 — progress 硬编码为 0,进度条永远显示 0%
Author
Owner

P2 修复完成

问题:progress 硬编码为 0,进度条永远显示 0%

修复方案:processing 状态时改为 indeterminate 条纹流动动画

修改文件

  • GeneratePage.tsx — 移除硬编码 width,添加 indeterminate class
  • MyVoices.tsx — 同上
  • generate.css — 添加条纹流动 + 脉冲动画
  • my-voices.css — 同上

视觉效果:条纹持续流动 + 「处理中…」文字脉冲呼吸

TypeScript 零错误,已 push。P3 暂不处理。

@灵应 请复审 🙏

## ✅ P2 修复完成 **问题**:progress 硬编码为 0,进度条永远显示 0% **修复方案**:processing 状态时改为 indeterminate 条纹流动动画 **修改文件**: - `GeneratePage.tsx` — 移除硬编码 width,添加 indeterminate class - `MyVoices.tsx` — 同上 - `generate.css` — 添加条纹流动 + 脉冲动画 - `my-voices.css` — 同上 **视觉效果**:条纹持续流动 + 「处理中…」文字脉冲呼吸 TypeScript 零错误,已 push。P3 暂不处理。 @灵应 请复审 🙏
xiaoxia merged commit 62adcc0940 into develop 2026-07-02 18:27:04 +08:00
Sign in to join this conversation.