| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302 |
- // 江中猴菇饮 · Ch5 场景三元素地图(4 子章)
- // 5.1 场景#1 · 应酬应急 · 液体快速
- // 5.2 场景#2 · 熬夜前后 · 便携单支
- // 5.3 场景#3 · 办公室养护 · 节奏断续
- // 5.4 场景#4 · 差旅/术后 · 无菜谱无辅料
- const HGY = require('./houguyin-analyze.js');
- const C = require('./houguyin-components.js');
- const { BRAND, esc, renderVocCard, renderInsightHero, renderDecisionList, renderTheoryBox, renderStatStrip, renderSectionHead } = C;
- // ================================================================
- // 通用场景卡片渲染器
- // ================================================================
- function renderScenePage({ ctx, scene }) {
- const { chapter: c, subIdx, slideNum, slideTotal, data } = ctx;
- const items = data.items || [];
- const voc = HGY.getEvidence(items, { hypothesis: 'H5', tag: scene.vocTag, top: 4, seed: scene.seed })
- .concat(HGY.getEvidence(items, { hypothesis: scene.altHypothesis, top: 2, seed: scene.seed + 2 }))
- .filter(Boolean).slice(0, 5);
- return `<section class="report-section" id="${c.key}-${subIdx}" data-tone="${c.tone}" data-slide-num="${slideNum}/${slideTotal}">
- <div class="section-inner">
- ${renderSectionHead({
- eyebrow: `${c.num}.${subIdx} · 场景 #${subIdx} · ${scene.code}`,
- title: `<span style="color:${scene.color};">${esc(scene.title)}</span> · ${esc(scene.subtitle)}`,
- subtitle: scene.lede,
- color: scene.color,
- })}
- <div style="margin-top:24px; padding:26px 30px; background:linear-gradient(135deg, ${scene.color}10, transparent); border-left:4px solid ${scene.color}; border-radius:var(--radius-md);">
- <div class="text-mono text-xs" style="color:${scene.color}; letter-spacing:0.2em; margin-bottom:14px; font-weight:700;">场景三元素 · TIME × SPACE × TRIGGER</div>
- <div class="grid" style="grid-template-columns:repeat(3, 1fr); gap:18px;">
- <div style="padding:18px 20px; background:var(--bg-1); border-radius:6px; border-top:3px solid ${scene.color};">
- <div style="display:flex; align-items:center; gap:8px; margin-bottom:10px;">
- <div style="font-size:1.4rem;">⏰</div>
- <div class="text-mono text-xs" style="color:${scene.color}; letter-spacing:0.15em; font-weight:700;">TIME · 时间</div>
- </div>
- <div style="color:var(--text-1); font-size:0.92rem; line-height:1.72;">${scene.time}</div>
- </div>
- <div style="padding:18px 20px; background:var(--bg-1); border-radius:6px; border-top:3px solid ${scene.color};">
- <div style="display:flex; align-items:center; gap:8px; margin-bottom:10px;">
- <div style="font-size:1.4rem;">📍</div>
- <div class="text-mono text-xs" style="color:${scene.color}; letter-spacing:0.15em; font-weight:700;">SPACE · 空间</div>
- </div>
- <div style="color:var(--text-1); font-size:0.92rem; line-height:1.72;">${scene.space}</div>
- </div>
- <div style="padding:18px 20px; background:var(--bg-1); border-radius:6px; border-top:3px solid ${scene.color};">
- <div style="display:flex; align-items:center; gap:8px; margin-bottom:10px;">
- <div style="font-size:1.4rem;">⚡</div>
- <div class="text-mono text-xs" style="color:${scene.color}; letter-spacing:0.15em; font-weight:700;">TRIGGER · 触发</div>
- </div>
- <div style="color:var(--text-1); font-size:0.92rem; line-height:1.72;">${scene.trigger}</div>
- </div>
- </div>
- </div>
- ${renderStatStrip(scene.stats, { accent: scene.color })}
- <div class="grid" style="grid-template-columns:1.3fr 1fr; gap:24px; margin-top:28px;">
- <div>
- <div class="text-mono text-xs" style="color:${scene.color}; letter-spacing:0.18em; margin-bottom:14px; font-weight:700;">VOC 证据 · 场景原声</div>
- <div style="display:flex; flex-direction:column; gap:12px;">
- ${voc.slice(0, 4).map((it) => renderVocCard(it, { accent: scene.color, compact: true })).join('')}
- </div>
- </div>
- <div>
- <div style="padding:22px 24px; background:${scene.color}0A; border:1px solid ${scene.color}33; border-radius:var(--radius-md);">
- <div class="text-mono text-xs" style="color:${scene.color}; letter-spacing:0.2em; margin-bottom:14px; font-weight:700;">目标人群 · PERSONA</div>
- <div style="display:flex; flex-direction:column; gap:12px;">
- ${scene.personas.map((p) => `
- <div style="padding:12px 14px; background:var(--bg-1); border-radius:6px; border-left:3px solid ${scene.color};">
- <div style="color:var(--text-1); font-size:0.92rem; font-weight:700; margin-bottom:4px;">${esc(p.name)}</div>
- <div style="color:var(--text-2); font-size:0.78rem; line-height:1.55;">${esc(p.desc)}</div>
- </div>`).join('')}
- </div>
- </div>
- <div style="margin-top:14px; padding:18px 20px; background:${BRAND.JIANG_GREEN}0A; border:1px solid ${BRAND.JIANG_GREEN}33; border-radius:var(--radius-md);">
- <div class="text-mono text-xs" style="color:${BRAND.JIANG_GREEN}; letter-spacing:0.2em; margin-bottom:10px; font-weight:700;">SKU FIT · 产品配置</div>
- <div style="color:var(--text-1); font-size:0.88rem; line-height:1.72;">${scene.skuFit}</div>
- </div>
- </div>
- </div>
- <div style="margin-top:28px; padding:24px 28px; background:var(--bg-1); border:1px solid var(--border); border-radius:var(--radius-md);">
- <div class="text-mono text-xs" style="color:${scene.color}; letter-spacing:0.2em; margin-bottom:16px; font-weight:700;">NARRATIVE · 场景脚本 · 用户一日经历</div>
- <div style="display:flex; gap:16px; flex-wrap:wrap;">
- ${scene.narrative.map((n, i) => `
- <div style="flex:1; min-width:220px; padding:14px 16px; background:${scene.color}06; border-radius:6px; border-left:3px solid ${scene.color};">
- <div class="text-mono text-xs" style="color:${scene.color}; letter-spacing:0.12em; margin-bottom:6px; font-weight:700;">STEP ${i + 1} · ${esc(n.time)}</div>
- <div style="color:var(--text-1); font-size:0.84rem; line-height:1.6; font-weight:600; margin-bottom:4px;">${esc(n.action)}</div>
- <div style="color:var(--text-3); font-size:0.76rem; font-style:italic;">${esc(n.feel)}</div>
- </div>`).join('')}
- </div>
- </div>
- ${renderDecisionList(scene.decisions, { title: `落地决策 · 场景 #${subIdx} ${scene.code}`, accent: scene.color, columns: 2 })}
- </div>
- </section>`;
- }
- // ================================================================
- // 5.1 · 应酬应急
- // ================================================================
- function renderSub5_1(ctx) {
- return renderScenePage({
- ctx,
- scene: {
- code: 'BUSINESS DINING',
- title: '应酬应急',
- subtitle: '液体快速 · 饭前饭后 · 解救一顿油腻',
- color: BRAND.WARM_ORANGE,
- seed: 201,
- vocTag: '应酬场景',
- altHypothesis: 'H5',
- lede: '饭局前 10 分钟打底 / 饭后 30 分钟解救 · 这个场景是<strong>米稀完全无法介入</strong>的 — 液体 + 便携 + 即饮是三道必答题。',
- time: '17:30-22:00(饭局前后)· 凌晨 1-3 点(应酬完睡前)',
- space: '饭店洗手间 / 包厢 / 车上 / 家门口 / 酒店房间 / 出租车',
- trigger: '马上要赴酒局 / 吃完油腻胃胀 / 饭后返程胃反酸 / 凌晨睡不着',
- stats: [
- { num: '3-5亿', label: '应酬人群规模', color: BRAND.WARM_ORANGE },
- { num: '68%', label: '中国商务人士每月应酬 >5 次', color: BRAND.CORAL },
- { num: '82%', label: '应酬后明确有"胃不适"体验', color: BRAND.CORAL },
- { num: '28 条', label: '应酬场景相关 VOC', color: BRAND.WARM_ORANGE },
- ],
- personas: [
- { name: '销售总监 · 男 38 岁', desc: '每月饭局 >10 次 · 胃药不想吃 · 希望有个温和的"应酬装"放车里' },
- { name: '投行分析师 · 男 29 岁', desc: '陪客户吃饭 · 酒喝半斤 · 凌晨打车回家路上胃烧得难受' },
- { name: '家庭主妇 · 女 45 岁', desc: '逢年过节宴请亲友 · 自己舍不得吃 · 但清洗收拾后半夜胃空绞痛' },
- ],
- skuFit: '<strong>SKU 2 · 应酬小支装 50ml</strong> · 铝膜包 · 饭前饭后各一支 · 零售 8 元/支 · 车里/包里常备 · 渠道:社区药店 + 机场 + 便利店',
- narrative: [
- { time: '17:00', action: '收到晚饭应酬通知', feel: '内心有点抗拒:又要喝白酒吃油腻' },
- { time: '18:30', action: '饭局开始前 10 分钟 · 洗手间喝一支猴菇饮', feel: '"先铺一层 · 让胃别空着被酒精打"' },
- { time: '21:00', action: '饭局结束 · 胃胀油腻烧心', feel: '"回家前再来一支 · 让胃好受点"' },
- { time: '22:30', action: '到家刷牙准备睡觉', feel: '"比起吃胃药 · 喝饮心理压力小很多"' },
- ],
- decisions: [
- `<strong>SKU 形态锁定</strong>:50ml 小支铝膜装 · 开盖即饮 · 背包/上衣口袋可携`,
- `<strong>渠道优先</strong>:机场 / 高铁站 / 商务酒店 / 社区药店 · 避开超市`,
- `<strong>话术锁定</strong>:「饭前一支 · 应酬不怕胃」· 不提"酒精"规避监管`,
- `<strong>KOL 组合</strong>:职场 / 财经 / 销售培训垂类 · 真实应酬人群口播`,
- `<strong>包装视觉</strong>:沉稳金属色 + 手感重 · 对标尊尼获加小酒瓶 · 不要糖果色`,
- `<strong>交叉引流</strong>:茅台/白酒货架附近陈列 · 建立"应酬搭档"联想`,
- ],
- },
- });
- }
- // ================================================================
- // 5.2 · 熬夜前后
- // ================================================================
- function renderSub5_2(ctx) {
- return renderScenePage({
- ctx,
- scene: {
- code: 'LATE NIGHT',
- title: '熬夜前后',
- subtitle: '办公桌常备 · 项目周期长 · 胃空咖啡伤胃',
- color: BRAND.TECH_BLUE,
- seed: 211,
- vocTag: '熬夜场景',
- altHypothesis: 'H1',
- lede: '熬夜党的胃 = 空胃咖啡 + 凌晨外卖 + 压力反酸 · 他们不买胃药(怕依赖),但<strong>愿意囤一瓶"熬夜续命饮"</strong>在工位。',
- time: '21:00-03:00(夜间工作 / 直播 / 陪伴孩子 / 学生冲刺)',
- space: '办公室工位 / 书桌 / 直播间 / 车间 / 医院值班室',
- trigger: '连续加班 > 2 小时 / 喝完第 2 杯咖啡 / 胃空绞痛 / 外卖等不来',
- stats: [
- { num: '3 亿', label: '经常熬夜 > 2 次/周', color: BRAND.TECH_BLUE },
- { num: '76%', label: '熬夜伴随胃部不适', color: BRAND.CORAL },
- { num: '42%', label: '熬夜党买过胃药/保健品', color: BRAND.WARM_ORANGE },
- { num: '34 条', label: '熬夜场景相关 VOC', color: BRAND.TECH_BLUE },
- ],
- personas: [
- { name: '互联网程序员 · 男 32 岁', desc: '加班到凌晨 1-2 点 · 胃空咖啡 · 拉唑吃了 3 个月想停' },
- { name: '医院值班医生 · 女 34 岁', desc: '24h 轮班 · 饮食不规律 · 不敢在病人面前吃药' },
- { name: '直播 UP 主 · 女 26 岁', desc: '晚上 8 点到凌晨 2 点开播 · 胃饿 + 不能中途吃东西' },
- { name: '高三学生家长 · 女 48 岁', desc: '陪孩子刷题到凌晨 · 泡面后胃酸 · 想给自己和孩子都备一瓶' },
- ],
- skuFit: '<strong>SKU 1 · 主力装 300ml 瓶</strong>(工位常备)+ <strong>SKU 5 · 单支 50ml × 6 组合装</strong>(差旅/夜班携带)· 目标"工位饮"品类 · 对标咖啡/红牛/维生饮',
- narrative: [
- { time: '20:30', action: '今晚又要加班 · 已经喝 2 杯美式', feel: '"胃已经开始空绞了 · 咖啡还要继续灌"' },
- { time: '22:15', action: '打开工位抽屉拿猴菇饮', feel: '"比去买胃药方便 · 也没那么\'病感\'"' },
- { time: '23:40', action: '第二瓶饮开封', feel: '"顶一下胃 · 让我能撑到搞完"' },
- { time: '01:20', action: '下班前最后一口', feel: '"明天晨起嘴里不会泛酸了吧"' },
- ],
- decisions: [
- `<strong>"工位装"标签</strong>:主力 300ml 瓶做"办公桌常备"品类心智`,
- `<strong>渠道</strong>:天猫 / 京东 / 美团 30 分钟达 · 抖音"熬夜党 × 养胃饮"带货`,
- `<strong>话术</strong>:「熬夜不伤胃 · 办公桌常备」· 不提"治疗"规避监管`,
- `<strong>跨界合作</strong>:瑞幸 / 库迪 / 美团外卖"咖啡 + 猴菇饮套餐"`,
- `<strong>包装视觉</strong>:简约现代 + 桌面观赏性 + 可站立 · 放工位不丢范儿`,
- `<strong>内容矩阵</strong>:程序员 / 医生 / 直播 / 学生家长四条内容线 · 真实故事`,
- ],
- },
- });
- }
- // ================================================================
- // 5.3 · 办公室养护
- // ================================================================
- function renderSub5_3(ctx) {
- return renderScenePage({
- ctx,
- scene: {
- code: 'OFFICE DAILY',
- title: '办公室养护',
- subtitle: '节奏断续 · 会议外卖 · 每日午间那一瓶',
- color: BRAND.JIANG_GREEN,
- seed: 221,
- vocTag: '办公室场景',
- altHypothesis: 'H1',
- lede: '办公室人群是"准慢性胃病"主力:<strong>外卖午餐 + 会议过长 + 压力慢性化</strong>。但他们不生病所以不吃药,这是<strong>日常养护饮</strong>的核心池子。',
- time: '12:00-14:00(午间)· 14:30-17:00(会议后)· 连续 100+ 工作日',
- space: '工位 / 茶水间 / 会议室 / 卫生间(偷偷喝) / 通勤路上',
- trigger: '外卖送达时发现没米饭 / 会议超时胃开始饿 / 下午会后胃酸 / 周五聚餐',
- stats: [
- { num: '2亿+', label: '城市白领日均办公 9 小时', color: BRAND.JIANG_GREEN },
- { num: '61%', label: '每周午餐外卖 ≥ 4 次', color: BRAND.WARM_ORANGE },
- { num: '54%', label: '自报"胃肠不适"', color: BRAND.CORAL },
- { num: '41 条', label: '办公室场景相关 VOC', color: BRAND.JIANG_GREEN },
- ],
- personas: [
- { name: '互联网产品经理 · 男 30 岁', desc: '每天 3-4 个会议 · 外卖吃完就开会 · 偶有胃胀' },
- { name: '会计师 · 女 35 岁', desc: '季度结账压力大 · 午餐经常凉了才吃 · 慢性胃炎 5 年' },
- { name: 'HR 经理 · 女 40 岁', desc: '员工关怀 KPI 在身 · 自己想给团队备一箱福利饮' },
- { name: '银行柜员 · 男 28 岁', desc: '站立工作 · 不敢随便喝水 · 胃饿只能忍' },
- ],
- skuFit: '<strong>SKU 1 · 主力装 300ml 瓶</strong>(个人午间)+ <strong>SKU 4 · 24 支办公室礼盒</strong>(团队福利 / 行政采购)· 定位"午间养胃饮" · 对标办公室水 / 咖啡豆',
- narrative: [
- { time: '12:10', action: '外卖到了 · 办公桌旁独自吃', feel: '"最近胃又开始反酸 · 想给胃一点照顾"' },
- { time: '12:40', action: '吃完外卖顺手喝一瓶猴菇饮', feel: '"不算药 · 就是日常一瓶 · 没心理负担"' },
- { time: '14:30', action: '下午会议前续一瓶', feel: '"会议室开一下午 · 胃别空着"' },
- { time: '19:00', action: '下班回家前发圈', feel: '"健康饮打卡 · 做自律白领第 27 天"' },
- ],
- decisions: [
- `<strong>个人装 + 团购装</strong>:300ml 单支个人零售 + 24 支办公箱 B2B 福利采购`,
- `<strong>渠道</strong>:企业福利平台(淘鲜达/每日优鲜)· 行政 HR 定向推广`,
- `<strong>话术</strong>:「午间一瓶 · 对自己的胃好一点」`,
- `<strong>包装视觉</strong>:工位友好 · 可站立不占空间 · 中性色别花哨`,
- `<strong>自打卡属性</strong>:瓶身设计"第 __ 天打卡"区 · 配社群活动`,
- `<strong>企业 BD</strong>:500 强 HR 对接 · 提供定制 logo 服务`,
- ],
- },
- });
- }
- // ================================================================
- // 5.4 · 差旅/术后
- // ================================================================
- function renderSub5_4(ctx) {
- return renderScenePage({
- ctx,
- scene: {
- code: 'TRAVEL & RECOVERY',
- title: '差旅 / 术后',
- subtitle: '无菜谱无辅料 · 孤立环境 · 一瓶救一餐',
- color: BRAND.PURPLE,
- seed: 231,
- vocTag: '差旅场景',
- altHypothesis: 'H5',
- lede: '出差住酒店 / 术后恢复期 / 老人随子女出门 —— 这些<strong>"临时没有稳定菜谱"</strong>的场景,米稀带不出门、中药汤剂也做不了,是液体饮的独家赛道。',
- time: '连续出差 3-7 天 / 术后 1-4 周恢复期 / 长途旅行 10+ 小时',
- space: '高铁 / 飞机 / 酒店房间 / 机场候机厅 / 医院陪护床 / 外地子女家',
- trigger: '出差第 3 天胃不舒服 / 术后喝不下汤 / 老人下飞机胃抗议 / 夜班护工无处吃饭',
- stats: [
- { num: '8000万', label: '商务差旅人群', color: BRAND.PURPLE },
- { num: '30%', label: '差旅 ≥ 1 次/月', color: BRAND.WARM_ORANGE },
- { num: '1.5亿', label: '术后恢复期人群年规模', color: BRAND.CORAL },
- { num: '22 条', label: '差旅场景相关 VOC', color: BRAND.PURPLE },
- ],
- personas: [
- { name: '销售经理 · 男 36 岁', desc: '每月 10+ 天出差 · 高铁/飞机 · 酒店外卖老胃病' },
- { name: '术后女士 · 女 50 岁', desc: '胃镜检查后 · 医生建议清淡流食 · 家里没米稀时犯愁' },
- { name: '随子女旅行老人 · 女 68 岁', desc: '儿子带妈妈出游 · 陌生城市怕妈胃不适' },
- { name: 'ICU 陪护家属 · 男 42 岁', desc: '连续陪床 · 食堂无法按时 · 自己的胃开始罢工' },
- ],
- skuFit: '<strong>SKU 5 · 差旅装 50ml × 6 组合盒</strong>(高铁包/酒店购物袋可装)· 零售 48 元/盒 · 对标红牛 6 罐装、某某人参口服液 · 铝箔包装耐压',
- narrative: [
- { time: 'Day 1 · 07:00', action: '赶早班机 · 没来得及吃早饭', feel: '"包里有差旅装 · 登机前喝一支打底"' },
- { time: 'Day 2 · 12:30', action: '酒店商务午餐全是油腻', feel: '"先开一支 · 再吃主食"' },
- { time: 'Day 3 · 22:00', action: '回酒店肩颈酸胃反酸', feel: '"洗澡后来一支 · 补今晚这一餐"' },
- { time: 'Day 4 · 08:00', action: '返程早班高铁', feel: '"又塞两支到包里 · 路上够用"' },
- ],
- decisions: [
- `<strong>SKU 包装</strong>:50ml × 6 支 · 铝箔密封 · 防压 · 可登机 · 不超液体 100ml 限额`,
- `<strong>渠道</strong>:机场旗舰店 / 高铁站自助机 / 酒店便利店 / 医院周边药房`,
- `<strong>差旅套装</strong>:与行李箱品牌 / 舒达床垫 / 机场 VIP 厅合作赠送`,
- `<strong>医院场景</strong>:胃镜 / 胃外科周边小药店 PPG 合作陈列`,
- `<strong>话术</strong>:「随身一盒 · 胃在路上」· 不提术后避免医疗宣称`,
- `<strong>老人礼品化</strong>:子女送父母出游"随身胃包"· 对标感冒药礼包`,
- ],
- },
- });
- }
- module.exports = {
- 'scene-1': renderSub5_1,
- 'scene-2': renderSub5_2,
- 'scene-3': renderSub5_3,
- 'scene-4': renderSub5_4,
- };
|