blob: 8ab8577cd9d55a21fa61371253cffc2d50f411b9 [file] [log] [blame]
Xing Jinwenff16b1e2025-06-05 00:29:26 +08001<template>
2 <div class="login-page">
3 <!-- 背景装饰 -->
4 <div class="bg-decoration">
5 <div class="shape shape-1"></div>
6 <div class="shape shape-2"></div>
7 <div class="shape shape-3"></div>
8 </div>
9
10 <!-- 登录表单容器 -->
11 <div class="login-container">
12 <div class="login-card">
13 <!-- 头部信息 -->
14 <div class="login-header">
15 <div class="logo">
16 <el-icon size="48" color="#667eea"><Operation /></el-icon>
17 </div>
18 <h1 class="title">PT Tracker</h1>
19 <p class="subtitle">私有种子分享社区</p>
20 </div>
21
22 <!-- 登录表单 -->
23 <el-form
24 ref="loginFormRef"
25 :model="loginForm"
26 :rules="loginRules"
27 class="login-form"
28 size="large"
29 >
30 <el-form-item prop="user">
31 <el-input
32 v-model="loginForm.user"
33 placeholder="请输入用户名或邮箱"
34 clearable
35 :prefix-icon="User"
36 @keyup.enter="handleLogin"
37 />
38 </el-form-item>
39
40 <el-form-item prop="password">
41 <el-input
42 v-model="loginForm.password"
43 type="password"
44 placeholder="请输入密码"
45 show-password
46 :prefix-icon="Lock"
47 @keyup.enter="handleLogin"
48 />
49 </el-form-item>
50
51 <el-form-item>
52 <div class="login-options">
53 <el-checkbox v-model="rememberMe">记住登录</el-checkbox>
54 <el-link type="primary" :underline="false">忘记密码?</el-link>
55 </div>
56 </el-form-item>
57
58 <el-form-item>
59 <el-button
60 type="primary"
61 :loading="loginLoading"
62 style="width: 100%"
63 @click="handleLogin"
64 >
65 <span v-if="!loginLoading">登录</span>
66 <span v-else>登录中...</span>
67 </el-button>
68 </el-form-item>
69 </el-form>
70
71 <!-- 底部链接 -->
72 <div class="login-footer">
73 <span class="footer-text">还没有账号?</span>
74 <el-link
75 type="primary"
76 :underline="false"
77 @click="$router.push('/register')"
78 >
79 立即注册
80 </el-link>
81 </div>
82 </div>
83 </div>
84 </div>
85</template>
86
87<script>
88import { ref, reactive, computed } from 'vue'
89import { useRouter } from 'vue-router'
90import { useStore } from 'vuex'
91import { ElMessage } from 'element-plus'
92import { User, Lock, Operation } from '@element-plus/icons-vue'
93
94export default {
95 name: 'LoginView',
96 components: {
97 Operation
98 },
99 setup() {
100 const router = useRouter()
101 const store = useStore()
102 const loginFormRef = ref()
103 const rememberMe = ref(false)
104
105 // 安全地从store获取登录加载状态,添加防护检查
106 const loginLoading = computed(() => {
107 try {
108 return store?.getters?.['auth/loginLoading'] || false
109 } catch (error) {
110 console.warn('获取 loginLoading 状态失败:', error)
111 return false
112 }
113 })
114
115 // 表单数据
116 const loginForm = reactive({
117 user: '',
118 password: ''
119 })
120
121 // 验证规则
122 const loginRules = {
123 user: [
124 { required: true, message: '请输入用户名或邮箱', trigger: 'blur' },
125 { min: 3, message: '用户名至少3个字符', trigger: 'blur' }
126 ],
127 password: [
128 { required: true, message: '请输入密码', trigger: 'blur' },
129 { min: 6, message: '密码至少6个字符', trigger: 'blur' }
130 ]
131 }
132
133 // 登录处理
134 const handleLogin = async () => {
135 try {
136 // 表单验证
137 if (!loginFormRef.value) {
138 ElMessage.error('表单未准备就绪')
139 return
140 }
141
142 const valid = await loginFormRef.value.validate()
143 if (!valid) return
144
145 // 检查 store 是否可用
146 if (!store) {
147 ElMessage.error('系统初始化失败,请刷新页面重试')
148 return
149 }
150
151 // 调用store的登录action
152 await store.dispatch('auth/login', {
153 user: loginForm.user,
154 password: loginForm.password
155 })
156
157 // 如果选择记住登录,设置localStorage标记
158 if (rememberMe.value) {
159 localStorage.setItem('rememberLogin', 'true')
160 }
161
162 // 登录成功,跳转到首页
163 router.push('/home')
164
165 } catch (error) {
166 console.error('登录失败:', error)
167 ElMessage.error(error.message || '登录失败,请重试')
168 }
169 }
170
171 return {
172 loginFormRef,
173 loginForm,
174 loginRules,
175 loginLoading,
176 rememberMe,
177 handleLogin,
178 User,
179 Lock
180 }
181 }
182}
183</script>