Compare commits

...

1 Commits

Author SHA1 Message Date
xiaoxia 0240e2f58b fix(#1341): 修复智能剪辑封面生成的 3 个问题
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 42s
CI/CD Pipeline / Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / PR Build API Image (pull_request) Has been skipped
CI/CD Pipeline / PR Build Worker Image (pull_request) Has been skipped
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 1m47s
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 2m2s
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 2m2s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Successful in 1m20s
CI/CD Pipeline / Frontend Lint (pull_request) Failing after 1m27s
Preview Deploy / Deploy Preview Environment (pull_request) Failing after 2m12s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 2m14s
CI/CD Pipeline / PR Build Web Image (pull_request) Failing after 2m47s
CI/CD Pipeline / Validate - Code Quality (pull_request) Successful in 5m45s
CI/CD Pipeline / Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Canary Release to Production (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
CI/CD Pipeline / CI Gate (pull_request) Failing after 5s
AI Code Review / AI Code Review (pull_request) Successful in 6m51s
ACR Cleanup / ACR Image Cleanup (pull_request_target) Has been cancelled
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 47s
A. generatingRef 卡死 → 改用 useState + 300秒超时保护
B. Step6 缺少进度弹窗 → 添加 Modal + Spin 进度提示
C. 预览视频 URL 没回写 → 预览完成后保存到 plan.config.rendered_storage_key
2026-08-12 16:49:16 +08:00
4 changed files with 37 additions and 5 deletions
@@ -118,6 +118,10 @@ export interface EditPlanConfig {
generate_count?: number
/** 素材模式 */
material_mode?: string
/** 预览视频 URL(封面生成用) */
rendered_storage_key?: string
/** 生成任务 ID */
generation_task_id?: string
}
/* ── 模板草稿主体 ── */
@@ -1,4 +1,5 @@
import React from "react"
import { Modal, Spin } from "antd"
import type { CoverConfig } from "../../editing-planner/types"
import { useStep6Cover } from "../hooks/useStep6Cover"
import Button from "@/components/ui/Button"
@@ -18,6 +19,7 @@ interface Step6CoverSettingsProps {
const Step6CoverSettings: React.FC<Step6CoverSettingsProps> = (props) => {
const {
coverSettings,
generating,
generateAutoCover,
showCoverSettings,
setShowCoverSettings,
@@ -95,6 +97,14 @@ const Step6CoverSettings: React.FC<Step6CoverSettingsProps> = (props) => {
template={editingTemplate}
onSave={handleSaveTemplate}
/>
{/* AI 生成封面进度弹窗 */}
<Modal open={generating} closable={false} footer={null} centered>
<div style={{ textAlign: "center", padding: "24px 0" }}>
<Spin size="large" />
<p style={{ marginTop: 16, fontSize: 14, color: "#666" }}>AI ...</p>
</div>
</Modal>
</div>
)
}
@@ -4,6 +4,7 @@
*/
import { useState, useCallback, useMemo, useEffect, useRef } from "react"
import { createPreview, getPreviewStatus } from "@/api/generation"
import { updateEditPlan } from "@/api/template-editor/editPlans"
import type { PreviewTaskResponse, PreviewStatus as ApiPreviewStatus } from "@/api/generation"
import type { EditingTemplate } from "@/api/editing-planner"
import { safeExtractError } from "./generate-video/errorUtils"
@@ -250,6 +251,15 @@ export function useStep4Preview({
it.index === index ? { ...it, status: "ready", result, progress: 100 } : it,
),
)
// 保存预览视频 URL 到 plan config,供封面生成使用
if (result.videoUrl && selectedTemplate) {
updateEditPlan(selectedTemplate, {
config: { rendered_storage_key: result.videoUrl } as any,
}).catch((err) => {
console.warn("[Step4] 保存预览视频URL到plan config失败:", err)
})
}
return
}
@@ -30,7 +30,7 @@ export function useStep6Cover({
assetIds = [],
selectedTemplate = "",
}: UseStep6CoverProps) {
const generatingRef = useRef(false)
const [generating, setGenerating] = useState(false)
// ── 封面设置弹窗状态 ──
const [showCoverSettings, setShowCoverSettings] = useState(false)
@@ -67,7 +67,7 @@ export function useStep6Cover({
/** 调用后端智能封面 API,生成封面并更新预览 */
const generateAutoCover = useCallback(async () => {
if (generatingRef.current) {
if (generating) {
message.warning("封面正在生成中,请稍候...")
return
}
@@ -82,12 +82,17 @@ export function useStep6Cover({
return
}
generatingRef.current = true
setGenerating(true)
// 超时保护:300 秒后强制重置,防止 state 卡死导致按钮永久失效
const timeoutId = setTimeout(() => {
setGenerating(false)
}, 300000)
try {
const response = await generateCover(selectedTemplate, {
asset_ids: assetIds,
cover_type: "ai_frame",
})
clearTimeout(timeoutId)
const thumbnailUrl = response.cover?.image_url || ""
if (thumbnailUrl) {
onCoverSettingsChange({
@@ -100,12 +105,14 @@ export function useStep6Cover({
message.warning("封面生成未返回图片,请重试")
}
} catch (err) {
clearTimeout(timeoutId)
console.warn("[Step6] 智能封面生成失败:", err)
message.error("封面生成失败,请稍后重试")
} finally {
generatingRef.current = false
clearTimeout(timeoutId)
setGenerating(false)
}
}, [selectedTemplate, assetIds, coverSettings, onCoverSettingsChange])
}, [selectedTemplate, assetIds, coverSettings, onCoverSettingsChange, generating])
// ── 模板操作方法 ──
const handleSelectTemplate = useCallback((id: string) => {
@@ -165,6 +172,7 @@ export function useStep6Cover({
return {
coverSettings,
generating,
generateAutoCover,
totalDuration,
showCoverSettings,