From beabc932e61a0dfd7cdff3ff18a54f9b96cf4a38 Mon Sep 17 00:00:00 2001 From: xiaoxia Date: Tue, 21 Jul 2026 10:33:47 +0800 Subject: [PATCH] =?UTF-8?q?fix(web):=20=E4=BF=AE=E5=A4=8D=E7=94=9F?= =?UTF-8?q?=E6=88=90=E9=A1=B5=20API=20=E8=B0=83=E7=94=A8=E9=80=82=E9=85=8D?= =?UTF-8?q?=E6=96=B0=E6=A8=A1=E6=9D=BF=E7=BC=96=E8=BE=91=E5=99=A8=E6=9E=B6?= =?UTF-8?q?=E6=9E=84=20(#671)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: xiaoxia Co-committed-by: xiaoxia --- apps/web/e2e/core-generation.spec.ts | 29 +++++++++---------- apps/web/src/pages/generate/GeneratePage.tsx | 24 +++++++-------- .../voice-materials/VoiceMaterialLibrary.tsx | 0 apps/web/src/test/pages/GeneratePage.test.tsx | 21 +++++++++++--- 4 files changed, 42 insertions(+), 32 deletions(-) mode change 100755 => 100644 apps/web/src/pages/generate/GeneratePage.tsx mode change 100755 => 100644 apps/web/src/pages/voice-materials/VoiceMaterialLibrary.tsx diff --git a/apps/web/e2e/core-generation.spec.ts b/apps/web/e2e/core-generation.spec.ts index bd33efec8..d4e4fb6d8 100755 --- a/apps/web/e2e/core-generation.spec.ts +++ b/apps/web/e2e/core-generation.spec.ts @@ -219,16 +219,14 @@ test.describe("Core generation flow", () => { // Step 7: confirm and generate await expect(page.getByRole("heading", { name: /确认生成/ })).toBeVisible() - // Wait for plan creation API to be called - // 精确匹配 POST /template-editors(创建接口),排除所有子路径(/generate, /clips, /ai-recommend 等) - const createPlanPromise = page.waitForResponse( + // Wait for generation API to be called + // 新架构:GET 草稿自动创建 → PUT 更新内容 → POST /generate 触发生成 + // 等 generate 接口返回,确认生成流程启动 + const generatePromise = page.waitForResponse( (response) => { const url = response.url() const path = new URL(url).pathname - return ( - response.request().method() === "POST" && - (path.endsWith("/templates/drafts") || path.endsWith("/templates/drafts/")) - ) + return response.request().method() === "POST" && path.endsWith("/editor/generate") }, { timeout: 30_000 }, ) @@ -236,17 +234,18 @@ test.describe("Core generation flow", () => { // Click generate button await page.locator(".xx-btn-primary").filter({ hasText: "确认生成" }).first().click() - // Verify plan was created successfully - const planResp = await createPlanPromise - if (!planResp.ok()) { - const body = await planResp.text() + // Verify generation was triggered successfully + const genResp = await generatePromise + if (!genResp.ok()) { + const body = await genResp.text() console.error( - `[E2E DEBUG] 创建计划接口失败: status=${planResp.status()} url=${planResp.url()} body=${body.slice(0, 500)}`, + `[E2E DEBUG] 触发生成接口失败: status=${genResp.status()} url=${genResp.url()} body=${body.slice(0, 500)}`, ) } - expect(planResp.ok()).toBeTruthy() - const planData = (await planResp.json()) as { id: string } - expect(planData.id).toBeTruthy() + expect(genResp.ok()).toBeTruthy() + const genData = (await genResp.json()) as { plan_id: string; generation_task_id: string } + expect(genData.plan_id).toBeTruthy() + expect(genData.generation_task_id).toBeTruthy() // Generation may fail in test env (no worker), that's OK // Just verify the flow started - check page shows generation-related UI diff --git a/apps/web/src/pages/generate/GeneratePage.tsx b/apps/web/src/pages/generate/GeneratePage.tsx old mode 100755 new mode 100644 index 27df1161a..d95ce718d --- a/apps/web/src/pages/generate/GeneratePage.tsx +++ b/apps/web/src/pages/generate/GeneratePage.tsx @@ -25,11 +25,11 @@ import { import type { AssetItem } from "@/api/assets" import { getAssets, getAssetLibraries } from "@/api/assets" import { - createEditPlan, generateEditPlan, updateEditPlan, getGenerationTaskResults, getGenerationStatus, + getEditPlan, } from "@/api/templateEditor" import type { GeneratedVideo, EditPlanConfig, TitleConfig } from "@/api/templateEditor" import type { CoverConfig } from "../editing-planner/types" @@ -44,7 +44,6 @@ import { synthesizeSpeech, getTTSJobStatus, saveTtsToLibrary } from "@/api/tts" import { getTags, createTag } from "@/api/tags" import { useCloneProgress } from "@/hooks/useCloneProgress" import { useSearchParams, useNavigate } from "react-router-dom" -import { getEditPlan } from "@/api/templateEditor" import "./generate.css" const { Text } = Typography @@ -994,8 +993,11 @@ const GeneratePage: React.FC = () => { if (customVoiceText.trim()) voiceConfig.custom_text = customVoiceText.trim() } - const plan = await createEditPlan({ - template_id: selectedTemplate, + // 获取或创建草稿(新架构:GET /templates/{templateId}/editor 自动创建) + await getEditPlan(selectedTemplate) + + // 更新草稿内容 + 切换到 editing 状态 + await updateEditPlan(selectedTemplate, { name: titleSettings.title.trim(), config: { asset_ids: materialMode === "auto" ? smartSelectedIds : selectedMaterials, @@ -1018,17 +1020,14 @@ const GeneratePage: React.FC = () => { material_mode: materialMode, }, total_duration: duration, - source_edit_plan_id: editPlanId || undefined, + status: "editing", }) - // 后端要求计划处于 editing 状态才能触发渲染,自动转换状态 - await updateEditPlan(plan.id, { status: "editing" }) - - await generateEditPlan(plan.id) + await generateEditPlan(selectedTemplate) const poll = async () => { try { - const data = await getGenerationStatus(plan.id) + const data = await getGenerationStatus(selectedTemplate) if (data.plan_status === "completed") { setProgress(100) @@ -1075,7 +1074,7 @@ const GeneratePage: React.FC = () => { return String(val ?? "") } const errorMsg = safeExtract(rawMsg) - console.error("[生成失败] planId:", plan.id, "响应:", data) + console.error("[生成失败] templateId:", selectedTemplate, "响应:", data) setGenerateError(errorMsg) message.error(errorMsg) return @@ -1091,7 +1090,7 @@ const GeneratePage: React.FC = () => { > } catch (pollErr) { // 轮询接口本身出错(网络/鉴权等),记录并继续轮询一次 - console.error("[轮询出错] planId:", plan.id, pollErr) + console.error("[轮询出错] templateId:", selectedTemplate, pollErr) progressTimer.current = setTimeout(poll, 3000) as unknown as ReturnType< typeof setInterval > @@ -1198,7 +1197,6 @@ const GeneratePage: React.FC = () => { duration, autoSubtitles, bgm, - editPlanId, selectedTemplate, generateCount, materialMode, diff --git a/apps/web/src/pages/voice-materials/VoiceMaterialLibrary.tsx b/apps/web/src/pages/voice-materials/VoiceMaterialLibrary.tsx old mode 100755 new mode 100644 diff --git a/apps/web/src/test/pages/GeneratePage.test.tsx b/apps/web/src/test/pages/GeneratePage.test.tsx index f85c14af8..25b4975fc 100644 --- a/apps/web/src/test/pages/GeneratePage.test.tsx +++ b/apps/web/src/test/pages/GeneratePage.test.tsx @@ -214,10 +214,23 @@ vi.mock("@/api/titles", () => ({ })) vi.mock("@/api/templateEditor", () => ({ - createEditPlan: vi.fn().mockResolvedValue({ id: "test-plan" }), - generateEditPlan: vi.fn().mockResolvedValue({ task_id: "test-task" }), - updateEditPlan: vi.fn().mockResolvedValue({}), - getEditPlan: vi.fn().mockResolvedValue({}), + generateEditPlan: vi.fn().mockResolvedValue({ + plan_id: "test-plan", + generation_task_id: "test-task", + plan_status: "processing", + clip_count: 5, + }), + updateEditPlan: vi.fn().mockResolvedValue({ plan_id: "test-plan", template_id: "test-template" }), + getEditPlan: vi.fn().mockResolvedValue({ + plan_id: "test-plan", + template_id: "test-template", + name: "", + config: {}, + status: "draft", + }), + getGenerationStatus: vi + .fn() + .mockResolvedValue({ plan_status: "completed", generation_task_id: "test-task", clips: [] }), getGenerationTaskResults: vi.fn().mockResolvedValue({ items: [] }), }))