feat(admin-frontend): 初始化管理端登录功能

This commit is contained in:
yinjianm
2026-04-21 03:28:04 +08:00
parent 994819e8a0
commit 4cfda0fbf1
38 changed files with 4296 additions and 9 deletions
@@ -0,0 +1,60 @@
<script setup lang="ts">
import { useAppStore } from '@/stores/app'
const app = useAppStore()
</script>
<template>
<div class="dashboard">
<ElRow :gutter="20">
<ElCol :span="24">
<ElCard shadow="never">
<template #header>
<div class="card-header">
<span>欢迎使用</span>
</div>
</template>
<div class="welcome">
<h2>{{ app.title }}</h2>
<p class="version" v-if="app.version">版本{{ app.version }}</p>
<ElDivider />
<p class="hint">管理后台正在建设中更多功能即将上线</p>
</div>
</ElCard>
</ElCol>
</ElRow>
</div>
</template>
<style scoped>
.dashboard {
padding: 0;
}
.card-header {
display: flex;
align-items: center;
font-weight: 600;
}
.welcome {
text-align: center;
padding: 40px 0;
}
.welcome h2 {
margin: 0 0 8px;
font-size: 22px;
color: var(--el-text-color-primary);
}
.version {
color: var(--el-text-color-secondary);
font-size: 14px;
}
.hint {
color: var(--el-text-color-secondary);
font-size: 14px;
}
</style>
@@ -0,0 +1,148 @@
<script setup lang="ts">
import { reactive, ref } from 'vue'
import { useRouter } from 'vue-router'
import { useAuthStore } from '@/stores/auth'
import { ElMessage } from 'element-plus'
import type { FormInstance, FormRules } from 'element-plus'
const router = useRouter()
const auth = useAuthStore()
const formRef = ref<FormInstance>()
const loading = ref(false)
const form = reactive({
email: '',
password: '',
remember: false,
})
const rules: FormRules = {
email: [
{ required: true, message: '请输入邮箱', trigger: 'blur' },
{ type: 'email', message: '邮箱格式不正确', trigger: 'blur' },
],
password: [
{ required: true, message: '请输入密码', trigger: 'blur' },
{ min: 8, message: '密码至少 8 位', trigger: 'blur' },
],
}
async function onSubmit() {
const valid = await formRef.value?.validate().catch(() => false)
if (!valid) return
loading.value = true
try {
await auth.login(form.email, form.password, form.remember)
ElMessage.success('登录成功')
router.push('/dashboard')
} catch (err: unknown) {
const msg = err instanceof Error ? err.message : '登录失败'
ElMessage.error(msg)
} finally {
loading.value = false
}
}
</script>
<template>
<div class="login-container">
<div class="login-card">
<div class="login-header">
<h1 class="login-title">Xboard Admin</h1>
<p class="login-subtitle">管理后台</p>
</div>
<ElForm
ref="formRef"
:model="form"
:rules="rules"
label-position="top"
size="large"
@keyup.enter="onSubmit"
>
<ElFormItem label="邮箱" prop="email">
<ElInput
v-model="form.email"
placeholder="admin@example.com"
prefix-icon="Message"
/>
</ElFormItem>
<ElFormItem label="密码" prop="password">
<ElInput
v-model="form.password"
type="password"
placeholder="请输入密码"
prefix-icon="Lock"
show-password
/>
</ElFormItem>
<ElFormItem>
<ElCheckbox v-model="form.remember">记住登录</ElCheckbox>
</ElFormItem>
<ElFormItem>
<ElButton
type="primary"
:loading="loading"
class="login-btn"
@click="onSubmit"
>
{{ loading ? '登录中...' : '登 录' }}
</ElButton>
</ElFormItem>
</ElForm>
</div>
</div>
</template>
<style scoped>
.login-container {
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f3460 100%);
padding: 20px;
}
.login-card {
width: 100%;
max-width: 420px;
padding: 40px;
background: var(--el-bg-color);
border-radius: 12px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
}
.login-header {
text-align: center;
margin-bottom: 32px;
}
.login-title {
font-size: 24px;
font-weight: 700;
color: var(--el-text-color-primary);
margin: 0 0 8px;
}
.login-subtitle {
font-size: 14px;
color: var(--el-text-color-secondary);
margin: 0;
}
.login-btn {
width: 100%;
}
@media (max-width: 480px) {
.login-card {
padding: 24px;
}
}
</style>