| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411 |
- // ==============================================================================
- // AI短视频起号变现 · VOC 深度洞察报告 · 主渲染器
- // ==============================================================================
- // 01 · Cover
- // 02 · Agenda
- // 03-05 · Ch1 诘问起点(3 子章)
- // 06-09 · Ch2 六大赛道VOC验证(4 子章)
- // 10-12 · Ch3 选品与变现路径VOC(3 子章)
- // 13-15 · Ch4 人设信任度VOC(3 子章)
- // 16-18 · Ch5 平台政策与风险VOC(3 子章)
- // 19-21 · Ch6 投放ROI与运营VOC(3 子章)
- // 22-25 · Ch7 30天起号SOP(4 子章)
- // 26-27 · Ch8 矩阵化与规模化路径(2 子章)
- // 总计 25 slides(初始占位版)
- // ==============================================================================
- const STYLES = require('./voc-styles.js');
- const SCRIPTS = require('./voc-scripts.js');
- const LA = require('./shortdrama-analyze.js');
- const C = require('./lactic-components.js');
- const { BRAND, esc, fmtLikes } = C;
- const CHAPTERS = [
- { id: 1, num: '1', key: 'challenge', title: '诘问起点', en: 'THE CHALLENGE', tone: 'rose', color: BRAND.CORAL, icon: '🎯',
- summary: 'AI短视频工具爆发 · 工具平权时代 · "起号变现"才是真正的瓶颈' },
- { id: 2, num: '2', key: 'track_voc', title: 'AI视频赛道全图谱 VOC', en: 'TRACK SPECTRUM VOC', tone: 'blue', color: BRAND.TECH_BLUE, icon: '📊',
- summary: '20+AI视频赛道全景扫描·流量型/变现型/壁垒型/热点型四象限定位·真实起号数据反向验证' },
- { id: 3, num: '3', key: 'product_voc', title: '选品与变现路径 VOC', en: 'PRODUCT & MONETIZE', tone: 'amber', color: BRAND.SUNNY_YELLOW, icon: '🛒',
- summary: '什么品好卖?什么变现路径最靠谱?挂车带货/知识付费/私域引流/代运营真实收入验证' },
- { id: 4, num: '4', key: 'persona_voc', title: '人设信任度 VOC', en: 'PERSONA & TRUST', tone: 'purple', color: BRAND.PURPLE, icon: '🎭',
- summary: 'AI数字人 vs 真人出镜——信任度差距到底多大?AI+真人混合的最优解是什么?' },
- { id: 5, num: '5', key: 'policy_voc', title: '平台政策与风险 VOC', en: 'PLATFORM POLICY', tone: 'red', color: BRAND.WINE_RED, icon: '⚠️',
- summary: '限流/封号/搬运判定——抖音快手对AI内容的真实红线在哪里?' },
- { id: 6, num: '6', key: 'roi_voc', title: '投放 ROI 与运营 VOC', en: 'ROI & OPERATIONS', tone: 'orange', color: BRAND.WARM_ORANGE, icon: '📈',
- summary: '抖+/千川投AI短视频的ROI真实数据 · 不同阶段投放策略与预算' },
- { id: 7, num: '7', key: 'sop_voc', title: '30 天起号 SOP', en: '30-DAY SOP', tone: 'green', color: BRAND.JIANG_GREEN, icon: '🗓',
- summary: '从 0 到变现的四阶段执行计划:冷启动→千粉→变现→稳定 · 每天发什么、投多少、盯什么数据' },
- { id: 8, num: '8', key: 'matrix_voc', title: '矩阵化与规模化路径', en: 'MATRIX & SCALE', tone: 'green', color: BRAND.LACTIC_MINT, icon: '🚀',
- summary: '单号跑通 → 多号矩阵 → 代运营/培训变现 · 从月入5k到月入50k的规模化路径' },
- ];
- const CHAPTER_SUBSECTIONS = {
- challenge: [
- '残酷现实·80%AI账号在1000粉前放弃',
- '工具平权时代·成功者与失败者的根本区别',
- 'VOC反向验证·从真实创作者的社媒声音中找答案',
- ],
- track_voc: [
- '流量型赛道·萌娃/萌宠/搞笑/情感/风景/音乐——涨粉快但变现需策略',
- '变现型赛道·数字人带货/好物测评/穿搭种草——离钱最近但信任门槛高',
- '壁垒型赛道·知识科普/微短剧/技能教学/行业IP——门槛高但长线价值大',
- '赛道四象限模型·如何根据自身资源匹配最优赛道',
- ],
- product_voc: [
- '带货型选品·食品/百货/服装/母婴/家居的AI带货数据',
- '服务型变现·知识付费/私域引流/代运营的真实价格与需求',
- '变现路径ROI对比·挂车vs知识付费vs私域vs星图vs代运营',
- ],
- persona_voc: [
- '五类人设信任度对比·真实人物/数字人/萌娃/虚拟场景/AI+真人混合',
- 'AI痕迹接受度边界·用户什么时候会因为AI而划走',
- '人设一致性×粉丝粘性·频繁切换AI风格的影响',
- ],
- policy_voc: [
- '抖音AI内容政策·限流触发条件×AI标签的真实影响',
- '多号矩阵搬运判定·AI去重技术的有效边界',
- '封号案例库·真实VOC中的封号/限流经验汇总',
- ],
- roi_voc: [
- '抖+投放ROI·AI短视频不同账号类型的投放数据',
- '千川投放策略·数字人带货vs真人带货的ROI对比',
- '冷启动投放预算·0-1000粉阶段的最优投放策略',
- ],
- sop_voc: [
- '冷启动期 Day1-7·破0粉×测方向×高密度测试',
- '起号期 Day8-15·冲刺千粉×放大模型×投放测试',
- '变现期 Day16-25·开通橱窗×选品挂车×转化优化',
- '稳定期 Day26-30·数据复盘×矩阵复制×规模化',
- ],
- matrix_voc: [
- '单号→多号矩阵·内容复用×去重策略×账号管理',
- '规模化变现·代运营/培训/素材售卖的三条增长曲线',
- ],
- };
- const CHAPTER_HERO_LINES = {
- challenge: `当前AI短视频工具(<strong style="color:${BRAND.CORAL};">即梦/可灵/火山引擎</strong>)已高度成熟,单条视频生产成本降至 <strong style="color:${BRAND.CORAL};">5-24 元</strong>,技术门槛趋近于零。但残酷现实是:<strong style="color:${BRAND.CORAL};">80%的AI短视频账号在1000粉之前放弃</strong>。成功起号者与失败者的根本区别不在工具,而在于是否做对了<strong style="color:${BRAND.LACTIC_MINT};">赛道选择 × 选品匹配 × 人设定位 × 投放节奏</strong>这四步。本章直面根本困境:<strong>方向困境 / 流量困境 / 变现困境 / 合规困境 / 信息过载</strong>。`,
- track_voc: `AI短视频赛道远不止6种——从<strong style="color:${BRAND.TECH_BLUE};">流量型</strong>(萌娃/萌宠/搞笑/情感/风景/音乐)到<strong style="color:${BRAND.TECH_BLUE};">变现型</strong>(数字人带货/好物测评/穿搭种草/探店打卡)再到<strong style="color:${BRAND.TECH_BLUE};">壁垒型</strong>(知识科普/微短剧/技能教学/行业IP/历史解说),每个赛道都有不同的起号逻辑、涨粉曲线和变现天花板。本章建立一套<strong style="color:${BRAND.LACTIC_MINT};">"流量-变现-壁垒"三维归类框架</strong>,帮助你根据自身资源(时间/预算/技能/行业背景)科学匹配最优赛道,而非盲目跟风。</p><p style="color:var(--text-2); font-size:0.92rem; line-height:1.7; margin-top:8px;">核心方法论:<strong style="color:${BRAND.CORAL};">不是"哪个赛道好"的问题,而是"哪个赛道适合你"的问题</strong>。本章基于<strong>抖音+小红书</strong>真实VOC数据,逐赛道验证起号成功率、涨粉速度、变现效率和竞争激烈度。`,
- product_voc: `不同账号类型对应完全不同的选品逻辑和变现路径。<strong style="color:${BRAND.SUNNY_YELLOW};">数字人带货</strong>适合低价快消(食品/日用9.9-69元),<strong style="color:${BRAND.SUNNY_YELLOW};">AI换装</strong>适合服装美妆(49-199元),<strong style="color:${BRAND.SUNNY_YELLOW};">AI萌娃</strong>适合母婴用品和知识付费。变现路径的优先级排序——<strong>挂车带货 > 知识付费 > 私域引流 > 代运营 > 星图广告</strong>——需要VOC验证真实收入数据和转化效率。`,
- persona_voc: `AI短视频的人设是<strong style="color:${BRAND.PURPLE};">信任的锚点</strong>。五种人设类型——<strong>真实人物出镜 / 数字人拟真 / AI萌娃萌宠 / AI虚拟场景 / AI+真人混合</strong>——在信任度、涨粉速度和变现效率上差异巨大。核心VOC问题:<strong style="color:${BRAND.PURPLE};">AI痕迹的接受度边界在哪里?</strong>用户什么时候会因为"一看就是AI做的"而划走/不信任/举报?`,
- policy_voc: `<strong style="color:${BRAND.WINE_RED};">平台政策是AI短视频最大的不确定变量</strong>。抖音/快手对纯AI内容的限流/标签政策持续收紧,"如何合规地用AI"比"如何用AI做爆款"更关键。核心问题:<strong style="color:${BRAND.WINE_RED};">AI标签究竟是加分还是减分?多号矩阵化会被判定搬运吗?限流的真实触发条件是什么?</strong>本章基于真实VOC中的封号/限流案例,绘制平台政策风险地图。`,
- roi_voc: `AI短视频的投放不是"有钱就烧"——不同账号类型、不同阶段的投放策略完全不同。<strong style="color:${BRAND.WARM_ORANGE};">冷启动期</strong>不投流、纯靠自然流量验证内容;<strong style="color:${BRAND.WARM_ORANGE};">起号期</strong>抖+测试投放单条30-50元;<strong style="color:${BRAND.WARM_ORANGE};">变现期</strong>千川精准投放ROI>1.5才放量。本章基于真实VOC中的投放经验数据,验证各阶段的预算、ROI和最优策略。`,
- sop_voc: `基于VOC数据反向验证的<strong style="color:${BRAND.JIANG_GREEN};">30天起号变现SOP</strong>:<strong>冷启动期 Day1-7</strong>(破0粉,测方向,不投流)→ <strong>起号期 Day8-15</strong>(冲刺千粉,放大已验证模型,抖+测试投放)→ <strong>变现期 Day16-25</strong>(开通橱窗/挂车,选品匹配,千川精准投放)→ <strong>稳定期 Day26-30</strong>(数据复盘,矩阵复制,规模化)。每阶段的<strong>目标/内容策略/投放预算/关键指标/常见坑</strong>全部基于VOC实证。`,
- blueprint: `当单号模型跑通后,<strong style="color:${BRAND.LACTIC_MINT};">矩阵化</strong>是放大收益的最短路径:一个爆款内容模板 → AI批量变体 → 多号分发 → 放大10倍流量。<strong style="color:${BRAND.LACTIC_MINT};">规模化变现</strong>的三条增长曲线:① 矩阵带货(月入3-10万)→ ② 代运营服务(月入5-20万)→ ③ 培训/知识付费(月入10-50万)。每个阶段都有真实的VOC案例和量化阈值。`,
- };
- function sn(n) { return String(n).padStart(2, '0'); }
- function renderNav() {
- const dots = [
- { tip: '封面', href: '#s0' },
- { tip: '目录', href: '#agenda' },
- ...CHAPTERS.map((c) => ({ tip: `${c.num} ${c.title}`, href: `#${c.key}` })),
- ];
- return `<nav class="nav-rail" aria-label="章节导航">
- ${dots.map((d, i) => `<a class="nav-dot${i === 0 ? ' active' : ''}" href="${d.href}" data-tip="${esc(d.tip)}" data-idx="${i}"></a>`).join('')}
- </nav>
- <div class="top-bar">
- <div class="brand-logo">AI短视频起号变现<span class="dot">·</span>VOC 深度洞察报告 v1.0</div>
- <div class="text-mono text-xs" style="color:var(--text-3);">全赛道矩阵 / 8 假设 / 30天 SOP</div>
- </div>`;
- }
- function renderKbdHint() {
- return `<div class="kbd-hint" id="kbdHint">
- <span>键盘切换</span>
- <kbd>↑</kbd><kbd>↓</kbd>
- <span>或</span>
- <kbd>PgUp</kbd><kbd>PgDn</kbd>
- </div>`;
- }
- function renderCover({ product, collectedAt, slideNum, slideTotal, meta }) {
- const totalComments = meta?.comments || 0;
- const platformCount = Object.values(meta?.platforms || {}).filter((n) => n > 0).length;
- const trackCount = meta?.productsCount || 0;
- const stage = meta?.stage || 'skeleton';
- const tier = meta?.sourceTier || 'unknown';
- const isReal = tier === 'real-collected';
- const sourceBadge = isReal
- ? { label: '真实采集 · 抖音 + 小红书评论颗粒度', color: BRAND.JIANG_GREEN, icon: '✓' }
- : { label: '骨架版 · 待 VOC 数据加载', color: BRAND.CORAL, icon: '○' };
- const commentsDisplay = totalComments.toLocaleString();
- return `<section class="report-section" id="s0" data-tone="amber" data-slide-num="${slideNum}/${slideTotal}" style="min-height:100vh;padding:0;">
- <div class="cover-hero">
- <div class="aurora" aria-hidden="true"><span></span><span></span><span></span></div>
- <div class="cover-grid-bg"></div>
- <div class="cover-content">
- <div class="cover-meta rise-in" style="display:flex; justify-content:space-between; align-items:center; gap:16px; flex-wrap:wrap;">
- <span>AI短视频 · VOC 深度洞察 · 2026</span>
- <span style="display:inline-flex; align-items:center; gap:6px; padding:4px 12px; background:${sourceBadge.color}15; color:${sourceBadge.color}; border:1px solid ${sourceBadge.color}55; border-radius:16px; font-family:var(--font-mono); font-size:0.72rem; letter-spacing:0.12em; font-weight:600;">
- <span style="font-size:0.9rem;">${sourceBadge.icon}</span>${esc(sourceBadge.label)}
- </span>
- </div>
- <div class="cover-title-stack">
- <p class="text-mono rise-in" style="color:${BRAND.LACTIC_MINT}; font-size:0.9rem;letter-spacing:0.2em;margin-bottom:18px;">全赛道矩阵 × 8 假设 × 30天 SOP · 四维 VOC 验证</p>
- <h1 class="cover-title rise-in">${esc(product)}<br/><span style="color:${BRAND.LACTIC_MINT}; -webkit-text-fill-color:${BRAND.LACTIC_MINT}; background:none; font-size:0.66em;">VOC 深度洞察报告</span></h1>
- <p class="text-poster rise-in" style="margin-top:20px;color:var(--text-2); font-size:1.42rem;">
- 从 <strong style="color:${BRAND.CORAL};">80%放弃率</strong> 到 <strong style="color:${BRAND.LACTIC_MINT};">可复制的起号变现SOP</strong>
- </p>
- </div>
- <p class="cover-sub fade-up">
- 以 <strong style="color:${BRAND.LACTIC_MINT};">${commentsDisplay}</strong> 条真实多平台 VOC 评论为证据底座,
- 反向验证 <strong style="color:${BRAND.TECH_BLUE};">20+ AI赛道类型</strong>的起号难度与变现效率,
- 覆盖 <strong style="color:${BRAND.SUNNY_YELLOW};">12 个选品品类</strong> × <strong style="color:${BRAND.PURPLE};">5 种人设类型</strong> × <strong style="color:${BRAND.WINE_RED};">平台政策红线</strong> × <strong style="color:${BRAND.WARM_ORANGE};">投放ROI</strong>,
- 输出从 <strong style="color:${BRAND.CORAL};">0 粉</strong> 到 <strong style="color:${BRAND.JIANG_GREEN};">稳定变现</strong> 的 <strong style="color:${BRAND.JIANG_GREEN};">30天可执行SOP</strong>。
- </p>
- <div class="cover-stats fade-up" style="grid-template-columns:repeat(6, 1fr); max-width:1100px;">
- <div class="cover-stat"><div class="num">${commentsDisplay}</div><div class="lbl">真实 VOC</div></div>
- <div class="cover-stat"><div class="num">${platformCount}</div><div class="lbl">采集平台</div></div>
- <div class="cover-stat"><div class="num">20+</div><div class="lbl">AI赛道</div></div>
- <div class="cover-stat"><div class="num">8</div><div class="lbl">核心假设</div></div>
- <div class="cover-stat"><div class="num">${trackCount}</div><div class="lbl">关键词维度</div></div>
- <div class="cover-stat"><div class="num">${slideTotal}</div><div class="lbl">slides</div></div>
- </div>
- <div class="fade-up" style="margin-top:32px; padding:14px 20px; background:${BRAND.LACTIC_MINT}08; border-left:3px solid ${BRAND.LACTIC_MINT}; border-radius:4px; max-width:920px; margin-left:auto; margin-right:auto; text-align:left;">
- <div class="text-mono text-xs" style="color:${BRAND.LACTIC_MINT}; letter-spacing:0.14em; margin-bottom:6px; font-weight:700;">DATA FOUNDATION · 数据底座</div>
- <p style="color:var(--text-2); font-size:0.82rem; line-height:1.6; margin:0;">
- 本报告基于 <strong style="color:${BRAND.LACTIC_MINT};">docs/短剧变现/raw/_merged.json</strong> 真实多平台采集:
- 抖音 <strong>${meta?.platforms?.douyin || '待采集'}</strong> 条 + 小红书 <strong>${meta?.platforms?.xhs || '待采集'}</strong> 条。
- 每条 VOC 带 <code style="background:${BRAND.JIANG_GREEN}15; padding:1px 5px; border-radius:3px; color:${BRAND.JIANG_GREEN};">source=real-collected</code> 明确标识。
- </p>
- </div>
- <p class="text-mono text-xs fade-up" style="margin-top:40px; color:var(--text-3);">SCROLL DOWN · 采集截止 ${esc(collectedAt || '')} · ${commentsDisplay} 条真实 VOC</p>
- </div>
- </div>
- </section>`;
- }
- function renderAgenda({ slideNum, slideTotal }) {
- return `<section class="report-section" id="agenda" data-tone="amber" data-slide-num="${slideNum}/${slideTotal}">
- <div class="section-inner">
- <div class="section-head rise-in">
- <div class="section-eyebrow" style="color:${BRAND.LACTIC_MINT};">CONTENTS · 8 章认知递进</div>
- <h2 class="text-h1"><span class="headline-anim">从诘问到蓝图 · AI短视频起号变现全链路 VOC 实证</span></h2>
- <p class="section-sub">按<strong style="color:${BRAND.LACTIC_MINT};">认知深度递进</strong>:① 诘问 → ② 赛道VOC → ③ 选品变现 → ④ 人设信任 → ⑤ 平台风险 → ⑥ 投放ROI → ⑦ 30天SOP → ⑧ 矩阵规模化</p>
- </div>
- <div class="grid" style="grid-template-columns:repeat(2, 1fr); gap:22px; margin-top:20px;">
- ${CHAPTERS.map((c, i) => `
- <a href="#${c.key}" class="fade-up" style="text-decoration:none; display:block; background:var(--bg-1); border:1px solid var(--border); border-left:4px solid ${c.color}; border-radius:var(--radius-md); padding:24px; transition:all .35s cubic-bezier(.2,.7,.2,1); position:relative; overflow:hidden;" onmouseover="this.style.transform='translateY(-4px)'; this.style.borderColor='${c.color}'; this.style.boxShadow='0 20px 60px -20px ${c.color}55'" onmouseout="this.style.transform='translateY(0)'; this.style.borderColor='var(--border)'; this.style.boxShadow='none'">
- <div style="position:absolute; top:-18px; right:-10px; font-family:var(--font-head); font-weight:900; font-size:8rem; line-height:1; color:${c.color}; opacity:.08; letter-spacing:-0.06em; pointer-events:none;">${c.num}</div>
- <div style="display:flex; justify-content:space-between; align-items:start; margin-bottom:14px;">
- <div class="text-mono text-xs" style="color:${c.color}; letter-spacing:0.18em; font-weight:700;">CH ${c.num} · ${c.en}</div>
- <div style="font-size:1.6rem; filter:grayscale(20%);">${c.icon}</div>
- </div>
- <h3 class="text-h2" style="margin:0 0 10px; color:var(--text-1); font-size:1.38rem;">${esc(c.title)}</h3>
- <p style="color:var(--text-2); font-size:0.88rem; line-height:1.6; margin-bottom:12px;">${esc(c.summary)}</p>
- <div style="display:flex; flex-wrap:wrap; gap:5px; margin-bottom:12px;">
- ${(CHAPTER_SUBSECTIONS[c.key] || []).slice(0, 5).map((sub, j) => `<span style="padding:3px 8px; background:${c.color}15; color:${c.color}; border-radius:3px; font-size:0.66rem; font-weight:600;">${c.num}.${j + 1} ${esc(sub.split('·')[0])}</span>`).join('')}
- </div>
- <div style="padding-top:12px; border-top:1px solid var(--border); display:flex; justify-content:space-between; align-items:center;">
- <span class="text-xs text-mono" style="color:var(--text-3); letter-spacing:0.12em;">→ 跳转章节</span>
- <span class="text-mono text-xs" style="color:${c.color};">${i + 1} / ${CHAPTERS.length}</span>
- </div>
- </a>`).join('')}
- </div>
- <div class="fade-up" style="margin-top:44px; padding:22px 26px; background:linear-gradient(135deg, ${BRAND.LACTIC_MINT}10, ${BRAND.JIANG_GREEN}06); border:1px solid ${BRAND.LACTIC_MINT}22; border-radius:var(--radius-md);">
- <div class="text-mono text-xs" style="color:${BRAND.LACTIC_MINT}; letter-spacing:0.15em; margin-bottom:10px;">METHODOLOGY · 方法论自律</div>
- <div style="color:var(--text-1); font-size:0.98rem; line-height:1.72;">
- 本报告严格遵循 《<strong style="color:${BRAND.LACTIC_MINT};">docs/短剧变现/0.基础调研.md + 1.场景的补充.md</strong>》反向验证方法论:<br/>
- <strong style="color:${BRAND.CORAL};">❌ 不做</strong>:理论推导、"我觉得什么赛道好"、脱离VOC的拍脑袋建议;<br/>
- <strong style="color:${BRAND.JIANG_GREEN};">✅ 做</strong>:8条核心假设 H1-H8 × 多平台VOC实证 × 6大赛道 × 12选品品类 × 5人设类型 × 投放ROI × 30天可执行SOP;<br/>
- 每一个结论都附 <strong style="color:${BRAND.LACTIC_MINT};">真实用户原声</strong>(昵称+平台+点赞数)+ <strong style="color:${BRAND.TECH_BLUE};">量化数据</strong> + <strong style="color:${BRAND.SAGE};">可执行决策项</strong> 三重验证。
- </div>
- </div>
- </div>
- </section>`;
- }
- function renderChapterDivider({ chapter, slideNum, slideTotal }) {
- const c = chapter;
- const heroLine = CHAPTER_HERO_LINES[c.key] || c.summary;
- const subs = CHAPTER_SUBSECTIONS[c.key] || [];
- return `<section class="report-section" id="${c.key}" data-tone="${c.tone}" data-slide-num="${slideNum}/${slideTotal}" style="justify-content:center;">
- <div class="section-inner">
- <div class="rise-in" style="text-align:center; margin-bottom:40px;">
- <div style="font-family:var(--font-head); font-weight:900; font-size:clamp(5rem, 14vw, 11rem); line-height:0.9; color:${c.color}; opacity:0.12; letter-spacing:-0.06em;">0${c.num}</div>
- <div class="text-mono text-xs" style="color:${c.color}; letter-spacing:0.3em; margin-top:-2rem; font-weight:700;">CHAPTER ${c.num} · ${c.en}</div>
- </div>
- <div class="rise-in" style="text-align:center; margin-bottom:36px;">
- <div style="font-size:3.2rem; margin-bottom:14px;">${c.icon}</div>
- <h2 class="text-poster" style="font-size:clamp(2.4rem, 5.2vw, 4.2rem); color:var(--text-1); letter-spacing:-0.025em;">${esc(c.title)}</h2>
- <p style="color:${c.color}; font-family:var(--font-mono); font-size:0.92rem; letter-spacing:0.18em; margin-top:12px; font-weight:600;">${c.en}</p>
- </div>
- <div class="fade-up" style="max-width:960px; margin:0 auto; text-align:center; padding:28px 32px; background:linear-gradient(135deg, ${c.color}0C, transparent); border-left:3px solid ${c.color}; border-radius:var(--radius-md);">
- <p style="color:var(--text-1); font-size:1.08rem; line-height:1.82;">${heroLine}</p>
- </div>
- <div class="fade-up" style="margin-top:40px; display:grid; grid-template-columns:repeat(${Math.min(subs.length, 5)}, 1fr); gap:14px; max-width:1100px; margin-left:auto; margin-right:auto;">
- ${subs.map((sub, i) => `
- <div style="padding:16px 14px; background:var(--bg-1); border:1px solid ${c.color}22; border-radius:var(--radius-sm); text-align:center;">
- <div class="text-mono text-xs" style="color:${c.color}; letter-spacing:0.15em; margin-bottom:6px; font-weight:700;">${c.num}.${i + 1}</div>
- <div style="color:var(--text-1); font-size:0.86rem; line-height:1.5;">${esc(sub)}</div>
- </div>`).join('')}
- </div>
- <div class="fade-up" style="margin-top:48px; text-align:center;">
- <div class="text-mono text-xs" style="color:var(--text-3); letter-spacing:0.3em;">SCROLL DOWN · ${subs.length} 个子章 · VOC 实证 × 数据 × 决策</div>
- </div>
- </div>
- </section>`;
- }
- function renderComingSoon({ chapter, subIdx, sub, slideNum, slideTotal, targetBatch, meta }) {
- const c = chapter;
- const hs = LA.CHAPTER_HYPOTHESIS_MAP[c.key] || [];
- const hsCount = hs.reduce((s, h) => s + (meta?.hypotheses?.[h] || 0), 0);
- return `<section class="report-section" id="${c.key}-${subIdx}" data-tone="${c.tone}" data-slide-num="${slideNum}/${slideTotal}">
- <div class="section-inner">
- <div class="section-head rise-in">
- <div class="section-eyebrow" style="color:${c.color};">${c.num}.${subIdx} · ${esc((sub || '').split('·')[0].toUpperCase())}</div>
- <h2 class="text-h1"><span class="headline-anim">${esc(sub)}</span></h2>
- <p class="section-sub">此子章将在 <strong style="color:${c.color};">Batch ${targetBatch}</strong> 填充 VOC 证据卡 + 理论映射 + 决策项</p>
- </div>
- <div class="fade-up" style="margin-top:40px; padding:40px; background:${c.color}08; border:1px dashed ${c.color}55; border-radius:var(--radius-lg); text-align:center;">
- <div style="font-size:3.4rem; margin-bottom:18px;">🚧</div>
- <div class="text-h2" style="color:${c.color}; margin-bottom:12px;">Coming in Batch ${targetBatch}</div>
- ${hsCount ? `
- <div style="display:inline-flex; align-items:center; gap:10px; padding:8px 16px; background:${BRAND.JIANG_GREEN}12; color:${BRAND.JIANG_GREEN}; border:1px solid ${BRAND.JIANG_GREEN}44; border-radius:20px; margin-bottom:20px; font-family:var(--font-mono); font-size:0.82rem; font-weight:600;">
- <span>✓</span> 数据就绪 · ${hsCount} 条 ${hs.join('/')} 相关真实 VOC
- </div><br/>
- <p style="color:var(--text-2); font-size:0.92rem; max-width:680px; margin:0 auto; line-height:1.7;">
- docs/短剧变现/raw/_merged.json 已就绪 <strong style="color:${BRAND.LACTIC_MINT};">${meta?.comments || 0} 条真实 VOC</strong>,<br/>
- Batch ${targetBatch} 将基于本假设的 <strong style="color:${c.color};">${hsCount} 条</strong> 证据 + 理论工具,输出 <strong>证据卡 × 理论映射 × 决策项</strong>。
- </p>` : `
- <p style="color:var(--text-2); font-size:0.95rem; max-width:600px; margin:0 auto; line-height:1.7;">
- Batch ${targetBatch} 将基于已采集 VOC 数据填充本子章内容。
- </p>`}
- </div>
- </div>
- </section>`;
- }
- const SUB_TO_BATCH = {
- 'challenge': 2,
- 'track_voc': 2,
- 'product_voc': 2,
- 'persona_voc': 3,
- 'policy_voc': 3,
- 'roi_voc': 4,
- 'sop_voc': 4,
- 'matrix_voc': 5,
- };
- let SLIDE_RENDERERS = {};
- function tryRequire(modPath) {
- try { return require(modPath); } catch (e) { return null; }
- }
- const CH1 = tryRequire('./shortdrama-ch1-challenge.js');
- const CH2 = tryRequire('./shortdrama-ch2-track-voc.js');
- const CH3 = tryRequire('./shortdrama-ch3-product-voc.js');
- const CH4 = tryRequire('./shortdrama-ch4-persona-voc.js');
- const CH5 = tryRequire('./shortdrama-ch5-policy-voc.js');
- const CH6 = tryRequire('./shortdrama-ch6-roi-voc.js');
- const CH7 = tryRequire('./shortdrama-ch7-sop-voc.js');
- const CH8 = tryRequire('./shortdrama-ch8-matrix-voc.js');
- SLIDE_RENDERERS = {
- ...(CH1 || {}),
- ...(CH2 || {}),
- ...(CH3 || {}),
- ...(CH4 || {}),
- ...(CH5 || {}),
- ...(CH6 || {}),
- ...(CH7 || {}),
- ...(CH8 || {}),
- };
- function buildHTML({ product, collectedAt } = {}) {
- product = product || 'AI短视频起号变现';
- collectedAt = collectedAt || new Date().toISOString().slice(0, 10);
- const data = LA.loadMerged();
- const meta = LA.getMeta(data);
- let slideTotal = 2;
- for (const c of CHAPTERS) {
- slideTotal += 1 + (CHAPTER_SUBSECTIONS[c.key] || []).length;
- }
- const slides = [];
- let num = 1;
- slides.push(renderCover({ product, collectedAt, slideNum: sn(num), slideTotal: sn(slideTotal), meta }));
- num++;
- slides.push(renderAgenda({ slideNum: sn(num), slideTotal: sn(slideTotal) }));
- num++;
- for (const c of CHAPTERS) {
- slides.push(renderChapterDivider({ chapter: c, slideNum: sn(num), slideTotal: sn(slideTotal) }));
- num++;
- const subs = CHAPTER_SUBSECTIONS[c.key] || [];
- for (let i = 0; i < subs.length; i++) {
- const subIdx = i + 1;
- const subKey = `${c.key}-${subIdx}`;
- const renderer = SLIDE_RENDERERS[subKey];
- const slideCtx = {
- chapter: c,
- subIdx,
- sub: subs[i],
- slideNum: sn(num),
- slideTotal: sn(slideTotal),
- data,
- meta,
- };
- if (renderer) {
- slides.push(renderer(slideCtx));
- } else {
- slides.push(renderComingSoon({ ...slideCtx, targetBatch: SUB_TO_BATCH[c.key] || 2, meta }));
- }
- num++;
- }
- }
- return `<!DOCTYPE html>
- <html lang="zh-CN">
- <head>
- <meta charset="UTF-8"/>
- <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
- <title>${esc(product)} · VOC 深度洞察报告</title>
- ${STYLES}
- </head>
- <body>
- ${renderNav()}
- ${renderKbdHint()}
- <div class="progress-line" id="progressLine"></div>
- <main class="deck">
- ${slides.join('\n')}
- </main>
- <script>${SCRIPTS}</script>
- </body>
- </html>`;
- }
- module.exports = {
- buildHTML,
- BRAND,
- CHAPTERS,
- CHAPTER_SUBSECTIONS,
- CHAPTER_HERO_LINES,
- SUB_TO_BATCH,
- renderCover,
- renderAgenda,
- renderChapterDivider,
- renderComingSoon,
- };
|