fix(#1677): AI Review 反馈修复——标题校验/TTS依赖收窄/排序健壮性/预览数硬上限
- 单视频标题校验与 buildPayload.validateGenerateInputs 对齐:aiAutoSelect 自动模式允许空标题(后端生成,既有设计),手动模式必填,逻辑显式化 - TTS 试听 effect 依赖收窄到 previewTitles[0](variant0Title),编辑其他 变体标题不再触发多余 TTS 请求 - BatchGenerationGrid 排序加 (variantIndex || 0) 兜底防 NaN - CanvasPreviewGrid 渲染数加 MAX_PREVIEW_COUNT(10) 硬上限,防媒体元素过多卡顿
This commit is contained in:
@@ -132,6 +132,8 @@ const GeneratePage: React.FC = () => {
|
||||
|
||||
const [previewVoiceAudioUrl, setPreviewVoiceAudioUrl] = useState<string | null>(null)
|
||||
const ttsAbortRef = useRef<AbortController | null>(null)
|
||||
// TTS 试听文案:批量跟随变体0标题(仅取首项,避免编辑其他变体标题触发多余 TTS 请求)
|
||||
const variant0Title = isBatch ? previewTitles[0] || "" : ""
|
||||
|
||||
useEffect(() => {
|
||||
const voiceAsset = voiceMaterials.find((m) => m.id === selectedVoice)
|
||||
@@ -141,7 +143,7 @@ const GeneratePage: React.FC = () => {
|
||||
}
|
||||
|
||||
// 批量模式下 TTS 文案跟随变体0标题;单视频跟随主标题
|
||||
const ttsTitle = isBatch ? previewTitles[0] || "" : titleSettings.title
|
||||
const ttsTitle = isBatch ? variant0Title || "" : titleSettings.title
|
||||
const voiceId = selectedClonedVoice || selectedVoice
|
||||
if (!voiceId || !ttsTitle) {
|
||||
setPreviewVoiceAudioUrl(null)
|
||||
@@ -174,7 +176,7 @@ const GeneratePage: React.FC = () => {
|
||||
selectedVoice,
|
||||
selectedClonedVoice,
|
||||
titleSettings.title,
|
||||
previewTitles,
|
||||
variant0Title,
|
||||
isBatch,
|
||||
voiceMaterials,
|
||||
])
|
||||
@@ -321,9 +323,13 @@ const GeneratePage: React.FC = () => {
|
||||
message.warning("请为每个勾选的视频输入标题")
|
||||
return
|
||||
}
|
||||
} else if (!titleSettings.aiAutoSelect && !titleSettings.title?.trim()) {
|
||||
message.warning("请先选择或输入标题")
|
||||
return
|
||||
} else if (!titleSettings.title?.trim()) {
|
||||
// 与 buildPayload.validateGenerateInputs 一致:AI 自动选标题模式(aiAutoSelect)
|
||||
// 允许空标题由后端生成;手动模式必须填写,避免提交空标题
|
||||
if (!titleSettings.aiAutoSelect) {
|
||||
message.warning("请先选择或输入标题")
|
||||
return
|
||||
}
|
||||
}
|
||||
if (!previewReady) {
|
||||
message.warning("预览素材正在加载,请稍候")
|
||||
|
||||
@@ -22,7 +22,7 @@ const BatchGenerationGrid: React.FC<BatchGenerationGridProps> = ({
|
||||
titles,
|
||||
onRetryTask,
|
||||
}) => {
|
||||
const sorted = [...tasks].sort((a, b) => a.variantIndex - b.variantIndex)
|
||||
const sorted = [...tasks].sort((a, b) => (a.variantIndex || 0) - (b.variantIndex || 0))
|
||||
|
||||
return (
|
||||
<div className="xx-form-section">
|
||||
|
||||
@@ -12,6 +12,7 @@ import type { AssetItem } from "@/api/assets"
|
||||
import type { EditingTemplate } from "@/api/editing-planner"
|
||||
import type { TitleSettings } from "../types"
|
||||
import FrontendPreviewPlayer from "./FrontendPreviewPlayer"
|
||||
import { MAX_PREVIEW_COUNT } from "../constants"
|
||||
|
||||
interface CanvasPreviewGridProps {
|
||||
count: number
|
||||
@@ -41,9 +42,11 @@ const CanvasPreviewGrid: React.FC<CanvasPreviewGridProps> = ({
|
||||
onToggleSelect,
|
||||
selectable = true,
|
||||
}) => {
|
||||
// 硬上限保护:同时播放的媒体元素数量不超过 MAX_PREVIEW_COUNT(10),避免浏览器卡顿
|
||||
const safeCount = Math.max(1, Math.min(count, MAX_PREVIEW_COUNT))
|
||||
return (
|
||||
<div className="xx-canvas-grid">
|
||||
{Array.from({ length: count }, (_, i) => {
|
||||
{Array.from({ length: safeCount }, (_, i) => {
|
||||
const checked = selectedIds.includes(i)
|
||||
return (
|
||||
<div
|
||||
|
||||
Reference in New Issue
Block a user