Files
nl-mall/src/views/login/LoginPage.vue
2025-05-28 12:56:36 +08:00

253 lines
6.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="login-page min-h-screen bg-gradient-to-br from-blue-400 to-purple-600 flex items-center justify-center p-4">
<div class="login-form w-full max-w-md bg-white/95 backdrop-blur-sm p-8 rounded-2xl shadow-2xl">
<!-- 头部 -->
<div class="text-center mb-8">
<div class="flex items-center justify-center mb-4">
<svg class="w-12 h-12 text-red-600" viewBox="0 0 24 24" fill="currentColor">
<path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"></path>
</svg>
</div>
<h1 class="text-3xl font-bold text-gray-800 mb-2">欢迎回来</h1>
<p class="text-gray-600">登录您的淘宝账户</p>
</div>
<!-- 登录表单 -->
<el-form
ref="loginFormRef"
:model="loginForm"
:rules="loginRules"
@submit.prevent="handleLogin"
>
<el-form-item prop="username">
<el-input
v-model="loginForm.username"
placeholder="用户名或手机号"
size="large"
prefix-icon="User"
/>
</el-form-item>
<el-form-item prop="password">
<el-input
v-model="loginForm.password"
type="password"
placeholder="密码"
size="large"
prefix-icon="Lock"
show-password
/>
</el-form-item>
<div class="flex items-center justify-between mb-6">
<el-checkbox v-model="rememberMe">记住我</el-checkbox>
<el-link type="primary" :underline="false">忘记密码</el-link>
</div>
<el-button
type="primary"
size="large"
class="w-full"
:loading="loading"
@click="handleLogin"
>
{{ loading ? '登录中...' : '登录' }}
</el-button>
</el-form>
<!-- 快速登录选项 -->
<div class="mt-6">
<div class="text-center text-sm text-gray-600 mb-4">或者使用以下方式快速登录</div>
<div class="grid grid-cols-3 gap-3">
<el-button
v-for="option in quickLoginOptions"
:key="option.type"
@click="quickLogin(option.type)"
class="quick-login-btn"
>
<div class="text-center">
<div class="text-2xl mb-1">{{ option.icon }}</div>
<div class="text-xs">{{ option.name }}</div>
</div>
</el-button>
</div>
</div>
<!-- 注册链接 -->
<div class="mt-8 text-center">
<span class="text-gray-600">还没有账户</span>
<el-link
type="primary"
:underline="false"
@click="globalState.showRegisterModal()"
class="ml-1"
>
立即注册
</el-link>
</div>
<!-- 返回首页 -->
<div class="mt-4 text-center">
<router-link
to="/"
class="text-gray-500 hover:text-gray-700 text-sm transition"
>
返回首页
</router-link>
</div>
</div>
</div>
</template>
<script setup>
import { ref, reactive, inject, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
const router = useRouter()
const globalState = inject('globalState')
const loginFormRef = ref()
const loading = ref(false)
const rememberMe = ref(false)
const loginForm = reactive({
username: '',
password: ''
})
const loginRules = {
username: [
{ required: true, message: '请输入用户名', trigger: 'blur' }
],
password: [
{ required: true, message: '请输入密码', trigger: 'blur' },
{ min: 6, message: '密码长度不能少于6位', trigger: 'blur' }
]
}
const quickLoginOptions = [
{ type: 'demo', name: '演示账号', icon: '👤' },
{ type: 'admin', name: '管理员', icon: '👑' },
{ type: 'guest', name: '游客模式', icon: '🎯' }
]
const handleLogin = async () => {
if (!loginFormRef.value) return
try {
await loginFormRef.value.validate()
if (!loginForm.username || !loginForm.password) {
ElMessage.error('请输入用户名和密码')
return
}
loading.value = true
// 模拟登录延迟
await new Promise(resolve => setTimeout(resolve, 1000))
// 创建用户数据
const userData = {
id: Date.now(),
username: loginForm.username,
email: loginForm.username + '@example.com',
avatar: 'https://cdn.seovx.com/ha/?mom=302&w=100&h=100',
balance: Math.floor(Math.random() * 10000) + 1000,
joinDate: new Date().toISOString(),
level: 'VIP会员'
}
// 生成token
const token = 'fake_token_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9)
// 保存到localStorage
globalState.updateUser(userData)
localStorage.setItem('userToken', token)
loading.value = false
ElMessage.success('登录成功,正在跳转...')
// 跳转回首页
setTimeout(() => {
router.push('/')
}, 1500)
} catch (error) {
loading.value = false
}
}
const quickLogin = (type) => {
let userData
switch (type) {
case 'demo':
userData = {
id: 10001,
username: '演示用户',
email: 'demo@taobao.com',
avatar: 'https://cdn.seovx.com/ha/?mom=302&w=100&h=100',
balance: 5888.88,
joinDate: '2023-01-01T00:00:00.000Z',
level: 'VIP会员'
}
break
case 'admin':
userData = {
id: 10002,
username: '管理员',
email: 'admin@taobao.com',
avatar: 'https://cdn.seovx.com/ha/?mom=302&w=100&h=100',
balance: 99999.99,
joinDate: '2023-01-01T00:00:00.000Z',
level: '超级VIP'
}
break
case 'guest':
userData = {
id: 10003,
username: '游客用户',
email: 'guest@taobao.com',
avatar: 'https://cdn.seovx.com/ha/?mom=302&w=100&h=100',
balance: 0,
joinDate: new Date().toISOString(),
level: '普通用户'
}
break
}
const token = 'fake_token_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9)
globalState.updateUser(userData)
localStorage.setItem('userToken', token)
ElMessage.success('登录成功,正在跳转...')
setTimeout(() => {
router.push('/')
}, 1500)
}
// 检查是否已经登录
onMounted(() => {
if (globalState?.currentUser) {
ElMessage.success('您已经登录,正在跳转...')
setTimeout(() => {
router.push('/')
}, 1500)
}
})
</script>
<style lang="scss" scoped>
.quick-login-btn {
height: auto;
padding: 12px 8px;
}
.quick-login-btn:hover {
border-color: #ff2222;
color: #ff2222;
}
</style>