|
|
|
|
@ -0,0 +1,195 @@
|
|
|
|
|
<template>
|
|
|
|
|
<div class="register-container">
|
|
|
|
|
<div class="register-wrapper">
|
|
|
|
|
<div class="register-card">
|
|
|
|
|
<div class="register-header">
|
|
|
|
|
<h2 class="register-title">用户注册</h2>
|
|
|
|
|
</div>
|
|
|
|
|
<el-form
|
|
|
|
|
ref="registerFormRef"
|
|
|
|
|
:model="registerForm"
|
|
|
|
|
:rules="registerRules"
|
|
|
|
|
class="register-form"
|
|
|
|
|
size="large"
|
|
|
|
|
>
|
|
|
|
|
<el-form-item prop="username">
|
|
|
|
|
<el-input
|
|
|
|
|
v-model="registerForm.username"
|
|
|
|
|
placeholder="请输入用户名"
|
|
|
|
|
:prefix-icon="User"
|
|
|
|
|
:disabled="loading"
|
|
|
|
|
/>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item prop="password">
|
|
|
|
|
<el-input
|
|
|
|
|
v-model="registerForm.password"
|
|
|
|
|
type="password"
|
|
|
|
|
placeholder="请输入密码"
|
|
|
|
|
:prefix-icon="Lock"
|
|
|
|
|
:disabled="loading"
|
|
|
|
|
show-password
|
|
|
|
|
/>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item prop="confirmPassword">
|
|
|
|
|
<el-input
|
|
|
|
|
v-model="registerForm.confirmPassword"
|
|
|
|
|
type="password"
|
|
|
|
|
placeholder="请确认密码"
|
|
|
|
|
:prefix-icon="Lock"
|
|
|
|
|
:disabled="loading"
|
|
|
|
|
show-password
|
|
|
|
|
@keyup.enter="handleRegister"
|
|
|
|
|
/>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item>
|
|
|
|
|
<el-button
|
|
|
|
|
type="primary"
|
|
|
|
|
class="register-btn"
|
|
|
|
|
:loading="loading"
|
|
|
|
|
@click="handleRegister"
|
|
|
|
|
>
|
|
|
|
|
{{ loading ? '注册中...' : '注册' }}
|
|
|
|
|
</el-button>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item>
|
|
|
|
|
<div class="login-link">
|
|
|
|
|
已有账号?<router-link to="/login">立即登录</router-link>
|
|
|
|
|
</div>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-form>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
|
|
import { User, Lock } from '@element-plus/icons-vue'
|
|
|
|
|
import { ElMessage, FormInstance, FormRules } from 'element-plus'
|
|
|
|
|
import { useUserStore } from '@/stores/modules/user'
|
|
|
|
|
import { useRouter } from 'vue-router'
|
|
|
|
|
|
|
|
|
|
const router = useRouter()
|
|
|
|
|
const userStore = useUserStore()
|
|
|
|
|
|
|
|
|
|
const registerFormRef = ref<FormInstance>()
|
|
|
|
|
const loading = ref(false)
|
|
|
|
|
|
|
|
|
|
const registerForm = reactive({
|
|
|
|
|
username: '',
|
|
|
|
|
password: '',
|
|
|
|
|
confirmPassword: ''
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
const validateConfirmPassword = (_rule: any, value: string, callback: any) => {
|
|
|
|
|
if (value !== registerForm.password) {
|
|
|
|
|
callback(new Error('两次输入的密码不一致'))
|
|
|
|
|
} else {
|
|
|
|
|
callback()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const registerRules: FormRules = {
|
|
|
|
|
username: [
|
|
|
|
|
{ required: true, message: '请输入用户名', trigger: 'blur' },
|
|
|
|
|
{ min: 1, max: 50, message: '用户名长度不超过50字符', trigger: 'blur' }
|
|
|
|
|
],
|
|
|
|
|
password: [
|
|
|
|
|
{ required: true, message: '请输入密码', trigger: 'blur' },
|
|
|
|
|
{ min: 6, message: '密码长度不能少于6位', trigger: 'blur' }
|
|
|
|
|
],
|
|
|
|
|
confirmPassword: [
|
|
|
|
|
{ required: true, message: '请确认密码', trigger: 'blur' },
|
|
|
|
|
{ validator: validateConfirmPassword, trigger: 'blur' }
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const handleRegister = async () => {
|
|
|
|
|
if (!registerFormRef.value) return
|
|
|
|
|
|
|
|
|
|
const valid = await registerFormRef.value.validate().catch(() => false)
|
|
|
|
|
if (!valid) return
|
|
|
|
|
|
|
|
|
|
loading.value = true
|
|
|
|
|
try {
|
|
|
|
|
await userStore.register({
|
|
|
|
|
username: registerForm.username,
|
|
|
|
|
password: registerForm.password
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
ElMessage.success('注册成功,请登录')
|
|
|
|
|
router.push('/login')
|
|
|
|
|
} catch (error: any) {
|
|
|
|
|
ElMessage.error(error?.response?.data?.message || error?.message || '注册失败')
|
|
|
|
|
} finally {
|
|
|
|
|
loading.value = false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
|
.register-container {
|
|
|
|
|
width: 100vw;
|
|
|
|
|
height: 100vh;
|
|
|
|
|
background: linear-gradient(135deg, #1e3a5f 0%, #0d2137 100%);
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.register-wrapper {
|
|
|
|
|
width: 100%;
|
|
|
|
|
max-width: 400px;
|
|
|
|
|
padding: 20px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.register-card {
|
|
|
|
|
background: #fff;
|
|
|
|
|
border-radius: 12px;
|
|
|
|
|
padding: 40px;
|
|
|
|
|
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.register-header {
|
|
|
|
|
text-align: center;
|
|
|
|
|
margin-bottom: 30px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.register-title {
|
|
|
|
|
font-size: 24px;
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
color: #333;
|
|
|
|
|
margin: 0;
|
|
|
|
|
padding-bottom: 10px;
|
|
|
|
|
border-bottom: 3px solid #1e3a5f;
|
|
|
|
|
display: inline-block;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.register-form {
|
|
|
|
|
.el-form-item {
|
|
|
|
|
margin-bottom: 20px;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.register-btn {
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: 44px;
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.login-link {
|
|
|
|
|
width: 100%;
|
|
|
|
|
text-align: center;
|
|
|
|
|
color: #666;
|
|
|
|
|
|
|
|
|
|
a {
|
|
|
|
|
color: #1e3a5f;
|
|
|
|
|
text-decoration: none;
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
|
|
|
|
&:hover {
|
|
|
|
|
text-decoration: underline;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</style>
|