diff --git a/src/routes/posts/[slug]/+page.server.ts b/src/routes/posts/[slug]/+page.server.ts index 8b3f8b3..a89f97b 100644 --- a/src/routes/posts/[slug]/+page.server.ts +++ b/src/routes/posts/[slug]/+page.server.ts @@ -1,5 +1,22 @@ import type { PageServerLoad } from './$types'; -import { error } from '@sveltejs/kit'; +import { error, isHttpError } from '@sveltejs/kit'; + +interface PostRow { + id: number; + slug: string; + title: string; + content: string; + cover: string | null; + date: string; + category_name: string | null; + category_slug: string | null; + author: string | null; + series_id: number | null; + series_name: string | null; + series_slug: string | null; + series_description: string | null; + series_weight: number | null; +} export const load: PageServerLoad = async ({ platform, params }) => { const db = platform?.env?.DB; @@ -28,51 +45,88 @@ export const load: PageServerLoad = async ({ platform, params }) => { return { post: { + id: 1, + slug, title: slug === 'hello-world' ? 'Hello, BlogFlare! (Fallback)' : 'The Beauty of Typecho Theme VOID', content: dummyMarkdown, + cover: null, date: '2026-07-12', author: 'Admin' }, tags: [ { name: 'Welcome', id: 1 }, { name: 'Design', id: 2 } - ] + ], + series: null, + seriesPosts: [] }; } try { - const postRes = await db.prepare( + const post = await db.prepare( `SELECT p.id, p.slug, p.title, p.content, p.cover, p.published_at as date, c.name as category_name, c.slug as category_slug, - u.username as author_name + u.username as author, + s.id as series_id, s.name as series_name, s.slug as series_slug, + s.description as series_description, p.series_weight FROM posts p LEFT JOIN categories c ON p.category_id = c.id LEFT JOIN users u ON p.author_id = u.id + LEFT JOIN series s ON p.series_id = s.id WHERE p.slug = ?` - ).bind(slug).first(); - - const post: any = postRes; + ).bind(slug).first(); if (!post) { error(404, 'Post not found'); } - const tagsQuery: any = await db.prepare( + const tagsQuery = await db.prepare( `SELECT t.name, t.id FROM tags t JOIN post_tags pt ON t.id = pt.tag_id WHERE pt.post_id = ?` - ).bind(post.id).all(); + ).bind(post.id).all<{ name: string; id: number }>(); const tags = tagsQuery.results || []; + let series: { + id: number; + name: string; + slug: string; + description: string | null; + } | null = null; + let seriesPosts: Array<{ + id: number; + slug: string; + title: string; + series_weight: number | null; + published_at: string; + }> = []; + if (post.series_id && post.series_name && post.series_slug) { + series = { + id: post.series_id, + name: post.series_name, + slug: post.series_slug, + description: post.series_description + }; + const seriesQuery = await db.prepare( + `SELECT id, slug, title, series_weight, published_at + FROM posts + WHERE series_id = ? + ORDER BY series_weight IS NULL, series_weight ASC, published_at ASC, id ASC` + ).bind(post.series_id).all(); + seriesPosts = seriesQuery.results as unknown as typeof seriesPosts; + } return { post: { ...post, date: new Date(post.date as string).toLocaleDateString() }, - tags + tags, + series, + seriesPosts }; - } catch (err) { + } catch (err: unknown) { + if (isHttpError(err, 404)) throw err; console.error('Error fetching post:', err); error(500, 'Internal Server Error'); } diff --git a/src/routes/posts/[slug]/+page.svelte b/src/routes/posts/[slug]/+page.svelte index 83217e0..ae56872 100644 --- a/src/routes/posts/[slug]/+page.svelte +++ b/src/routes/posts/[slug]/+page.svelte @@ -1,5 +1,6 @@ + + + 全部{$page.data.aliases?.series || '系列'} - {$page.data.site?.title || 'BlogFlare'} + + +
+
+ +
+
+ + diff --git a/src/routes/series/[slug]/+page.server.ts b/src/routes/series/[slug]/+page.server.ts new file mode 100644 index 0000000..2a3d3fb --- /dev/null +++ b/src/routes/series/[slug]/+page.server.ts @@ -0,0 +1,40 @@ +import { error, isHttpError } from '@sveltejs/kit'; +import type { PageServerLoad } from './$types'; + +export const load: PageServerLoad = async ({ platform, params }) => { + const db = platform?.env?.DB; + if (!db) throw error(500, '数据库未连接'); + + try { + const series = await db + .prepare('SELECT id, name, slug, description FROM series WHERE slug = ?') + .bind(params.slug) + .first<{ id: number; name: string; slug: string; description: string | null }>(); + if (!series) throw error(404, '系列不存在'); + + const { results } = await db + .prepare( + `SELECT id, slug, title, series_weight, published_at + FROM posts + WHERE series_id = ? + ORDER BY series_weight IS NULL, series_weight ASC, published_at ASC, id ASC` + ) + .bind(series.id) + .all(); + + return { + series, + posts: results as unknown as Array<{ + id: number; + slug: string; + title: string; + series_weight: number | null; + published_at: string; + }> + }; + } catch (err: unknown) { + if (isHttpError(err, 404)) throw err; + console.error('Error fetching series detail:', err); + throw error(500, '读取系列失败'); + } +}; diff --git a/src/routes/series/[slug]/+page.svelte b/src/routes/series/[slug]/+page.svelte new file mode 100644 index 0000000..7542f60 --- /dev/null +++ b/src/routes/series/[slug]/+page.svelte @@ -0,0 +1,84 @@ + + + + {data.series.name} - {$page.data.site?.title || 'BlogFlare'} + + +
+
+
+ + +
    + {#each data.posts as post, index (post.id)} +
  1. + {post.series_weight ?? index + 1} + {post.title} + +
  2. + {:else} +
  3. 这个系列还没有文章。
  4. + {/each} +
+
+
+
+ +