From 31bc1d1996b770c89e702b2fa89faec1984d5944 Mon Sep 17 00:00:00 2001 From: xiaoxia Date: Mon, 20 Jul 2026 08:23:56 +0800 Subject: [PATCH] =?UTF-8?q?fix(phase9):=20=E4=BF=AE=E5=A4=8Deslint?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E4=B8=8Eunit=20test=E6=97=B6=E5=BA=8F?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 删除未使用的CheckCircleOutlined import - 将SMART_MATCH_REASONS和AI_TITLE_TEMPLATES移到组件外,消除react-hooks/exhaustive-deps警告 - presetVoices使用useMemo包裹,避免引用不稳定导致的依赖警告 - 将handleRetryGenerate移到handleGenerate定义之后,修复TDZ初始化时序错误 --- apps/web/src/pages/generate/GeneratePage.tsx | 67 ++++++++++---------- 1 file changed, 35 insertions(+), 32 deletions(-) diff --git a/apps/web/src/pages/generate/GeneratePage.tsx b/apps/web/src/pages/generate/GeneratePage.tsx index 6581ba83b..02e846f65 100755 --- a/apps/web/src/pages/generate/GeneratePage.tsx +++ b/apps/web/src/pages/generate/GeneratePage.tsx @@ -4,14 +4,13 @@ * 左右布局:左侧 generate-form + 右侧 generate-preview * 保留所有现有业务逻辑(API 调用、URL 参数、CloneModal、TTS 等) */ -import React, { useState, useRef, useCallback, useEffect } from "react" +import React, { useState, useRef, useCallback, useEffect, useMemo } from "react" import { useQuery, useMutation } from "@tanstack/react-query" import { Typography, message, Select, Modal } from "antd" import { AudioOutlined, ThunderboltOutlined, CheckCircleFilled, - CheckCircleOutlined, CloseCircleOutlined, LoadingOutlined, PlayCircleOutlined, @@ -253,6 +252,30 @@ const SMART_MATCH_REASONS = [ "人物表情生动", ] +const AI_TITLE_TEMPLATES: Record = { + catchy: [ + "震惊!{topic}居然还能这样操作", + "99%的人都不知道的{topic}秘诀", + "{topic}的终极指南,看完直接封神", + "别再走弯路了!{topic}看这一篇就够", + "一个视频讲透{topic},建议收藏", + ], + emotional: [ + "致每一个在{topic}路上坚持的人", + "关于{topic},我想说句真心话", + "{topic}背后的故事,看完沉默了", + "为什么我劝你一定要了解{topic}", + "这才是{topic}最动人的样子", + ], + informative: [ + "{topic}完整科普:从入门到精通", + "深度解析{topic}的核心原理", + "{topic}行业趋势报告|2026最新版", + "三分钟带你全面了解{topic}", + "{topic}常见问题与解决方案汇总", + ], +} + /* ================================================================ 组件 ================================================================ */ @@ -466,7 +489,10 @@ const GeneratePage: React.FC = () => { queryKey: ["preset-voices"], queryFn: fetchPresetVoices, }) - const presetVoices: PresetVoiceItem[] = presetVoicesData?.items ?? [] + const presetVoices: PresetVoiceItem[] = useMemo( + () => presetVoicesData?.items ?? [], + [presetVoicesData], + ) /* ── TTS 自定义合成状态 ── */ const [customAudioUrl, setCustomAudioUrl] = useState(null) @@ -598,29 +624,6 @@ const GeneratePage: React.FC = () => { }, []) /* ── 智能标题生成 ── */ - const AI_TITLE_TEMPLATES: Record = { - catchy: [ - "震惊!{topic}居然还能这样操作", - "99%的人都不知道的{topic}秘诀", - "{topic}的终极指南,看完直接封神", - "别再走弯路了!{topic}看这一篇就够", - "一个视频讲透{topic},建议收藏", - ], - emotional: [ - "致每一个在{topic}路上坚持的人", - "关于{topic},我想说句真心话", - "{topic}背后的故事,看完沉默了", - "为什么我劝你一定要了解{topic}", - "这才是{topic}最动人的样子", - ], - informative: [ - "{topic}完整科普:从入门到精通", - "深度解析{topic}的核心原理", - "{topic}行业趋势报告|2026最新版", - "三分钟带你全面了解{topic}", - "{topic}常见问题与解决方案汇总", - ], - } const extractTopic = (text: string): string => { const keywords = text @@ -766,12 +769,6 @@ const GeneratePage: React.FC = () => { return { label: "即将完成", icon: "✨" } } - /* 重新生成(失败后重试) */ - const handleRetryGenerate = useCallback(() => { - setGenerateError(null) - handleGenerate() - }, [handleGenerate]) - const handleCloneSuccess = useCallback( (voice: VoiceClone) => { addClone(voice) @@ -1209,6 +1206,12 @@ const GeneratePage: React.FC = () => { smartSelectedIds, ]) + /* 重新生成(失败后重试) */ + const handleRetryGenerate = useCallback(() => { + setGenerateError(null) + handleGenerate() + }, [handleGenerate]) + /* ── 下载视频 ── */ const handleDownload = useCallback(async () => { if (!generatedVideos.length) return