253 lines
6.7 KiB
Vue
253 lines
6.7 KiB
Vue
<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> |