diff --git a/src/features/script/components/ScriptGenerator.tsx b/src/features/script/components/ScriptGenerator.tsx index 6526793d..9cb4a048 100644 --- a/src/features/script/components/ScriptGenerator.tsx +++ b/src/features/script/components/ScriptGenerator.tsx @@ -22,21 +22,17 @@ import { Alert } from '@/components/ui/alert'; import { Badge } from '@/components/ui/badge'; import { Button } from '@/components/ui/button'; import { Card as CardBase } from '@/components/ui/card'; +import { Input } from '@/components/ui/input'; import { Progress } from '@/components/ui/progress'; import { Tag } from '@/components/ui/tag'; import { Text, Title, Paragraph } from '@/components/ui/typography'; import { - Form, - FormItem, - useForm, - Input, Select, Space, Divider, RadioGroup, Radio, RadioButton, - type FormValues, } from '@/components/ui/ui-components'; import { useModel, useModelCost } from '@/core/hooks/useModel'; import { useProject } from '@/core/hooks/useProject'; @@ -111,7 +107,30 @@ export function ScriptGenerator({ const { selectedModel, isConfigured } = useModel(); const { estimateScriptCost, formatCost } = useModelCost(); - const form = useForm(); + // form refactor 2026-06-04: removed
//useForm AntD-style bridge. + // The script generator config is a flat bag of 8 primitive fields with no + // cross-field validation, so plain useState is the simplest correct form + // library here. The handleGenerate callback already received a FormValues + // dict from onFinish — rewrap the 8 fields into the same shape. + const [topic, setTopic] = useState(''); + const [keywords, setKeywords] = useState([]); + const [style, setStyle] = useState('professional'); + const [tone, setTone] = useState('friendly'); + const [length, setLength] = useState('medium'); + const [audience, setAudience] = useState('general'); + const [language, setLanguage] = useState('zh'); + const [requirements, setRequirements] = useState(''); + + const buildFormValues = () => ({ + topic, + keywords, + style, + tone, + length, + audience, + language, + requirements, + }); const [isGenerating, setIsGenerating] = useState(false); const [progress, setProgress] = useState(0); const [generatedScript, setGeneratedScript] = useState(null); @@ -119,16 +138,16 @@ export function ScriptGenerator({ // 估算成本 const estimatedCost = useCallback(() => { - const length = form.getValues?.()?.length || 'medium'; - const wordCount = LENGTH_OPTIONS.find((l) => l.value === length)?.words || '500-800字'; + const currentLength = buildFormValues().length; + const wordCount = LENGTH_OPTIONS.find((l) => l.value === currentLength)?.words || '500-800字'; const avgWords = parseInt(wordCount.split('-')[0]) + 200; return formatCost(estimateScriptCost(avgWords)); - }, [form, estimateScriptCost, formatCost]); + }, [buildFormValues, estimateScriptCost, formatCost]); // 生成脚本 const handleGenerate = useCallback( - async (values: FormValues) => { - const formData = values as ScriptFormValues; + async (values?: ScriptFormValues) => { + const formData = values ?? (buildFormValues() as unknown as ScriptFormValues); if (!selectedModel) { toast.warning('请先选择 AI 模型'); setShowModelSelector(true); @@ -203,8 +222,8 @@ export function ScriptGenerator({ // 重新生成 const handleRegenerate = useCallback(() => { - form.handleSubmit(handleGenerate)(); - }, [form, handleGenerate]); + void handleGenerate(); + }, [handleGenerate]); return (
@@ -260,84 +279,81 @@ export function ScriptGenerator({ - {/* 生成表单 */} - / 桥接被移除,改为原生 + 受控 state */} + { + e.preventDefault(); + void handleGenerate(); }} className={styles.form} > - - } /> - - - - ({ value: opt.value, label: opt.label }))} - /> - - - - - 中文 - English - - - - -