diff --git a/apps/web/src/pages/generate/hooks/useGenerateVideo.ts b/apps/web/src/pages/generate/hooks/useGenerateVideo.ts index 1507d6e30..1abe14a44 100644 --- a/apps/web/src/pages/generate/hooks/useGenerateVideo.ts +++ b/apps/web/src/pages/generate/hooks/useGenerateVideo.ts @@ -9,27 +9,11 @@ import { generateEditPlan, updateEditPlan, getEditPlan } from "@/api/template-ed import type { UseGenerateVideoProps } from "./generate-video/types" import { getGenerationPhase } from "./generate-video/phase" import { useGenerationPolling } from "./generate-video/useGenerationPolling" -import { buildVoiceConfig } from "./generate-video/voiceConfig" +import { buildEditPlanPayload, validateGenerateInputs } from "./generate-video/buildPayload" import { extractBackendError, translateError } from "./generate-video/errorUtils" export function useGenerateVideo(props: UseGenerateVideoProps) { - const { - titleSettings, - selectedTemplate, - selectedMaterials, - materialMode, - smartSelectedIds, - voiceMode, - selectedVoice, - selectedClonedVoice, - coverSettings, - videoRatio, - style, - duration, - autoSubtitles, - bgm, - generateCount, - } = props + const { selectedTemplate } = props /* ── 生成状态 ── */ const [generating, setGenerating] = useState(false) @@ -58,16 +42,9 @@ export function useGenerateVideo(props: UseGenerateVideoProps) { /* ── 生成视频 ── */ const generate = useCallback(async () => { - if (!titleSettings.title.trim()) { - message.warning("请先选择或输入标题") - return - } - if (materialMode === "manual" && selectedMaterials.length === 0) { - message.warning("请至少选择一个素材") - return - } - if (voiceMode === "clone" && !selectedClonedVoice) { - message.warning("请先选择一个克隆音色") + const errorMsg = validateGenerateInputs(props) + if (errorMsg) { + message.warning(errorMsg) return } @@ -78,41 +55,13 @@ export function useGenerateVideo(props: UseGenerateVideoProps) { clearTimer() try { - const voiceConfig = buildVoiceConfig({ - voiceMode, - selectedVoice, - selectedClonedVoice, - }) + const payload = buildEditPlanPayload(props) // 获取或创建草稿 await getEditPlan(selectedTemplate) // 更新草稿内容 + 切换到 editing 状态 - await updateEditPlan(selectedTemplate, { - name: titleSettings.title.trim(), - config: { - asset_ids: materialMode === "auto" ? smartSelectedIds : selectedMaterials, - title_config: { - ai_auto_select: titleSettings.aiAutoSelect, - content: titleSettings.title, - position: titleSettings.position, - font_preset: titleSettings.font, - font_color: titleSettings.color, - font_size: titleSettings.size, - }, - cover_config: coverSettings, - ...voiceConfig, - ratio: videoRatio, - style, - duration, - auto_subtitles: autoSubtitles, - bgm, - generate_count: generateCount, - material_mode: materialMode, - }, - total_duration: duration, - status: "editing", - }) + await updateEditPlan(selectedTemplate, payload) await generateEditPlan(selectedTemplate) startPolling() @@ -125,25 +74,7 @@ export function useGenerateVideo(props: UseGenerateVideoProps) { setGenerateError(finalMsg) message.error(finalMsg) } - }, [ - titleSettings, - selectedMaterials, - selectedVoice, - voiceMode, - selectedClonedVoice, - videoRatio, - style, - duration, - autoSubtitles, - bgm, - selectedTemplate, - generateCount, - materialMode, - coverSettings, - smartSelectedIds, - clearTimer, - startPolling, - ]) + }, [props, selectedTemplate, clearTimer, startPolling]) /* 重新生成(失败后重试) */ const retry = useCallback(() => { @@ -209,3 +140,4 @@ export function useGenerateVideo(props: UseGenerateVideoProps) { } export default useGenerateVideo +