diff --git a/CHANGELOG.md b/CHANGELOG.md index d530429..d2fb07f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -418,6 +418,12 @@ - 任务恢复链里的失败提示统一成“先补信息 / 需人工处理”,不再弹出“暂不支持自动恢复”这类生硬口径。 - `额度` 页把“后续再接真实套餐”改成当前就能落地的套餐表达,明确按预算、动作池和项目阶段去配置套餐。 +### 基于任务继续生产的视频动作统一改成 direct-execute + +- 所有通过 `renderPipelineJobTag()` 渲染出来的 `做 AI 视频 / 做实拍剪辑`,现在都会直接走 `OneLiner` 执行器,不再落回旧的 `job-to-*` 表单打开流。 +- 从任务详情、复盘列表、生产中心等位置点这些动作时,会先关闭当前详情层,再直接创建对应任务并跳到真实任务详情,和文案生成链保持一致。 +- 前端回归新增了 `PIPELINE_GUARDS -> direct-create-*` 的断言,避免后续映射退回旧入口。 + ### 文案生成也并进 direct-execute - `任务详情 -> 用摘要写文案` 和旧的 `job-to-generate-copy` 现在都会直接走 `OneLiner` 执行器,不再先弹回传统文案表单。 diff --git a/web/storyforge-web-v4/assets/app.js b/web/storyforge-web-v4/assets/app.js index e5d3a3b..1c717d4 100644 --- a/web/storyforge-web-v4/assets/app.js +++ b/web/storyforge-web-v4/assets/app.js @@ -205,13 +205,13 @@ const PIPELINE_GUARDS = { aiVideo: { label: "AI 视频", openAction: "open-ai-video", - jobAction: "job-to-ai-video", + jobAction: "direct-create-ai-video", dependencies: ["n8n", "huobao"] }, realCut: { label: "实拍剪辑", openAction: "open-real-cut", - jobAction: "job-to-real-cut", + jobAction: "direct-create-real-cut", dependencies: ["n8n", "cutvideo"] } }; @@ -12397,6 +12397,9 @@ document.addEventListener("click", async (event) => { return; } if (name === "direct-create-ai-video") { + if (action.dataset.jobId) { + closeActionModal(); + } await runDirectWorkbenchAction("create-ai-video", { busyLabel: "正在创建 AI 视频任务...", errorTitle: "创建 AI 视频任务失败", @@ -12409,6 +12412,9 @@ document.addEventListener("click", async (event) => { return; } if (name === "direct-create-real-cut") { + if (action.dataset.jobId) { + closeActionModal(); + } await runDirectWorkbenchAction("create-real-cut", { busyLabel: "正在创建实拍剪辑任务...", errorTitle: "创建实拍剪辑任务失败", diff --git a/web/storyforge-web-v4/tests/workbench-pages.test.mjs b/web/storyforge-web-v4/tests/workbench-pages.test.mjs index bc3be28..16e1cf7 100644 --- a/web/storyforge-web-v4/tests/workbench-pages.test.mjs +++ b/web/storyforge-web-v4/tests/workbench-pages.test.mjs @@ -394,6 +394,16 @@ test("job detail and follow-up flows use direct generate-copy execution and pers assert.match(clickActions, /name === "job-to-generate-copy"[\s\S]*runDirectWorkbenchAction\("generate-copy"/); }); +test("pipeline follow-up tags route source-job actions through direct execute handlers", () => { + const pipelineGuards = extractBetween(APP, "const PIPELINE_GUARDS = {", "const ONELINER_INTENT_LABELS = {"); + const clickActions = extractBetween(APP, "document.addEventListener(\"click\", async (event) => {", "document.addEventListener(\"submit\", async (event) => {"); + + assert.match(pipelineGuards, /jobAction:\s*"direct-create-ai-video"/); + assert.match(pipelineGuards, /jobAction:\s*"direct-create-real-cut"/); + assert.match(clickActions, /name === "direct-create-ai-video"[\s\S]*if \(action\.dataset\.jobId\) \{[\s\S]*closeActionModal\(\);/); + assert.match(clickActions, /name === "direct-create-real-cut"[\s\S]*if \(action\.dataset\.jobId\) \{[\s\S]*closeActionModal\(\);/); +}); + test("discovery and production screens expose compact mobile flow summaries", () => { const discovery = extractBetween(APP, "function renderDiscoveryScreen()", "function renderTrackingScreen()"); const production = extractBetween(APP, "function renderProductionScreen()", "function renderReviewScreen()");