diff --git a/src/routes/admin/posts/+page.server.ts b/src/routes/admin/posts/+page.server.ts index b70d8d6..fd6fdf5 100644 --- a/src/routes/admin/posts/+page.server.ts +++ b/src/routes/admin/posts/+page.server.ts @@ -11,41 +11,93 @@ interface PostListRow { category?: string; series?: string; } -export const load: PageServerLoad = async ({ platform }) => { +export const load: PageServerLoad = async ({ url, platform }) => { const db = platform?.env?.DB; if (!db) { return { - posts: [] + posts: [], + filterTag: null }; } + const tagIdParam = url.searchParams.get('tagId'); + const tagId = tagIdParam ? parseInt(tagIdParam, 10) : null; + let filterTag: { id: number; name: string } | null = null; + + if (tagId && !Number.isNaN(tagId)) { + try { + const tagRes = await db + .prepare('SELECT id, name FROM tags WHERE id = ?') + .bind(tagId) + .first<{ id: number; name: string }>(); + if (tagRes) { + filterTag = tagRes; + } + } catch (err: any) { + console.error('Error fetching filter tag:', err); + } + } + try { let results: PostListRow[]; try { - const queryRes = await db - .prepare( - `SELECT p.id, p.title, p.slug, p.published_at as date, u.username as author, - c.name as category, s.name as series - FROM posts p - LEFT JOIN users u ON p.author_id = u.id - LEFT JOIN categories c ON p.category_id = c.id - LEFT JOIN series s ON p.series_id = s.id - ORDER BY p.published_at DESC` - ) - .all(); - results = queryRes.results; + if (filterTag) { + const queryRes = await db + .prepare( + `SELECT p.id, p.title, p.slug, p.published_at as date, u.username as author, + c.name as category, s.name as series + FROM posts p + INNER JOIN post_tags pt ON p.id = pt.post_id + LEFT JOIN users u ON p.author_id = u.id + LEFT JOIN categories c ON p.category_id = c.id + LEFT JOIN series s ON p.series_id = s.id + WHERE pt.tag_id = ? + ORDER BY p.published_at DESC` + ) + .bind(filterTag.id) + .all(); + results = queryRes.results; + } else { + const queryRes = await db + .prepare( + `SELECT p.id, p.title, p.slug, p.published_at as date, u.username as author, + c.name as category, s.name as series + FROM posts p + LEFT JOIN users u ON p.author_id = u.id + LEFT JOIN categories c ON p.category_id = c.id + LEFT JOIN series s ON p.series_id = s.id + ORDER BY p.published_at DESC` + ) + .all(); + results = queryRes.results; + } } catch (err: any) { // Fallback query if categories table or category_id column is missing - const queryRes = await db - .prepare( - `SELECT p.id, p.title, p.slug, p.published_at as date, u.username as author - FROM posts p - LEFT JOIN users u ON p.author_id = u.id - ORDER BY p.published_at DESC` - ) - .all(); - results = queryRes.results.map((r) => ({ ...r, category: '', series: '' })); + if (filterTag) { + const queryRes = await db + .prepare( + `SELECT p.id, p.title, p.slug, p.published_at as date, u.username as author + FROM posts p + INNER JOIN post_tags pt ON p.id = pt.post_id + LEFT JOIN users u ON p.author_id = u.id + WHERE pt.tag_id = ? + ORDER BY p.published_at DESC` + ) + .bind(filterTag.id) + .all(); + results = queryRes.results.map((r) => ({ ...r, category: '', series: '' })); + } else { + const queryRes = await db + .prepare( + `SELECT p.id, p.title, p.slug, p.published_at as date, u.username as author + FROM posts p + LEFT JOIN users u ON p.author_id = u.id + ORDER BY p.published_at DESC` + ) + .all(); + results = queryRes.results.map((r) => ({ ...r, category: '', series: '' })); + } } // Format date for display @@ -62,11 +114,12 @@ export const load: PageServerLoad = async ({ platform }) => { }); return { - posts: formattedPosts + posts: formattedPosts, + filterTag }; } catch (err: any) { console.error('Error fetching admin posts list:', err); - return { posts: [] }; + return { posts: [], filterTag }; } }; diff --git a/src/routes/admin/posts/+page.svelte b/src/routes/admin/posts/+page.svelte index 8998b30..5936c27 100644 --- a/src/routes/admin/posts/+page.svelte +++ b/src/routes/admin/posts/+page.svelte @@ -28,6 +28,17 @@ +{#if data.filterTag} +
+
+ 正在筛选{$page.data.aliases?.tag || '标签'}: + #{data.filterTag.name} + (共 {data.posts.length} 篇) +
+ +
+{/if} + {#if data.posts.length > 0}
{#if selectedIds.length > 0} @@ -66,7 +77,17 @@ {#if data.posts.length === 0}
-

还没有发布任何{$page.data.aliases?.post || '文章'}

+ {#if data.filterTag} +

+ {$page.data.aliases?.tag || '标签'} "{data.filterTag.name}" 下暂无关联{$page.data.aliases + ?.post || '文章'} +

+ + {:else} +

还没有发布任何{$page.data.aliases?.post || '文章'}

+ {/if}
{:else} @@ -197,4 +218,32 @@ text-decoration: underline; text-underline-offset: 4px; } + + .filter-banner { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 20px; + padding: 10px 16px; + background: rgba(0, 0, 0, 0.03); + border-left: 3px solid var(--accent-color, #419b38); + } + + .filter-info { + display: flex; + align-items: center; + gap: 8px; + font-size: 0.95rem; + color: var(--text-color); + } + + .filter-tag-badge { + font-weight: 600; + color: var(--accent-color, #419b38); + } + + .filter-count { + color: var(--text-muted, rgba(0, 0, 0, 0.6)); + font-size: 0.85rem; + } diff --git a/src/routes/admin/tags/+page.svelte b/src/routes/admin/tags/+page.svelte index b0dd0c9..b258338 100644 --- a/src/routes/admin/tags/+page.svelte +++ b/src/routes/admin/tags/+page.svelte @@ -1,4 +1,5 @@