Files
xiaoxia-saas/apps/web/src/pages/generate/hooks/useStepNavigation.ts
T
saas-agent d9aa362bbf
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (pull_request) Successful in 2s
CI/CD Pipeline / Check push changed paths (pull_request) Has been skipped
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 1s
CI/CD Pipeline / Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / PR Build API Image (pull_request) Has been skipped
Preview Deploy / Deploy Preview Environment (pull_request) Failing after 58s
CI/CD Pipeline / Frontend Lint (pull_request) Failing after 55s
CI/CD Pipeline / PR Build Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
PR Automation / Auto Approve on CI Green (pull_request) Successful in 1m5s
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / Frontend Unit Tests (pull_request) Successful in 1m54s
CI/CD Pipeline / PR Build Web Image (pull_request) Failing after 1m58s
CI/CD Pipeline / Build Production API Image (pull_request) Has been cancelled
CI/CD Pipeline / Build Production Web Image (pull_request) Has been cancelled
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been cancelled
CI/CD Pipeline / Deploy Production (pull_request) Has been cancelled
CI/CD Pipeline / Production Browser E2E (pull_request) Has been cancelled
CI/CD Pipeline / Canary Release to Production (pull_request) Has been cancelled
CI/CD Pipeline / CI Gate (pull_request) Has been cancelled
CI/CD Pipeline / Validate - Style (pull_request) Has been cancelled
CI/CD Pipeline / Validate - Security (pull_request) Has been cancelled
CI/CD Pipeline / Validate - Python (mypy + alembic) (pull_request) Has been cancelled
AI Code Review / AI Code Review (pull_request) Has been cancelled
PR Automation / Auto Merge on CI Green + Approved (pull_request) Has been cancelled
feat(generate): #1970 智能剪辑流程重构 - 选择模式→素材→标题→确认→封面
## 主流程改造
- STEPS 改为 5 步:选择模式→选择素材→选择标题→确认生成→选择封面
- 原"选择配音"步骤从主流程移除,改为 Step1 下一步分支弹窗
- Step1 新组件 Step1EditMode:模式卡片(🎲随机混剪/📖叙事剪辑,紫底紫框) + 生成设置(数量-/+1-10、比例9:16/16:9、智能降重开关默认开)

## 新增 3 个弹窗
- VoiceSelectModal(随机混剪):复用配音库音频卡片+▶试听,无 TTS/克隆入口
- ScriptSelectModal(叙事剪辑):搜索框+300ms防抖+命中黄高亮+标签筛选(全部/带货/工厂/测评/教程/口播/种草)+max-height 420px 卡片列表
- TtsVoiceModal(叙事剪辑合成配音):Tabs(✨系统音色/🎙️我的克隆音色) + 2列音色卡片 + 合成按钮 + loading(spinner+"正在合成配音..."+"通常10-30秒")

## Step2 素材页
- 叙事剪辑模式显示"🤖 AI智能匹配"紫色提示卡

## Step4 确认页
- 摘要卡片按 editMode 展示剪辑模式+配音来源/文案标题+TTS音色+比例+降重

## payload 新增字段
- assembly_mode('random'|'narrative')、script_id、tts_voice_id、tts_voice_source('preset'|'clone')、dedup_enabled(默认true)、video_ratio('9:16')

## 不改动
- Step3/Step5 内容、文案库/配音库页面、AI数字人
2026-09-17 23:37:39 +08:00

91 lines
3.0 KiB
TypeScript

/**
* GeneratePage 步骤导航(#1970 流程重构)
* 步骤:选择模式(1) → 选择素材(2) → 选择标题(3) → 确认生成(4) → 选择封面(5)
*
* - 步骤1(选择模式):下一步分支由外层弹窗处理(VoiceSelectModal / ScriptSelectModal),
* 本 hook 的 goNext 仅在未选模式时拦截;外层 Modal onConfirm 里主动 setCurrentStep(2)。
* - 步骤2(选择素材):弹数量选择弹窗(PreviewCountModal),确认后跳步骤3。
* - 步骤3 底部按钮是「确认生成视频」(由 GenerateStepActions 调 onConfirmGenerate),
* 创建成功后跳步骤4;本 hook 的 goNext 只负责 2→3 和 4→5 的「下一步」。
* - 步骤4(确认生成进度页):全部渲染完成后「下一步」解锁进封面。
*/
import { message } from "antd"
import type { TitleSettings } from "../types"
import type { EditMode } from "../components/Step1EditMode"
export interface UseStepNavigationOptions {
currentStep: number
setCurrentStep: (step: number | ((prev: number) => number)) => void
editMode: EditMode
materialMode: "manual" | "auto"
selectedMaterials: string[]
smartSelectedIds: string[]
titleSettings: TitleSettings
/** 是否已完成视频生成(步骤4全部渲染完成后才能进入封面) */
generated: boolean
/** 点素材下一步时弹出数量选择弹窗 */
onOpenCountModal: () => void
/** 步骤1下一步:根据 editMode 打开对应弹窗(随机→配音 / 叙事→文案) */
onOpenStep1Modal: () => void
}
export interface UseStepNavigationReturn {
goNext: () => void
goPrev: () => void
}
export const useStepNavigation = (options: UseStepNavigationOptions): UseStepNavigationReturn => {
const {
currentStep,
setCurrentStep,
materialMode,
selectedMaterials,
smartSelectedIds,
generated,
onOpenCountModal,
onOpenStep1Modal,
} = options
const goNext = () => {
if (currentStep === 1) {
// 步骤1:先校验素材/配音等由弹窗负责,goNext 只负责触发弹窗
onOpenStep1Modal()
return
}
if (currentStep === 2) {
// 素材校验
if (materialMode === "manual" && selectedMaterials.length === 0) {
message.warning("请至少选择一个素材")
return
}
if (materialMode === "auto" && smartSelectedIds.length === 0) {
message.warning("请先进行智能匹配并选择素材")
return
}
// 弹数量选择弹窗
onOpenCountModal()
return
}
// 步骤4(确认生成):全部渲染完成后才能下一步进封面
if (currentStep === 4) {
if (!generated) {
message.warning("视频还在渲染中,请等待生成完成")
return
}
}
if (currentStep < 5) {
setCurrentStep((s) => s + 1)
}
}
const goPrev = () => {
if (currentStep > 1) {
setCurrentStep((s) => s - 1)
}
}
return { goNext, goPrev }
}
export default useStepNavigation