/** * Step 7 确认生成 Hook * 封装生成确认页的展示逻辑 */ import { useMemo } from "react" import { useQuery } from "@tanstack/react-query" import type { EditingTemplate } from "@/api/editing-planner" import type { GeneratedVideo } from "@/api/template-editor" import type { CoverConfig } from "../types/cover" import type { VoiceClone } from "@/api/voice-clone" import type { PresetVoiceItem } from "@/api/voices" import { getAssetsByKind } from "@/api/assets" import { COVER_MODE_LABELS } from "../constants" interface UseStep7GenerateProps { templates: EditingTemplate[] selectedTemplate: string materialMode: "manual" | "auto" selectedMaterials: string[] smartSelectedIds: string[] title: string voiceMode: "preset" | "custom" | "clone" selectedVoice: string selectedClonedVoice: string presetVoices: PresetVoiceItem[] clonedVoices: VoiceClone[] coverSettings: CoverConfig generateCount: number onGenerateCountChange: (count: number) => void generating: boolean generated: boolean generateError: string | null progress: number generatedVideos: GeneratedVideo[] } export function useStep7Generate({ templates, selectedTemplate, materialMode, selectedMaterials, smartSelectedIds, title, voiceMode: _voiceMode, selectedVoice, selectedClonedVoice: _selectedClonedVoice, presetVoices: _presetVoices, clonedVoices: _clonedVoices, coverSettings, generateCount, onGenerateCountChange, generating, generated, generateError, progress, generatedVideos, }: UseStep7GenerateProps) { const templateName = useMemo( () => templates.find((t) => t.id === selectedTemplate)?.name ?? "未选择", [templates, selectedTemplate], ) const materialSummary = useMemo(() => { if (materialMode === "auto") { return `${smartSelectedIds.length} 个素材(智能匹配)` } return `${selectedMaterials.length} 个素材` }, [materialMode, selectedMaterials.length, smartSelectedIds.length]) // 从配音素材库中查找 voiceName const { data: voiceMaterials = [] } = useQuery({ queryKey: ["assets", "voice"], queryFn: () => getAssetsByKind("voice", { limit: 50 }), }) const voiceName = useMemo(() => { const asset = voiceMaterials.find((v) => v.id === selectedVoice) return asset ? asset.name : "未选择" }, [voiceMaterials, selectedVoice]) const coverSummary = useMemo(() => { if (!coverSettings.enabled) return "不使用" return COVER_MODE_LABELS[coverSettings.mode] || "智能封面" }, [coverSettings]) const getGenerationPhase = (p: number) => { if (p < 20) return { label: "分析素材与配置", icon: "🔍" } if (p < 50) return { label: "智能剪辑合成", icon: "🎬" } if (p < 80) return { label: "渲染视频中", icon: "⚡" } return { label: "即将完成", icon: "✨" } } const handleDecrement = () => { onGenerateCountChange(Math.max(1, generateCount - 1)) } const handleIncrement = () => { onGenerateCountChange(Math.min(10, generateCount + 1)) } const handleScrollToPreview = () => { const el = document.querySelector(".xx-preview-section") el?.scrollIntoView({ behavior: "smooth", block: "start" }) } return { templateName, materialSummary, title, voiceName, coverSummary, generateCount, handleDecrement, handleIncrement, generating, generated, generateError, progress, generatedVideos, getGenerationPhase, handleScrollToPreview, } } export default useStep7Generate