first commit
This commit is contained in:
272
src/pages/auth/Register.vue
Normal file
272
src/pages/auth/Register.vue
Normal file
@@ -0,0 +1,272 @@
|
||||
<template>
|
||||
<div class="w-full auth-fade-in">
|
||||
<!-- 标题 -->
|
||||
<div class="text-center mb-8">
|
||||
<h2 class="auth-title">创建账号</h2>
|
||||
<p class="auth-subtitle">请填写以下信息完成注册</p>
|
||||
</div>
|
||||
|
||||
<form class="space-y-4" @submit.prevent="onRegister">
|
||||
<!-- 手机号输入 -->
|
||||
<div>
|
||||
<label class="auth-label">手机号</label>
|
||||
<el-input
|
||||
v-model="form.phone"
|
||||
name="register-phone"
|
||||
placeholder="请输入手机号"
|
||||
size="large"
|
||||
clearable
|
||||
maxlength="11"
|
||||
:disabled="loading"
|
||||
class="auth-input"
|
||||
>
|
||||
<template #prefix>
|
||||
<svg class="w-4 h-4 text-gray-400" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path
|
||||
d="M2 3a1 1 0 011-1h2.153a1 1 0 01.986.836l.74 4.435a1 1 0 01-.54 1.06l-1.548.773a11.037 11.037 0 006.105 6.105l.774-1.548a1 1 0 011.059-.54l4.435.74a1 1 0 01.836.986V17a1 1 0 01-1 1h-2C7.82 18 2 12.18 2 5V3z"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
</el-input>
|
||||
</div>
|
||||
|
||||
<!-- 验证码输入 -->
|
||||
<div>
|
||||
<label class="auth-label">验证码</label>
|
||||
<div class="flex gap-3">
|
||||
<el-input
|
||||
v-model="form.code"
|
||||
name="register-code"
|
||||
placeholder="请输入验证码"
|
||||
size="large"
|
||||
maxlength="6"
|
||||
:disabled="loading"
|
||||
class="auth-input"
|
||||
>
|
||||
<template #prefix>
|
||||
<svg class="w-4 h-4 text-gray-400" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M18 8A6 6 0 006 8c0 3.314-4.03 6-6 6s6 2.686 6 6a6 6 0 0012 0c0-3.314 4.03-6 6-6s-6-2.686-6-6z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
</el-input>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="large"
|
||||
:disabled="!canSendCode || loading"
|
||||
@click="sendCode"
|
||||
:loading="sendingCode"
|
||||
class="auth-button !px-6 !min-w-[120px]"
|
||||
>
|
||||
{{ countdown > 0 ? `${countdown}s` : '获取验证码' }}
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 密码输入 -->
|
||||
<div>
|
||||
<label class="auth-label">设置密码</label>
|
||||
<el-input
|
||||
v-model="form.password"
|
||||
name="register-password"
|
||||
type="password"
|
||||
placeholder="请设置密码(至少6位)"
|
||||
size="large"
|
||||
show-password
|
||||
:disabled="loading"
|
||||
class="auth-input"
|
||||
>
|
||||
<template #prefix>
|
||||
<svg class="w-4 h-4 text-gray-400" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M5 9V7a5 5 0 0110 0v2a2 2 0 012 2v5a2 2 0 01-2 2H5a2 2 0 01-2-2v-5a2 2 0 012-2zm8-2v2H7V7a3 3 0 016 0z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
</el-input>
|
||||
</div>
|
||||
|
||||
<!-- 确认密码输入 -->
|
||||
<div>
|
||||
<label class="auth-label">确认密码</label>
|
||||
<el-input
|
||||
v-model="form.confirmPassword"
|
||||
name="register-confirm-password"
|
||||
type="password"
|
||||
placeholder="请再次输入密码"
|
||||
size="large"
|
||||
show-password
|
||||
:disabled="loading"
|
||||
class="auth-input"
|
||||
>
|
||||
<template #prefix>
|
||||
<svg class="w-4 h-4 text-gray-400" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M5 9V7a5 5 0 0110 0v2a2 2 0 012 2v5a2 2 0 01-2 2H5a2 2 0 01-2-2v-5a2 2 0 012-2zm8-2v2H7V7a3 3 0 016 0z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
</el-input>
|
||||
</div>
|
||||
|
||||
<!-- 操作链接 -->
|
||||
<div class="text-center py-2">
|
||||
<router-link to="/auth/login" class="auth-link text-sm"> 已有账号?去登录 </router-link>
|
||||
</div>
|
||||
|
||||
<!-- 注册按钮 -->
|
||||
<el-button
|
||||
type="primary"
|
||||
size="large"
|
||||
class="auth-button w-full !h-12 !text-base !font-medium"
|
||||
native-type="submit"
|
||||
:loading="loading"
|
||||
:disabled="!canSubmit"
|
||||
>
|
||||
{{ loading ? '注册中...' : '注册' }}
|
||||
</el-button>
|
||||
</form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="UserRegister">
|
||||
import { useUserStore } from '@/stores/user'
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
const router = useRouter()
|
||||
const userStore = useUserStore()
|
||||
|
||||
// 表单数据
|
||||
const form = ref({
|
||||
phone: '',
|
||||
code: '',
|
||||
password: '',
|
||||
confirmPassword: '',
|
||||
})
|
||||
|
||||
// 状态
|
||||
const loading = ref(false)
|
||||
const sendingCode = ref(false)
|
||||
const countdown = ref(0)
|
||||
let countdownTimer = null
|
||||
|
||||
// 计算属性
|
||||
const canSendCode = computed(() => {
|
||||
return form.value.phone && form.value.phone.length === 11 && countdown.value === 0
|
||||
})
|
||||
|
||||
const canSubmit = computed(() => {
|
||||
return (
|
||||
form.value.phone &&
|
||||
form.value.phone.length === 11 &&
|
||||
form.value.code &&
|
||||
form.value.code.length === 6 &&
|
||||
form.value.password &&
|
||||
form.value.password.length >= 6 &&
|
||||
form.value.confirmPassword &&
|
||||
form.value.confirmPassword === form.value.password
|
||||
)
|
||||
})
|
||||
|
||||
// 发送验证码
|
||||
const sendCode = async () => {
|
||||
if (!canSendCode.value) return
|
||||
|
||||
sendingCode.value = true
|
||||
try {
|
||||
const result = await userStore.sendCode(form.value.phone, 'register')
|
||||
if (result.success) {
|
||||
ElMessage.success('验证码发送成功')
|
||||
startCountdown()
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('验证码发送失败:', error)
|
||||
} finally {
|
||||
sendingCode.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 开始倒计时
|
||||
const startCountdown = () => {
|
||||
countdown.value = 60
|
||||
countdownTimer = setInterval(() => {
|
||||
countdown.value--
|
||||
if (countdown.value <= 0) {
|
||||
clearInterval(countdownTimer)
|
||||
}
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
// 注册
|
||||
const onRegister = async () => {
|
||||
if (!canSubmit.value) return
|
||||
|
||||
if (form.value.password !== form.value.confirmPassword) {
|
||||
ElMessage.error('两次密码不一致')
|
||||
return
|
||||
}
|
||||
|
||||
loading.value = true
|
||||
try {
|
||||
const registerData = {
|
||||
phone: form.value.phone,
|
||||
password: form.value.password,
|
||||
confirmPassword: form.value.confirmPassword,
|
||||
code: form.value.code,
|
||||
}
|
||||
|
||||
const result = await userStore.register(registerData)
|
||||
if (result.success) {
|
||||
ElMessage.success('注册成功,请登录')
|
||||
router.push('/auth/login')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('注册失败:', error)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 组件卸载时清理定时器
|
||||
onUnmounted(() => {
|
||||
if (countdownTimer) {
|
||||
clearInterval(countdownTimer)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 输入框样式优化 */
|
||||
:deep(.el-input__wrapper) {
|
||||
border-radius: 8px !important;
|
||||
transition: all 0.3s ease !important;
|
||||
}
|
||||
|
||||
:deep(.el-input__wrapper:hover) {
|
||||
border-color: #3b82f6 !important;
|
||||
}
|
||||
|
||||
:deep(.el-input__wrapper.is-focus) {
|
||||
border-color: #3b82f6 !important;
|
||||
box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1) !important;
|
||||
}
|
||||
|
||||
/* 按钮样式优化 */
|
||||
:deep(.el-button--primary) {
|
||||
border-radius: 8px !important;
|
||||
font-weight: 500 !important;
|
||||
transition: all 0.3s ease !important;
|
||||
}
|
||||
|
||||
:deep(.el-button--primary:hover) {
|
||||
transform: translateY(-1px) !important;
|
||||
box-shadow: 0 4px 12px rgba(59, 130, 246, 0.3) !important;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user