b0f5d6a51c
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>
863 lines
32 KiB
JavaScript
863 lines
32 KiB
JavaScript
/**
|
||
* 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, '&')
|
||
.replace(/</g, '<')
|
||
.replace(/>/g, '>')
|
||
.replace(/"/g, '"');
|
||
}
|
||
|
||
/** @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, ''');
|
||
|
||
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 1–7', desc: 'README 即落地页:30 秒 GIF + Quick Start。', tag: '文档' },
|
||
{ title: 'Day 8–14', desc: 'Show HN + 中文社区,Star 0→120。', tag: '推广' },
|
||
{ title: 'Day 15–30', 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 公开发布内容',
|
||
}),
|
||
};
|
||
}
|