import { eq, desc, asc } from 'drizzle-orm' import { useDB, schema } from '../../utils/db.js' /** * 实体表数据构建器 * 当 key 对应独立实体表时,从实体表动态读取数据, * 同时合并 site_content 中的元数据(summary/seo 等) */ function buildFromEntityTable(db, key, siteData) { switch (key) { case 'reviews': { const items = db.select().from(schema.reviews) .where(eq(schema.reviews.published, true)) .orderBy(asc(schema.reviews.sortOrder), desc(schema.reviews.id)) .all() .map(r => ({ id: r.id, nickname: r.author, travelDate: r.date, productVersion: r.title, screenshot: '', content: r.content, rating: r.rating, scenes: [], concerns: [], })) // 合并 site_content 的 summary(如果有/ const summary = siteData?.summary || { totalCount: items.length, approvalRate: '98%', } // 用实体表 items 覆盖 site_content 的 items return { summary, items } } case 'faq': { const items = db.select().from(schema.faqs) .where(eq(schema.faqs.published, true)) .orderBy(asc(schema.faqs.sortOrder), asc(schema.faqs.id)) .all() // site_content 有分类结构则保留,把实体表的问答作为「全部」 if (siteData?.categories) return siteData return { categories: [{ id: 'all', name: '常见问题', questions: items.map(f => ({ question: f.question, answer: f.answer, })), }], } } case 'gallery': { const items = db.select().from(schema.galleryItems) .where(eq(schema.galleryItems.published, true)) .orderBy(asc(schema.galleryItems.sortOrder), asc(schema.galleryItems.id)) .all() const works = items.map(g => ({ id: g.id, title: g.title, category: g.category, location: g.location, description: g.description, image: g.image, orientation: g.orientation, })) const categories = siteData?.categories || [{key:"all",label:"全部作品"}] return { seo: siteData?.seo || {}, intro: siteData?.intro || {}, categories, works, } } case 'stories': { const items = db.select().from(schema.stories) .where(eq(schema.stories.published, true)) .orderBy(asc(schema.stories.sortOrder), desc(schema.stories.id)) .all() .map(s => ({ ...s, sections: s.sections ? JSON.parse(s.sections) : [], keyMoments: s.keyMoments ? JSON.parse(s.keyMoments) : [], })) return { stories: items } } case 'news': { const items = db.select().from(schema.articles) .where(eq(schema.articles.published, true)) .orderBy(desc(schema.articles.id)) .all() .filter(a => a.type === 'news') .map(a => ({ id: a.slug, title: a.title, summary: a.summary, content: a.content, category: a.category, coverImage: a.coverImage, author: a.author, tags: a.tags ? JSON.parse(a.tags) : [], date: a.createdAt, })) return { articles: items } } case 'blog': { const items = db.select().from(schema.articles) .where(eq(schema.articles.published, true)) .orderBy(desc(schema.articles.id)) .all() .filter(a => a.type === 'blog') .map(a => ({ id: a.slug, title: a.title, summary: a.summary, content: a.content, category: a.category, coverImage: a.coverImage, author: a.author, tags: a.tags ? JSON.parse(a.tags) : [], seoTitle: a.seoTitle, seoDescription: a.seoDesc, seoKeywords: a.seoKeywords, date: a.createdAt, })) return { articles: items } } default: return null } } // 有entity表的 key 列表 const ENTITY_KEYS = ['reviews', 'faq', 'gallery', 'stories', 'news', 'blog'] export default defineEventHandler(async (event) => { const key = getRouterParam(event, 'key') const db = useDB() // 读site_content(作为元数据或兜底) const item = db.select().from(schema.siteContent) .where(eq(schema.siteContent.key, key)) .get() const siteData = item ? JSON.parse(item.data) : null // 如果是实体表key,优先从实体表构建 if (ENTITY_KEYS.includes(key)) { const result = buildFromEntityTable(db, key, siteData) if (result) { setHeader(event, 'Cache-Control', 'public, max-age=60') return result } } // 普通 site_content key if (!siteData) { throw createError({ statusCode: 404, message: `未找到配置项: ${key}` }) } setHeader(event, 'Cache-Control', 'public, max-age=60') return siteData })