Files
memind/scripts/plaza-rich-content.mjs
T
Your Name b0f5d6a51c Extract memind_adm admin server, add local dev tooling, and remove image-generation.
Split platform admin and ops APIs into standalone admin-server.mjs with network guards; simplify billing to RMB token pricing, refactor user auth, and add rsync deploy plus local-test scripts and docs.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-17 16:39:39 -07:00

863 lines
32 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Plaza page HTML — matches john 公开区 style (探索世界 / TKMind 发布页).
* Dark immersive hero + glass cards + gradient accent text. CSP-safe, no JS.
*/
const CSP =
"default-src 'none'; style-src 'unsafe-inline' https:; img-src data: https:; font-src https: data:; base-uri 'none'; form-action 'none'; script-src 'none'";
function esc(s) {
return String(s ?? '')
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;');
}
/** @param {object} opts */
export function buildJohnPage(opts) {
const {
title,
description,
tag,
tagEmoji = '✦',
accent = '#2d7d6a',
accent2 = '#4ecdc4',
bgDark = '#0a1628',
heroImage,
heroTitleHtml,
heroSubtitle,
heroBtn = '了解更多',
sections = [],
footer = 'Powered by TKMind',
} = opts;
const coverMeta = JSON.stringify({
tag: tag ?? title,
emoji: tagEmoji,
accent,
accent2: bgDark,
subtitle: heroSubtitle?.slice(0, 80) ?? title,
cover: heroImage?.includes('unsplash') ? heroImage.replace('w=1600', 'w=800') : '',
}).replace(/'/g, '&#39;');
const sectionHtml = sections
.map((sec) => {
if (sec.type === 'cards') {
return `
<section class="section">
<h2>${esc(sec.title)}</h2>
${sec.hint ? `<p class="hint">${esc(sec.hint)}</p>` : ''}
<div class="grid">
${sec.items
.map(
(c) => `
<div class="card">
${c.img ? `<div class="card-img" style="background-image:url('${c.img}')"></div>` : ''}
<div class="card-body">
<h3>${esc(c.title)}</h3>
${c.location ? `<div class="location">${esc(c.location)}</div>` : ''}
<p>${esc(c.desc)}</p>
${c.tag ? `<span class="tag">${esc(c.tag)}</span>` : ''}
</div>
</div>`,
)
.join('')}
</div>
</section>`;
}
if (sec.type === 'metrics') {
return `
<section class="section">
<h2>${esc(sec.title)}</h2>
${sec.hint ? `<p class="hint">${sec.hint}</p>` : ''}
<div class="grid metrics">
${sec.items
.map(
(m) => `
<div class="card metric">
<div class="metric-val">${esc(m.value)}</div>
<div class="metric-label">${esc(m.label)}</div>
${m.note ? `<p>${esc(m.note)}</p>` : ''}
</div>`,
)
.join('')}
</div>
</section>`;
}
if (sec.type === 'quote') {
return `
<section class="section quote-section">
<blockquote>${sec.html}</blockquote>
</section>`;
}
return `
<section class="section">
<h2>${esc(sec.title)}</h2>
${sec.hint ? `<p class="hint">${esc(sec.hint)}</p>` : ''}
<div class="prose">${sec.html ?? ''}</div>
</section>`;
})
.join('\n');
return `<!DOCTYPE html>
<html lang="zh-CN">
<head><meta http-equiv="Content-Security-Policy" content="${CSP}"><style id="mindspace-preview-shell">html,body{margin:0;padding:0;background:#f5f0e5}body{min-height:100%}</style>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="${esc(description)}">
<meta name="mindspace-cover" content='${coverMeta}'>
<title>${esc(title)}</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", Roboto, sans-serif;
background: ${bgDark};
color: #fff;
min-height: 100vh;
}
.hero {
position: relative;
height: 70vh;
min-height: 420px;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
overflow: hidden;
}
.hero-bg {
position: absolute;
inset: 0;
background: url('${heroImage}') center/cover no-repeat;
filter: brightness(0.42) saturate(1.08);
z-index: 0;
}
.hero-overlay {
position: absolute;
inset: 0;
background: linear-gradient(to top, ${bgDark} 0%, transparent 62%);
z-index: 1;
}
.hero-content { position: relative; z-index: 2; padding: 24px; max-width: 720px; }
.hero-tag {
display: inline-block;
font-size: 12px;
letter-spacing: 4px;
background: rgba(255,255,255,0.12);
padding: 6px 18px;
border-radius: 20px;
margin-bottom: 20px;
backdrop-filter: blur(4px);
border: 1px solid rgba(255,255,255,0.08);
}
.hero h1 {
font-size: clamp(32px, 6vw, 58px);
font-weight: 800;
letter-spacing: -1px;
line-height: 1.15;
margin-bottom: 12px;
}
.hero h1 em {
font-style: normal;
background: linear-gradient(135deg, ${accent}, ${accent2});
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.hero p {
font-size: clamp(15px, 2vw, 19px);
color: rgba(255,255,255,0.58);
max-width: 520px;
margin: 0 auto 28px;
line-height: 1.65;
}
.hero .btn {
display: inline-block;
padding: 14px 36px;
background: linear-gradient(135deg, ${accent}, ${accent2});
border-radius: 50px;
color: #fff;
font-size: 15px;
font-weight: 600;
text-decoration: none;
box-shadow: 0 8px 28px ${accent}44;
}
.section { max-width: 1100px; margin: 0 auto; padding: 72px 24px; }
.section h2 { font-size: 26px; font-weight: 700; margin-bottom: 8px; }
.section .hint { color: rgba(255,255,255,0.38); font-size: 15px; margin-bottom: 36px; }
.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 20px; }
.grid.metrics { grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
.card {
background: rgba(255,255,255,0.04);
border-radius: 16px;
overflow: hidden;
border: 1px solid rgba(255,255,255,0.06);
transition: transform .25s, border-color .25s;
}
.card:hover { transform: translateY(-3px); border-color: ${accent2}44; }
.card-img { height: 168px; background-size: cover; background-position: center; }
.card-body { padding: 20px; }
.card-body h3 { font-size: 17px; font-weight: 600; margin-bottom: 4px; }
.card-body .location { font-size: 13px; color: rgba(255,255,255,0.32); margin-bottom: 8px; }
.card-body p { font-size: 14px; color: rgba(255,255,255,0.52); line-height: 1.65; }
.card-body .tag {
display: inline-block;
font-size: 11px;
background: ${accent2}22;
color: ${accent2};
padding: 3px 12px;
border-radius: 12px;
margin-top: 10px;
}
.metric { padding: 24px; text-align: center; }
.metric-val { font-size: 32px; font-weight: 800; color: ${accent2}; letter-spacing: -.02em; }
.metric-label { font-size: 11px; letter-spacing: .12em; text-transform: uppercase; color: rgba(255,255,255,.35); margin: 6px 0 8px; }
.metric p { font-size: 13px; color: rgba(255,255,255,.45); }
.prose { color: rgba(255,255,255,.62); font-size: 15px; line-height: 1.75; }
.prose ul { padding-left: 20px; margin-top: 12px; }
.prose li { margin-bottom: 8px; }
.prose table { width: 100%; border-collapse: collapse; margin-top: 16px; font-size: 14px; }
.prose th, .prose td { padding: 10px 12px; border-bottom: 1px solid rgba(255,255,255,.08); text-align: left; }
.prose th { color: rgba(255,255,255,.35); font-size: 11px; text-transform: uppercase; letter-spacing: .08em; }
.prose .code {
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
font-size: 13px;
background: rgba(0,0,0,.35);
border: 1px solid rgba(255,255,255,.08);
padding: 16px 18px;
border-radius: 12px;
margin-top: 16px;
color: rgba(255,255,255,.75);
overflow-x: auto;
white-space: pre-wrap;
}
blockquote {
border-left: 3px solid ${accent2};
padding: 20px 24px;
background: rgba(255,255,255,.04);
border-radius: 0 14px 14px 0;
color: rgba(255,255,255,.65);
font-size: 16px;
line-height: 1.7;
font-style: italic;
}
.quote-section { padding-top: 0; }
.footer {
text-align: center;
padding: 40px 24px;
color: rgba(255,255,255,0.22);
font-size: 13px;
border-top: 1px solid rgba(255,255,255,0.04);
}
</style>
</head>
<body>
<section class="hero">
<div class="hero-bg"></div>
<div class="hero-overlay"></div>
<div class="hero-content">
<div class="hero-tag">${tagEmoji} ${esc(tag)}</div>
<h1>${heroTitleHtml}</h1>
<p>${esc(heroSubtitle)}</p>
<a href="#" class="btn">${esc(heroBtn)}</a>
</div>
</section>
${sectionHtml}
<div class="footer">${esc(footer)}</div>
</body>
</html>`;
}
const IMG = {
travel: 'https://images.unsplash.com/photo-1480796925566-7970b0633882?w=1600&q=80',
malaysia: 'https://images.unsplash.com/photo-1596422846544-75c675fcd5d0?w=1600&q=80',
kyoto: 'https://images.unsplash.com/photo-1493976040374-85c8e577f47e?w=1600&q=80',
growth: 'https://images.unsplash.com/photo-1460925895917-afdab827c52f?w=1600&q=80',
ai: 'https://images.unsplash.com/photo-1677440866019-21780ecad995?w=1600&q=80',
supply: 'https://images.unsplash.com/photo-1586528116311-ad8dd3c8310d?w=1600&q=80',
llm: 'https://images.unsplash.com/photo-1676299085922-0a9a504459f8?w=1600&q=80',
rust: 'https://images.unsplash.com/photo-1515879214367-846362d3526?w=1600&q=80',
cyber: 'https://images.unsplash.com/photo-1514565131-fce0801e5785?w=1600&q=80',
music: 'https://images.unsplash.com/photo-1511379938544-be09687a4d4b?w=1600&q=80',
desk: 'https://images.unsplash.com/photo-1497215842964-222b430dc094?w=1600&q=80',
write: 'https://images.unsplash.com/photo-1455390582260-0446deae2f3f?w=1600&q=80',
data: 'https://images.unsplash.com/photo-1551288049-bebda4e38f71?w=1600&q=80',
coffee: 'https://images.unsplash.com/photo-1495474472287-4d71bcdd2085?w=1600&q=80',
pilates: 'https://images.unsplash.com/photo-1518611012118-696072aa579a?w=1600&q=80',
opensource: 'https://images.unsplash.com/photo-1555066931-4365d14bab8c?w=1600&q=80',
wish: 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=1600&q=80',
guide: 'https://images.unsplash.com/photo-1516321318423-f06f85e504b3?w=1600&q=80',
};
/** post_id -> { summary, html, skipHtml? } */
export const ENRICHMENTS = {
'ea817fe6-fc46-491a-9f9a-f5638ff2299e': {
summary: '12 类 Prompt 场景模板,参照 TKMind 公开页深色风格,附 CoT / JSON 输出范例。',
html: buildJohnPage({
title: 'LLM Prompt 工程速查表',
description: 'LLM Prompt 工程速查表',
tag: '学习笔记',
tagEmoji: '📚',
accent: '#4ecdc4',
accent2: '#2d7d6a',
heroImage: IMG.llm,
heroTitleHtml: 'Prompt <em>工程</em><br>速查表',
heroSubtitle: '角色设定、Few-shot、CoT、结构化输出——一张表搞定常见场景。',
heroBtn: '查看模板',
sections: [
{
type: 'metrics',
title: '核心数据',
hint: '团队内部 4 周样本',
items: [
{ value: '12', label: '场景模板', note: '写作 / 分析 / 代码 / 客服' },
{ value: '68%', label: '迭代减少', note: '对比无框架 Prompt' },
{ value: '3', label: '原则', note: '具体 · 约束 · 示例' },
],
},
{
type: 'text',
title: '框架对照',
hint: '按场景选结构',
html: `<table><thead><tr><th>场景</th><th>结构</th><th>关键句</th></tr></thead><tbody>
<tr><td>复杂推理</td><td>CoT + 分步</td><td>请先列出假设,再逐步推导</td></tr>
<tr><td>稳定 JSON</td><td>Schema + 示例</td><td>仅输出 JSON,不要 markdown</td></tr>
<tr><td>风格迁移</td><td>角色 + 反例</td><td>不要像官方通稿,要像同事微信</td></tr>
</tbody></table>
<div class="code">你是一位资深产品分析师。基于下方数据输出 JSON:
{"insights":[],"risk":"","next_step":""}
约束:不要编造未提供的数据。</div>`,
},
{
type: 'quote',
html: '好 Prompt 不是更长,而是<span style="color:#4ecdc4">边界更清晰</span>——输入是什么、输出长什么样、什么不能做。',
},
],
}),
},
'65aaa356-5197-4bf3-9491-da03c0d7313a': {
summary: '用图书馆借书类比讲清 Rust ownership / borrow / lifetime,附自测题。',
html: buildJohnPage({
title: 'Rust 所有权模型 15 分钟图解',
description: 'Rust 所有权模型图解',
tag: '学习笔记',
tagEmoji: '🦀',
accent: '#f97316',
accent2: '#fb923c',
heroImage: IMG.rust,
heroTitleHtml: 'Rust <em>所有权</em><br>15 分钟图解',
heroSubtitle: '不用背规则表——用生活类比一次搞懂 move、borrow 和 lifetime。',
sections: [
{
type: 'cards',
title: '三个核心概念',
hint: '图书馆借书类比',
items: [
{ title: 'Ownership', location: '📖 书籍归属', desc: '每本书同一时刻只有一个主人;赋值即转交。', tag: 'move' },
{ title: 'Borrow', location: '🔖 临时借阅', desc: '&T 只读借阅;&mut T 独占写借阅。', tag: 'borrow' },
{ title: 'Lifetime', location: '⏳ 借书条', desc: '编译器保证引用不会比数据活得更久。', tag: 'lifetime' },
],
},
{
type: 'quote',
html: 'Q: let s2 = s1; println!("{s1}"); 会怎样?<br>A: 编译错误——s1 已被 move 到 s2。',
},
],
}),
},
'a02d114f-d565-4941-bf22-9534d71b7398': {
summary: 'Q2 从 2.1 万 DAU 到 10.3 万:漏斗、渠道 ROI 与 3 个关键增长实验。',
html: buildJohnPage({
title: 'Q2 产品增长复盘',
description: 'Q2 产品增长复盘',
tag: '职场报告',
tagEmoji: '📊',
accent: '#2d7d6a',
accent2: '#4ecdc4',
heroImage: IMG.growth,
heroTitleHtml: 'Q2 增长 <em>复盘</em>',
heroSubtitle: '从 2.1 万 DAU 到 10.3 万,拆解漏斗、渠道与关键实验。',
sections: [
{
type: 'metrics',
title: '关键指标',
items: [
{ value: '10.3万', label: 'DAU', note: '+390% vs Q1' },
{ value: '34%', label: 'D7 留存', note: '+6pp' },
{ value: '1:3.2', label: 'LTV/CAC', note: '信息流获客' },
],
},
{
type: 'quote',
html: '最大杠杆:首次 24 小时内的<span style="color:#4ecdc4">模板引导</span>——「一键生成周报」上线后激活率 +9pp。',
},
],
}),
},
'eaf1b80b-667f-401b-ae90-6b740a878c21': {
summary: 'AI 客服 30 天落地:自动解决率 61%,含周计划与踩坑记录。',
html: buildJohnPage({
title: 'AI 客服落地 30 天执行报告',
description: 'AI 客服 30 天执行报告',
tag: '职场报告',
tagEmoji: '🤖',
accent: '#60a5fa',
accent2: '#3b82f6',
heroImage: IMG.ai,
heroTitleHtml: 'AI 客服 <em>30 天</em><br>落地报告',
heroSubtitle: '从需求澄清、知识库搭建到全量上线,记录真实指标与踩坑。',
sections: [
{
type: 'metrics',
title: '上线成果',
items: [
{ value: '61%', label: '自动解决率', note: 'W4 达成' },
{ value: '6.2s', label: '平均首响', note: '较人工快 47 倍' },
{ value: '4.6', label: 'CSAT', note: '5 分制' },
],
},
{
type: 'cards',
title: '执行里程碑',
hint: '每周交付物',
items: [
{ title: 'W1 语料', desc: '清洗 1.2 万条工单,标注 8 大意图。', tag: '完成' },
{ title: 'W2 知识库', desc: '政策/物流/售后三层结构上线。', tag: '完成' },
{ title: 'W3 灰度', desc: '5% 流量,低置信度转人工。', tag: '完成' },
{ title: 'W4 全量', desc: '峰值 QPS 120,排队时长 -38%。', tag: '完成' },
],
},
],
}),
},
'c6609c83-0557-481f-ad8b-9cbed2fd3b49': {
summary: '供应链数字化周报第 18 期:周转 36 天、缺货率 1.8%。',
html: buildJohnPage({
title: '供应链数字化周报 · 第 18 期',
description: '供应链数字化周报',
tag: '职场报告',
tagEmoji: '🏭',
accent: '#94a3b8',
accent2: '#64748b',
heroImage: IMG.supply,
heroTitleHtml: '供应链 <em>周报</em><br>第 18 期',
heroSubtitle: '库存周转、缺货预警与供应商协同进展一览。',
sections: [
{
type: 'metrics',
title: '本周指标',
items: [
{ value: '36天', label: '库存周转', note: '目标 ≤38天 ✓' },
{ value: '1.8%', label: '缺货率', note: '-0.4pp' },
{ value: '92%', label: '准时交货', note: 'TOP20 供应商' },
],
},
],
}),
},
'b883bd9e-f348-491b-aae3-e1085f48d878': {
summary: '吉隆坡 + 槟城 5 日轻量路线,人均 ¥680/天,含美食与交通贴士。',
html: buildJohnPage({
title: '马来西亚 5 日轻量旅行攻略',
description: '马来西亚旅行攻略',
tag: '旅行攻略',
tagEmoji: '✈️',
accent: '#2d7d6a',
accent2: '#4ecdc4',
heroImage: IMG.malaysia,
heroTitleHtml: '马来西亚 <em>5 日</em><br>轻量攻略',
heroSubtitle: '吉隆坡都市感 + 槟城慢生活,适合第一次入境东南亚。',
sections: [
{
type: 'metrics',
title: '行程概览',
items: [
{ value: '¥3,400', label: '人均预算', note: '舒适型' },
{ value: '5天', label: '行程', note: 'KL 2 + 槟城 3' },
{ value: '11km', label: '日步行', note: '轻松不赶路' },
],
},
{
type: 'cards',
title: '每日亮点',
hint: '精选推荐',
items: [
{ img: 'https://images.unsplash.com/photo-1596422846544-75c675fcd5d0?w=600&q=60', title: '吉隆坡', location: '📍 双子塔 · 茨厂街', desc: '夜景 + 黑风洞半日。', tag: 'Day 1-2' },
{ img: 'https://images.unsplash.com/photo-1585409670713-2f7eeeca9e84?w=600&q=60', title: '槟城', location: '📍 乔治市 · 升旗山', desc: '壁画街 + 榴莲宵夜。', tag: 'Day 3-5' },
],
},
],
}),
},
'e468a32f-8bb7-4663-b065-07042b5d1222': {
summary: '京都红叶季 8 条小众散步路线 + 3 家深夜食堂。',
html: buildJohnPage({
title: '京都红叶季小众散步地图',
description: '京都红叶季散步地图',
tag: '旅行攻略',
tagEmoji: '🍁',
accent: '#dc2626',
accent2: '#f87171',
heroImage: IMG.kyoto,
heroTitleHtml: '京都 <em>红叶季</em><br>散步地图',
heroSubtitle: '避开人潮,专注可步行、可吃饭、可拍照的小众动线。',
sections: [
{
type: 'cards',
title: '推荐路线',
hint: '早出发避人流',
items: [
{ img: 'https://images.unsplash.com/photo-1493976040374-85c8e577f47e?w=600&q=60', title: '东山东坊 → 真如堂', location: '📍 07:30 出发', desc: '光线柔和,约 2.5 小时。', tag: '徒步' },
{ img: 'https://images.unsplash.com/photo-1545569341-9f1cfc6129a1?w=600&q=60', title: '哲学之道北段', location: '📍 逆向步行', desc: '从银阁寺方向避开旅行团。', tag: '人文' },
{ title: '先斗町深夜食堂', location: '📍 21:00 后', desc: '居酒屋不排队,推荐「一」。', tag: '美食' },
],
},
],
}),
},
'964edee4-f1f8-4e86-92c1-e96d83955eb2': {
summary: '赛博水墨城市主视觉:霓虹层 + 字体系统 + 社媒延展规格。',
html: buildJohnPage({
title: '赛博水墨城市概念海报',
description: '赛博水墨城市概念海报',
tag: '创意作品',
tagEmoji: '🎨',
accent: '#c084fc',
accent2: '#a855f7',
bgDark: '#0f0a1a',
heroImage: IMG.cyber,
heroTitleHtml: '赛博 <em>水墨</em><br>城市海报',
heroSubtitle: '东方未来主义主 KV,适用于科技展与 AI 主题活动。',
sections: [
{
type: 'cards',
title: '视觉规范',
items: [
{ title: '主色', desc: '#A855F7 · #6366F1 · 墨黑 #0A0A12', tag: '配色' },
{ title: '字体', desc: '思源宋体 Heavy + Inter 正文', tag: '字体' },
{ title: '输出', desc: '4:5 主海报 · 16:9 Banner · 1080 方图', tag: '规格' },
],
},
],
}),
},
'463b66e2-0aa7-4f7f-96d9-bbd56a93bb00': {
summary: 'EP《夜航船》封面摄影方向、霓虹蓝配色与巡演海报版式。',
html: buildJohnPage({
title: '独立音乐人首张 EP 视觉方案',
description: 'EP 视觉方案',
tag: '创意作品',
tagEmoji: '🎵',
accent: '#818cf8',
accent2: '#6366f1',
bgDark: '#0a0a1a',
heroImage: IMG.music,
heroTitleHtml: 'EP <em>夜航船</em><br>视觉方案',
heroSubtitle: '封面、流媒体横幅与巡演海报的统一视觉语言。',
sections: [
{
type: 'cards',
title: '设计要素',
items: [
{ title: '摄影', desc: '长曝光车轨 + 单人侧影,主光 5600K。', tag: '封面' },
{ title: '字体', desc: '造字工房力黑 + Bebas Neue。', tag: '排版' },
{ title: '测试', desc: '55×55 缩略图仍可识别船形剪影。', tag: '可用性' },
],
},
],
}),
},
'3497b24c-f8d2-4577-9a59-8a0751eb020a': {
summary: '12 个桌面改造细节:光照、线缆、显示器高度与数字 Minimal。',
html: buildJohnPage({
title: '极简桌面改造',
description: '极简桌面改造',
tag: '生活记录',
tagEmoji: '🌿',
accent: '#2d7d6a',
accent2: '#4ecdc4',
heroImage: IMG.desk,
heroTitleHtml: '极简 <em>桌面</em><br>改造指南',
heroSubtitle: '12 个提升专注的细节,周末即可完成。',
sections: [
{
type: 'cards',
title: '改造清单',
hint: '按优先级排序',
items: [
{ title: '显示器高度', desc: '屏幕中心距桌面 15–20cm 下方,对齐视线。', tag: '人体工学' },
{ title: '单线收纳', desc: '电源 + 显示 + Hub 一次走线。', tag: '整洁' },
{ title: '4000K 主光', desc: '台灯从非惯用手侧 45° 打光。', tag: '光照' },
{ title: '数字 Minimal', desc: 'Dock 仅留 5 个常用图标。', tag: '专注' },
],
},
],
}),
},
'dfa76402-2b56-4816-babb-ec2b8e6d97e6': {
summary: '21 天晨间自由书写挑战:情绪曲线与 3 个固化习惯。',
html: buildJohnPage({
title: '晨间写作 21 天挑战',
description: '晨间写作挑战',
tag: '生活记录',
tagEmoji: '✍️',
accent: '#fbbf24',
accent2: '#f59e0b',
heroImage: IMG.write,
heroTitleHtml: '晨间 <em>写作</em><br>21 天挑战',
heroSubtitle: '每天 06:30–06:50,不修改、不评判,只把脑子里的声音写到纸上。',
sections: [
{
type: 'metrics',
title: '挑战成果',
items: [
{ value: '21/21', label: '完成天数', note: '零中断' },
{ value: '18min', label: '平均时长', note: '目标 20min' },
{ value: '↓32%', label: '焦虑自评', note: 'W1 vs W3' },
],
},
{
type: 'quote',
html: '第 14 天:「原来焦虑不是敌人,是未命名的期待。」',
},
],
}),
},
'50434e70-97f3-4c7f-beb5-2c36b2c30885': {
summary: '618 GMV ¥2840 万归因:渠道 × 品类 × 客单三层下钻。',
html: buildJohnPage({
title: '电商大促 GMV 归因看板',
description: 'GMV 归因看板',
tag: '数据分析',
tagEmoji: '📈',
accent: '#38bdf8',
accent2: '#0ea5e9',
heroImage: IMG.data,
heroTitleHtml: 'GMV <em>归因</em><br>看板',
heroSubtitle: '618 全周期 GMV ¥2840 万,渠道、品类、客单三层下钻。',
sections: [
{
type: 'metrics',
title: '总览',
items: [
{ value: '¥2840万', label: '总 GMV', note: 'YoY +41%' },
{ value: '¥268', label: '客单价', note: '+12%' },
{ value: '38%', label: '直播占比', note: '+9pp' },
],
},
{
type: 'text',
title: '渠道拆解',
html: `<table><thead><tr><th>渠道</th><th>GMV</th><th>ROI</th></tr></thead><tbody>
<tr><td>信息流</td><td>¥920万</td><td>1:2.8</td></tr>
<tr><td>直播</td><td>¥1080万</td><td>1:4.1</td></tr>
<tr><td>自然搜索</td><td>¥640万</td><td>—</td></tr>
</tbody></table>`,
},
],
}),
},
'15ddb795-972e-4aa4-8a33-409b01645de9': {
summary: 'Cohort 留存模板:D1/D7/D30 + 异常排查 checklist。',
html: buildJohnPage({
title: '用户留存 Cohort 分析模板',
description: 'Cohort 留存分析',
tag: '数据分析',
tagEmoji: '📈',
accent: '#a78bfa',
accent2: '#8b5cf6',
heroImage: IMG.data,
heroTitleHtml: 'Cohort <em>留存</em><br>分析模板',
heroSubtitle: '按注册周看 D1/D7/D30,附异常波动排查清单。',
sections: [
{
type: 'text',
title: '留存矩阵',
html: `<table><thead><tr><th>注册周</th><th>用户量</th><th>D1</th><th>D7</th><th>D30</th></tr></thead><tbody>
<tr><td>W22</td><td>12,400</td><td>48%</td><td>31%</td><td>18%</td></tr>
<tr><td>W23</td><td>15,100</td><td>52%</td><td>34%</td><td>—</td></tr>
</tbody></table>`,
},
],
}),
},
'd601b63c-e986-4a49-8267-f3bcb8de20f5': {
summary: '社区咖啡店开业 7 天:首日 186 杯、会员转化 23%。',
html: buildJohnPage({
title: '社区咖啡店开业 7 天运营手记',
description: '咖啡店开业手记',
tag: '门店展示',
tagEmoji: '☕',
accent: '#d97706',
accent2: '#fbbf24',
heroImage: IMG.coffee,
heroTitleHtml: '咖啡店 <em>7 天</em><br>运营手记',
heroSubtitle: '45㎡ 社区底商,第 7 天单日杯量破 200。',
sections: [
{
type: 'metrics',
title: '开业数据',
items: [
{ value: '186杯', label: '首日销量', note: '超预期 24%' },
{ value: '23%', label: '会员转化', note: '扫码领券' },
{ value: '¥86', label: '坪效/日', note: '第 7 天峰值' },
],
},
{
type: 'quote',
html: '选址关键:<span style="color:#fbbf24">500m 内 3 个办公出口 + 1 个地铁口</span>。',
},
],
}),
},
'ad198274-1457-4ded-ba85-000ef9534fd4': {
summary: '618 普拉提限定套餐:早鸟 ¥599,附预约转化话术。',
html: buildJohnPage({
title: '普拉提工作室 618 活动页',
description: '普拉提 618 活动',
tag: '门店展示',
tagEmoji: '🧘',
accent: '#f472b6',
accent2: '#ec4899',
bgDark: '#1a0a14',
heroImage: IMG.pilates,
heroTitleHtml: 'Flow Pilates<br><em>618 限定</em>',
heroSubtitle: '小团课体验 + 体态评估,仅 618 期间。',
sections: [
{
type: 'cards',
title: '活动套餐',
items: [
{ title: '早鸟套餐 A · ¥599', desc: '3 次小团课 + 1 次私教评估(原价 ¥980)', tag: '早鸟' },
{ title: '续课套餐 B · ¥1,299', desc: '10 次小团课 + 赠 2 次,60 天有效', tag: '续课' },
],
},
],
}),
},
'c0da7a1b-ffb1-4f51-a664-ec45381f694d': {
summary: '开源项目 0→200 Star / 17 付费用户的冷启动复盘。',
html: buildJohnPage({
title: '开源副业项目冷启动笔记',
description: '开源冷启动笔记',
tag: '其他',
tagEmoji: '💡',
accent: '#34d399',
accent2: '#10b981',
heroImage: IMG.opensource,
heroTitleHtml: '开源 <em>冷启动</em><br>笔记',
heroSubtitle: '从 0 Star 到首批付费用户的 6 个关键动作。',
sections: [
{
type: 'cards',
title: '里程碑',
items: [
{ title: 'Day 17', desc: 'README 即落地页:30 秒 GIF + Quick Start。', tag: '文档' },
{ title: 'Day 814', desc: 'Show HN + 中文社区,Star 0→120。', tag: '推广' },
{ title: 'Day 1530', desc: 'Pro ¥29/月,17 个付费用户。', tag: '变现' },
],
},
],
}),
},
'c62fbf64-2611-46a5-9a25-38b3432f9669': {
summary: '2026 四维度愿望清单:学习、健康、关系、创作。',
html: buildJohnPage({
title: '给未来的自己:2026 愿望清单',
description: '2026 愿望清单',
tag: '其他',
tagEmoji: '🎯',
accent: '#f093fb',
accent2: '#f5576c',
bgDark: '#0a0a0a',
heroImage: IMG.wish,
heroTitleHtml: '给未来的 <em>自己</em>',
heroSubtitle: '学习、健康、关系、创作——每个维度 3 个可验证里程碑。',
sections: [
{
type: 'cards',
title: '2026 目标墙',
items: [
{ title: '📚 学习', desc: '24 本书 · 1 门系统课 · 12 篇公开笔记', tag: '成长' },
{ title: '🌿 健康', desc: '每周运动 ≥3 · 23:30 前入睡 · 体检全绿', tag: '身体' },
{ title: '✨ 创作', desc: 'MindSpace 发布 20 页 · 广场 100 收藏', tag: '输出' },
],
},
],
}),
},
'4c1bf255-d7fd-4065-9044-d347579f85e4': {
summary: 'MindSpace 公开发布四步指南,参照 john 公开区页面风格。',
html: buildJohnPage({
title: 'MindSpace 公开发布指南',
description: 'MindSpace 公开发布指南',
tag: '指南',
tagEmoji: '✦',
accent: '#f093fb',
accent2: '#f5576c',
bgDark: '#0a0a0a',
heroImage: IMG.guide,
heroTitleHtml: 'MindSpace<br><em>发布指南</em>',
heroSubtitle: '4 步将 AI 创作变为可分享、可被发现的真实作品。',
sections: [
{
type: 'cards',
title: '发布流程',
items: [
{ title: '1. 完成页面', desc: 'Agent 生成或手动编辑,标题与摘要清晰。', tag: '创作' },
{ title: '2. 发布公开', desc: '通过安全扫描,获得 /u/用户名/pages/ 链接。', tag: '发布' },
{ title: '3. 推送广场', desc: '选择分类与封面,审核后展示。', tag: '广场' },
{ title: '4. 分享迭代', desc: '根据阅读数据优化首屏内容。', tag: '增长' },
],
},
],
}),
},
'00918152-b21a-4011-8139-b4b27dc9a111': {
summary: '精选瑞士、马尔代夫与京都目的地灵感,含行程亮点与出发指南。',
skipHtml: true,
html: '',
},
'90632cb4-c64d-45d0-8934-c9c53c43c1f9': {
summary: '618 限定迪士尼主题盛典:城堡光影秀、亲子工作坊与早鸟礼遇。',
skipHtml: true,
html: '',
},
};
export function getEnrichment(postId, fallbackTitle) {
const item = ENRICHMENTS[postId];
if (item) return item;
return {
summary: `${fallbackTitle} — MindSpace 精选`,
html: buildJohnPage({
title: fallbackTitle,
description: fallbackTitle,
tag: '精选',
heroImage: IMG.guide,
heroTitleHtml: esc(fallbackTitle),
heroSubtitle: 'MindSpace 公开发布内容',
}),
};
}