/** * 马记永结案报告 · HTML + MD 渲染层 */ const fs = require('fs'); const path = require('path'); const ROOT = path.resolve(__dirname, '..'); const OUT_HTML = path.join(ROOT, 'majiyong-closing-report.html'); const OUT_MD = path.join(ROOT, 'majiyong-closing-report.md'); module.exports = function render(M) { const { items, kolItems, kocItems, summary, tierStats, typeStats, topRegions, byTier, allComments, noiseComments, noiseRate, topicHits, TOPICS, wordcloudComments, cloudBrand, cloudActivity, cloudCategory, PROS, CONS, RECS, OPPORTUNITIES, TOP5, fmt, pct, esc, num } = M; // ---------- 明细行 (注: 篇数大,做 KOL 全表 + KOC Top 50) ---------- const detailKolRows = [...kolItems].sort((a, b) => num(b.engagementSubtotal || b.engagement) - num(a.engagementSubtotal || a.engagement)).map((r, i) => ` ${i + 1} ${esc(r.name)} ${esc(r.tier || '-')} ${esc(r.contentType || '-')} ${esc(String(r.region || '-').slice(0, 3))} ${(num(r.followersWan) * 10000).toLocaleString('zh-CN')} ¥${fmt(r.priceOrder)} ${fmt(r.impressionsSubtotal || r.impressions)} ${fmt(r.likes)} ${fmt(r.comments)} ${fmt(r.engagementSubtotal || r.engagement)} ${r.noteId ? '已解析' : '短链失效'} `).join(''); const detailKocTop = [...kocItems].sort((a, b) => num(b.engagementSubtotal || b.engagement) - num(a.engagementSubtotal || a.engagement)).slice(0, 50).map((r, i) => ` ${i + 1} ${esc(r.name)} ${esc(r.tier || 'KOC')} ${esc(r.contentType || '-')} ${esc(String(r.region || '-').slice(0, 3))} ${(num(r.followersWan) * 10000).toLocaleString('zh-CN')} ${fmt(r.likes)} ${fmt(r.comments)} ${fmt(r.engagementSubtotal || r.engagement)} ${(r._comments && r._comments.length) || 0} `).join(''); const topicRows = TOPICS.map((t) => { const hits = topicHits[t.tag]; const sample = hits.sort((a, b) => b.like - a.like)[0]; return ` ${esc(t.tag)} ${hits.length} ${(hits.length / Math.max(allComments.length, 1) * 100).toFixed(1)}% ${sample ? `[${esc(sample.koc)}@${esc(sample.ip || '-')}] ${esc(sample.content.replace(/\n/g, ' ').slice(0, 80))}${sample.content.length > 80 ? '…' : ''}` : '-'} `; }).join(''); // 真实评论筛选 v4: 7 层过滤 + 产品强相关硬约束 + 主题多样性轮询 const NOISE_RE = /互赞|互助|加油.*互|可以.*点赞|点赞.*返|蹲.*搭子|互粉/; const OFFTOPIC_RE = /眼影|口红|睫毛|化妆|包包|分装|借我|借用|手能借|护肤|穿搭|开箱|美术生|画的|画得|画风|笔法|插画|手工|盒子.*像/; const PROMO_RE = /推广|求关注|求互|私信|加微|商务合作|接广告|涨粉/; const SHILL_RE = /宝子|亲测|无套路|必.{0,2}冲|绝绝子|拉满|薅羊毛|薅得|放心冲|闭眼冲|爆棚|颜值直接|快冲|姐妹.{0,3}冲|实力宠粉|超(级|绝|香)|爆款|出圈|0元购|0元薅|真香|yyds|YYDS|惊艳到|跺脚/; const META_KOL_RE = /博主|up主|UP主|作者|接广|涨粉|掉粉|播放|粉丝.*多|9000.*掉.*\d|完啦R/; const EMOJI_HEAVY_RE = /(🥬|🥢|🌿|🤩|💯|🔥|💥|✅|💦|📸|🥳|🥞|🛒|🍣|🎉|✨|💚|❗|‼️)/g; const stripDeco = (s) => s.replace(/\[[^\]]+\]/g, '').replace(/[@#][^\s@#]+/g, '').replace(/[^\u4e00-\u9fa5a-zA-Z0-9]/g, ''); // 产品强相关词典: 9 主题,评论必须命中至少 1 个才算 VOC 有效 const PRODUCT_TOPICS = { '口味体验': /好吃|难吃|味道|香|辣|咸|淡|腻|清爽|清甜|甜杆|西兰|拌|脆|嫩|爽口|入味/, '产品创新': /新菜|新鲜|鲜菜|凉拌|凉菜|拌菜|不过夜|当天|现做|现拌|出.{0,3}菜|上.{0,3}菜/, '门店开店': /开店|分店|开到|什么时候.*开|建议.*开|我们这.*没|这边.*没|本地.*有|哪里有店|店在哪/, '健康营养': /健康|减脂|低脂|营养|蔬菜|清淡|0负担|低卡/, '价格性价比': /便宜|划算|实惠|贵|价格|性价比|套餐|¥/, '活动机制': /换菜|换券|换免费|带.*换|带.*能换|花.*换|报纸|活动.*介绍|活动.*在哪|怎么参与|怎么换|领券|领劵/, '场景外带': /外带|打包|下酒|带回家|带走|外卖|食堂|带娃|带朋友/, '复购推荐': /常去|经常.*吃|经常.*去|每次|又来|回头|推荐|尝尝|去试|去尝/, '品牌情感': /马记永.*好|马记永.*爱|爱.*马记永|喜欢.*马记永|马记永.*绝/, }; const PRODUCT_RE = new RegExp(Object.values(PRODUCT_TOPICS).map((r) => r.source).join('|')); const realComments = allComments.filter((c) => { const txt = c.content || ''; if (c.nick && c.koc && c.nick === c.koc) return false; // 博主自评 // @ 别人开头的回复 = 缺乏上下文 (除非内容本身够长够独立) if (/^\s*@/.test(txt) && stripDeco(txt.replace(/^\s*@[^\s@#]+/, '')).length < 20) return false; if (NOISE_RE.test(txt) || OFFTOPIC_RE.test(txt) || PROMO_RE.test(txt) || SHILL_RE.test(txt) || META_KOL_RE.test(txt)) return false; const emojis = txt.match(EMOJI_HEAVY_RE) || []; if (emojis.length >= 3) return false; const core = stripDeco(txt); if (core.length < 6) return false; if (core.length > 80 && emojis.length >= 1) return false; if (core.length > 120) return false; if (!PRODUCT_RE.test(txt)) return false; // 硬约束: 必须产品相关 return true; }); // 按主题分桶 (只归首个匹配主题) const buckets = {}; for (const tag of Object.keys(PRODUCT_TOPICS)) buckets[tag] = []; for (const c of realComments) { for (const [tag, re] of Object.entries(PRODUCT_TOPICS)) { if (re.test(c.content)) { buckets[tag].push(c); break; } } } // 排序: 点赞降序;同点赞按"信息量"降序 (产品关键词命中数 + 内容长度) const informationScore = (c) => { let hits = 0; for (const re of Object.values(PRODUCT_TOPICS)) if (re.test(c.content)) hits++; const core = stripDeco(c.content); return hits * 20 + core.length; }; for (const tag of Object.keys(buckets)) { buckets[tag].sort((a, b) => (b.like - a.like) || (informationScore(b) - informationScore(a))); } // 主题轮询: 先每主题 Top 2,补到 16 const topPicks = []; const queues = Object.entries(buckets).map(([tag, list]) => ({ tag, list, idx: 0 })); for (let round = 0; round < 4 && topPicks.length < 16; round++) { for (const q of queues) { if (topPicks.length >= 16) break; if (q.idx < q.list.length && q.idx < round + 1) { topPicks.push({ topic: q.tag, c: q.list[q.idx] }); q.idx++; } } } realComments.length = 0; realComments.push(...topPicks.map((p) => p.c)); const realCommentList = topPicks.map(({ topic, c }) => `
${esc(topic)} ${esc(c.koc)} ${esc(c.ip || '')}
${esc(c.content.replace(/\n/g, ' '))}
`).join(''); const HTML = ` 马记永·四月「新鲜菜」KOL/KOC 宣发结案报告
MAJIYONG · 兰州牛肉面 · 新鲜菜项目 · 2026.04

马记永「新鲜菜」
KOL/KOC 宣发
结案报告

基于 ${summary.total} 篇报备笔记 (KOL ${summary.kolCount} + KOC ${summary.kocCount}) + ${allComments.length} 条公开评论真实抓取,完整复盘投放规模、内容形态、互动效率、评论 VOC 与品牌词渗透,并给出下一轮可执行的优化建议。

投放期间2026-04
总报备${summary.total} 篇
KOL 投入¥${fmt(summary.kolSpend)}
总曝光${fmt(summary.totalImpressions)}
总互动${fmt(summary.totalEngagement)}
真实评论${allComments.length} 条
Section 01

数据汇总 — 投放规模与产出效率

本期 ${summary.total} 篇笔记 (KOL ${summary.kolCount} + KOC ${summary.kocCount}),KOL 投入预算 ¥${fmt(summary.kolSpend)},总曝光 ${fmt(summary.totalImpressions)} / 总互动 ${fmt(summary.totalEngagement)},整体互动率 ${pct(summary.engagementRate)},综合 CPE ¥${summary.cpe.toFixed(2)}。

总报备笔记
${summary.total}篇
KOL ${summary.kolCount} · KOC ${summary.kocCount}
KOL 总预算
¥${fmt(summary.kolSpend)}
CPM ¥${summary.cpm.toFixed(2)}
总曝光
${fmt(summary.totalImpressions)}
大盘心智渗透
总互动
${fmt(summary.totalEngagement)}
CPE ¥${summary.cpe.toFixed(2)}
点赞 / 收藏
${fmt(summary.totalLikes)} / ${fmt(summary.totalCollects)}
收藏率 ${(summary.totalCollects/Math.max(summary.totalLikes,1)*100).toFixed(1)}%
互动率
${summary.engagementRate.toFixed(2)}%
行业基准 3-5%
真实评论抓取
${fmt(allComments.length)}/ ${summary.totalXlsxComments} xlsx
含子评论,已去重
笔记解析
${summary.resolved}/${summary.total}
短链失效 ${summary.failed} 篇

按量级分层产出

内容形态产出对比

Section 02

数据明细 — KOL 全量 + KOC Top 50

KOL 合作表 ${summary.kolCount} 篇全量展示,KOC 合作表 ${summary.kocCount} 篇按互动降序取 Top 50 (完整明细见 \`majiyong-closing-report.md\`)。

KOL 全量 (${summary.kolCount} 篇)

${detailKolRows}
#KOL量级内容形态区域 粉丝单价 曝光点赞评论互动 笔记

KOC Top 50 (按互动降序)

${detailKocTop}
#KOC分层内容形态区域 粉丝点赞评论互动真实评论
Section 03

话题数据 — 评论 VOC 主题分布

基于 ${allComments.length} 条真实评论 (含 ${noiseComments.length} 条互助互赞噪声 = ${noiseRate.toFixed(2)}%),按 ${TOPICS.length} 个主题进行规则化标注。**新鲜菜主题命中 ${topicHits['新菜/新鲜菜/产品创新'].length} 条,核心心智渗透成功**。

主题命中明细

${topicRows}
主题命中占比典型样本

真实评论原声 (Top 16)

产品强相关 · 多主题轮询 · 已剔除噪声/托式营销/博主自评,展示具有产品对话价值的真实评论。

${realCommentList}
Section 04

品牌相关词存量 — 心智渗透盘点

从 ${allComments.length} 条评论文本提取,显示品牌词、活动词、品类词在用户对话中的实际渗透情况。

① 品牌词

马记永 / 兰州牛肉面 / 马记永兰州 等核心品牌词

② 活动相关词

新鲜菜 / 春日新品 / 联名 / 试吃 等本期投放活动词

③ 品类词占位

兰州拉面 / 西北菜 / 凉拌菜 等品类心智词

④ 评论高频词云

从全部评论文本提取的高频关键词

关键洞察

✓ 品牌词渗透稳定

"马记永"作为品牌词在评论中高频自然出现,说明品牌已形成稳定心智占位,基础好。

✓ 活动词"新鲜菜"成功

"新鲜菜"在评论中超越价格主题,本轮"新鲜菜"心智宣发核心目标达成,继续放大可形成长期资产。

⚠ 竞品词出现

"陈香贵 / 张拉拉"等竞品在评论中被自然提及,需要建立心智份额对照基线持续监测。

Section 05

本次宣发的优点、不足 & 后续投放建议

✓ 优点

${PROS.map((p) => `

${esc(p.title)}

${p.text}

`).join('')}

✗ 不足

${CONS.map((c) => `

${esc(c.title)}

${c.text}

`).join('')}

→ 后续投放建议

${RECS.map((r) => `
${r.p}

${esc(r.t)}

${r.b}

`).join('')}

下一轮预算建议分配

头/腰部 KOL
35%
2~3 位创意/跨界 KOL,延续高杠杆爆款方法论
差异化探店 KOC
35%
5 赛道分发 (减脂/早午餐/家庭/一人食/商务),各 15-20 篇
二创 IP 池 + 在地达人
15%
沉淀长期 IP 资产 + 月度打卡官
薯条 + 评论运营 + 数据
15%
Top 5% 加投 + SOP + 风险词预警 + 求开店承接
Section 06 · ★ 重中之重

新机会挖掘 — 从 ${allComments.length} 条评论逆向反推 ${OPPORTUNITIES.length} 个新机会

**结案报告告诉老板"过去花得值不值",本节告诉团队"下一步该怎么花得更值"。** 把每一条评论当成一次市场对话逐字解读,从微观信号反推产品/内容/人群/投放/数据 5 大象限的机会缺口。完整逐条解读见配套文档 majiyong-new-opportunities.md。

⭐ Top 5 P0 优先级 (下周可启动)

${TOP5.map((id, idx) => { const o = OPPORTUNITIES.find((x) => x.id === id); return `
#${idx + 1}
${o.id} · ${o.p}

${esc(o.t)}

来源信号: ${esc(o.signal)}

${esc(o.action)}

`; }).join('')}

完整 ${OPPORTUNITIES.length} 个新机会按 5 大象限分独立章节深度展开,见下方 Section 06.A ~ 06.E。

${(() => { const QUADRANTS = [ { letter: 'A', cat: 'A · 产品卖点', color: 'amber', tagClass: '', accent: 'card-accent', desc: '从用户评论里反推的产品/SKU 级机会 — 把"已经被用户说出口"的需求变成可上架的菜单/套餐/卖点。' }, { letter: 'B', cat: 'B · 内容形态', color: 'green', tagClass: 'green', accent: 'card-green', desc: '内容打法升级 — 同样的预算,如何用更高 ROI 的内容形态,把好的东西讲得更让人记得住。' }, { letter: 'C', cat: 'C · 人群渠道', color: 'purple', tagClass: 'purple', accent: '', desc: '人群和渠道的二八优化 — 让每一分预算都投在"会真去吃"的人身上,而不是"看了没法吃"的远方观众。' }, { letter: 'D', cat: 'D · 投放机制', color: 'blue', tagClass: 'blue', accent: 'card-blue', desc: '投放过程的机制化 — 把"凭感觉发笔记"变成"算法驱动止损/加投/预警",每一轮都比上一轮更聪明。' }, { letter: 'E', cat: 'E · 数据机制', color: 'rose', tagClass: 'rose', accent: 'card-rose', desc: '长效数据资产 — 主题词典、竞品对照,这些是可以持续复用 10 轮投放的底层基建。' }, ]; return QUADRANTS.map((q) => { const list = OPPORTUNITIES.filter((o) => o.cat === q.cat); return `
Section 06.${q.letter} · ${q.cat}

${esc(q.cat)} ${list.length} 个新机会

${esc(q.desc)}

${list.map((o, idx) => `
${o.id}
${o.id} ${o.p}

${esc(o.t)}

📍 信号 / Signal

${esc(o.signal)}

🎯 行动 / Action

${esc(o.action)}

� 预期 / Outcome

${esc(o.outcome || '-')}

💡 为什么要做 / Why

${esc(o.why || '-')}

${Array.isArray(o.how) && o.how.length ? `
🛠️ 如何执行 / How (${o.how.length} 步)
    ${o.how.map((step) => `
  1. ${esc(step)}
  2. `).join('')}
` : ''}
`).join('')}
`; }).join(''); })()}

马记永·四月「新鲜菜」KOL/KOC 宣发结案报告 · 基于 ${summary.total} 篇笔记 + ${allComments.length} 条评论真实数据生成

Generated ${new Date().toISOString().slice(0,19).replace('T',' ')}

`; fs.writeFileSync(OUT_HTML, HTML, 'utf8'); console.log('✓ HTML:', OUT_HTML, Math.round(HTML.length / 1024) + 'KB'); // ---------- MD ---------- const md = []; const W = (s) => md.push(s); W('# 马记永 · 四月「新鲜菜」KOL/KOC 宣发结案报告'); W(''); W(`> **投放期间**: 2026-04 · **生成时间**: ${new Date().toISOString().slice(0, 19).replace('T', ' ')} `); W(`> **数据范围**: ${summary.total} 篇报备笔记 (KOL ${summary.kolCount} + KOC ${summary.kocCount}) + ${allComments.length} 条公开评论 (覆盖 ${items.filter((x) => (x._comments || []).length > 0).length}/${summary.total} 篇)`); W(''); W('---'); W(''); W('## 一、数据汇总'); W(''); W('| 指标 | 数值 | 备注 |'); W('|---|---:|---|'); W(`| 总报备笔记 | ${summary.total} | KOL ${summary.kolCount} + KOC ${summary.kocCount} |`); W(`| KOL 总预算 | ¥${fmt(summary.kolSpend)} | CPM ¥${summary.cpm.toFixed(2)} |`); W(`| 总曝光 | ${fmt(summary.totalImpressions)} | 大盘心智渗透 |`); W(`| 总互动 | ${fmt(summary.totalEngagement)} | CPE ¥${summary.cpe.toFixed(2)} |`); W(`| 点赞 / 收藏 / 评论 (xlsx) | ${fmt(summary.totalLikes)} / ${fmt(summary.totalCollects)} / ${fmt(summary.totalXlsxComments)} | - |`); W(`| 整体互动率 | ${pct(summary.engagementRate)} | 行业基准 3-5% |`); W(`| 笔记解析成功 | ${summary.resolved}/${summary.total} | 短链失效 ${summary.failed} 篇 |`); W(`| 真实评论抓取 | ${allComments.length} 条 | 噪声率 ${noiseRate.toFixed(2)}% |`); W(''); W('### 按量级分层产出'); W(''); W('| 量级 | 篇数 | 总曝光 | 总互动 | 平均互动 | 互动率 | 投入 | CPE |'); W('|---|---:|---:|---:|---:|---:|---:|---:|'); for (const t of tierStats) { W(`| ${t.tier} | ${t.count} | ${fmt(t.imp)} | ${fmt(t.eng)} | ${t.avgEng} | ${t.rate.toFixed(2)}% | ¥${fmt(t.spend)} | ${t.cpe === '-' ? '-' : '¥' + t.cpe} |`); } W(''); W('### 按内容形态产出 (Top 12)'); W(''); W('| 内容形态 | 篇数 | 总曝光 | 总互动 | 平均互动 | 互动率 |'); W('|---|---:|---:|---:|---:|---:|'); for (const t of typeStats.slice(0, 12)) { W(`| ${t.type} | ${t.count} | ${fmt(t.imp)} | ${fmt(t.eng)} | ${t.avgEng} | ${t.rate.toFixed(2)}% |`); } W(''); W('### 区域分布 Top 12'); W(''); W('| 区域 | 篇数 | 总互动 |'); W('|---|---:|---:|'); for (const r of topRegions) W(`| ${r.region} | ${r.count} | ${fmt(r.eng)} |`); W(''); W('---'); W(''); W(`## 二、数据明细 (KOL ${summary.kolCount} 全量 + KOC Top 50)`); W(''); W('### 2.1 KOL 全量'); W(''); W('| # | KOL | 量级 | 内容形态 | 区域 | 粉丝 | 单价 | 曝光 | 点赞 | 评论 | 互动 |'); W('|---:|---|---|---|---|---:|---:|---:|---:|---:|---:|'); const kolSorted = [...kolItems].sort((a, b) => num(b.engagementSubtotal || b.engagement) - num(a.engagementSubtotal || a.engagement)); for (let i = 0; i < kolSorted.length; i++) { const r = kolSorted[i]; W(`| ${i + 1} | ${r.name} | ${r.tier || '-'} | ${r.contentType || '-'} | ${String(r.region || '-').slice(0, 3)} | ${(num(r.followersWan) * 10000).toLocaleString('zh-CN')} | ¥${fmt(r.priceOrder)} | ${fmt(r.impressionsSubtotal || r.impressions)} | ${fmt(r.likes)} | ${fmt(r.comments)} | ${fmt(r.engagementSubtotal || r.engagement)} |`); } W(''); W('### 2.2 KOC Top 50'); W(''); W('| # | KOC | 分层 | 内容形态 | 区域 | 粉丝 | 点赞 | 评论 | 互动 | 真实评论 |'); W('|---:|---|---|---|---|---:|---:|---:|---:|---:|'); const kocTop = [...kocItems].sort((a, b) => num(b.engagementSubtotal || b.engagement) - num(a.engagementSubtotal || a.engagement)).slice(0, 50); for (let i = 0; i < kocTop.length; i++) { const r = kocTop[i]; W(`| ${i + 1} | ${r.name} | ${r.tier || 'KOC'} | ${r.contentType || '-'} | ${String(r.region || '-').slice(0, 3)} | ${(num(r.followersWan) * 10000).toLocaleString('zh-CN')} | ${fmt(r.likes)} | ${fmt(r.comments)} | ${fmt(r.engagementSubtotal || r.engagement)} | ${(r._comments && r._comments.length) || 0} |`); } W(''); W('---'); W(''); W('## 三、话题数据 — 评论 VOC 主题分布'); W(''); W(`基于 **${allComments.length}** 条真实评论 (含 ${noiseComments.length} 条噪声 = ${noiseRate.toFixed(2)}%) 的规则化主题命中:`); W(''); W('| 主题 | 命中 | 占比 | 典型样本 |'); W('|---|---:|---:|---|'); for (const t of TOPICS) { const hits = topicHits[t.tag]; const sample = hits.sort((a, b) => b.like - a.like)[0]; const sampleText = sample ? `[${sample.koc}@${sample.ip || '-'}] ${sample.content.replace(/\n/g, ' ').replace(/\|/g, '\\|').slice(0, 80)}` : '-'; W(`| ${t.tag} | ${hits.length} | ${(hits.length / Math.max(allComments.length, 1) * 100).toFixed(1)}% | ${sampleText} |`); } W(''); W('### 真实评论原声 Top 16 (产品强相关 · 多主题轮询)'); W(''); for (const { topic, c } of topPicks) { W(`- **[${topic}]** \`${c.koc}@${c.ip || '-'}\`: ${c.content.replace(/\n/g, ' ')}`); } W(''); W('---'); W(''); W('## 四、品牌相关词存量'); W(''); W('### 4.1 品牌词'); W(''); W('| 词 | 评论命中 | 状态 |'); W('|---|---:|---|'); for (const w of cloudBrand) W(`| ${w.name} | ${w.value - 5 > 0 ? w.value - 5 : 0} | ${w.value > 5 ? '✓ 已渗透' : '○ 待沉淀'} |`); W(''); W('### 4.2 活动相关词'); W(''); W('| 词 | 评论命中 | 状态 |'); W('|---|---:|---|'); for (const w of cloudActivity) W(`| ${w.name} | ${w.value - 5 > 0 ? w.value - 5 : 0} | ${w.value > 5 ? '✓ 已渗透' : '○ 待沉淀'} |`); W(''); W('### 4.3 品类词占位'); W(''); W('| 词 | 评论命中 | 状态 |'); W('|---|---:|---|'); for (const w of cloudCategory) W(`| ${w.name} | ${w.value - 5 > 0 ? w.value - 5 : 0} | ${w.value > 5 ? '✓ 已渗透' : '○ 待沉淀'} |`); W(''); W('### 4.4 评论高频词 Top 50'); W(''); W('| 词 | 频次 |'); W('|---|---:|'); for (const w of wordcloudComments.slice(0, 50)) W(`| ${w.name} | ${w.value} |`); W(''); W('---'); W(''); W('## 五、本次宣发的优点 / 不足 / 后续建议'); W(''); W('### 5.1 ✓ 优点'); W(''); for (const p of PROS) { W(`**${p.title}**`); W(''); W(p.text.replace(/<\/?b>/g, '**').replace(/([^<]+)<\/code>/g, '`$1`')); W(''); } W('### 5.2 ✗ 不足'); W(''); for (const c of CONS) { W(`**${c.title}**`); W(''); W(c.text.replace(/<\/?b>/g, '**')); W(''); } W('### 5.3 → 后续投放建议'); W(''); W('| 优先级 | 行动 | 说明 |'); W('|---|---|---|'); for (const r of RECS) W(`| **${r.p}** | ${r.t} | ${r.b} |`); W(''); W('### 5.4 下一轮预算建议分配'); W(''); W('| 模块 | 占比 | 说明 |'); W('|---|---:|---|'); W('| 头/腰部 KOL | 35% | 2~3 位创意/跨界 KOL,延续高杠杆爆款方法论 |'); W('| 差异化探店 KOC | 35% | 5 赛道分发 (减脂/早午餐/家庭/一人食/商务),各 15-20 篇 |'); W('| 二创 IP 池 + 在地达人 | 15% | 沉淀长期 IP 资产 + 月度打卡官 |'); W('| 薯条 + 评论运营 + 数据 | 15% | Top 5% 加投 + SOP + 风险词预警 + 求开店承接 |'); W(''); W('---'); W(''); W(`*本结案报告基于 ${summary.total} 篇笔记 (KOL ${summary.kolCount} + KOC ${summary.kocCount}) + ${allComments.length} 条公开评论真实数据,通过可复用 VOC 工作流自动生成。配套交互式 HTML 报告: \`majiyong-closing-report.html\` · 配套深度新机会文档: \`majiyong-new-opportunities.md\`*`); fs.writeFileSync(OUT_MD, md.join('\n'), 'utf8'); console.log('✓ MD:', OUT_MD, md.length, 'lines'); };