feat: align web platforms to domestic rollout
This commit is contained in:
@@ -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() {
|
||||
<h4>${escapeHtml(review.title)}</h4>
|
||||
<p>${escapeHtml(brief(review.highlights || review.next_actions || review.notes || "已保存复盘,待继续补充表现数据。", 92))}</p>
|
||||
<div class="task-meta">
|
||||
<span class="tag blue">${escapeHtml(review.platform || "douyin")}</span>
|
||||
<span class="tag blue">${escapeHtml(platformLabel(review.platform || "douyin"))}</span>
|
||||
<span class="tag ${statusTone(review.verdict || "blue")}">${escapeHtml(review.verdict || "已记录")}</span>
|
||||
${review.publish_url ? `<a class="tag" href="${escapeHtml(review.publish_url)}" target="_blank" rel="noreferrer">打开链接</a>` : ""}
|
||||
<span class="tag clickable-tag" data-action="open-review-edit" data-review-id="${escapeHtml(review.id)}">编辑</span>
|
||||
@@ -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) => `<span class="chip ${index === 0 ? "active" : ""}">${escapeHtml(label)}</span>`).join("");
|
||||
platforms.innerHTML = ACTIVE_PLATFORM_CHIPS.map((label, index) => `<span class="chip ${index === 0 ? "active" : ""}">${escapeHtml(label)}</span>`).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 || "",
|
||||
|
||||
@@ -94,7 +94,8 @@
|
||||
<span class="chip">抖音</span>
|
||||
<span class="chip">小红书</span>
|
||||
<span class="chip">B站</span>
|
||||
<span class="chip">YouTube</span>
|
||||
<span class="chip">快手</span>
|
||||
<span class="chip">视频号</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="topbar-right">
|
||||
@@ -244,10 +245,10 @@
|
||||
</div>
|
||||
<div class="entity-card pad">
|
||||
<div class="entity-cell">
|
||||
<div class="avatar-lg">YT</div>
|
||||
<div class="avatar-lg">KS</div>
|
||||
<div>
|
||||
<div class="cell-title">Grow With Data</div>
|
||||
<div class="cell-desc">YouTube · Knowledge Shorts</div>
|
||||
<div class="cell-title">老K拆增长</div>
|
||||
<div class="cell-desc">快手 · 知识短视频</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="entity-meta">
|
||||
@@ -416,8 +417,8 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="entity-card pad">
|
||||
<div class="cell-title">海外 Shorts 试水项目</div>
|
||||
<div class="cell-desc">已确定平台为 YouTube,尚未正式开账号,先做题材验证</div>
|
||||
<div class="cell-title">视频号试水项目</div>
|
||||
<div class="cell-desc">已确定平台为微信视频号,尚未正式开账号,先做题材验证</div>
|
||||
<div class="entity-meta">
|
||||
<span class="tag orange">待绑定账号</span>
|
||||
<span class="tag">先做调研</span>
|
||||
@@ -437,7 +438,7 @@
|
||||
<div class="insight-card">
|
||||
<h4>导入单条作品</h4>
|
||||
<ul>
|
||||
<li>支持抖音 / 小红书 / B站 / 视频号 / YouTube 链接</li>
|
||||
<li>支持抖音 / 小红书 / B站 / 视频号 / 快手链接</li>
|
||||
<li>可选择“手动关联 Agent”或“自动关联最近使用 Agent”</li>
|
||||
<li>进入导入分析 Agent 队列后再分类</li>
|
||||
</ul>
|
||||
@@ -445,7 +446,7 @@
|
||||
<div class="insight-card">
|
||||
<h4>导入创作者主页</h4>
|
||||
<ul>
|
||||
<li>输入抖音、小红书、B站、快手、视频号、YouTube 主页链接</li>
|
||||
<li>输入抖音、小红书、B站、快手、视频号主页链接</li>
|
||||
<li>自动建立参考账号卡片</li>
|
||||
<li>也可手动指定 Agent</li>
|
||||
</ul>
|
||||
@@ -515,7 +516,7 @@
|
||||
<p>已绑定 · 最近同步:今天 08:46 · 当前图文收藏信号强于视频信号</p>
|
||||
</div>
|
||||
<div class="task-item">
|
||||
<h4>视频号 / 快手 / YouTube / 哔哩哔哩</h4>
|
||||
<h4>视频号 / 快手 / 哔哩哔哩</h4>
|
||||
<p>不绑定也能先做预调研。</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -806,8 +807,8 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="task-item">
|
||||
<h4>Grow With Data</h4>
|
||||
<p>YouTube · 关联 Agent:海外 Shorts 助手 · 最近更新:3 天前</p>
|
||||
<h4>老K拆增长</h4>
|
||||
<p>快手 · 关联 Agent:短视频节奏助手 · 最近更新:3 天前</p>
|
||||
<div class="task-meta">
|
||||
<span class="tag">等待下次抓取</span>
|
||||
</div>
|
||||
@@ -875,8 +876,8 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="review-card">
|
||||
<h4>Grow With Data · 《3 hooks for Shorts》</h4>
|
||||
<p>海外 Shorts 助手判断:更适合补充节奏和结构,不建议直接照搬表达。</p>
|
||||
<h4>老K拆增长 · 《3 个留人钩子拆解》</h4>
|
||||
<p>短视频节奏助手判断:更适合补充节奏和结构,不建议直接照搬表达。</p>
|
||||
<div class="task-meta">
|
||||
<span class="tag">结构可借</span>
|
||||
<span class="tag orange">表达不直接照搬</span>
|
||||
@@ -1194,7 +1195,7 @@
|
||||
<div class="playbook-list">
|
||||
<div class="playbook-item active">
|
||||
<h4>强观点短视频开头模板</h4>
|
||||
<p>抖音 / YouTube Shorts · 反常识开头 · 高评论</p>
|
||||
<p>抖音 / 快手短视频 · 反常识开头 · 高评论</p>
|
||||
</div>
|
||||
<div class="playbook-item">
|
||||
<h4>高信任教育图文结构模板</h4>
|
||||
@@ -1202,7 +1203,7 @@
|
||||
</div>
|
||||
<div class="playbook-item">
|
||||
<h4>案例拆解型长视频切片模板</h4>
|
||||
<p>B站 / YouTube · 适合做知识型切片</p>
|
||||
<p>B站 / 视频号 · 适合做知识型切片</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1237,7 +1238,7 @@
|
||||
<h4>覆盖平台</h4>
|
||||
<ul>
|
||||
<li>抖音 / 小红书 / 快手</li>
|
||||
<li>微信视频号 / YouTube / 哔哩哔哩</li>
|
||||
<li>微信视频号 / 快手 / 哔哩哔哩</li>
|
||||
<li>按勾选平台先跑市场调研</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -1264,7 +1265,6 @@
|
||||
<span class="chip active">小红书</span>
|
||||
<span class="chip">快手</span>
|
||||
<span class="chip">微信视频号</span>
|
||||
<span class="chip">YouTube</span>
|
||||
<span class="chip">哔哩哔哩</span>
|
||||
</div>
|
||||
|
||||
@@ -1321,7 +1321,7 @@
|
||||
</div>
|
||||
<div class="task-item">
|
||||
<h4>分镜助手-副业避坑</h4>
|
||||
<p>学习源:反常识开头 + 失败案例 Playbook · 平台:抖音 / YouTube Shorts · 变现:广告合作</p>
|
||||
<p>学习源:反常识开头 + 失败案例 Playbook · 平台:抖音 / 快手短视频 · 变现:广告合作</p>
|
||||
<div class="task-meta">
|
||||
<span class="tag orange">待补学习集</span>
|
||||
<span class="tag">主模型:豆包</span>
|
||||
@@ -1685,7 +1685,7 @@
|
||||
<div class="day"><strong>周四</strong><div class="slot">B站:长视频切片<br />18:30</div></div>
|
||||
<div class="day"><strong>周五</strong><div class="slot">抖音:栏目连载 03<br />20:00</div></div>
|
||||
<div class="day"><strong>周六</strong><div class="slot">小红书:案例图文<br />13:00</div></div>
|
||||
<div class="day"><strong>周日</strong><div class="slot">YouTube Shorts:A/B 版<br />21:00</div></div>
|
||||
<div class="day"><strong>周日</strong><div class="slot">视频号:A/B 版<br />21:00</div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1866,7 +1866,7 @@
|
||||
<p>文案积分 265 / 封面积分 182 / 视频积分 41。主要消耗在高分参考内容导入后的封面多版本测试。</p>
|
||||
</div>
|
||||
<div class="task-item">
|
||||
<h4>海外 Shorts 试水项目</h4>
|
||||
<h4>视频号试水项目</h4>
|
||||
<p>视频积分占比偏高,建议先多做文案和封面验证,再放大视频试投。</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user