Add image-designer skill, align billing to DeepSeek ×1, and enrich Plaza demo.
Introduce AI image generation with chat shortcut and agent API, improve MindSpace chat-to-page save resolution, and seed Plaza covers with production deploy scripts. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -845,9 +845,21 @@ export const ENRICHMENTS = {
|
||||
},
|
||||
};
|
||||
|
||||
export function getEnrichment(postId, fallbackTitle) {
|
||||
export function getEnrichment(postId, fallbackTitle, meta = {}) {
|
||||
const item = ENRICHMENTS[postId];
|
||||
if (item) return item;
|
||||
|
||||
const categorySlug = meta.categorySlug ?? meta.category_slug ?? '';
|
||||
const summary = meta.summary ?? '';
|
||||
const tags = meta.tags ?? [];
|
||||
|
||||
if (categorySlug) {
|
||||
return {
|
||||
summary: summary || `${fallbackTitle} — MindSpace 精选内容`,
|
||||
html: buildCategoryPage(categorySlug, fallbackTitle, summary || fallbackTitle, tags),
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
summary: `${fallbackTitle} — MindSpace 精选`,
|
||||
html: buildJohnPage({
|
||||
@@ -860,3 +872,215 @@ export function getEnrichment(postId, fallbackTitle) {
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
const CATEGORY_THEMES = {
|
||||
'work-report': {
|
||||
tag: '职场报告',
|
||||
tagEmoji: '📊',
|
||||
accent: '#2d7d6a',
|
||||
accent2: '#4ecdc4',
|
||||
images: [IMG.growth, IMG.ai, IMG.supply, IMG.guide],
|
||||
},
|
||||
'study-notes': {
|
||||
tag: '学习笔记',
|
||||
tagEmoji: '📚',
|
||||
accent: '#f97316',
|
||||
accent2: '#fb923c',
|
||||
images: [IMG.rust, IMG.llm, IMG.guide, IMG.opensource],
|
||||
},
|
||||
creative: {
|
||||
tag: '创意作品',
|
||||
tagEmoji: '🎨',
|
||||
accent: '#c084fc',
|
||||
accent2: '#a855f7',
|
||||
images: [IMG.cyber, IMG.music, IMG.guide],
|
||||
},
|
||||
business: {
|
||||
tag: '门店展示',
|
||||
tagEmoji: '🏪',
|
||||
accent: '#d97706',
|
||||
accent2: '#fbbf24',
|
||||
images: [IMG.coffee, IMG.pilates, IMG.guide],
|
||||
},
|
||||
travel: {
|
||||
tag: '旅行攻略',
|
||||
tagEmoji: '✈️',
|
||||
accent: '#2d7d6a',
|
||||
accent2: '#4ecdc4',
|
||||
images: [IMG.malaysia, IMG.kyoto, IMG.travel, IMG.guide],
|
||||
},
|
||||
'data-analysis': {
|
||||
tag: '数据分析',
|
||||
tagEmoji: '📈',
|
||||
accent: '#38bdf8',
|
||||
accent2: '#0ea5e9',
|
||||
images: [IMG.data, IMG.growth, IMG.guide],
|
||||
},
|
||||
lifestyle: {
|
||||
tag: '生活记录',
|
||||
tagEmoji: '🌿',
|
||||
accent: '#2d7d6a',
|
||||
accent2: '#4ecdc4',
|
||||
images: [IMG.desk, IMG.write, IMG.guide],
|
||||
},
|
||||
other: {
|
||||
tag: '其他',
|
||||
tagEmoji: '💡',
|
||||
accent: '#34d399',
|
||||
accent2: '#10b981',
|
||||
images: [IMG.opensource, IMG.wish, IMG.guide],
|
||||
},
|
||||
};
|
||||
|
||||
function hashTitle(title) {
|
||||
let hash = 0;
|
||||
for (let i = 0; i < title.length; i += 1) {
|
||||
hash = (hash * 31 + title.charCodeAt(i)) >>> 0;
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
function buildHeroTitleHtml(title) {
|
||||
const trimmed = String(title).trim();
|
||||
if (trimmed.length <= 6) {
|
||||
return `<em>${esc(trimmed)}</em>`;
|
||||
}
|
||||
const splitAt = Math.min(8, Math.ceil(trimmed.length * 0.42));
|
||||
const head = trimmed.slice(0, splitAt);
|
||||
const tail = trimmed.slice(splitAt);
|
||||
return `${esc(head)}<em>${esc(tail)}</em>`;
|
||||
}
|
||||
|
||||
function buildCategorySections(categorySlug, title, summary, tags) {
|
||||
const tagList =
|
||||
tags.length > 0
|
||||
? `<ul>${tags.map((tag) => `<li>${esc(tag)}</li>`).join('')}</ul>`
|
||||
: '';
|
||||
|
||||
const metricsPool = {
|
||||
'work-report': [
|
||||
{ value: '92%', label: '目标完成', note: '本期 OKR' },
|
||||
{ value: '3', label: '关键实验', note: '已验证假设' },
|
||||
{ value: '↓18%', label: '阻塞时长', note: '较上期' },
|
||||
],
|
||||
'study-notes': [
|
||||
{ value: '15min', label: '阅读时长', note: '核心章节' },
|
||||
{ value: '8', label: '要点', note: '可复用片段' },
|
||||
{ value: '3', label: '练习题', note: '附参考答案' },
|
||||
],
|
||||
creative: [
|
||||
{ value: '4K', label: '输出规格', note: '主视觉' },
|
||||
{ value: '3', label: '延展场景', note: '社媒 / 印刷' },
|
||||
{ value: '12', label: '配色', note: '品牌体系' },
|
||||
],
|
||||
business: [
|
||||
{ value: '+24%', label: '转化提升', note: '活动期' },
|
||||
{ value: '4.8', label: '评分', note: '5 分制' },
|
||||
{ value: '86%', label: '复购意向', note: '问卷样本' },
|
||||
],
|
||||
travel: [
|
||||
{ value: '5-10', label: '行程天数', note: '弹性安排' },
|
||||
{ value: '¥680', label: '日均预算', note: '舒适型参考' },
|
||||
{ value: '12+', label: '精选点位', note: '含美食' },
|
||||
],
|
||||
'data-analysis': [
|
||||
{ value: '3层', label: '下钻维度', note: '渠道/品类/客单' },
|
||||
{ value: '99%', label: '数据覆盖', note: '核心指标' },
|
||||
{ value: 'T+1', label: '刷新频率', note: '看板更新' },
|
||||
],
|
||||
lifestyle: [
|
||||
{ value: '21天', label: '挑战周期', note: '习惯养成' },
|
||||
{ value: '12', label: '实践要点', note: '可执行清单' },
|
||||
{ value: '↓32%', label: '焦虑自评', note: '挑战前后' },
|
||||
],
|
||||
other: [
|
||||
{ value: '6', label: '关键动作', note: '冷启动路径' },
|
||||
{ value: '1000+', label: '读者', note: '累计触达' },
|
||||
{ value: '4.6', label: '满意度', note: '反馈均值' },
|
||||
],
|
||||
};
|
||||
|
||||
const cardsPool = {
|
||||
'work-report': [
|
||||
{ title: '背景与目标', desc: '明确本期业务目标与衡量口径,对齐 stakeholder 预期。', tag: '目标' },
|
||||
{ title: '执行进展', desc: '按里程碑拆解完成度,标注风险与依赖项。', tag: '进展' },
|
||||
{ title: '数据洞察', desc: '用 3 个核心指标讲清「发生了什么、为什么」。', tag: '洞察' },
|
||||
{ title: '下一步', desc: '列出 2–3 个可验证的下一周期动作。', tag: '行动' },
|
||||
],
|
||||
'study-notes': [
|
||||
{ title: '核心概念', desc: '用一句话 + 生活类比建立直觉,再展开细节。', tag: '概念' },
|
||||
{ title: '常见误区', desc: '面试与实践中高频踩坑点对照表。', tag: '避坑' },
|
||||
{ title: '代码/例题', desc: '可复制片段,标注输入输出与边界条件。', tag: '实践' },
|
||||
],
|
||||
travel: [
|
||||
{ title: 'Day 1–2', desc: '抵达与市区精华,控制步行强度。', tag: '行程' },
|
||||
{ title: 'Day 3–4', desc: '深度体验与小众点位,预留弹性时间。', tag: '深度' },
|
||||
{ title: '美食地图', desc: '早/午/晚各 2 家备选,标注人均与排队时段。', tag: '美食' },
|
||||
],
|
||||
creative: [
|
||||
{ title: '概念阐述', desc: '设计意图、受众与使用场景说明。', tag: '概念' },
|
||||
{ title: '视觉规范', desc: '字体、配色、网格与留白规则。', tag: '规范' },
|
||||
{ title: '延展应用', desc: '海报、社媒、印刷等多场景适配方案。', tag: '延展' },
|
||||
],
|
||||
};
|
||||
|
||||
const sections = [
|
||||
{
|
||||
type: 'metrics',
|
||||
title: '核心亮点',
|
||||
hint: title,
|
||||
items: metricsPool[categorySlug] ?? metricsPool.other,
|
||||
},
|
||||
];
|
||||
|
||||
if (cardsPool[categorySlug]) {
|
||||
sections.push({
|
||||
type: 'cards',
|
||||
title: '内容结构',
|
||||
hint: summary.slice(0, 60),
|
||||
items: cardsPool[categorySlug],
|
||||
});
|
||||
}
|
||||
|
||||
sections.push({
|
||||
type: 'text',
|
||||
title: '详细说明',
|
||||
html: `<p>${esc(summary)}</p>${tagList}`,
|
||||
});
|
||||
|
||||
sections.push({
|
||||
type: 'quote',
|
||||
html: `「${esc(title)}」—— 由 <span style="color:#4ecdc4">MindSpace</span> 创作并公开发布到 TKMind 广场。`,
|
||||
});
|
||||
|
||||
return sections;
|
||||
}
|
||||
|
||||
export function buildCategoryPage(categorySlug, title, summary, tags = []) {
|
||||
const theme = CATEGORY_THEMES[categorySlug] ?? CATEGORY_THEMES.other;
|
||||
const heroImage = theme.images[hashTitle(title) % theme.images.length];
|
||||
const bgDark = categorySlug === 'creative' ? '#0f0a1a' : '#0a1628';
|
||||
|
||||
return buildJohnPage({
|
||||
title,
|
||||
description: summary,
|
||||
tag: theme.tag,
|
||||
tagEmoji: theme.tagEmoji,
|
||||
accent: theme.accent,
|
||||
accent2: theme.accent2,
|
||||
bgDark,
|
||||
heroImage,
|
||||
heroTitleHtml: buildHeroTitleHtml(title),
|
||||
heroSubtitle: summary,
|
||||
heroBtn: '开始阅读',
|
||||
sections: buildCategorySections(categorySlug, title, summary, tags),
|
||||
footer: 'TKMind Plaza · MindSpace 公开发布',
|
||||
});
|
||||
}
|
||||
|
||||
// legacy export — post_id keyed enrichments kept for existing seeded posts
|
||||
export function getEnrichmentLegacy(postId, fallbackTitle) {
|
||||
const item = ENRICHMENTS[postId];
|
||||
if (item) return item;
|
||||
return getEnrichment(postId, fallbackTitle);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user