From 068b3dbbbb01bc713cce2396d8931913327b3fd3 Mon Sep 17 00:00:00 2001 From: seaHi Date: Wed, 29 Jul 2026 10:49:01 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=87=8D=E6=9E=84=E5=90=8E=E5=8F=B0?= =?UTF-8?q?=E5=B8=83=E5=B1=80=E5=B9=B6=E6=B7=BB=E5=8A=A0=E7=AB=99=E7=82=B9?= =?UTF-8?q?=E5=8A=A8=E6=80=81=E8=AE=BE=E7=BD=AE=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/routes/admin/+layout.server.ts | 46 ++++- src/routes/admin/+layout.svelte | 24 ++- src/routes/admin/+page.server.ts | 10 +- src/routes/admin/+page.svelte | 48 ++++- src/routes/admin/settings/+page.server.ts | 76 ++++++- src/routes/admin/settings/+page.svelte | 234 +++++++++++++++++++++- 6 files changed, 409 insertions(+), 29 deletions(-) diff --git a/src/routes/admin/+layout.server.ts b/src/routes/admin/+layout.server.ts index ec238fd..8782bf2 100644 --- a/src/routes/admin/+layout.server.ts +++ b/src/routes/admin/+layout.server.ts @@ -1,7 +1,49 @@ import type { LayoutServerLoad } from './$types'; -export const load: LayoutServerLoad = async ({ locals }) => { +export const load: LayoutServerLoad = async ({ locals, platform }) => { + const db = platform?.env?.DB; + + let aliases = { + post: '文章', + page: '页面', + category: '分类', + tag: '标签' + }; + + let site = { + title: 'BlogFlare', + description: 'A high-performance blog powered by Cloudflare D1, R2, and KV.' + }; + + if (db) { + try { + const { results } = await db.prepare( + "SELECT key, value FROM settings WHERE key LIKE 'alias.%' OR key LIKE 'site.%'" + ).all(); + + if (results && results.length > 0) { + results.forEach((row: any) => { + if (row.key.startsWith('alias.')) { + const type = row.key.split('.')[1]; + if (type && type in aliases) { + (aliases as any)[type] = row.value; + } + } else if (row.key.startsWith('site.')) { + const type = row.key.split('.')[1]; + if (type && type in site) { + (site as any)[type] = row.value; + } + } + }); + } + } catch (e) { + console.error('Failed to load settings', e); + } + } + return { - user: locals.user + user: locals.user, + aliases, + site }; }; diff --git a/src/routes/admin/+layout.svelte b/src/routes/admin/+layout.svelte index 13e7abc..5635c92 100644 --- a/src/routes/admin/+layout.svelte +++ b/src/routes/admin/+layout.svelte @@ -17,24 +17,34 @@ - 后台管理 - BlogFlare + 后台管理 - {$page.data.site?.title || 'BlogFlare'}
- BlogFlare Admin + {$page.data.site?.title || 'BlogFlare'} Admin
@@ -52,7 +73,7 @@ } .stat-card:hover { - border-color: var(--accent-color, #bd6262); + border-color: var(--accent-color, #419b38); } .stat-card h3 { @@ -71,16 +92,27 @@ } .action-link { - display: inline-block; + display: inline-flex; + align-items: center; font-size: 0.95rem; color: var(--text-color); font-weight: 600; border-bottom: 1px solid rgba(0, 0, 0, 0.2); transition: all 0.2s; + text-decoration: none; + } + + .arrow-icon { + margin-left: 6px; + transition: transform 0.2s cubic-bezier(0.25, 0.46, 0.45, 0.94); + } + + .stat-card:hover .arrow-icon { + transform: translate(3px, -3px); } .stat-card:hover .action-link { - color: var(--accent-color, #bd6262); - border-bottom-color: var(--accent-color, #bd6262); + color: var(--accent-color, #419b38); + border-bottom-color: var(--accent-color, #419b38); } diff --git a/src/routes/admin/settings/+page.server.ts b/src/routes/admin/settings/+page.server.ts index 662be43..944488d 100644 --- a/src/routes/admin/settings/+page.server.ts +++ b/src/routes/admin/settings/+page.server.ts @@ -1,8 +1,78 @@ -import type { PageServerLoad } from './$types'; +import { fail } from '@sveltejs/kit'; +import type { PageServerLoad, Actions } from './$types'; + +export const load: PageServerLoad = async ({ locals, platform }) => { + const db = platform?.env?.DB; + let settings: Record = {}; + + if (db) { + try { + const { results } = await db.prepare("SELECT key, value FROM settings").all(); + results.forEach((row: any) => { + settings[row.key] = row.value; + }); + } catch (e) { + console.error('Failed to load settings', e); + } + } -export const load: PageServerLoad = async ({ platform, locals }) => { return { user: locals.user, - platformEnv: !!platform?.env?.DB ? 'Cloudflare D1 (Connected)' : 'Local Mock' + platformEnv: !!db ? 'Cloudflare D1 (Connected)' : 'Local Mock', + settings }; }; + +export const actions: Actions = { + updateSiteInfo: async ({ request, platform }) => { + const db = platform?.env?.DB; + if (!db) return fail(500, { error: '数据库未连接' }); + + const data = await request.formData(); + const updates = [ + { key: 'site.title', value: data.get('site_title')?.toString() || 'BlogFlare' }, + { key: 'site.description', value: data.get('site_description')?.toString() || 'A high-performance blog powered by Cloudflare D1, R2, and KV.' }, + { key: 'r2.public_domain', value: data.get('r2_public_domain')?.toString() || 'https://assets.yourdomain.com' } + ]; + + try { + for (const { key, value } of updates) { + await db.prepare( + `INSERT INTO settings (key, value, updated_at) + VALUES (?, ?, CURRENT_TIMESTAMP) + ON CONFLICT(key) DO UPDATE SET value = excluded.value, updated_at = CURRENT_TIMESTAMP` + ).bind(key, value).run(); + } + return { success: true }; + } catch (e) { + console.error('Failed to update site info', e); + return fail(500, { error: '保存站点信息失败' }); + } + }, + updateAliases: async ({ request, platform }) => { + const db = platform?.env?.DB; + if (!db) return fail(500, { error: '数据库未连接' }); + + const data = await request.formData(); + const updates = [ + { key: 'alias.post', value: data.get('alias_post')?.toString() || '文章' }, + { key: 'alias.page', value: data.get('alias_page')?.toString() || '页面' }, + { key: 'alias.category', value: data.get('alias_category')?.toString() || '分类' }, + { key: 'alias.tag', value: data.get('alias_tag')?.toString() || '标签' } + ]; + + try { + for (const { key, value } of updates) { + await db.prepare( + `INSERT INTO settings (key, value, updated_at) + VALUES (?, ?, CURRENT_TIMESTAMP) + ON CONFLICT(key) DO UPDATE SET value = excluded.value, updated_at = CURRENT_TIMESTAMP` + ).bind(key, value).run(); + } + return { success: true }; + } catch (e) { + console.error('Failed to update aliases', e); + return fail(500, { error: '保存失败' }); + } + } +}; diff --git a/src/routes/admin/settings/+page.svelte b/src/routes/admin/settings/+page.svelte index 99dafdc..bc566f5 100644 --- a/src/routes/admin/settings/+page.svelte +++ b/src/routes/admin/settings/+page.svelte @@ -1,20 +1,66 @@

系统设置

+
+ + + +
+ +{#if form?.success} +
+ 设置保存成功! +
+{/if} + +{#if form?.error} +
+ {form.error} +
+{/if} +
+ {#if activeTab === 'basic'} +
+

站点基础信息

+

设置您的网站名称和一句话描述,这些信息将展示在首页和浏览器标题中。

+ +
+
+
+ + +
+
+ + +
+
+ + + 请确保不要以斜杠 / 结尾 +
+
+ +
+ +
+
+
+ {/if} + + {#if activeTab === 'system'}
-

博客信息

-
- 博客名称 - BlogFlare -
+

系统信息

主题风格 Typecho Theme VOID @@ -40,6 +86,42 @@ Cloudflare Access (Zero Trust)
+ {/if} + + {#if activeTab === 'terms'} +
+

个性化术语设定

+

您可以根据部署场景(如教学系统、文档库)自定义后台各模块的显示名称,例如将“文章”改为“实验手册”。

+ +
+
+
+ + +
+
+ + +
+
+ +
+
+ + +
+
+ + +
+
+ +
+ +
+
+
+ {/if}