blob: 8ab8577cd9d55a21fa61371253cffc2d50f411b9 [file] [log] [blame]
<template>
<div class="login-page">
<!-- 背景装饰 -->
<div class="bg-decoration">
<div class="shape shape-1"></div>
<div class="shape shape-2"></div>
<div class="shape shape-3"></div>
</div>
<!-- 登录表单容器 -->
<div class="login-container">
<div class="login-card">
<!-- 头部信息 -->
<div class="login-header">
<div class="logo">
<el-icon size="48" color="#667eea"><Operation /></el-icon>
</div>
<h1 class="title">PT Tracker</h1>
<p class="subtitle">私有种子分享社区</p>
</div>
<!-- 登录表单 -->
<el-form
ref="loginFormRef"
:model="loginForm"
:rules="loginRules"
class="login-form"
size="large"
>
<el-form-item prop="user">
<el-input
v-model="loginForm.user"
placeholder="请输入用户名或邮箱"
clearable
:prefix-icon="User"
@keyup.enter="handleLogin"
/>
</el-form-item>
<el-form-item prop="password">
<el-input
v-model="loginForm.password"
type="password"
placeholder="请输入密码"
show-password
:prefix-icon="Lock"
@keyup.enter="handleLogin"
/>
</el-form-item>
<el-form-item>
<div class="login-options">
<el-checkbox v-model="rememberMe">记住登录</el-checkbox>
<el-link type="primary" :underline="false">忘记密码?</el-link>
</div>
</el-form-item>
<el-form-item>
<el-button
type="primary"
:loading="loginLoading"
style="width: 100%"
@click="handleLogin"
>
<span v-if="!loginLoading">登录</span>
<span v-else>登录中...</span>
</el-button>
</el-form-item>
</el-form>
<!-- 底部链接 -->
<div class="login-footer">
<span class="footer-text">还没有账号?</span>
<el-link
type="primary"
:underline="false"
@click="$router.push('/register')"
>
立即注册
</el-link>
</div>
</div>
</div>
</div>
</template>
<script>
import { ref, reactive, computed } from 'vue'
import { useRouter } from 'vue-router'
import { useStore } from 'vuex'
import { ElMessage } from 'element-plus'
import { User, Lock, Operation } from '@element-plus/icons-vue'
export default {
name: 'LoginView',
components: {
Operation
},
setup() {
const router = useRouter()
const store = useStore()
const loginFormRef = ref()
const rememberMe = ref(false)
// 安全地从store获取登录加载状态,添加防护检查
const loginLoading = computed(() => {
try {
return store?.getters?.['auth/loginLoading'] || false
} catch (error) {
console.warn('获取 loginLoading 状态失败:', error)
return false
}
})
// 表单数据
const loginForm = reactive({
user: '',
password: ''
})
// 验证规则
const loginRules = {
user: [
{ required: true, message: '请输入用户名或邮箱', trigger: 'blur' },
{ min: 3, message: '用户名至少3个字符', trigger: 'blur' }
],
password: [
{ required: true, message: '请输入密码', trigger: 'blur' },
{ min: 6, message: '密码至少6个字符', trigger: 'blur' }
]
}
// 登录处理
const handleLogin = async () => {
try {
// 表单验证
if (!loginFormRef.value) {
ElMessage.error('表单未准备就绪')
return
}
const valid = await loginFormRef.value.validate()
if (!valid) return
// 检查 store 是否可用
if (!store) {
ElMessage.error('系统初始化失败,请刷新页面重试')
return
}
// 调用store的登录action
await store.dispatch('auth/login', {
user: loginForm.user,
password: loginForm.password
})
// 如果选择记住登录,设置localStorage标记
if (rememberMe.value) {
localStorage.setItem('rememberLogin', 'true')
}
// 登录成功,跳转到首页
router.push('/home')
} catch (error) {
console.error('登录失败:', error)
ElMessage.error(error.message || '登录失败,请重试')
}
}
return {
loginFormRef,
loginForm,
loginRules,
loginLoading,
rememberMe,
handleLogin,
User,
Lock
}
}
}
</script>