feat: add demo site config

This commit is contained in:
engigu
2025-12-25 21:46:06 +08:00
parent 9bf9e5b5b8
commit 9c77601215
9 changed files with 67 additions and 6 deletions
+1 -1
View File
@@ -111,7 +111,7 @@ export const api = {
changePassword: (data: { old_password: string; new_password: string }) =>
request('/settings/password', { method: 'POST', body: JSON.stringify(data) }),
getSite: () => request<SiteSettings>('/settings/site'),
getPublicSite: () => request<{ title: string; subtitle: string; icon: string }>('/settings/public'),
getPublicSite: () => request<{ title: string; subtitle: string; icon: string; demo_mode: boolean }>('/settings/public'),
updateSite: (data: SiteSettings) =>
request('/settings/site', { method: 'PUT', body: JSON.stringify(data) }),
getScheduler: () => request<SchedulerSettings>('/settings/scheduler'),
+7
View File
@@ -17,6 +17,7 @@ const loading = ref(false)
const siteTitle = ref('白虎面板')
const siteSubtitle = ref('轻量级定时任务管理系统')
const siteIcon = ref('')
const demoMode = ref(false)
async function loadSiteSettings() {
try {
@@ -24,7 +25,13 @@ async function loadSiteSettings() {
siteTitle.value = res.title || '白虎面板'
siteSubtitle.value = res.subtitle || '轻量级定时任务管理系统'
siteIcon.value = res.icon || ''
demoMode.value = res.demo_mode || false
document.title = siteTitle.value
// 演示模式下自动填充账号密码
if (demoMode.value) {
username.value = 'admin'
password.value = '123456'
}
// 设置 favicon
if (siteIcon.value && siteIcon.value.trim().startsWith('<svg')) {
const blob = new Blob([siteIcon.value], { type: 'image/svg+xml' })
+26 -5
View File
@@ -1,16 +1,31 @@
<script setup lang="ts">
import { ref } from 'vue'
import { ref, onMounted } from 'vue'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { AlertTriangle } from 'lucide-vue-next'
import { api } from '@/api'
import { toast } from 'vue-sonner'
const oldPassword = ref('')
const newPassword = ref('')
const confirmPassword = ref('')
const demoMode = ref(false)
async function loadDemoMode() {
try {
const res = await api.settings.getPublicSite()
demoMode.value = res.demo_mode || false
} catch {
// ignore
}
}
async function changePassword() {
if (demoMode.value) {
toast.error('演示模式下不能修改密码')
return
}
if (!oldPassword.value || !newPassword.value) {
toast.error('请填写完整')
return
@@ -33,24 +48,30 @@ async function changePassword() {
toast.error(e.message || '修改失败')
}
}
onMounted(loadDemoMode)
</script>
<template>
<div class="space-y-4">
<div v-if="demoMode" class="flex items-center gap-2 p-3 rounded-md bg-destructive/10 text-destructive text-sm">
<AlertTriangle class="h-4 w-4 shrink-0" />
<span>演示模式下不能修改密码</span>
</div>
<div class="grid grid-cols-1 sm:grid-cols-4 items-center gap-2 sm:gap-4">
<Label class="sm:text-right">原密码</Label>
<Input v-model="oldPassword" type="password" placeholder="请输入原密码" class="sm:col-span-3" />
<Input v-model="oldPassword" type="password" placeholder="请输入原密码" class="sm:col-span-3" :disabled="demoMode" />
</div>
<div class="grid grid-cols-1 sm:grid-cols-4 items-center gap-2 sm:gap-4">
<Label class="sm:text-right">新密码</Label>
<Input v-model="newPassword" type="password" placeholder="请输入新密码(至少6位)" class="sm:col-span-3" />
<Input v-model="newPassword" type="password" placeholder="请输入新密码(至少6位)" class="sm:col-span-3" :disabled="demoMode" />
</div>
<div class="grid grid-cols-1 sm:grid-cols-4 items-center gap-2 sm:gap-4">
<Label class="sm:text-right">确认密码</Label>
<Input v-model="confirmPassword" type="password" placeholder="请再次输入新密码" class="sm:col-span-3" />
<Input v-model="confirmPassword" type="password" placeholder="请再次输入新密码" class="sm:col-span-3" :disabled="demoMode" />
</div>
<div class="flex justify-end pt-2">
<Button @click="changePassword">修改密码</Button>
<Button @click="changePassword" :disabled="demoMode">修改密码</Button>
</div>
</div>
</template>