Files
intc-vue3/src/views/register.vue
2026-01-09 00:22:08 +08:00

399 lines
9.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="register">
<div class="register-container">
<div class="register-form-wrapper">
<el-form ref="registerRef" :model="registerForm" :rules="registerRules" class="register-form">
<div class="form-header">
<h3 class="title">智聪科技注册平台</h3>
<p class="subtitle">创建您的账户开启智能之旅</p>
</div>
<el-form-item prop="username">
<el-input v-model="registerForm.username" type="text" size="large" auto-complete="off" placeholder="请输入账号">
<template #prefix><svg-icon icon-class="user" class="el-input__icon input-icon" /></template>
</el-input>
</el-form-item>
<el-form-item prop="password">
<el-input v-model="registerForm.password" type="password" size="large" auto-complete="off" placeholder="请输入密码" @keyup.enter="handleRegister">
<template #prefix><svg-icon icon-class="password" class="el-input__icon input-icon" /></template>
</el-input>
</el-form-item>
<el-form-item prop="confirmPassword">
<el-input
v-model="registerForm.confirmPassword"
type="password"
size="large"
auto-complete="off"
placeholder="请确认密码"
@keyup.enter="handleRegister"
>
<template #prefix><svg-icon icon-class="password" class="el-input__icon input-icon" /></template>
</el-input>
</el-form-item>
<el-form-item prop="code" v-if="captchaEnabled" class="code-item">
<el-input size="large" v-model="registerForm.code" auto-complete="off" placeholder="请输入验证码" @keyup.enter="handleRegister">
<template #prefix><svg-icon icon-class="validCode" class="el-input__icon input-icon" /></template>
</el-input>
<div class="register-code">
<img :src="codeUrl" @click="getCode" class="register-code-img" />
</div>
</el-form-item>
<el-form-item class="submit-item">
<el-button :loading="loading" size="large" type="primary" class="register-btn" @click.prevent="handleRegister">
<span v-if="!loading">立即注册</span>
<span v-else>注册中...</span>
</el-button>
</el-form-item>
<div class="login-link">
<span class="link-text">已有账户</span>
<router-link class="link-type" :to="'/login'">立即登录</router-link>
</div>
</el-form>
</div>
</div>
<!-- 底部 -->
<div class="el-register-footer">
<span>Copyright © 2026 qdintc All Rights Reserved.</span>
</div>
</div>
</template>
<script setup>
import { ElMessageBox } from 'element-plus'
import { getCodeImg, register } from '@/api/login'
const router = useRouter()
const { proxy } = getCurrentInstance()
const registerForm = ref({
username: '',
password: '',
resource: '1',
confirmPassword: '',
code: '',
uuid: ''
})
const equalToPassword = (rule, value, callback) => {
if (registerForm.value.password !== value) {
callback(new Error('两次输入的密码不一致'))
} else {
callback()
}
}
const registerRules = {
username: [
{ required: true, trigger: 'blur', message: '请输入您的账号' },
{ min: 2, max: 20, message: '用户账号长度必须介于 2 和 20 之间', trigger: 'blur' }
],
password: [
{ required: true, trigger: 'blur', message: '请输入您的密码' },
{ min: 5, max: 20, message: '用户密码长度必须介于 5 和 20 之间', trigger: 'blur' }
],
confirmPassword: [
{ required: true, trigger: 'blur', message: '请再次输入您的密码' },
{ required: true, validator: equalToPassword, trigger: 'blur' }
],
code: [{ required: true, trigger: 'change', message: '请输入验证码' }]
}
const codeUrl = ref('')
const loading = ref(false)
const captchaEnabled = ref(true)
function handleRegister() {
registerForm.value.resource = '1'
proxy.$refs.registerRef.validate((valid) => {
if (valid) {
loading.value = true
register(registerForm.value)
.then((res) => {
const username = registerForm.value.username
ElMessageBox.alert("<font color='red'>恭喜你,您的账号 " + username + ' 注册成功!</font>', '系统提示', {
dangerouslyUseHTMLString: true,
type: 'success'
})
.then(() => {
router.push('/login')
})
.catch(() => {})
})
.catch(() => {
loading.value = false
if (captchaEnabled) {
getCode()
}
})
}
})
}
function getCode() {
getCodeImg().then((res) => {
captchaEnabled.value = res.captchaEnabled === undefined ? true : res.captchaEnabled
if (captchaEnabled.value) {
codeUrl.value = 'data:image/gif;base64,' + res.img
registerForm.value.uuid = res.uuid
}
})
}
getCode()
</script>
<style lang="scss" scoped>
.register {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
position: relative;
overflow: hidden;
// 科技感背景动画
&::before {
content: '';
position: absolute;
top: -50%;
left: -50%;
width: 200%;
height: 200%;
background: radial-gradient(circle, rgba(255, 255, 255, 0.1) 1px, transparent 1px);
background-size: 50px 50px;
animation: gridMove 20s linear infinite;
}
}
@keyframes gridMove {
0% {
transform: translate(0, 0);
}
100% {
transform: translate(50px, 50px);
}
}
.register-container {
position: relative;
z-index: 1;
}
.register-form-wrapper {
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(20px);
border-radius: 20px;
padding: 50px 45px;
width: 460px;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3), 0 0 0 1px rgba(255, 255, 255, 0.1);
transition: all 0.3s ease;
&:hover {
transform: translateY(-5px);
box-shadow: 0 25px 70px rgba(0, 0, 0, 0.35), 0 0 0 1px rgba(255, 255, 255, 0.15);
}
}
.form-header {
text-align: center;
margin-bottom: 40px;
.title {
margin: 0;
font-size: 32px;
font-weight: 800;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
letter-spacing: 1px;
}
.subtitle {
margin: 12px 0 0 0;
font-size: 14px;
color: #999;
font-weight: 400;
}
}
.register-form {
:deep(.el-form-item) {
margin-bottom: 24px;
}
:deep(.el-input__wrapper) {
height: 52px;
border-radius: 12px;
border: 2px solid #e8e8e8;
background: #fafafa;
transition: all 0.3s ease;
box-shadow: none;
&:hover {
border-color: #667eea;
background: #ffffff;
}
&.is-focus {
border-color: #667eea;
background: #ffffff;
box-shadow: 0 0 0 4px rgba(102, 126, 234, 0.1);
}
}
:deep(.el-input__inner) {
font-size: 15px;
color: #333;
&::placeholder {
color: #bbb;
font-weight: 400;
}
}
:deep(.el-input__icon) {
font-size: 18px;
color: #999;
}
.input-icon {
width: 18px;
height: 18px;
}
}
// 验证码区域
.code-item {
:deep(.el-form-item__content) {
display: flex;
gap: 12px;
.el-input {
flex: 1;
}
}
}
.register-code {
width: 120px;
height: 52px;
flex-shrink: 0;
.register-code-img {
width: 100%;
height: 100%;
border-radius: 12px;
cursor: pointer;
transition: all 0.3s ease;
border: 2px solid #e8e8e8;
&:hover {
border-color: #667eea;
transform: scale(1.05);
}
}
}
// 提交按钮
.submit-item {
margin-top: 35px;
margin-bottom: 20px;
.register-btn {
width: 100%;
height: 52px;
border-radius: 12px;
font-size: 16px;
font-weight: 600;
letter-spacing: 2px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border: none;
box-shadow: 0 8px 20px rgba(102, 126, 234, 0.35);
transition: all 0.3s ease;
&:hover {
transform: translateY(-2px);
box-shadow: 0 12px 28px rgba(102, 126, 234, 0.5);
}
&:active {
transform: translateY(0);
}
}
}
// 登录链接
.login-link {
text-align: center;
margin-top: 20px;
.link-text {
color: #999;
font-size: 14px;
margin-right: 8px;
}
.link-type {
font-size: 14px;
font-weight: 600;
color: #667eea;
position: relative;
padding-bottom: 2px;
text-decoration: none;
&::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 0;
height: 2px;
background: linear-gradient(90deg, #667eea, #764ba2);
transition: width 0.3s ease;
}
&:hover {
color: #764ba2;
&::after {
width: 100%;
}
}
}
}
// 底部版权
.el-register-footer {
position: fixed;
bottom: 20px;
left: 0;
right: 0;
text-align: center;
color: rgba(255, 255, 255, 0.8);
font-size: 13px;
letter-spacing: 1px;
z-index: 2;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}
// 响应式优化
@media (max-width: 768px) {
.register-form-wrapper {
width: 90%;
padding: 40px 30px;
}
.form-header .title {
font-size: 26px;
}
}
</style>