- 将“图片上传”和“API 与 AI 集成”卡片调整为双列同行显示 - 移除“系统与安全环境”面板中无需展示的“主题风格”项 - 服务端增加对 R2 环境变量的读取,并在面板中展示 R2 存储绑定状态
This commit is contained in:
1 parent
fe8ea56d9b
commit
d5ae0d392b
2 files changed
+96
-77
No files matched your search
@@ -6,6 +6,7 @@ import { fetchAnalytics } from '$lib/server/cloudflare';
|
|||||||
|
|
||||||
export const load: PageServerLoad = async ({ locals, platform }) => {
|
export const load: PageServerLoad = async ({ locals, platform }) => {
|
||||||
const db = platform?.env?.DB;
|
const db = platform?.env?.DB;
|
||||||
|
const r2 = platform?.env?.R2;
|
||||||
const settings: Record<string, string> = {};
|
const settings: Record<string, string> = {};
|
||||||
|
|
||||||
if (db) {
|
if (db) {
|
||||||
@@ -22,6 +23,7 @@ export const load: PageServerLoad = async ({ locals, platform }) => {
|
|||||||
return {
|
return {
|
||||||
user: locals.user,
|
user: locals.user,
|
||||||
platformEnv: db ? 'Cloudflare D1 (Connected)' : 'Local Mock',
|
platformEnv: db ? 'Cloudflare D1 (Connected)' : 'Local Mock',
|
||||||
|
r2Env: r2 ? 'Cloudflare R2 (Connected)' : 'Local Mock',
|
||||||
settings,
|
settings,
|
||||||
analytics: fetchAnalytics(platform) // Streaming promise
|
analytics: fetchAnalytics(platform) // Streaming promise
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -121,10 +121,6 @@
|
|||||||
|
|
||||||
<div class="settings-card">
|
<div class="settings-card">
|
||||||
<h3>系统与安全环境</h3>
|
<h3>系统与安全环境</h3>
|
||||||
<div class="info-row">
|
|
||||||
<span class="label">主题风格</span>
|
|
||||||
<span class="value">Typecho Theme VOID</span>
|
|
||||||
</div>
|
|
||||||
<div class="info-row">
|
<div class="info-row">
|
||||||
<span class="label">驱动框架</span>
|
<span class="label">驱动框架</span>
|
||||||
<span class="value">SvelteKit 5 + Cloudflare</span>
|
<span class="value">SvelteKit 5 + Cloudflare</span>
|
||||||
@@ -137,6 +133,10 @@
|
|||||||
<span class="label">数据库绑定</span>
|
<span class="label">数据库绑定</span>
|
||||||
<span class="value"><span class="badge">{data.platformEnv}</span></span>
|
<span class="value"><span class="badge">{data.platformEnv}</span></span>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="info-row">
|
||||||
|
<span class="label">R2存储绑定</span>
|
||||||
|
<span class="value"><span class="badge">{data.r2Env}</span></span>
|
||||||
|
</div>
|
||||||
<div class="info-row">
|
<div class="info-row">
|
||||||
<span class="label">鉴权模式</span>
|
<span class="label">鉴权模式</span>
|
||||||
<span class="value">Cloudflare Access (Zero Trust)</span>
|
<span class="value">Cloudflare Access (Zero Trust)</span>
|
||||||
@@ -144,80 +144,83 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="settings-card full-width">
|
<div class="two-columns-row">
|
||||||
<h3>图片上传</h3>
|
<div class="settings-card">
|
||||||
<form
|
<h3>图片上传</h3>
|
||||||
method="POST"
|
<form
|
||||||
action="?/updateUploads"
|
method="POST"
|
||||||
use:enhance={() => {
|
action="?/updateUploads"
|
||||||
return async ({ update }) => {
|
use:enhance={() => {
|
||||||
await update({ reset: false });
|
return async ({ update }) => {
|
||||||
};
|
await update({ reset: false });
|
||||||
}}
|
};
|
||||||
class="alias-form"
|
}}
|
||||||
>
|
class="alias-form"
|
||||||
<label class="toggle-label">
|
>
|
||||||
<input type="checkbox" name="upload_auto_webp" value="true" bind:checked={autoWebp} />
|
<label class="toggle-label">
|
||||||
<span class="toggle-text">上传图片时自动转换为 WebP</span>
|
<input type="checkbox" name="upload_auto_webp" value="true" bind:checked={autoWebp} />
|
||||||
</label>
|
<span class="toggle-text">上传图片时自动转换为 WebP</span>
|
||||||
<p class="desc">
|
</label>
|
||||||
默认关闭。开启后,后台各入口上传的 JPEG / PNG 图片会在浏览器中以 80% 质量转换为
|
<p class="desc">
|
||||||
WebP,保持原尺寸及透明背景。GIF、动态 PNG 和已有 WebP 保持原格式。
|
默认关闭。开启后,后台各入口上传的 JPEG / PNG 图片会在浏览器中以 80% 质量转换为
|
||||||
仅影响新上传图片;直接调用上传 API 的客户端需自行转换。
|
WebP,保持原尺寸及透明背景。GIF、动态 PNG 和已有 WebP 保持原格式。
|
||||||
</p>
|
仅影响新上传图片;直接调用上传 API 的客户端需自行转换。
|
||||||
<div class="form-actions">
|
</p>
|
||||||
<Button type="submit" variant="primary">保存上传设置</Button>
|
<div class="form-actions" style="margin-top: auto;">
|
||||||
</div>
|
<Button type="submit" variant="primary">保存上传设置</Button>
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="settings-card full-width">
|
|
||||||
<h3>API 与 AI 集成</h3>
|
|
||||||
<p class="desc">
|
|
||||||
配置允许 AI 或第三方工具直接管理文章的 API 访问令牌 (Token)。请求 API 时请在 HTTP Header
|
|
||||||
中添加 <code>Authorization: Bearer <Token></code>。
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<form
|
|
||||||
method="POST"
|
|
||||||
action="?/updateApiToken"
|
|
||||||
use:enhance={() => {
|
|
||||||
return async ({ update }) => {
|
|
||||||
update({ reset: false });
|
|
||||||
};
|
|
||||||
}}
|
|
||||||
class="alias-form"
|
|
||||||
>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="agent_api_token">API Token</label>
|
|
||||||
<div style="display: flex; gap: 10px; align-items: center; width: 100%;">
|
|
||||||
<TextInput
|
|
||||||
type={showApiToken ? 'text' : 'password'}
|
|
||||||
id="agent_api_token"
|
|
||||||
name="agent_api_token"
|
|
||||||
bind:value={apiToken}
|
|
||||||
placeholder="留空则禁用对外 API 访问"
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
type="button"
|
|
||||||
variant="secondary"
|
|
||||||
style="white-space: nowrap;"
|
|
||||||
onclick={() => (showApiToken = !showApiToken)}
|
|
||||||
>
|
|
||||||
{showApiToken ? '隐藏' : '显示'}
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
type="button"
|
|
||||||
variant="secondary"
|
|
||||||
style="white-space: nowrap;"
|
|
||||||
onclick={generateApiToken}>自动生成</Button
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</form>
|
||||||
<div class="form-actions">
|
</div>
|
||||||
<Button type="submit" variant="primary">保存 Token</Button>
|
|
||||||
</div>
|
<div class="settings-card">
|
||||||
</form>
|
<h3>API 与 AI 集成</h3>
|
||||||
|
<p class="desc">
|
||||||
|
配置允许 AI 或第三方工具直接管理文章的 API 访问令牌 (Token)。请求 API 时请在 HTTP Header
|
||||||
|
中添加 <code>Authorization: Bearer <Token></code>。
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<form
|
||||||
|
method="POST"
|
||||||
|
action="?/updateApiToken"
|
||||||
|
use:enhance={() => {
|
||||||
|
return async ({ update }) => {
|
||||||
|
update({ reset: false });
|
||||||
|
};
|
||||||
|
}}
|
||||||
|
class="alias-form"
|
||||||
|
style="height: 100%; display: flex; flex-direction: column;"
|
||||||
|
>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="agent_api_token">API Token</label>
|
||||||
|
<div style="display: flex; gap: 10px; align-items: center; width: 100%;">
|
||||||
|
<TextInput
|
||||||
|
type={showApiToken ? 'text' : 'password'}
|
||||||
|
id="agent_api_token"
|
||||||
|
name="agent_api_token"
|
||||||
|
bind:value={apiToken}
|
||||||
|
placeholder="留空则禁用对外 API 访问"
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
variant="secondary"
|
||||||
|
style="white-space: nowrap;"
|
||||||
|
onclick={() => (showApiToken = !showApiToken)}
|
||||||
|
>
|
||||||
|
{showApiToken ? '隐藏' : '显示'}
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
variant="secondary"
|
||||||
|
style="white-space: nowrap;"
|
||||||
|
onclick={generateApiToken}>自动生成</Button
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-actions" style="margin-top: auto;">
|
||||||
|
<Button type="submit" variant="primary">保存 Token</Button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
@@ -387,6 +390,20 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.two-columns-row {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 25px;
|
||||||
|
align-items: stretch;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
.two-columns-row {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.full-width {
|
.full-width {
|
||||||
grid-column: 1 / -1;
|
grid-column: 1 / -1;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user