This commit is contained in:
1 parent
bf304cee0f
commit
5a2f55a872
2 files changed
+80
-178
No files matched your search
@@ -34,54 +34,13 @@ export const load: PageServerLoad = async ({ locals, platform }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const actions: Actions = {
|
export const actions: Actions = {
|
||||||
updateWebAnalytics: async ({ request, platform }) => {
|
updateBasicSettings: async ({ request, platform }) => {
|
||||||
const db = platform?.env?.DB;
|
const db = platform?.env?.DB;
|
||||||
if (!db) return fail(500, { error: '数据库未连接' });
|
if (!db) return fail(500, { error: '数据库未连接' });
|
||||||
|
|
||||||
const data = await request.formData();
|
const data = await request.formData();
|
||||||
const token = data.get('web_analytics_token')?.toString().trim() || '';
|
const autoWebp = data.get('upload_auto_webp') === 'true' ? 'true' : 'false';
|
||||||
|
|
||||||
try {
|
|
||||||
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('site.web_analytics_token', token)
|
|
||||||
.run();
|
|
||||||
return { success: true };
|
|
||||||
} catch (err: any) {
|
|
||||||
console.error('Failed to update web analytics token', err);
|
|
||||||
return fail(500, { error: '保存统计设置失败' });
|
|
||||||
}
|
|
||||||
},
|
|
||||||
updateUploads: async ({ request, platform }) => {
|
|
||||||
const db = platform?.env?.DB;
|
|
||||||
if (!db) return fail(500, { error: '数据库未连接' });
|
|
||||||
|
|
||||||
const data = await request.formData();
|
|
||||||
const enabled = data.get('upload_auto_webp') === 'true';
|
|
||||||
try {
|
|
||||||
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('upload.auto_webp', String(enabled))
|
|
||||||
.run();
|
|
||||||
return { success: true };
|
|
||||||
} catch (err) {
|
|
||||||
console.error('Failed to update upload settings', err);
|
|
||||||
return fail(500, { error: '保存图片上传设置失败' });
|
|
||||||
}
|
|
||||||
},
|
|
||||||
updateSiteInfo: async ({ request, platform }) => {
|
|
||||||
const db = platform?.env?.DB;
|
|
||||||
if (!db) return fail(500, { error: '数据库未连接' });
|
|
||||||
|
|
||||||
const data = await request.formData();
|
|
||||||
const updates = [
|
const updates = [
|
||||||
{ key: 'site.title', value: data.get('site_title')?.toString() || 'BlogFlare' },
|
{ key: 'site.title', value: data.get('site_title')?.toString() || 'BlogFlare' },
|
||||||
{
|
{
|
||||||
@@ -99,6 +58,12 @@ export const actions: Actions = {
|
|||||||
{
|
{
|
||||||
key: 'site.launch_date',
|
key: 'site.launch_date',
|
||||||
value: data.get('site_launch_date')?.toString() || ''
|
value: data.get('site_launch_date')?.toString() || ''
|
||||||
|
},
|
||||||
|
{ key: 'upload.auto_webp', value: autoWebp },
|
||||||
|
{ key: 'agent.api_token', value: data.get('agent_api_token')?.toString() || '' },
|
||||||
|
{
|
||||||
|
key: 'site.web_analytics_token',
|
||||||
|
value: data.get('web_analytics_token')?.toString().trim() || ''
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -115,30 +80,8 @@ export const actions: Actions = {
|
|||||||
}
|
}
|
||||||
return { success: true };
|
return { success: true };
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
console.error('Failed to update site info', err);
|
console.error('Failed to update basic settings', err);
|
||||||
return fail(500, { error: '保存站点信息失败' });
|
return fail(500, { error: '保存基础设置失败' });
|
||||||
}
|
|
||||||
},
|
|
||||||
updateApiToken: async ({ request, platform }) => {
|
|
||||||
const db = platform?.env?.DB;
|
|
||||||
if (!db) return fail(500, { error: '数据库未连接' });
|
|
||||||
|
|
||||||
const data = await request.formData();
|
|
||||||
const token = data.get('agent_api_token')?.toString() || '';
|
|
||||||
|
|
||||||
try {
|
|
||||||
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('agent.api_token', token)
|
|
||||||
.run();
|
|
||||||
return { success: true };
|
|
||||||
} catch (err: unknown) {
|
|
||||||
console.error('Failed to update api token', err);
|
|
||||||
return fail(500, { error: '保存 API Token 失败' });
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
updateAliases: async ({ request, platform }) => {
|
updateAliases: async ({ request, platform }) => {
|
||||||
|
|||||||
@@ -63,20 +63,47 @@
|
|||||||
|
|
||||||
<div class="settings-container">
|
<div class="settings-container">
|
||||||
{#if activeTab === 'basic'}
|
{#if activeTab === 'basic'}
|
||||||
<div class="settings-card full-width">
|
<div class="settings-card full-width" style="margin-bottom: 25px;">
|
||||||
<div class="settings-section">
|
<div class="settings-section" style="padding: 0;">
|
||||||
<h3>站点基础信息</h3>
|
<h3>系统与安全环境</h3>
|
||||||
|
<div class="info-grid">
|
||||||
|
<div class="info-item">
|
||||||
|
<span class="label">驱动框架</span>
|
||||||
|
<span class="value">SvelteKit 5 + Cloudflare</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-item">
|
||||||
|
<span class="label">当前管理员</span>
|
||||||
|
<span class="value">{data.user?.email || '未知用户'}</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-item">
|
||||||
|
<span class="label">数据库绑定</span>
|
||||||
|
<span class="value"><span class="badge">{data.platformEnv}</span></span>
|
||||||
|
</div>
|
||||||
|
<div class="info-item">
|
||||||
|
<span class="label">R2存储绑定</span>
|
||||||
|
<span class="value"><span class="badge">{data.r2Env}</span></span>
|
||||||
|
</div>
|
||||||
|
<div class="info-item">
|
||||||
|
<span class="label">鉴权模式</span>
|
||||||
|
<span class="value">Cloudflare Access (Zero Trust)</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<form
|
<div class="settings-card full-width">
|
||||||
method="POST"
|
<form
|
||||||
action="?/updateSiteInfo"
|
method="POST"
|
||||||
use:enhance={() => {
|
action="?/updateBasicSettings"
|
||||||
return async ({ update }) => {
|
use:enhance={() => {
|
||||||
update({ reset: false });
|
return async ({ update }) => {
|
||||||
};
|
update({ reset: false });
|
||||||
}}
|
};
|
||||||
class="alias-form"
|
}}
|
||||||
>
|
class="alias-form"
|
||||||
|
>
|
||||||
|
<div class="settings-section">
|
||||||
|
<h3>站点基础信息</h3>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="site_title">网站标题</label>
|
<label for="site_title">网站标题</label>
|
||||||
@@ -121,89 +148,31 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-actions" style="justify-content: flex-start;">
|
|
||||||
<Button type="submit" variant="primary">保存</Button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr class="section-divider" />
|
|
||||||
|
|
||||||
<div class="settings-section">
|
|
||||||
<h3>系统与安全环境</h3>
|
|
||||||
<div class="info-grid">
|
|
||||||
<div class="info-item">
|
|
||||||
<span class="label">驱动框架</span>
|
|
||||||
<span class="value">SvelteKit 5 + Cloudflare</span>
|
|
||||||
</div>
|
|
||||||
<div class="info-item">
|
|
||||||
<span class="label">当前管理员</span>
|
|
||||||
<span class="value">{data.user?.email || '未知用户'}</span>
|
|
||||||
</div>
|
|
||||||
<div class="info-item">
|
|
||||||
<span class="label">数据库绑定</span>
|
|
||||||
<span class="value"><span class="badge">{data.platformEnv}</span></span>
|
|
||||||
</div>
|
|
||||||
<div class="info-item">
|
|
||||||
<span class="label">R2存储绑定</span>
|
|
||||||
<span class="value"><span class="badge">{data.r2Env}</span></span>
|
|
||||||
</div>
|
|
||||||
<div class="info-item">
|
|
||||||
<span class="label">鉴权模式</span>
|
|
||||||
<span class="value">Cloudflare Access (Zero Trust)</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr class="section-divider" />
|
<hr class="section-divider" />
|
||||||
|
|
||||||
<div class="settings-section">
|
<div class="settings-section">
|
||||||
<h3>图片上传</h3>
|
<h3>图片上传</h3>
|
||||||
<form
|
|
||||||
method="POST"
|
|
||||||
action="?/updateUploads"
|
|
||||||
use:enhance={() => {
|
|
||||||
return async ({ update }) => {
|
|
||||||
await update({ reset: false });
|
|
||||||
};
|
|
||||||
}}
|
|
||||||
class="alias-form"
|
|
||||||
>
|
|
||||||
<label class="toggle-label">
|
<label class="toggle-label">
|
||||||
<input type="checkbox" name="upload_auto_webp" value="true" bind:checked={autoWebp} />
|
<input type="checkbox" name="upload_auto_webp" value="true" bind:checked={autoWebp} />
|
||||||
<span class="toggle-text">上传图片时自动转换为 WebP</span>
|
<span class="toggle-text">上传图片时自动转换为 WebP</span>
|
||||||
</label>
|
</label>
|
||||||
<p class="desc">
|
<p class="desc" style="margin-top: 10px;">
|
||||||
默认关闭。开启后,后台各入口上传的 JPEG / PNG 图片会在浏览器中以 80% 质量转换为
|
默认关闭。开启后,后台各入口上传的 JPEG / PNG 图片会在浏览器中以 80% 质量转换为
|
||||||
WebP,保持原尺寸及透明背景。GIF、动态 PNG 和已有 WebP 保持原格式。
|
WebP,保持原尺寸及透明背景。GIF、动态 PNG 和已有 WebP 保持原格式。
|
||||||
仅影响新上传图片;直接调用上传 API 的客户端需自行转换。
|
仅影响新上传图片;直接调用上传 API 的客户端需自行转换。
|
||||||
</p>
|
</p>
|
||||||
<div class="form-actions" style="justify-content: flex-start;">
|
</div>
|
||||||
<Button type="submit" variant="primary">保存上传设置</Button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr class="section-divider" />
|
<hr class="section-divider" />
|
||||||
|
|
||||||
<div class="settings-section">
|
<div class="settings-section">
|
||||||
<h3>API 与 AI 集成</h3>
|
<h3>API 与 AI 集成</h3>
|
||||||
<p class="desc">
|
<p class="desc">
|
||||||
配置允许 AI 或第三方工具直接管理文章的 API 访问令牌 (Token)。请求 API 时请在 HTTP Header
|
配置允许 AI 或第三方工具直接管理文章的 API 访问令牌 (Token)。请求 API 时请在 HTTP Header
|
||||||
中添加 <code>Authorization: Bearer <Token></code>。
|
中添加 <code>Authorization: Bearer <Token></code>。
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<form
|
|
||||||
method="POST"
|
|
||||||
action="?/updateApiToken"
|
|
||||||
use:enhance={() => {
|
|
||||||
return async ({ update }) => {
|
|
||||||
update({ reset: false });
|
|
||||||
};
|
|
||||||
}}
|
|
||||||
class="alias-form"
|
|
||||||
>
|
|
||||||
<div class="form-group" style="max-width: 500px;">
|
<div class="form-group" style="max-width: 500px;">
|
||||||
<label for="agent_api_token">API Token</label>
|
<label for="agent_api_token">API Token</label>
|
||||||
<div style="display: flex; gap: 10px; align-items: center; width: 100%;">
|
<div style="display: flex; gap: 10px; align-items: center; width: 100%;">
|
||||||
@@ -230,31 +199,17 @@
|
|||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-actions" style="justify-content: flex-start;">
|
</div>
|
||||||
<Button type="submit" variant="primary">保存 Token</Button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr class="section-divider" />
|
<hr class="section-divider" />
|
||||||
|
|
||||||
<div class="settings-section">
|
<div class="settings-section">
|
||||||
<h3>Cloudflare Web Analytics</h3>
|
<h3>Cloudflare Web Analytics</h3>
|
||||||
<p class="desc">
|
<p class="desc">
|
||||||
填写 Cloudflare Web Analytics 统计脚本中的 token,用于采集页面浏览量和访问次数。 请勿填写
|
填写 Cloudflare Web Analytics 统计脚本中的 token,用于采集页面浏览量和访问次数。
|
||||||
Site Tag;它是查询标识,不能用于浏览器采集。后台查询还需配置 CF_ACCOUNT_ID, 并确保
|
请勿填写 Site Tag;它是查询标识,不能用于浏览器采集。后台查询还需配置 CF_ACCOUNT_ID,
|
||||||
CF_API_TOKEN 具有该账户的 Account Settings Read 和 Account Analytics Read 权限。
|
并确保 CF_API_TOKEN 具有该账户的 Account Settings Read 和 Account Analytics Read 权限。
|
||||||
</p>
|
</p>
|
||||||
<form
|
|
||||||
method="POST"
|
|
||||||
action="?/updateWebAnalytics"
|
|
||||||
use:enhance={() => {
|
|
||||||
return async ({ update }) => {
|
|
||||||
update({ reset: false });
|
|
||||||
};
|
|
||||||
}}
|
|
||||||
class="alias-form"
|
|
||||||
>
|
|
||||||
<div class="form-group" style="max-width: 500px;">
|
<div class="form-group" style="max-width: 500px;">
|
||||||
<label for="web_analytics_token">Web Analytics Token</label>
|
<label for="web_analytics_token">Web Analytics Token</label>
|
||||||
<TextInput
|
<TextInput
|
||||||
@@ -265,11 +220,15 @@
|
|||||||
placeholder="留空则禁用数据拉取和自动注入"
|
placeholder="留空则禁用数据拉取和自动注入"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-actions" style="justify-content: flex-start;">
|
</div>
|
||||||
<Button type="submit" variant="primary">保存统计设置</Button>
|
|
||||||
</div>
|
<div
|
||||||
</form>
|
class="form-actions"
|
||||||
</div>
|
style="margin-top: 30px; justify-content: flex-start; border-top: 1px solid var(--border-color, rgba(0,0,0,0.1)); padding-top: 20px;"
|
||||||
|
>
|
||||||
|
<Button type="submit" variant="primary">保存基础设置</Button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user