From 9a753f60d875f6efb084557983801228d5a02982 Mon Sep 17 00:00:00 2001 From: kris Date: Mon, 23 Mar 2026 08:38:51 +0800 Subject: [PATCH] feat: align web platforms to domestic rollout --- web/storyforge-web-v4/assets/app.js | 81 +++++++++++++++-------------- web/storyforge-web-v4/index.html | 40 +++++++------- 2 files changed, 61 insertions(+), 60 deletions(-) diff --git a/web/storyforge-web-v4/assets/app.js b/web/storyforge-web-v4/assets/app.js index fa8a2ca..7457157 100644 --- a/web/storyforge-web-v4/assets/app.js +++ b/web/storyforge-web-v4/assets/app.js @@ -35,6 +35,14 @@ const appState = { }; const INTEGRATION_ORDER = ["local_model", "cutvideo", "huobao", "n8n", "asr"]; +const ACTIVE_PLATFORMS = [ + { value: "douyin", label: "抖音" }, + { value: "xiaohongshu", label: "小红书" }, + { value: "bilibili", label: "哔哩哔哩" }, + { value: "kuaishou", label: "快手" }, + { value: "wechat_video", label: "微信视频号" } +]; +const ACTIVE_PLATFORM_CHIPS = ["全平台", "抖音", "小红书", "B站", "快手", "视频号"]; const INTEGRATION_META = { local_model: { label: "本机模型", @@ -81,6 +89,24 @@ function safeArray(value) { return Array.isArray(value) ? value : []; } +function getPlatformOptions() { + return ACTIVE_PLATFORMS.map((item) => ({ value: item.value, label: item.label })); +} + +function normalizePlatformValue(value, fallback = "douyin") { + const normalized = String(value || "").trim().toLowerCase(); + if (!normalized) return fallback; + const byValue = ACTIVE_PLATFORMS.find((item) => item.value === normalized); + if (byValue) return byValue.value; + const byLabel = ACTIVE_PLATFORMS.find((item) => item.label === value); + return byLabel?.value || fallback; +} + +function platformLabel(value) { + const matched = ACTIVE_PLATFORMS.find((item) => item.value === normalizePlatformValue(value, "")); + return matched?.label || String(value || "抖音"); +} + function escapeHtml(value) { return String(value ?? "") .replaceAll("&", "&") @@ -2136,7 +2162,7 @@ function renderReviewScreen() {

${escapeHtml(review.title)}

${escapeHtml(brief(review.highlights || review.next_actions || review.notes || "已保存复盘,待继续补充表现数据。", 92))}

- ${escapeHtml(review.platform || "douyin")} + ${escapeHtml(platformLabel(review.platform || "douyin"))} ${escapeHtml(review.verdict || "已记录")} ${review.publish_url ? `打开链接` : ""} 编辑 @@ -2221,8 +2247,7 @@ function renderTopbar() { topPills[2].textContent = `任务 ${formatNumber(appState.dashboard?.recent_jobs?.length || 0)}`; } if (platforms) { - const chips = ["全平台", "抖音", "小红书", "B站", "YouTube"]; - platforms.innerHTML = chips.map((label, index) => `${escapeHtml(label)}`).join(""); + platforms.innerHTML = ACTIVE_PLATFORM_CHIPS.map((label, index) => `${escapeHtml(label)}`).join(""); } } @@ -2399,18 +2424,11 @@ function openImportHomepageAction() { const assistants = getAssistantOptions(project.id); openActionModal({ title: "导入主页并同步", - description: "适合抖音 / 小红书 / B站 / YouTube 主页。先建内容源,再触发同步与分析。", + description: "适合抖音 / 小红书 / B站 / 快手 / 视频号主页。先建内容源,再触发同步与分析。", submitLabel: "开始同步", fields: [ { name: "projectId", label: "归属项目", type: "select", value: project.id, options: getProjectOptions() }, - { name: "platform", label: "平台", type: "select", value: "douyin", options: [ - { value: "douyin", label: "抖音" }, - { value: "xiaohongshu", label: "小红书" }, - { value: "bilibili", label: "哔哩哔哩" }, - { value: "youtube", label: "YouTube" }, - { value: "kuaishou", label: "快手" }, - { value: "wechat_video", label: "微信视频号" } - ] }, + { name: "platform", label: "平台", type: "select", value: "douyin", options: getPlatformOptions() }, { name: "title", label: "标题", placeholder: "例如:创业口播对标账号" }, { name: "handle", label: "账号名 / handle", placeholder: "可选" }, { name: "sourceUrl", label: "主页链接", type: "url", placeholder: "https://..." }, @@ -2420,12 +2438,13 @@ function openImportHomepageAction() { onSubmit: async (values) => { if (!values.sourceUrl?.trim()) throw new Error("请填写主页链接"); const projectId = values.projectId || project.id; + const platform = normalizePlatformValue(values.platform, "douyin"); const source = await storyforgeFetch("/v2/content-sources", { method: "POST", body: { project_id: projectId, source_kind: "creator_account", - platform: values.platform || "douyin", + platform, handle: values.handle || "", source_url: values.sourceUrl.trim(), title: values.title || values.handle || "主页对标", @@ -2439,7 +2458,7 @@ function openImportHomepageAction() { knowledge_base_id: getProjectKnowledgeBases(projectId)[0]?.id || kb?.id || "", assistant_id: values.assistantId || "", content_source_id: source.id, - platform: values.platform || "douyin", + platform, handle: values.handle || "", source_url: values.sourceUrl.trim(), title: values.title || values.handle || "主页对标", @@ -2469,14 +2488,7 @@ function openImportSelectedAccountAction() { submitLabel: currentSource ? "继续同步" : "导入并同步", fields: [ { name: "projectId", label: "归属项目", type: "select", value: project.id, options: getProjectOptions() }, - { name: "platform", label: "平台", type: "select", value: "douyin", options: [ - { value: "douyin", label: "抖音" }, - { value: "xiaohongshu", label: "小红书" }, - { value: "bilibili", label: "哔哩哔哩" }, - { value: "youtube", label: "YouTube" }, - { value: "kuaishou", label: "快手" }, - { value: "wechat_video", label: "微信视频号" } - ] }, + { name: "platform", label: "平台", type: "select", value: normalizePlatformValue(currentSource?.platform || "douyin"), options: getPlatformOptions() }, { name: "title", label: "内容源标题", value: currentSource?.title || `${account.nickname || account.douyin_id || "对标账号"} 对标主页` }, { name: "handle", label: "账号标识", value: currentSource?.handle || account.douyin_id || "" }, { name: "sourceUrl", label: "主页链接", type: "url", value: currentSource?.source_url || account.profile_url || "", placeholder: "https://..." }, @@ -2488,6 +2500,7 @@ function openImportSelectedAccountAction() { onSubmit: async (values) => { if (!values.sourceUrl?.trim()) throw new Error("请先填写主页链接"); const projectId = values.projectId || project.id; + const platform = normalizePlatformValue(values.platform, "douyin"); const source = currentSource && currentSource.project_id === projectId ? currentSource : await storyforgeFetch("/v2/content-sources", { @@ -2495,7 +2508,7 @@ function openImportSelectedAccountAction() { body: { project_id: projectId, source_kind: "creator_account", - platform: values.platform || "douyin", + platform, handle: values.handle || "", source_url: values.sourceUrl.trim(), title: values.title || values.handle || account.nickname || "对标主页", @@ -2512,7 +2525,7 @@ function openImportSelectedAccountAction() { knowledge_base_id: getProjectKnowledgeBases(projectId)[0]?.id || kb?.id || "", assistant_id: values.assistantId || "", content_source_id: source.id, - platform: values.platform || "douyin", + platform, handle: values.handle || account.douyin_id || "", source_url: values.sourceUrl.trim(), title: values.title || account.nickname || values.handle || "对标主页", @@ -2993,12 +3006,7 @@ function openGenerateCopyAction(defaults = {}) { submitLabel: "开始生成", fields: [ { name: "brief", label: "创作需求", type: "textarea", rows: 5, value: defaults.brief || getJobSeedBrief(sourceJob), placeholder: "例如:给创业者写一条 60 字内的短视频开场文案" }, - { name: "platform", label: "平台", type: "select", value: "抖音", options: [ - { value: "抖音", label: "抖音" }, - { value: "小红书", label: "小红书" }, - { value: "哔哩哔哩", label: "哔哩哔哩" }, - { value: "YouTube", label: "YouTube" } - ] }, + { name: "platform", label: "平台", type: "select", value: normalizePlatformValue(defaults.platform || "douyin"), options: getPlatformOptions() }, { name: "audience", label: "受众", value: "创业者" }, { name: "extraRequirements", label: "额外要求", placeholder: "例如:强结论开头,结尾带 CTA" } ], @@ -3008,7 +3016,7 @@ function openGenerateCopyAction(defaults = {}) { method: "POST", body: { brief: values.brief.trim(), - platform: values.platform || "抖音", + platform: platformLabel(values.platform || "douyin"), audience: values.audience || "创业者", extra_requirements: values.extraRequirements || "", knowledge_base_ids: safeArray(assistant.knowledge_base_ids) @@ -3127,14 +3135,7 @@ function openReviewAction(defaults = {}) { { name: "title", label: "标题", value: existingReview?.title || defaults.title || sourceJob?.title || "", placeholder: "例如:创业口播 3 月 22 日复盘" }, { name: "sourceJobId", label: "关联任务", type: "select", value: existingReview?.source_job_id || defaults.sourceJobId || sourceJob?.id || "", options: [{ value: "", label: "不关联任务" }, ...getCompletedJobOptions()] }, { name: "assistantId", label: "负责 Agent", type: "select", value: existingReview?.assistant_id || getSelectedAssistant()?.id || assistants[0]?.value || "", options: [{ value: "", label: "先不绑定" }, ...assistants] }, - { name: "platform", label: "平台", type: "select", value: existingReview?.platform || defaults.platform || "douyin", options: [ - { value: "douyin", label: "抖音" }, - { value: "xiaohongshu", label: "小红书" }, - { value: "bilibili", label: "哔哩哔哩" }, - { value: "youtube", label: "YouTube" }, - { value: "kuaishou", label: "快手" }, - { value: "wechat_video", label: "微信视频号" } - ] }, + { name: "platform", label: "平台", type: "select", value: normalizePlatformValue(existingReview?.platform || defaults.platform || "douyin"), options: getPlatformOptions() }, { name: "contentType", label: "内容类型", type: "select", value: existingReview?.content_type || "video", options: [ { value: "video", label: "视频" }, { value: "image_text", label: "图文" }, @@ -3164,7 +3165,7 @@ function openReviewAction(defaults = {}) { source_job_id: values.sourceJobId || "", assistant_id: values.assistantId || "", title: values.title.trim(), - platform: values.platform || "douyin", + platform: normalizePlatformValue(values.platform, "douyin"), content_type: values.contentType || "video", publish_url: values.publishUrl || "", published_at: values.publishedAt || "", diff --git a/web/storyforge-web-v4/index.html b/web/storyforge-web-v4/index.html index f482df1..a8ba636 100644 --- a/web/storyforge-web-v4/index.html +++ b/web/storyforge-web-v4/index.html @@ -94,7 +94,8 @@ 抖音 小红书 B站 - YouTube + 快手 + 视频号
@@ -244,10 +245,10 @@
-
YT
+
KS
-
Grow With Data
-
YouTube · Knowledge Shorts
+
老K拆增长
+
快手 · 知识短视频
@@ -416,8 +417,8 @@
-
海外 Shorts 试水项目
-
已确定平台为 YouTube,尚未正式开账号,先做题材验证
+
视频号试水项目
+
已确定平台为微信视频号,尚未正式开账号,先做题材验证
待绑定账号 先做调研 @@ -437,7 +438,7 @@

导入单条作品

    -
  • 支持抖音 / 小红书 / B站 / 视频号 / YouTube 链接
  • +
  • 支持抖音 / 小红书 / B站 / 视频号 / 快手链接
  • 可选择“手动关联 Agent”或“自动关联最近使用 Agent”
  • 进入导入分析 Agent 队列后再分类
@@ -445,7 +446,7 @@

导入创作者主页

    -
  • 输入抖音、小红书、B站、快手、视频号、YouTube 主页链接
  • +
  • 输入抖音、小红书、B站、快手、视频号主页链接
  • 自动建立参考账号卡片
  • 也可手动指定 Agent
@@ -515,7 +516,7 @@

已绑定 · 最近同步:今天 08:46 · 当前图文收藏信号强于视频信号

-

视频号 / 快手 / YouTube / 哔哩哔哩

+

视频号 / 快手 / 哔哩哔哩

不绑定也能先做预调研。

@@ -806,8 +807,8 @@
-

Grow With Data

-

YouTube · 关联 Agent:海外 Shorts 助手 · 最近更新:3 天前

+

老K拆增长

+

快手 · 关联 Agent:短视频节奏助手 · 最近更新:3 天前

等待下次抓取
@@ -875,8 +876,8 @@
-

Grow With Data · 《3 hooks for Shorts》

-

海外 Shorts 助手判断:更适合补充节奏和结构,不建议直接照搬表达。

+

老K拆增长 · 《3 个留人钩子拆解》

+

短视频节奏助手判断:更适合补充节奏和结构,不建议直接照搬表达。

结构可借 表达不直接照搬 @@ -1194,7 +1195,7 @@

强观点短视频开头模板

-

抖音 / YouTube Shorts · 反常识开头 · 高评论

+

抖音 / 快手短视频 · 反常识开头 · 高评论

高信任教育图文结构模板

@@ -1202,7 +1203,7 @@

案例拆解型长视频切片模板

-

B站 / YouTube · 适合做知识型切片

+

B站 / 视频号 · 适合做知识型切片

@@ -1237,7 +1238,7 @@

覆盖平台

@@ -1264,7 +1265,6 @@ 小红书 快手 微信视频号 - YouTube 哔哩哔哩 @@ -1321,7 +1321,7 @@

分镜助手-副业避坑

-

学习源:反常识开头 + 失败案例 Playbook · 平台:抖音 / YouTube Shorts · 变现:广告合作

+

学习源:反常识开头 + 失败案例 Playbook · 平台:抖音 / 快手短视频 · 变现:广告合作

待补学习集 主模型:豆包 @@ -1685,7 +1685,7 @@
周四
B站:长视频切片
18:30
周五
抖音:栏目连载 03
20:00
周六
小红书:案例图文
13:00
-
周日
YouTube Shorts:A/B 版
21:00
+
周日
视频号:A/B 版
21:00
@@ -1866,7 +1866,7 @@

文案积分 265 / 封面积分 182 / 视频积分 41。主要消耗在高分参考内容导入后的封面多版本测试。

-

海外 Shorts 试水项目

+

视频号试水项目

视频积分占比偏高,建议先多做文案和封面验证,再放大视频试投。