59 lines
2.6 KiB
Vue
59 lines
2.6 KiB
Vue
<script setup lang="ts">
|
||
import {
|
||
PhArrowRight as ArrowRight,
|
||
PhEye as Eye,
|
||
PhEyeSlash as EyeSlash,
|
||
PhLockKey as LockKey,
|
||
PhUser as User,
|
||
} from '@phosphor-icons/vue'
|
||
|
||
definePageMeta({ layout: false })
|
||
const { data: publicSite } = await useFetch<{ data: { brand: { name: string; englishName: string; logo: string; subSlogan: string } } }>('/api/public/site')
|
||
const loginBrand = computed(() => publicSite.value?.data.brand ?? { name: '慧遇书院', englishName: 'HUIYU ACADEMY', logo: '/images/brand-mark-v2.png', subSlogan: '用科技与专业,陪伴每一次心灵的成长' })
|
||
useHead(() => ({ title: `后台管理登录|${loginBrand.value.name}` }))
|
||
|
||
const form = reactive({ username: 'admin', password: '' })
|
||
const showPassword = ref(false)
|
||
const loading = ref(false)
|
||
const error = ref('')
|
||
|
||
async function login() {
|
||
error.value = ''
|
||
loading.value = true
|
||
try {
|
||
await $fetch('/api/auth/login', { method: 'POST', body: form })
|
||
await navigateTo('/admin')
|
||
} catch (cause: any) {
|
||
error.value = cause?.data?.statusMessage || '登录失败,请稍后重试'
|
||
} finally {
|
||
loading.value = false
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<template>
|
||
<main class="login-page">
|
||
<div class="login-brand">
|
||
<BrandLogo :src="loginBrand.logo" :name="loginBrand.name" :english-name="loginBrand.englishName" />
|
||
<div>
|
||
<h1>身心疗愈<br>科技赋能</h1>
|
||
<p>{{ loginBrand.subSlogan }}</p>
|
||
</div>
|
||
</div>
|
||
<section class="login-card">
|
||
<p class="eyebrow">HUIYU CONTENT SYSTEM</p>
|
||
<h2>后台管理登录</h2>
|
||
<p class="login-intro">欢迎回来,请登录管理员账号</p>
|
||
<form @submit.prevent="login">
|
||
<label>账号</label>
|
||
<div class="field"><User :size="22" /><input v-model.trim="form.username" autocomplete="username" placeholder="请输入账号" required></div>
|
||
<label>密码</label>
|
||
<div class="field"><LockKey :size="22" /><input v-model="form.password" :type="showPassword ? 'text' : 'password'" autocomplete="current-password" placeholder="请输入密码" required><button type="button" aria-label="切换密码显示" @click="showPassword = !showPassword"><EyeSlash v-if="showPassword" :size="21" /><Eye v-else :size="21" /></button></div>
|
||
<p v-if="error" class="form-error" role="alert">{{ error }}</p>
|
||
<button class="login-submit" type="submit" :disabled="loading"><span>{{ loading ? '登录中…' : '登录后台' }}</span><ArrowRight :size="21" /></button>
|
||
</form>
|
||
<p class="security-note">安全连接已启用,登录状态受保护</p>
|
||
</section>
|
||
</main>
|
||
</template>
|