From 8ecbca9cb0cf2485d8f708b30d34302118982d62 Mon Sep 17 00:00:00 2001 From: kris Date: Mon, 6 Apr 2026 09:16:55 +0800 Subject: [PATCH] feat: prefer direct import and tracking updates --- CHANGELOG.md | 6 +++ web/storyforge-web-v4/assets/app.js | 43 +++++++++++++++++++ .../tests/workbench-pages.test.mjs | 6 +++ 3 files changed, 55 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a5247cd..fcfc67e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ ## 2026-04-06 +### 导入当前对标与更新跟踪账号开始优先直执行 + +- `导入当前对标` 在当前项目里已有内容源配置或可直接拿到主页链接时,会优先直接触发同步,而不是默认打开旧表单。 +- `更新跟踪账号` 在当前账号已经处于跟踪中时,会直接沿用现有跟踪配置触发更新;只有首次加入跟踪时才继续保留表单。 +- 这样 `找对标 -> 接入项目 / 跟踪` 这条链在有足够上下文时也收成了 direct-execute。 + ### 查相似与保存对标关系入口开始优先直执行 - `查相似` 入口在当前已经选中账号时,会优先直接触发相似账号搜索,而不是先打开旧表单。 diff --git a/web/storyforge-web-v4/assets/app.js b/web/storyforge-web-v4/assets/app.js index d9656af..ad9bcc8 100644 --- a/web/storyforge-web-v4/assets/app.js +++ b/web/storyforge-web-v4/assets/app.js @@ -12173,10 +12173,53 @@ document.addEventListener("click", async (event) => { return; } if (name === "open-import-selected-account") { + const account = getSelectedAccount(); + const project = getSelectedProject(); + if (account?.id && project?.id) { + const currentSource = getCurrentProjectSourcesForAccount(account, project.id)[0]; + const sourceUrl = String(currentSource?.source_url || getAccountProfileUrl(account) || "").trim(); + if (sourceUrl) { + await runDirectDiscoveryAction("import-homepage", { + source_url: sourceUrl, + title: currentSource?.title || `${getAccountName(account) || "当前对标"} 对标主页`, + handle: currentSource?.handle || getAccountHandle(account) || "", + assistant_id: currentSource?.assistant_id || getSelectedAssistant()?.id || "", + knowledge_base_id: getProjectKnowledgeBases(project.id)[0]?.id || "", + max_items: Number(currentSource?.metadata?.max_items || 6), + skip_existing: true, + auto_trigger_analysis: true + }, { + projectId: project.id, + platform: normalizePlatformValue(currentSource?.platform || getAccountPlatform(account)), + busyLabel: currentSource ? "正在继续同步当前对标..." : "正在导入当前对标...", + errorTitle: currentSource ? "继续同步当前对标失败" : "导入当前对标失败" + }); + return; + } + } openImportSelectedAccountAction(); return; } if (name === "open-track-selected-account") { + const account = getSelectedAccount(); + const trackedItem = account?.id + ? safeArray(appState.trackingAccounts).find((item) => item.tracked_account_id === account.id) + : null; + const project = getSelectedProject(); + if (account?.id && trackedItem && project?.id) { + await runDirectDiscoveryAction("track-account", { + target_account_id: account.id, + assistant_id: trackedItem.assistant_id || getSelectedAssistant()?.id || "", + note: trackedItem.note || "", + refresh_now: true + }, { + projectId: project.id, + platform: normalizePlatformValue(trackedItem.platform || getAccountPlatform(account)), + busyLabel: "正在更新跟踪账号...", + errorTitle: "更新跟踪失败" + }); + return; + } openTrackSelectedAccountAction(); return; } diff --git a/web/storyforge-web-v4/tests/workbench-pages.test.mjs b/web/storyforge-web-v4/tests/workbench-pages.test.mjs index b25ae78..220e690 100644 --- a/web/storyforge-web-v4/tests/workbench-pages.test.mjs +++ b/web/storyforge-web-v4/tests/workbench-pages.test.mjs @@ -1458,6 +1458,12 @@ test("smart discovery entrypoints prefer direct execute before falling back to f assert.match(clicks, /name === "open-benchmark-link"[\s\S]*const candidate = safeArray\(appState\.lastSimilaritySearch\?\.candidates\)\[0\] \|\| null;/); assert.match(clicks, /name === "open-benchmark-link"[\s\S]*runDirectDiscoveryAction\("save-benchmark-link"/); assert.match(clicks, /name === "open-benchmark-link"[\s\S]*openBenchmarkLinkAction\(\);/); + assert.match(clicks, /name === "open-import-selected-account"[\s\S]*const currentSource = getCurrentProjectSourcesForAccount\(account, project\.id\)\[0\];/); + assert.match(clicks, /name === "open-import-selected-account"[\s\S]*runDirectDiscoveryAction\("import-homepage"/); + assert.match(clicks, /name === "open-import-selected-account"[\s\S]*openImportSelectedAccountAction\(\);/); + assert.match(clicks, /name === "open-track-selected-account"[\s\S]*const trackedItem = account\?\.id/); + assert.match(clicks, /name === "open-track-selected-account"[\s\S]*runDirectDiscoveryAction\("track-account"/); + assert.match(clicks, /name === "open-track-selected-account"[\s\S]*openTrackSelectedAccountAction\(\);/); }); test("declared static workbench actions are wired into explicit handlers", () => {