#!/usr/bin/env node // ============================================================================== // 乳酸菌素片儿童版 VOC 质量审计脚本 // ============================================================================== // 检查:重复 / 跳题 / 内容过短 / 纯表情 / 与章节主题不相关等问题 // ============================================================================== const LA = require('./lactic-analyze.js'); const data = LA.loadMerged(); const items = data.items; function dump(title, arr, maxShow = 5) { console.log('\n' + '─'.repeat(60)); console.log(`【${title}】`); console.log('─'.repeat(60)); arr.slice(0, maxShow).forEach((it, i) => { console.log(` [${i + 1}] ${it.platform.toUpperCase()} · ${it.keyword} · ${it.nickname} · ♥${it.likes}`); console.log(` 「${(it.content || '').slice(0, 160)}」`); }); } console.log('========================================='); console.log('江中乳酸菌素片儿童版 · VOC 质量审计'); console.log(`总条数:${items.length} / 平台:${Object.keys(data.meta?.platforms || {}).join('+')}`); console.log('========================================='); // === 1. 检查 Ch1.1 引用的爆款 VOC 是否相关 === console.log('\n▶ Ch1.1 · 成人版爆款 VOC(应该都提到乳酸菌素片/肠胃)'); const adultHit = LA.getEvidence(items, { keyword: '乳酸菌素片', contentMatch: /肠鸣|胃胀|神药|便秘|好了|有用|治好|咕噜/, minChars: 20, top: 4, seed: 7, }); dump('Ch1.1 成人版爆款', adultHit); // === 2. 检查 Ch2.1 妈咪爱 VOC === console.log('\n▶ Ch2.1 · 妈咪爱家长场景(应该是宝宝/孩子相关)'); const maomi = LA.getEvidence(items, { keyword: '妈咪爱', contentMatch: /宝宝|孩子|月|胀气|胀肚|便秘|腹泻|医生|儿科|医院/, minChars: 30, top: 4, seed: 7, }); dump('Ch2.1 妈咪爱场景', maomi); // === 3. 检查 Ch2.2 亿活/金双岐 === console.log('\n▶ Ch2.2 · 亿活/金双岐(应该是腹泻/抗生素/菌群相关)'); const yihuo = LA.getEvidence(items, { keyword: '亿活 儿童', contentMatch: /腹泻|抗生素|酵母菌|布拉氏|发烧|宝宝|孩子|儿童|药店/, minChars: 30, top: 3, seed: 5, }); dump('Ch2.2 亿活', yihuo); const jinshuangqi = LA.getEvidence(items, { keyword: '金双岐', contentMatch: /拉肚|便秘|菌群|三联|嚼|腹泻|宝宝|孩子/, minChars: 25, top: 3, seed: 9, }); dump('Ch2.2 金双岐', jinshuangqi); // === 4. 检查 Ch3.1 合生元 === console.log('\n▶ Ch3.1 · 合生元(应该是儿童/宝宝场景)'); const hsy = LA.getEvidence(items, { keyword: '合生元益生菌', contentMatch: /宝宝|孩子|奶味|便秘|拉肚|幼儿园|月龄|岁/, minChars: 30, top: 4, seed: 7, }); dump('Ch3.1 合生元', hsy); // === 5. 检查 Ch3.2 万益蓝(不应该出现成人减肥)=== console.log('\n▶ Ch3.2 · 万益蓝(此产品主打成人减肥,儿童 VOC 稀薄 - 是我们要揭示的定位错位)'); const wyl = LA.getEvidence(items, { keyword: '万益蓝益生菌', minChars: 30, top: 3, seed: 13 }); dump('Ch3.2 万益蓝 top', wyl); // === 6. 检查 Ch3.2 拜奥 === console.log('\n▶ Ch3.2 · 拜奥(应该是宝宝/胀气/滴剂相关)'); const baiao = LA.getEvidence(items, { keyword: '拜奥益生菌', contentMatch: /宝宝|孩子|月|胀气|绿便|滴/, minChars: 20, top: 3, seed: 7, }); dump('Ch3.2 拜奥', baiao); // === 7. 场景 Ch5 检查 === console.log('\n▶ Ch5.1 · 入园生病'); const entry = LA.getEvidence(items, { contentMatch: /入园|幼儿园|开学|交叉感染|集体|开园|托班|小班/, minChars: 20, top: 4, seed: 5, }); dump('Ch5.1 入园', entry); console.log('\n▶ Ch5.2 · 抗生素后'); const abx = LA.getEvidence(items, { contentMatch: /抗生素|消炎药|头孢|阿莫西林|输液|杀菌|菌群|肠道菌群/, minChars: 30, top: 4, seed: 7, }); dump('Ch5.2 抗生素后', abx); console.log('\n▶ Ch5.3 · 挑食积食'); const picky = LA.getEvidence(items, { contentMatch: /挑食|饭渣|不爱吃饭|厌食|专注度|饮食|食欲|脾胃|不吃菜/, minChars: 30, top: 4, seed: 7, }); dump('Ch5.3 挑食', picky); console.log('\n▶ Ch5.4 · 换季腹泻'); const season = LA.getEvidence(items, { contentMatch: /换季|春秋|天气转凉|季节|秋冬|春夏|拉稀|腹泻反复|反复拉/, minChars: 25, top: 4, seed: 7, }); dump('Ch5.4 换季', season); // === 8. 重复检查 === console.log('\n▶ 全量重复检查(前 40 字相同视为重复)'); const bucket = new Map(); for (const it of items) { const key = (it.content || '').slice(0, 40); if (!bucket.has(key)) bucket.set(key, []); bucket.get(key).push(it); } const dupGroups = [...bucket.values()].filter((g) => g.length > 1).sort((a, b) => b.length - a.length); console.log(`共 ${dupGroups.length} 组重复`); dupGroups.slice(0, 5).forEach((g, i) => { console.log(` [重复组 ${i + 1}] ${g.length} 条`); console.log(` 「${g[0].content.slice(0, 80)}」`); console.log(` 出现在关键词: ${[...new Set(g.map((x) => x.keyword))].slice(0, 5).join(', ')}`); }); // === 9. 潜在跳题 VOC(短/纯表情/无关内容)=== console.log('\n▶ 潜在跳题 VOC(纯表情 / 过短 / 无肠道/益生菌/儿童相关词)'); const offtopic = items.filter((it) => { const c = it.content || ''; if (c.length < 15) return true; const stripped = c.replace(/\[[^\]]+\]/g, '').replace(/[\s\p{P}\p{Emoji_Presentation}\p{Extended_Pictographic}]/gu, ''); if (stripped.length < 8) return true; const hasRelevant = /肠|胃|便|益生菌|宝宝|孩子|儿童|娃|月|岁|奶|辅食|菌|消化|乳酸/.test(c); return !hasRelevant && (it.likes || 0) >= 100; }); console.log(`共 ${offtopic.length} 条潜在跳题(高赞 >100)`); offtopic.slice(0, 10).sort((a, b) => b.likes - a.likes).forEach((it, i) => { console.log(` [${i + 1}] ♥${it.likes} · ${it.keyword} · ${it.nickname}: ${(it.content || '').slice(0, 120)}`); }); console.log('\n========================================='); console.log('✅ 审计完成'); console.log('=========================================');