Fix admin login and add subscription popup settings
Some checks failed
docker-images / build-and-push (admin, admin, termi-astro-admin, admin/Dockerfile) (push) Failing after 6s
docker-images / build-and-push (backend, backend, termi-astro-backend, backend/Dockerfile) (push) Failing after 5s
docker-images / build-and-push (frontend, frontend, termi-astro-frontend, frontend/Dockerfile) (push) Failing after 6s

This commit is contained in:
2026-04-01 00:05:16 +08:00
parent 350262c910
commit 660b255700
19 changed files with 1096 additions and 32 deletions

View File

@@ -53,8 +53,8 @@ import type {
import { getRuntimeAdminBaseUrl, normalizeAdminBaseUrl } from '@/lib/runtime-config'
const envApiBase = normalizeAdminBaseUrl(import.meta.env.VITE_API_BASE)
const DEV_API_BASE = 'http://localhost:5150'
const PROD_DEFAULT_API_PORT = '5150'
const DEV_DEFAULT_API_HOST = '127.0.0.1'
function getApiBase() {
const runtimeApiBase = getRuntimeAdminBaseUrl('apiBaseUrl')
@@ -67,11 +67,12 @@ function getApiBase() {
}
if (import.meta.env.DEV) {
return DEV_API_BASE
}
if (typeof window !== 'undefined') {
const { protocol, hostname } = window.location
return `${protocol}//${hostname}:${PROD_DEFAULT_API_PORT}`
}
if (typeof window === 'undefined') {
return DEV_API_BASE
return `http://${DEV_DEFAULT_API_HOST}:${PROD_DEFAULT_API_PORT}`
}
const { protocol, hostname } = window.location

View File

@@ -329,6 +329,10 @@ export interface AdminSiteSettingsResponse {
notification_webhook_url: string | null
notification_comment_enabled: boolean
notification_friend_link_enabled: boolean
subscription_popup_enabled: boolean
subscription_popup_title: string
subscription_popup_description: string
subscription_popup_delay_seconds: number
search_synonyms: string[]
}
@@ -387,6 +391,10 @@ export interface SiteSettingsPayload {
notificationWebhookUrl?: string | null
notificationCommentEnabled?: boolean
notificationFriendLinkEnabled?: boolean
subscriptionPopupEnabled?: boolean
subscriptionPopupTitle?: string | null
subscriptionPopupDescription?: string | null
subscriptionPopupDelaySeconds?: number | null
searchSynonyms?: string[]
}

View File

@@ -158,6 +158,10 @@ function toPayload(form: AdminSiteSettingsResponse): SiteSettingsPayload {
notificationWebhookUrl: form.notification_webhook_url,
notificationCommentEnabled: form.notification_comment_enabled,
notificationFriendLinkEnabled: form.notification_friend_link_enabled,
subscriptionPopupEnabled: form.subscription_popup_enabled,
subscriptionPopupTitle: form.subscription_popup_title,
subscriptionPopupDescription: form.subscription_popup_description,
subscriptionPopupDelaySeconds: form.subscription_popup_delay_seconds,
searchSynonyms: form.search_synonyms,
}
}
@@ -595,6 +599,70 @@ export function SiteSettingsPage() {
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle></CardTitle>
<CardDescription>
/
</CardDescription>
</CardHeader>
<CardContent className="space-y-5">
<label className="flex items-start gap-3 rounded-2xl border border-border/70 bg-background/60 p-4">
<input
type="checkbox"
checked={form.subscription_popup_enabled}
onChange={(event) =>
updateField('subscription_popup_enabled', event.target.checked)
}
className="mt-1 h-4 w-4 rounded border-input text-primary focus:ring-ring"
/>
<div>
<div className="font-medium"></div>
<p className="mt-1 text-sm leading-6 text-muted-foreground">
</p>
</div>
</label>
<div className="grid gap-4 lg:grid-cols-2">
<Field label="弹窗标题" hint="建议直接传达价值,例如“订阅更新”或“别错过新文章”。">
<Input
value={form.subscription_popup_title}
onChange={(event) =>
updateField('subscription_popup_title', event.target.value)
}
/>
</Field>
<Field label="触发延迟(秒)" hint="建议保持在 1020 秒,避免首屏强打断。">
<Input
type="number"
min={3}
max={120}
value={form.subscription_popup_delay_seconds}
onChange={(event) =>
updateField(
'subscription_popup_delay_seconds',
event.target.value ? Number(event.target.value) : 18,
)
}
/>
</Field>
</div>
<Field
label="弹窗说明"
hint="建议明确订阅收益、需要邮箱确认,以及可随时退订,降低打扰感。"
>
<Textarea
value={form.subscription_popup_description}
onChange={(event) =>
updateField('subscription_popup_description', event.target.value)
}
/>
</Field>
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle>SEO</CardTitle>

View File

@@ -172,7 +172,7 @@ export function SubscriptionsPage() {
<div className="space-y-3">
<Badge variant="secondary"></Badge>
<div>
<h2 className="text-3xl font-semibold tracking-tight"> / / Digest</h2>
<h2 className="text-3xl font-semibold tracking-tight"> / / </h2>
<p className="mt-2 max-w-3xl text-sm leading-7 text-muted-foreground">
Webhook / Discord / Telegram / ntfy retry pending
</p>