blob: 67a262fd988b03807c66c5040e0988c0647d6b8c [file] [log] [blame]
Xing Jinwenff16b1e2025-06-05 00:29:26 +08001<template>
2 <div class="register-page">
3 <div class="bg-decoration">
4 <div class="shape shape-1"></div>
5 <div class="shape shape-2"></div>
6 <div class="shape shape-3"></div>
7 </div>
8
9 <div class="register-container">
10 <div class="register-card">
11 <div class="register-header">
12 <div class="logo">
13 <el-icon size="48" color="#a8edea"><UserFilled /></el-icon>
14 </div>
15 <h1 class="title">加入 PT Tracker</h1>
16 <p class="subtitle">开始你的资源分享之旅</p>
17 </div>
18
19 <!-- 注册表单 -->
20 <el-form
21 ref="registerFormRef"
22 :model="registerForm"
23 :rules="registerRules"
24 class="register-form"
25 size="large"
26 >
27 <el-form-item prop="username">
28 <el-input
29 v-model="registerForm.username"
30 placeholder="请输入用户名"
31 clearable
32 :prefix-icon="User"
33 />
34 </el-form-item>
35
36 <el-form-item prop="email">
37 <el-input
38 v-model="registerForm.email"
39 placeholder="请输入邮箱地址"
40 clearable
41 :prefix-icon="Message"
42 />
43 </el-form-item>
44
45 <el-form-item prop="password">
46 <el-input
47 v-model="registerForm.password"
48 type="password"
49 placeholder="请输入密码"
50 show-password
51 :prefix-icon="Lock"
52 />
53 </el-form-item>
54
55 <el-form-item prop="confirmPassword">
56 <el-input
57 v-model="registerForm.confirmPassword"
58 type="password"
59 placeholder="请确认密码"
60 show-password
61 :prefix-icon="Lock"
62 />
63 </el-form-item>
64
65 <el-form-item prop="agreement">
66 <el-checkbox v-model="registerForm.agreement">
67 我已阅读并同意
68 <el-link type="primary" :underline="false">《用户协议》</el-link>
69
70 <el-link type="primary" :underline="false">《隐私政策》</el-link>
71 </el-checkbox>
72 </el-form-item>
73
74 <el-form-item>
75 <el-button
76 type="primary"
77 :loading="registerLoading"
78 style="width: 100%"
79 @click="handleRegister"
80 >
81 <span v-if="!registerLoading">注册</span>
82 <span v-else>注册中...</span>
83 </el-button>
84 </el-form-item>
85 </el-form>
86
87 <div class="register-footer">
88 <span class="footer-text">已有账号?</span>
89 <el-link
90 type="primary"
91 :underline="false"
92 @click="$router.push('/login')"
93 >
94 立即登录
95 </el-link>
96 </div>
97 </div>
98 </div>
99 </div>
100</template>
101
102<script>
103import { ref, reactive, computed } from 'vue'
104import { useRouter } from 'vue-router'
105import { useStore } from 'vuex'
106import { User, Lock, Message, UserFilled } from '@element-plus/icons-vue'
107
108export default {
109 name: 'RegisterView',
110 components: {
111 UserFilled
112 },
113 setup() {
114 const router = useRouter()
115 const store = useStore()
116 const registerFormRef = ref()
117
118 // 从store获取登录加载状态(注册和登录共用同一个loading状态)
119 const registerLoading = computed(() => store.getters['auth/loginLoading'])
120
121 // 表单数据
122 const registerForm = reactive({
123 username: '',
124 email: '',
125 password: '',
126 confirmPassword: '',
127 agreement: false
128 })
129
130 // 自定义验证规则
131 const validateConfirmPassword = (rule, value, callback) => {
132 if (value === '') {
133 callback(new Error('请再次输入密码'))
134 } else if (value !== registerForm.password) {
135 callback(new Error('两次输入密码不一致'))
136 } else {
137 callback()
138 }
139 }
140
141 const validateAgreement = (rule, value, callback) => {
142 if (!value) {
143 callback(new Error('请先同意用户协议和隐私政策'))
144 } else {
145 callback()
146 }
147 }
148
149 // 验证规则
150 const registerRules = {
151 username: [
152 { required: true, message: '请输入用户名', trigger: 'blur' },
153 { min: 3, max: 20, message: '用户名长度在3到20个字符', trigger: 'blur' },
154 { pattern: /^[a-zA-Z0-9_]+$/, message: '用户名只能包含字母、数字和下划线', trigger: 'blur' }
155 ],
156 email: [
157 { required: true, message: '请输入邮箱地址', trigger: 'blur' },
158 { type: 'email', message: '请输入正确的邮箱格式', trigger: 'blur' }
159 ],
160 password: [
161 { required: true, message: '请输入密码', trigger: 'blur' },
162 { min: 6, max: 20, message: '密码长度在6到20个字符', trigger: 'blur' }
163 ],
164 confirmPassword: [
165 { required: true, validator: validateConfirmPassword, trigger: 'blur' }
166 ],
167 agreement: [
168 { required: true, validator: validateAgreement, trigger: 'change' }
169 ]
170 }
171
172 // 注册处理
173 const handleRegister = async () => {
174 try {
175 // 表单验证
176 const valid = await registerFormRef.value.validate()
177 if (!valid) return
178
179 // 调用store的注册action
180 await store.dispatch('auth/register', {
181 username: registerForm.username,
182 email: registerForm.email,
183 password: registerForm.password
184 })
185
186 // 注册成功,跳转到首页
187 router.push('/home')
188
189 } catch (error) {
190 console.error('注册失败:', error)
191 // 错误信息已经在store中通过ElMessage显示了
192 }
193 }
194
195 return {
196 registerFormRef,
197 registerForm,
198 registerRules,
199 registerLoading,
200 handleRegister,
201 User,
202 Lock,
203 Message
204 }
205 }
206}
207</script>