ks-render-v3.js 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567
  1. #!/usr/bin/env node
  2. const fs = require('fs');
  3. const path = require('path');
  4. const ROOT = path.resolve(__dirname, '..', '..', '..');
  5. const OUT_FILE = path.join(ROOT, 'reports', 'KS-快聘-voc-insight-report.html');
  6. const hypos = [
  7. {h:'H1',title:'快聘是蓝领求职主阵地',count:596,color:'#F5A623'},
  8. {h:'H2',title:'直播带岗降低信息不对称',count:1930,color:'#00DC82'},
  9. {h:'H3',title:'薪资透明度是核心关切',count:1842,color:'#8B5CF6'},
  10. {h:'H4',title:'食宿条件影响求职决策',count:2194,color:'#FF4D8D'},
  11. {h:'H5',title:'入职流程便捷性',count:595,color:'#3B82F6'},
  12. {h:'H6',title:'求职被骗是普遍焦虑',count:4435,color:'#EF4444'},
  13. {h:'H7',title:'黑中介是核心痛点',count:3705,color:'#F97316'},
  14. {h:'H8',title:'工资结算方式差异',count:2417,color:'#6B6B6B'},
  15. ];
  16. const riskSignals = [
  17. {label:'骗',value:252,heat:514788,color:'#EF4444'},
  18. {label:'黑中介',value:109,heat:393762,color:'#EF4444'},
  19. {label:'坑',value:92,heat:375264,color:'#FF4D8D'},
  20. {label:'套路',value:45,heat:144842,color:'#F97316'},
  21. {label:'黑厂',value:43,heat:123531,color:'#FF4D8D'},
  22. {label:'押金',value:105,heat:95543,color:'#F5A623'},
  23. {label:'不退',value:70,heat:84106,color:'#F5A623'},
  24. {label:'陷阱',value:21,heat:74090,color:'#F97316'},
  25. ];
  26. const careFactors = [
  27. {label:'包吃包住',value:31,heat:89190,color:'#00DC82'},
  28. {label:'工资',value:186,heat:89081,color:'#00DC82'},
  29. {label:'加班费',value:20,heat:43986,color:'#3B82F6'},
  30. {label:'吃住',value:21,heat:34060,color:'#00DC82'},
  31. {label:'住宿',value:15,heat:25224,color:'#3B82F6'},
  32. {label:'当天入职',value:7,heat:19264,color:'#8B5CF6'},
  33. {label:'日结',value:30,heat:12651,color:'#8B5CF6'},
  34. {label:'靠谱',value:20,heat:9509,color:'#00DC82'},
  35. ];
  36. const keywords = [
  37. {label:'黑中介',value:109,heat:393762,color:'#EF4444'},
  38. {label:'找工作',value:95,heat:212718,color:'#3B82F6'},
  39. {label:'被坑',value:27,heat:147566,color:'#FF4D8D'},
  40. {label:'套路',value:52,heat:144858,color:'#F97316'},
  41. {label:'黑厂',value:44,heat:123531,color:'#FF4D8D'},
  42. {label:'工资',value:334,heat:117968,color:'#00DC82'},
  43. {label:'押金',value:105,heat:95543,color:'#F5A623'},
  44. {label:'包吃包住',value:44,heat:94771,color:'#00DC82'},
  45. ];
  46. const kwData = [
  47. {label:'包吃包住',value:785,color:'#00DC82'},
  48. {label:'克扣工资',value:776,color:'#EF4444'},
  49. {label:'黑中介',value:669,color:'#EF4444'},
  50. {label:'入职被坑',value:600,color:'#FF4D8D'},
  51. {label:'打工陷阱',value:593,color:'#F97316'},
  52. {label:'押金不退',value:523,color:'#F5A623'},
  53. ];
  54. const emotionSamples = [
  55. {keyword:'黑厂',direction:'负向',likes:91732,expr:'揭秘!广东5大黑厂有哪些?想不被坑,千万不要进'},
  56. {keyword:'入职被坑',direction:'负向',likes:6276,expr:'22年差点被骗去当咯咯哒 说什么模特走台下面的人送花就有提成'},
  57. {keyword:'求职被骗',direction:'负向',likes:8062,expr:'东北小伙被骗进厂干到S,马总竟是最大黒中芥!?'},
  58. {keyword:'打工陷阱',direction:'负向',likes:2857,expr:'找工作别踩坑!警惕黑中介套路与离谱高价工陷阱'},
  59. ];
  60. const highLikedComments = [
  61. {rank:1,likes:6276,expr:'22年差点被骗去当咯咯哒 说什么模特走台下面的人送花就有提成',kw:'入职被坑'},
  62. {rank:2,likes:2209,expr:'去买几个鸡蛋,打碎,放在沙发下面...',kw:'押金不退'},
  63. {rank:3,likes:808,expr:'我在广西就遇到过房东死活不退押金...',kw:'押金不退'},
  64. {rank:4,likes:533,expr:'做的不错,就该那样!有些房东太不像话了!',kw:'押金不退'},
  65. {rank:5,likes:491,expr:'无论怎么样,反正$黑中介$是赚了',kw:'黑中介'},
  66. {rank:6,likes:422,expr:'那暑假工能做什么啊',kw:'入职被坑'},
  67. {rank:7,likes:403,expr:'干的漂亮,支持小伙子不应该判刑...',kw:'黑中介'},
  68. {rank:8,likes:312,expr:'都绑起来了,都投降了,那人还要去喷那个喷雾',kw:'黑中介'},
  69. {rank:9,likes:311,expr:'为什么南方的房东都不退押金',kw:'押金不退'},
  70. {rank:10,likes:228,expr:'只要收身份证的都是,正常的面试只需要填表就行',kw:'黑中介'},
  71. ];
  72. function esc(s) { return String(s ?? '').replace(/[&<>"']/g, c => ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c])); }
  73. function fmtLikes(n) { if (n == null) return '0'; if (n >= 10000) return (n/10000).toFixed(1).replace(/\.0$/,'')+'w'; if (n >= 1000) return (n/1000).toFixed(1).replace(/\.0$/,'')+'k'; return String(n); }
  74. function fmtHeat(n) { if (n == null) return '0'; if (n >= 10000) return (n/10000).toFixed(1)+'w'; if (n >= 1000) return (n/1000).toFixed(1)+'k'; return String(n); }
  75. function barChart(rows, accent, maxW=900) {
  76. const max = Math.max(...rows.map(r=>r.value),1);
  77. const barH=36,gap=14,padL=140,padR=100,padV=16,W=maxW;
  78. const totalH = rows.length*(barH+gap)+padV*2;
  79. return `<div style="background:var(--bg-1);border:1px solid var(--border);border-radius:var(--radius-md);padding:20px 24px;">
  80. <svg viewBox="0 0 ${W} ${totalH}" style="width:100%;height:auto;" preserveAspectRatio="xMidYMid meet">
  81. ${rows.map((r,i)=>{const y=padV+i*(barH+gap);const w=Math.max((r.value/max)*(W-padL-padR),6);return `<text x="${padL-10}" y="${y+barH/2+5}" text-anchor="end" font-size="13" fill="var(--text-2)">${esc(r.label)}</text><rect x="${padL}" y="${y}" width="${w}" height="${barH}" rx="4" fill="${r.color||accent}" opacity="0.85"/><text x="${padL+w+10}" y="${y+barH/2+5}" font-size="13" font-weight="700" fill="${r.color||accent}" font-family="monospace">${esc(r.valueLabel||r.value)}</text>`;}).join('')}
  82. </svg>
  83. </div>`;
  84. }
  85. function vocCard(comment) {
  86. return `<div style="background:linear-gradient(180deg,rgba(255, 255, 255, 0.03) 0%,rgba(255, 255, 255, 0.01) 100%),var(--bg-1);border:1px solid var(--border);border-radius:var(--radius-md);padding:20px 22px;backdrop-filter:blur(8px);">
  87. <div style="display:flex;justify-content:space-between;align-items:center;gap:10px;margin-bottom:12px;flex-wrap:wrap;">
  88. <div style="display:flex;align-items:center;gap:8px;">
  89. <span style="width:22px;height:22px;border-radius:50%;background:#1A1A1A;color:#fff;font-size:0.6rem;font-weight:700;display:flex;align-items:center;justify-content:center;">快</span>
  90. <span style="font-weight:600;font-size:0.85rem;">快手用户</span>
  91. </div>
  92. <div style="display:flex;align-items:center;gap:8px;">
  93. <span style="font-size:0.72rem;font-weight:600;color:#EF4444;">▼ 负向</span>
  94. <span style="font-size:0.72rem;color:var(--text-3);font-family:var(--font-mono);">♥${fmtLikes(comment.likes)}</span>
  95. </div>
  96. </div>
  97. <div style="font-size:0.92rem;line-height:1.65;color:var(--text-1);">"${esc(comment.expr)}"</div>
  98. <div style="margin-top:10px;font-size:0.72rem;color:var(--text-3);">关键词: ${esc(comment.kw)}</div>
  99. </div>`;
  100. }
  101. const html = `<!DOCTYPE html>
  102. <html lang="zh-CN"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1.0">
  103. <title>快手快聘 · VOC 深度洞察报告</title>
  104. <style>
  105. :root{--bg-0:#0A0A0A;--bg-1:#111111;--bg-2:#1A1A1A;--bg-3:#252525;--border:rgba(255,255,255,0.08);--border-strong:rgba(255,255,255,0.16);--text-1:#F5F5F5;--text-2:#A8A8A8;--text-3:#6B6B6B;--amber:#F5A623;--amber-glow:rgba(245,166,35,0.15);--green:#00DC82;--purple:#8B5CF6;--rose:#FF4D8D;--blue:#3B82F6;--red:#EF4444;--orange:#F97316;--font-head:'Inter','Noto Sans SC','PingFang SC','Microsoft YaHei',sans-serif;--font-body:'Noto Sans SC','Inter','PingFang SC','Microsoft YaHei',sans-serif;--font-mono:'JetBrains Mono','SF Mono','Fira Code',monospace;--max-w:1280px;--radius-sm:8px;--radius-md:12px;--radius-lg:20px;}
  106. *{margin:0;padding:0;box-sizing:border-box}
  107. html{scroll-behavior:smooth;font-size:16px;scroll-snap-type:y proximity;}
  108. body{font-family:var(--font-body);background:var(--bg-0);color:var(--text-1);line-height:1.65;-webkit-font-smoothing:antialiased;overflow-x:hidden}
  109. body::before{content:'';position:fixed;inset:0;pointer-events:none;z-index:0;background:radial-gradient(ellipse 900px 700px at var(--amb-x,20%) var(--amb-y,25%),rgba(245,166,35,0.10),transparent 60%),radial-gradient(ellipse 800px 600px at calc(100% - var(--amb-x,20%)) calc(100% - var(--amb-y,25%)),rgba(139,92,246,0.07),transparent 60%);transition:background 1.4s cubic-bezier(.2,.7,.2,1);}
  110. body::after{content:'';position:fixed;inset:0;pointer-events:none;z-index:0;background-image:linear-gradient(rgba(255, 255, 255, 0.015) 1px,transparent 1px),linear-gradient(90deg,rgba(255, 255, 255, 0.015) 1px,transparent 1px);background-size:80px 80px;mask-image:radial-gradient(ellipse 90% 95% at 50% 50%,black 0%,transparent 85%);-webkit-mask-image:radial-gradient(ellipse 90% 95% at 50% 50%,black 0%,transparent 85%);}
  111. main.deck{position:relative;z-index:1}
  112. ::selection{background:var(--amber);color:#000}
  113. .text-hero{font-family:var(--font-head);font-weight:900;letter-spacing:-0.04em;line-height:0.95;font-size:clamp(4rem,12vw,10rem)}
  114. .text-poster{font-family:var(--font-head);font-weight:800;letter-spacing:-0.03em;line-height:1.05;font-size:clamp(2.5rem,6vw,5rem)}
  115. .text-h1{font-family:var(--font-head);font-weight:700;letter-spacing:-0.02em;line-height:1.1;font-size:clamp(2rem,4vw,3.5rem)}
  116. .text-h2{font-family:var(--font-head);font-weight:700;letter-spacing:-0.015em;line-height:1.2;font-size:clamp(1.4rem,2.5vw,2rem)}
  117. .text-h3{font-weight:600;font-size:clamp(1.05rem,1.6vw,1.3rem);letter-spacing:-0.01em}
  118. .text-body{font-size:clamp(0.92rem,1.1vw,1rem);line-height:1.75;color:var(--text-2)}
  119. .text-sm{font-size:0.85rem;color:var(--text-2)}
  120. .text-xs{font-size:0.72rem;color:var(--text-3);letter-spacing:0.02em}
  121. .text-mono{font-family:var(--font-mono)}
  122. .text-amber{color:var(--amber)}.text-green{color:var(--green)}.text-purple{color:var(--purple)}.text-rose{color:var(--rose)}.text-blue{color:var(--blue)}.text-red{color:var(--red)}.text-orange{color:var(--orange)}
  123. section.report-section{min-height:100vh;padding:clamp(60px,10vh,120px) clamp(24px,6vw,80px);position:relative;border-bottom:1px solid var(--border);display:flex;flex-direction:column;justify-content:center;scroll-snap-align:start;scroll-snap-stop:always;overflow:hidden;isolation:isolate}
  124. section.report-section::before{content:attr(data-slide-num);position:absolute;top:clamp(20px,3vh,36px);right:clamp(24px,4vw,60px);font-family:var(--font-mono);font-weight:600;font-size:clamp(0.68rem,0.75vw,0.78rem);letter-spacing:0.25em;color:var(--text-3);z-index:4;pointer-events:none}
  125. section.report-section::after{content:'';position:absolute;inset:0;pointer-events:none;z-index:-1;background:radial-gradient(ellipse 70% 60% at 85% 15%,var(--slide-glow-1,rgba(245,166,35,0.06)),transparent 55%),radial-gradient(ellipse 60% 50% at 15% 85%,var(--slide-glow-2,rgba(139,92,246,0.04)),transparent 55%);opacity:0;transition:opacity 1s cubic-bezier(.2,.7,.2,1)}
  126. section.report-section.in-view::after{opacity:1}
  127. section.report-section[data-tone="amber"]{--slide-glow-1:rgba(245,166,35,0.10);--slide-glow-2:rgba(245,166,35,0.04)}
  128. section.report-section[data-tone="rose"]{--slide-glow-1:rgba(255,77,141,0.09);--slide-glow-2:rgba(255,77,141,0.04)}
  129. section.report-section[data-tone="green"]{--slide-glow-1:rgba(0,220,130,0.08);--slide-glow-2:rgba(0,220,130,0.03)}
  130. section.report-section[data-tone="purple"]{--slide-glow-1:rgba(139,92,246,0.10);--slide-glow-2:rgba(139,92,246,0.04)}
  131. section.report-section[data-tone="blue"]{--slide-glow-1:rgba(59,130,246,0.08);--slide-glow-2:rgba(59,130,246,0.03)}
  132. section.report-section[data-tone="orange"]{--slide-glow-1:rgba(249,115,22,0.10);--slide-glow-2:rgba(249,115,22,0.04)}
  133. section.report-section[data-tone="red"]{--slide-glow-1:rgba(239,68,68,0.10);--slide-glow-2:rgba(239,68,68,0.04)}
  134. .section-inner{width:100%;max-width:var(--max-w);margin:0 auto;position:relative}
  135. .section-head{margin-bottom:clamp(32px,5vh,64px)}
  136. .section-eyebrow{display:inline-flex;align-items:center;gap:10px;font-family:var(--font-mono);font-size:0.72rem;letter-spacing:0.18em;text-transform:uppercase;color:var(--amber);font-weight:500;margin-bottom:18px}
  137. .section-eyebrow::before{content:'';display:inline-block;width:24px;height:1px;background:var(--amber)}
  138. .section-sub{color:var(--text-2);font-size:1.05rem;max-width:720px;margin-top:14px;line-height:1.8}
  139. .grid{display:grid;gap:clamp(14px,1.6vw,22px)}
  140. .grid-2{grid-template-columns:repeat(auto-fit,minmax(320px,1fr))}
  141. .grid-3{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
  142. .grid-4{grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}
  143. .card{background:linear-gradient(180deg,rgba(255, 255, 255, 0.025) 0%,rgba(255, 255, 255, 0.008) 100%),var(--bg-1);border:1px solid var(--border);border-radius:var(--radius-md);padding:clamp(20px,2.2vw,32px);position:relative;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);transition:transform 0.4s cubic-bezier(.2,.7,.2,1),border-color 0.3s ease,box-shadow 0.4s ease}
  144. .card:hover{border-color:var(--border-strong);transform:translateY(-3px);box-shadow:0 12px 40px rgba(0,0,0,0.35),0 0 0 1px rgba(245,166,35,0.08)}
  145. .card.card-glow{box-shadow:0 0 40px rgba(245,166,35,0.06)}
  146. .card-accent{border-left:3px solid var(--amber);border-top:1px solid var(--border);border-right:1px solid var(--border);border-bottom:1px solid var(--border)}
  147. .metric{background:var(--bg-1);border:1px solid var(--border);border-radius:var(--radius-md);padding:clamp(24px,2.5vw,36px);position:relative;overflow:hidden}
  148. .metric::before{content:'';position:absolute;top:0;left:0;right:0;height:2px;background:linear-gradient(90deg,var(--amber),transparent);opacity:0.6}
  149. .metric .metric-label{font-family:var(--font-mono);font-size:0.7rem;letter-spacing:0.15em;text-transform:uppercase;color:var(--text-3);margin-bottom:10px}
  150. .metric .metric-value{font-family:var(--font-head);font-weight:800;font-size:clamp(2.2rem,4vw,3.5rem);letter-spacing:-0.03em;line-height:1;color:var(--text-1);margin-bottom:8px}
  151. .metric .metric-unit{font-family:var(--font-mono);font-size:0.85rem;color:var(--amber);font-weight:500}
  152. .metric .metric-sub{margin-top:14px;font-size:0.82rem;color:var(--text-2);line-height:1.5}
  153. .tag{display:inline-flex;align-items:center;gap:6px;padding:4px 10px;border-radius:4px;font-size:0.72rem;font-weight:500;letter-spacing:0.02em;font-family:var(--font-head);background:rgba(245,166,35,0.1);color:var(--amber);border:1px solid rgba(245,166,35,0.22)}
  154. .tag.green{background:rgba(0,220,130,0.08);color:var(--green);border-color:rgba(0,220,130,0.2)}
  155. .tag.purple{background:rgba(139,92,246,0.08);color:var(--purple);border-color:rgba(139,92,246,0.2)}
  156. .tag.rose{background:rgba(255,77,141,0.08);color:var(--rose);border-color:rgba(255,77,141,0.2)}
  157. .tag.blue{background:rgba(59,130,246,0.08);color:var(--blue);border-color:rgba(59,130,246,0.2)}
  158. .tag.orange{background:rgba(249,115,22,0.08);color:var(--orange);border-color:rgba(249,115,22,0.2)}
  159. .tag.red{background:rgba(239,68,68,0.08);color:var(--red);border-color:rgba(239,68,68,0.2)}
  160. .cover-hero{position:absolute;inset:0;display:flex;flex-direction:column;justify-content:center;padding:clamp(40px,8vh,100px) clamp(24px,6vw,80px);background:radial-gradient(ellipse 60% 80% at 30% 30%,rgba(245,166,35,0.08) 0%,transparent 70%),radial-gradient(ellipse 40% 60% at 80% 70%,rgba(139,92,246,0.05) 0%,transparent 70%),var(--bg-0)}
  161. .cover-grid-bg{position:absolute;inset:0;background-image:linear-gradient(rgba(255, 255, 255, 0.025) 1px,transparent 1px),linear-gradient(90deg,rgba(255, 255, 255, 0.025) 1px,transparent 1px);background-size:60px 60px;mask-image:radial-gradient(ellipse 80% 80% at 50% 50%,black 0%,transparent 70%);-webkit-mask-image:radial-gradient(ellipse 80% 80% at 50% 50%,black 0%,transparent 70%)}
  162. .footer{text-align:center;padding:40px 24px;color:var(--text-3);font-size:0.8rem;border-top:1px solid var(--border)}
  163. </style>
  164. </head>
  165. <body>
  166. <main class="deck">
  167. <!-- 封面 -->
  168. <section class="report-section" data-slide-num="COVER" data-tone="amber" style="position:relative;">
  169. <div class="cover-grid-bg"></div>
  170. <div class="cover-hero">
  171. <div class="section-eyebrow" style="margin-bottom:24px;">VOC 深度洞察报告</div>
  172. <h1 class="text-hero" style="margin-bottom:20px;">快手快聘</h1>
  173. <p class="text-body" style="font-size:1.2rem;max-width:600px;margin-bottom:24px;">"10个蓝领,9个都用快手" · 蓝领求职生态洞察</p>
  174. <div style="display:flex;gap:12px;flex-wrap:wrap;margin-bottom:32px;">
  175. <span class="tag">快手</span>
  176. <span class="tag green">7,902 条真实评论</span>
  177. <span class="tag purple">19 个关键词覆盖</span>
  178. <span class="tag blue">380 个视频</span>
  179. </div>
  180. <div class="text-xs" style="margin-top:20px;">2026/4/24 · Generated by OpenClaw VOC System</div>
  181. </div>
  182. </section>
  183. <!-- Ch1: 执行摘要 -->
  184. <section class="report-section" data-slide-num="01" data-tone="amber">
  185. <div class="section-inner">
  186. <div class="section-head">
  187. <div class="section-eyebrow">CHAPTER 01</div>
  188. <h2 class="text-h1">执行摘要</h2>
  189. <p class="section-sub">快手快聘蓝领求职生态核心洞察</p>
  190. </div>
  191. <div class="grid grid-4" style="margin-bottom:32px;">
  192. <div class="metric"><div class="metric-label">VOC总量</div><div class="metric-value" style="color:var(--amber);">7,902</div><div class="metric-sub">条真实评论</div></div>
  193. <div class="metric"><div class="metric-label">视频播放量</div><div class="metric-value" style="color:var(--green);">9456万</div><div class="metric-sub">TOP视频汇总</div></div>
  194. <div class="metric"><div class="metric-label">最强焦虑</div><div class="metric-value" style="color:var(--red);">H6</div><div class="metric-sub">求职被骗 4435条</div></div>
  195. <div class="metric"><div class="metric-label">战略地位</div><div class="metric-value" style="color:var(--rose);">第二</div><div class="metric-sub">仅次于电商</div></div>
  196. </div>
  197. <div class="card card-accent" style="margin-bottom:28px;padding:28px 32px;">
  198. <div class="text-amber" style="font-family:var(--font-mono);font-size:0.72rem;letter-spacing:0.15em;margin-bottom:14px;font-weight:600;">核心问题</div>
  199. <div class="text-h2" style="margin-bottom:12px;">蓝领求职最担心什么?最看重什么?</div>
  200. <p class="text-body">最强焦虑不是"工资低",而是"信息不真实、被骗、被坑、押金不退、工资被克扣"</p>
  201. </div>
  202. <div class="grid grid-3">
  203. <div class="card" style="border-left:3px solid var(--red);">
  204. <div style="font-size:1.6rem;margin-bottom:12px;">🛡️</div>
  205. <div style="font-weight:700;margin-bottom:8px;">风险焦虑</div>
  206. <p class="text-sm">被骗/被坑/黑中介/押金不退/克扣工资/打工陷阱 - 最稳定、最强烈的底层情绪</p>
  207. </div>
  208. <div class="card" style="border-left:3px solid var(--green);">
  209. <div style="font-size:1.6rem;margin-bottom:12px;">💰</div>
  210. <div style="font-weight:700;margin-bottom:8px;">确定性诉求</div>
  211. <p class="text-sm">工资真实、发薪稳定、包吃包住、当天入职、流程简单</p>
  212. </div>
  213. <div class="card" style="border-left:3px solid var(--purple);">
  214. <div style="font-size:1.6rem;margin-bottom:12px;">🤝</div>
  215. <div style="font-weight:700;margin-bottom:8px;">信任机制</div>
  216. <p class="text-sm">"老铁文化"+"眼见为实" - 快手在蓝领求职场景的核心竞争力</p>
  217. </div>
  218. </div>
  219. </div>
  220. </section>
  221. <!-- Ch2: 最担心什么 -->
  222. <section class="report-section" data-slide-num="02" data-tone="red">
  223. <div class="section-inner">
  224. <div class="section-head">
  225. <div class="section-eyebrow" style="color:var(--red);">CHAPTER 02</div>
  226. <h2 class="text-h1">蓝领求职时最担心什么</h2>
  227. <p class="section-sub">风险焦虑是最稳定、最强烈的底层情绪</p>
  228. </div>
  229. <div class="grid grid-2" style="margin-bottom:28px;">
  230. <div>
  231. <div class="section-eyebrow" style="color:var(--red);margin-bottom:16px;">风险信号排行(按热度)</div>
  232. ${barChart(riskSignals.slice(0,6),'#EF4444')}
  233. </div>
  234. <div class="card" style="border-left:3px solid var(--red);">
  235. <div style="font-weight:700;margin-bottom:16px;font-size:1.1rem;">高风险场景样本</div>
  236. <div style="line-height:2;font-size:0.88rem;color:var(--text-2);">
  237. <div style="margin-bottom:14px;padding-bottom:14px;border-bottom:1px solid var(--border);">
  238. <span style="color:var(--red);font-weight:600;">[黑中介] 热度203219</span><br/>
  239. <span style="font-size:0.8rem;">#万恶之源 #搞笑我是认真的 #搞笑 黑中介的噩梦,只要我不努力,你就过不上你想要的生活</span>
  240. </div>
  241. <div style="margin-bottom:14px;padding-bottom:14px;border-bottom:1px solid var(--border);">
  242. <span style="color:var(--red);font-weight:600;">[黑厂] 热度122687</span><br/>
  243. <span style="font-size:0.8rem;">揭秘!广东5大黑厂有哪些?想不被坑,千万不要进</span>
  244. </div>
  245. <div>
  246. <span style="color:var(--red);font-weight:600;">[入职被坑] 热度42121</span><br/>
  247. <span style="font-size:0.8rem;">#黑中介招工套路 ,刚开始签18块钱一个小时...</span>
  248. </div>
  249. </div>
  250. </div>
  251. </div>
  252. <div class="grid grid-3">
  253. <div class="card" style="border-top:2px solid var(--red);">
  254. <div style="font-size:1.6rem;margin-bottom:10px;">🚨</div>
  255. <div style="font-weight:700;color:var(--red);margin-bottom:8px;">招聘信息虚假</div>
  256. <p class="text-sm">"货不对版" - 承诺薪资、食宿条件与实际不符</p>
  257. </div>
  258. <div class="card" style="border-top:2px solid var(--orange);">
  259. <div style="font-size:1.6rem;margin-bottom:10px;">💸</div>
  260. <div style="font-weight:700;color:var(--orange);margin-bottom:8px;">押金陷阱</div>
  261. <p class="text-sm">预缴押金/培训费后招工方失联</p>
  262. </div>
  263. <div class="card" style="border-top:2px solid var(--amber);">
  264. <div style="font-size:1.6rem;margin-bottom:10px;">⚖️</div>
  265. <div style="font-weight:700;color:var(--amber);margin-bottom:8px;">权益无保障</div>
  266. <p class="text-sm">不签劳动合同、不上社保、欠薪维权难</p>
  267. </div>
  268. </div>
  269. </div>
  270. </section>
  271. <!-- Ch3: 最看重什么 -->
  272. <section class="report-section" data-slide-num="03" data-tone="green">
  273. <div class="section-inner">
  274. <div class="section-head">
  275. <div class="section-eyebrow" style="color:var(--green);">CHAPTER 03</div>
  276. <h2 class="text-h1">蓝领求职时最看重什么</h2>
  277. <p class="section-sub">确定性 + 即时性 = 快速入职决策</p>
  278. </div>
  279. <div class="grid grid-2" style="margin-bottom:28px;">
  280. <div>
  281. <div class="section-eyebrow" style="color:var(--green);margin-bottom:16px;">看重因素排行(按热度)</div>
  282. ${barChart(careFactors.slice(0,6),'#00DC82')}
  283. </div>
  284. <div class="card" style="border-left:3px solid var(--green);">
  285. <div style="font-weight:700;margin-bottom:16px;font-size:1.1rem;">高代表性样本</div>
  286. <div style="line-height:2;font-size:0.88rem;color:var(--text-2);">
  287. <div style="margin-bottom:12px;">
  288. <span style="color:var(--green);font-weight:600;">[工资日结] 热度48804</span><br/>
  289. <span style="font-size:0.8rem;">"..."</span>
  290. </div>
  291. <div style="margin-bottom:12px;">
  292. <span style="color:var(--green);font-weight:600;">[包吃包住] 热度15768</span><br/>
  293. <span style="font-size:0.8rem;">距你0.9km #找工作 #包吃包住 #勤杂工 #大龄工</span>
  294. </div>
  295. <div>
  296. <span style="color:var(--green);font-weight:600;">[当天入职] 热度17397</span><br/>
  297. <span style="font-size:0.8rem;">#不体检不收费当天安排 #当天来当天入职安排住宿</span>
  298. </div>
  299. </div>
  300. </div>
  301. </div>
  302. <div class="grid grid-4" style="margin-bottom:28px;">
  303. <div class="card" style="border-top:2px solid var(--green);text-align:center;">
  304. <div style="font-size:1.8rem;margin-bottom:10px;">👁️</div>
  305. <div style="font-weight:600;color:var(--green);font-size:0.9rem;margin-bottom:6px;">眼见为实</div>
  306. <p class="text-xs">直播展示车间、宿舍、食堂,消解信息不对称</p>
  307. </div>
  308. <div class="card" style="border-top:2px solid var(--blue);text-align:center;">
  309. <div style="font-size:1.8rem;margin-bottom:10px;">⚡</div>
  310. <div style="font-weight:600;color:var(--blue);font-size:0.9rem;margin-bottom:6px;">即时沟通</div>
  311. <p class="text-xs">实时互动答疑,无需等待反馈</p>
  312. </div>
  313. <div class="card" style="border-top:2px solid var(--purple);text-align:center;">
  314. <div style="font-size:1.8rem;margin-bottom:10px;">🚪</div>
  315. <div style="font-weight:600;color:var(--purple);font-size:0.9rem;margin-bottom:6px;">零门槛</div>
  316. <p class="text-xs">留联系方式即可求职,无需简历</p>
  317. </div>
  318. <div class="card" style="border-top:2px solid var(--amber);text-align:center;">
  319. <div style="font-size:1.8rem;margin-bottom:10px;">💯</div>
  320. <div style="font-weight:600;color:var(--amber);font-size:0.9rem;margin-bottom:6px;">薪资透明</div>
  321. <p class="text-xs">承诺的工资能兑现</p>
  322. </div>
  323. </div>
  324. </div>
  325. </section>
  326. <!-- Ch4: 情绪价值 -->
  327. <section class="report-section" data-slide-num="04" data-tone="purple">
  328. <div class="section-inner">
  329. <div class="section-head">
  330. <div class="section-eyebrow" style="color:var(--purple);">CHAPTER 04</div>
  331. <h2 class="text-h1">情绪价值强的表达</h2>
  332. <p class="section-sub">情绪价值的核心不是娱乐,而是"确定性"</p>
  333. </div>
  334. <div style="margin-bottom:28px;">
  335. <div class="section-eyebrow" style="color:var(--red);margin-bottom:16px;">▼ 负向情绪样本(高赞)</div>
  336. <div class="grid grid-2">
  337. ${emotionSamples.map(e=>`<div class="card" style="border-left:3px solid var(--red);">
  338. <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:12px;flex-wrap:wrap;gap:8px;">
  339. <span class="tag red">${esc(e.keyword)} · ${esc(e.direction)}</span>
  340. <span style="font-size:0.8rem;font-weight:700;color:var(--red);font-family:var(--font-mono);">♥${fmtLikes(e.likes)}</span>
  341. </div>
  342. <p style="font-size:0.9rem;line-height:1.6;color:var(--text-1);">"${esc(e.expr)}"</p>
  343. </div>`).join('')}
  344. </div>
  345. </div>
  346. <div class="card card-accent">
  347. <div style="font-weight:700;margin-bottom:14px;font-size:1rem;">情绪价值关键词体系</div>
  348. <div class="grid grid-4" style="gap:10px;">
  349. <div style="padding:10px 14px;background:rgba(245,166,35,0.08);border-radius:6px;font-size:0.82rem;text-align:center;">
  350. <div style="color:var(--amber);font-weight:600;">"眼见为实"</div>
  351. <div class="text-xs" style="margin-top:4px;">消解信息不对称</div>
  352. </div>
  353. <div style="padding:10px 14px;background:rgba(0,220,130,0.08);border-radius:6px;font-size:0.82rem;text-align:center;">
  354. <div style="color:var(--green);font-weight:600;">"老铁推荐"</div>
  355. <div class="text-xs" style="margin-top:4px;">熟人身份降低防备</div>
  356. </div>
  357. <div style="padding:10px 14px;background:rgba(139,92,246,0.08);border-radius:6px;font-size:0.82rem;text-align:center;">
  358. <div style="color:var(--purple);font-weight:600;">"来了就是兄弟"</div>
  359. <div class="text-xs" style="margin-top:4px;">归属感和人情味</div>
  360. </div>
  361. <div style="padding:10px 14px;background:rgba(239,68,68,0.08);border-radius:6px;font-size:0.82rem;text-align:center;">
  362. <div style="color:var(--red);font-weight:600;">"不骗人不套路"</div>
  363. <div class="text-xs" style="margin-top:4px;">真实可靠心智</div>
  364. </div>
  365. </div>
  366. </div>
  367. </div>
  368. </section>
  369. <!-- Ch5: 假设验证 H1-H4 -->
  370. <section class="report-section" data-slide-num="05" data-tone="amber">
  371. <div class="section-inner">
  372. <div class="section-head">
  373. <div class="section-eyebrow">CHAPTER 05</div>
  374. <h2 class="text-h1">H1-H8 假设验证</h2>
  375. <p class="section-sub">基于7,902条VOC的假设覆盖分析</p>
  376. </div>
  377. <div class="grid grid-2" style="margin-bottom:28px;">
  378. <div>
  379. <div class="section-eyebrow" style="color:var(--green);margin-bottom:16px;">H1-H4 假设覆盖</div>
  380. ${barChart(hypos.slice(0,4).map(h=>({label:h.h+' '+h.title.slice(0,8),value:h.count,color:h.color})),'#8B5CF6')}
  381. </div>
  382. <div>
  383. <div class="section-eyebrow" style="color:var(--rose);margin-bottom:16px;">H5-H8 假设覆盖</div>
  384. ${barChart(hypos.slice(4).map(h=>({label:h.h+' '+h.title.slice(0,8),value:h.count,color:h.color})),'#FF4D8D')}
  385. </div>
  386. </div>
  387. <div class="grid grid-4">
  388. <div class="card" style="border-top:2px solid var(--amber);text-align:center;padding:16px;">
  389. <div style="font-size:1.6rem;font-weight:800;color:var(--amber);">H1</div>
  390. <div class="text-xs" style="margin-top:6px;">快聘核心场景</div>
  391. <div style="font-weight:700;color:var(--amber);margin-top:4px;">596条</div>
  392. </div>
  393. <div class="card" style="border-top:2px solid var(--green);text-align:center;padding:16px;">
  394. <div style="font-size:1.6rem;font-weight:800;color:var(--green);">H2</div>
  395. <div class="text-xs" style="margin-top:6px;">信息不对称</div>
  396. <div style="font-weight:700;color:var(--green);margin-top:4px;">1930条</div>
  397. </div>
  398. <div class="card" style="border-top:2px solid var(--purple);text-align:center;padding:16px;">
  399. <div style="font-size:1.6rem;font-weight:800;color:var(--purple);">H3</div>
  400. <div class="text-xs" style="margin-top:6px;">薪资透明度</div>
  401. <div style="font-weight:700;color:var(--purple);margin-top:4px;">1842条</div>
  402. </div>
  403. <div class="card" style="border-top:2px solid var(--rose);text-align:center;padding:16px;">
  404. <div style="font-size:1.6rem;font-weight:800;color:var(--rose);">H6</div>
  405. <div class="text-xs" style="margin-top:6px;">求职被骗焦虑</div>
  406. <div style="font-weight:700;color:var(--rose);margin-top:4px;">4435条 ⭐</div>
  407. </div>
  408. </div>
  409. </div>
  410. </section>
  411. <!-- Ch6: 关键字分布 -->
  412. <section class="report-section" data-slide-num="06" data-tone="blue">
  413. <div class="section-inner">
  414. <div class="section-head">
  415. <div class="section-eyebrow" style="color:var(--blue);">CHAPTER 06</div>
  416. <h2 class="text-h1">用户关注关键字</h2>
  417. <p class="section-sub">跨视频与评论反复出现的关注焦点</p>
  418. </div>
  419. <div class="grid grid-2" style="margin-bottom:28px;">
  420. <div>
  421. <div class="section-eyebrow" style="color:var(--red);margin-bottom:16px;">风险类关键字(热度排行)</div>
  422. ${barChart(keywords.slice(0,5).map(k=>({label:k.label,value:k.heat,color:k.color})),'#EF4444')}
  423. </div>
  424. <div>
  425. <div class="section-eyebrow" style="color:var(--green);margin-bottom:16px;">保障类关键字(热度排行)</div>
  426. ${barChart(careFactors.slice(0,5).map(k=>({label:k.label,value:k.heat,color:k.color})),'#00DC82')}
  427. </div>
  428. </div>
  429. <div class="card">
  430. <div style="font-weight:700;margin-bottom:16px;font-size:1rem;">快聘核心场景关键字</div>
  431. <div class="grid grid-4" style="gap:10px;">
  432. <div style="text-align:center;padding:12px;background:var(--bg-2);border-radius:8px;">
  433. <div style="font-size:1.2rem;font-weight:700;color:var(--blue);">43</div>
  434. <div class="text-xs" style="margin-top:4px;">快聘相关</div>
  435. </div>
  436. <div style="text-align:center;padding:12px;background:var(--bg-2);border-radius:8px;">
  437. <div style="font-size:1.2rem;font-weight:700;color:var(--green);">44</div>
  438. <div class="text-xs" style="margin-top:4px;">包吃包住</div>
  439. </div>
  440. <div style="text-align:center;padding:12px;background:var(--bg-2);border-radius:8px;">
  441. <div style="font-size:1.2rem;font-weight:700;color:var(--purple);">29</div>
  442. <div class="text-xs" style="margin-top:4px;">岗位</div>
  443. </div>
  444. <div style="text-align:center;padding:12px;background:var(--bg-2);border-radius:8px;">
  445. <div style="font-size:1.2rem;font-weight:700;color:var(--orange);">51</div>
  446. <div class="text-xs" style="margin-top:4px;">发工资</div>
  447. </div>
  448. </div>
  449. </div>
  450. </div>
  451. </section>
  452. <!-- Ch7: 快聘战略位势 -->
  453. <section class="report-section" data-slide-num="07" data-tone="orange">
  454. <div class="section-inner">
  455. <div class="section-head">
  456. <div class="section-eyebrow" style="color:var(--orange);">CHAPTER 07</div>
  457. <h2 class="text-h1">快聘战略位势</h2>
  458. <p class="section-sub">"仅次于电商" · 日活数十万简历</p>
  459. </div>
  460. <div class="grid grid-3" style="margin-bottom:28px;">
  461. <div class="metric">
  462. <div class="metric-label">日活简历投递</div>
  463. <div class="metric-value" style="color:var(--orange);">数十万</div>
  464. <div class="metric-sub">内部仅次于电商</div>
  465. </div>
  466. <div class="metric">
  467. <div class="metric-label">月度服务求职者</div>
  468. <div class="metric-value" style="color:var(--green);">2.5亿</div>
  469. <div class="metric-sub">人次</div>
  470. </div>
  471. <div class="metric">
  472. <div class="metric-label">2024全年求职线索</div>
  473. <div class="metric-value" style="color:var(--blue);">3.47亿</div>
  474. <div class="metric-sub">次</div>
  475. </div>
  476. </div>
  477. <div class="grid grid-2">
  478. <div class="card" style="border-left:3px solid var(--orange);">
  479. <div style="font-weight:700;margin-bottom:14px;font-size:1rem;">快聘的战略逻辑</div>
  480. <div style="line-height:2.2;font-size:0.88rem;color:var(--text-2);">
  481. <div style="margin-bottom:10px;">
  482. <span style="color:var(--orange);font-weight:600;">● 用户价值层面</span><br/>
  483. <span style="font-size:0.82rem;">求职是蓝领用户的刚性高频需求</span>
  484. </div>
  485. <div style="margin-bottom:10px;">
  486. <span style="color:var(--orange);font-weight:600;">● 市场规模层面</span><br/>
  487. <span style="font-size:0.82rem;">蓝领招聘线上渗透率2025-2026年可达30%</span>
  488. </div>
  489. <div>
  490. <span style="color:var(--orange);font-weight:600;">● 竞争壁垒层面</span><br/>
  491. <span style="font-size:0.82rem;">用户即求职者,无需额外获客</span>
  492. </div>
  493. </div>
  494. </div>
  495. <div class="card" style="border-left:3px solid var(--green);">
  496. <div style="font-weight:700;margin-bottom:14px;font-size:1rem;">快聘的四大角色</div>
  497. <div style="line-height:2.2;font-size:0.88rem;color:var(--text-2);">
  498. <div style="margin-bottom:8px;">🌊 <span style="color:var(--green);font-weight:600;">流量入口</span> - 2.5亿月活蓝领用户</div>
  499. <div style="margin-bottom:8px;">📺 <span style="color:var(--green);font-weight:600;">岗位展示</span> - 直播带岗超500万场/年</div>
  500. <div style="margin-bottom:8px;">🤝 <span style="color:var(--green);font-weight:600;">信任建立</span> - "老铁文化"天然适配</div>
  501. <div>⚡ <span style="color:var(--green);font-weight:600;">快速转化</span> - 当天入职不是梦</div>
  502. </div>
  503. </div>
  504. </div>
  505. </div>
  506. </section>
  507. <!-- Ch8: 高赞评论 -->
  508. <section class="report-section" data-slide-num="08" data-tone="rose">
  509. <div class="section-inner">
  510. <div class="section-head">
  511. <div class="section-eyebrow" style="color:var(--rose);">CHAPTER 08</div>
  512. <h2 class="text-h1">VOC 高赞精选 TOP10</h2>
  513. <p class="section-sub">真实用户声音</p>
  514. </div>
  515. <div class="grid grid-2">
  516. ${highLikedComments.map(c=>`<div class="card" style="border-left:3px solid ${c.rank<=3?'var(--amber)':c.rank<=6?'var(--orange)':'var(--text-3)'};">
  517. <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:12px;flex-wrap:wrap;gap:8px;">
  518. <div style="display:flex;align-items:center;gap:8px;">
  519. <span style="width:22px;height:22px;border-radius:50%;background:var(--bg-2);color:var(--text-1);font-size:0.7rem;font-weight:700;display:flex;align-items:center;justify-content:center;">#${c.rank}</span>
  520. <span class="tag">${esc(c.kw)}</span>
  521. </div>
  522. <span style="font-size:0.85rem;font-weight:700;color:var(--red);font-family:var(--font-mono);">♥${fmtLikes(c.likes)}</span>
  523. </div>
  524. <p style="font-size:0.88rem;line-height:1.6;color:var(--text-1);">"${esc(c.expr)}"</p>
  525. </div>`).join('')}
  526. </div>
  527. </div>
  528. </section>
  529. </main>
  530. <footer class="footer">
  531. <div>快手快聘 · VOC 深度洞察报告</div>
  532. <div style="margin-top:8px;">数据来源:快手评论采集 · 7,902 条真实VOC · 19 个关键词 · 380 个视频</div>
  533. <div style="margin-top:4px;">Generated by OpenClaw · 2026/4/24</div>
  534. </footer>
  535. <script>
  536. const obs=new IntersectionObserver(s=>s.forEach(e=>{if(e.isIntersecting){e.target.classList.add('in-view')}}},{threshold:0.3});
  537. document.querySelectorAll('section.report-section').forEach(s=>obs.observe(s));
  538. document.querySelectorAll('.card').forEach(c=>{c.addEventListener('mouseenter',()=>{document.body.style.setProperty('--amb-x',(Math.random()*30+10)+'%');document.body.style.setProperty('--amb-y',(Math.random()*30+10)+'%')})});
  539. </script>
  540. </body>
  541. </html>`;
  542. fs.writeFileSync(OUT_FILE, html, 'utf8');
  543. console.log('✅ 深色风格报告已生成: ' + OUT_FILE);
  544. console.log(' VOC数据: 7,902 条 | 关键词: 19 个 | 视频: 380 个');