|
|
|
@ -90,207 +90,184 @@
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
<script setup lang="js" name="UserRegister">
|
|
|
|
|
import { ref, computed, onMounted } from 'vue';
|
|
|
|
|
import request from '@/utils/request';
|
|
|
|
|
import {ElMessage} from 'element-plus'
|
|
|
|
|
|
|
|
|
|
export default {
|
|
|
|
|
name: 'UserRegister',
|
|
|
|
|
setup(props, { emit }) {
|
|
|
|
|
const currentType = ref('username');
|
|
|
|
|
const cooldown = ref(0); //验证码倒计时
|
|
|
|
|
|
|
|
|
|
// 注册方式选项配置
|
|
|
|
|
const registerTypes = [
|
|
|
|
|
{ label: '用户名注册', value: 'username' },
|
|
|
|
|
{ label: '邮箱注册', value: 'email' },
|
|
|
|
|
{ label: '手机注册', value: 'phone' }
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
// 注册表单数据对象
|
|
|
|
|
const registerForm = ref({
|
|
|
|
|
username: '',
|
|
|
|
|
email: '',
|
|
|
|
|
phone: '',
|
|
|
|
|
password: '',
|
|
|
|
|
confirmPassword: '',
|
|
|
|
|
verifyCode: '', //验证码(邮箱/手机)
|
|
|
|
|
captcha: '' //图形验证码
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
//前端验证格式
|
|
|
|
|
const isValidInput = computed(() => {
|
|
|
|
|
const value = registerForm.value[currentType.value]
|
|
|
|
|
if (!value) return false
|
|
|
|
|
import { ElMessage } from 'element-plus';
|
|
|
|
|
|
|
|
|
|
const emit = defineEmits(['toggleForm']);
|
|
|
|
|
|
|
|
|
|
const currentType = ref('username');
|
|
|
|
|
const cooldown = ref(0); // 验证码倒计时
|
|
|
|
|
|
|
|
|
|
// 注册方式选项配置
|
|
|
|
|
const registerTypes = [
|
|
|
|
|
{ label: '用户名注册', value: 'username' },
|
|
|
|
|
{ label: '邮箱注册', value: 'email' },
|
|
|
|
|
{ label: '手机注册', value: 'phone' }
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
// 注册表单数据对象
|
|
|
|
|
const registerForm = ref({
|
|
|
|
|
username: '',
|
|
|
|
|
email: '',
|
|
|
|
|
phone: '',
|
|
|
|
|
password: '',
|
|
|
|
|
confirmPassword: '',
|
|
|
|
|
verifyCode: '', // 验证码(邮箱/手机)
|
|
|
|
|
captcha: '' // 图形验证码
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 前端验证格式
|
|
|
|
|
const isValidInput = computed(() => {
|
|
|
|
|
const value = registerForm.value[currentType.value];
|
|
|
|
|
if (!value) return false;
|
|
|
|
|
switch (currentType.value) {
|
|
|
|
|
case 'email':
|
|
|
|
|
return /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/.test(value);
|
|
|
|
|
case 'phone':
|
|
|
|
|
return /^1[3-9]\d{9}$/.test(value);
|
|
|
|
|
default:
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
switch(currentType.value) {
|
|
|
|
|
case 'email':
|
|
|
|
|
return /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/.test(value)
|
|
|
|
|
case 'phone':
|
|
|
|
|
return /^1[3-9]\d{9}$/.test(value)
|
|
|
|
|
default:
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
//图形验证码URL
|
|
|
|
|
const captchaUrl = ref('/user/captcha');
|
|
|
|
|
|
|
|
|
|
//输入框类型
|
|
|
|
|
const inputType = computed(() => {
|
|
|
|
|
switch(currentType.value) {
|
|
|
|
|
case 'email': return 'email';
|
|
|
|
|
case 'phone': return 'tel';
|
|
|
|
|
default: return 'text';
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
// 图形验证码URL
|
|
|
|
|
const captchaUrl = ref('/user/captcha');
|
|
|
|
|
|
|
|
|
|
//输入框文本
|
|
|
|
|
const placeholder = computed(() => {
|
|
|
|
|
switch(currentType.value) {
|
|
|
|
|
case 'email': return '请输入邮箱';
|
|
|
|
|
case 'phone': return '请输入手机号';
|
|
|
|
|
default: return '请输入用户名';
|
|
|
|
|
}
|
|
|
|
|
// 输入框类型
|
|
|
|
|
const inputType = computed(() => {
|
|
|
|
|
switch (currentType.value) {
|
|
|
|
|
case 'email': return 'email';
|
|
|
|
|
case 'phone': return 'tel';
|
|
|
|
|
default: return 'text';
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 输入框文本
|
|
|
|
|
const placeholder = computed(() => {
|
|
|
|
|
switch (currentType.value) {
|
|
|
|
|
case 'email': return '请输入邮箱';
|
|
|
|
|
case 'phone': return '请输入手机号';
|
|
|
|
|
default: return '请输入用户名';
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 邮箱/手机注册时显示验证码输入框
|
|
|
|
|
const showVerifyCode = computed(() => {
|
|
|
|
|
return ['email', 'phone'].includes(currentType.value);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 发送验证码方法(邮箱/手机注册时使用)
|
|
|
|
|
async function sendCode() {
|
|
|
|
|
if (cooldown.value > 0 || !isValidInput.value) return;
|
|
|
|
|
try {
|
|
|
|
|
// TODO:发送验证码请求
|
|
|
|
|
const response = await request.post(`/user/send-code`, {
|
|
|
|
|
type: currentType.value,
|
|
|
|
|
target: registerForm.value[currentType.value]
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
//邮箱/手机注册时显示验证码输入框
|
|
|
|
|
const showVerifyCode = computed(() => {
|
|
|
|
|
return ['email', 'phone'].includes(currentType.value);
|
|
|
|
|
});
|
|
|
|
|
if (response.success) {
|
|
|
|
|
ElMessage({
|
|
|
|
|
message: '验证码已发送',
|
|
|
|
|
type: 'info'
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 发送验证码方法(邮箱/手机注册时使用)
|
|
|
|
|
async function sendCode() {
|
|
|
|
|
if (cooldown.value > 0 || !isValidInput.value) return;
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
//TODO:发送验证码请求
|
|
|
|
|
const response = await request.post(`/user/send-code`, {
|
|
|
|
|
type: currentType.value,
|
|
|
|
|
target: registerForm.value[currentType.value]
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (response.success) {
|
|
|
|
|
ElMessage({
|
|
|
|
|
message: '验证码已发送',
|
|
|
|
|
type: 'info'
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 开始60秒倒计时
|
|
|
|
|
cooldown.value = 60;
|
|
|
|
|
const timer = setInterval(() => {
|
|
|
|
|
cooldown.value--;
|
|
|
|
|
if (cooldown.value <= 0) {
|
|
|
|
|
clearInterval(timer);
|
|
|
|
|
}
|
|
|
|
|
}, 1000);
|
|
|
|
|
// 开始60秒倒计时
|
|
|
|
|
cooldown.value = 60;
|
|
|
|
|
const timer = setInterval(() => {
|
|
|
|
|
cooldown.value--;
|
|
|
|
|
if (cooldown.value <= 0) {
|
|
|
|
|
clearInterval(timer);
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('发送验证码失败:', error);
|
|
|
|
|
alert('发送验证码失败,请稍后重试');
|
|
|
|
|
}
|
|
|
|
|
}, 1000);
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('发送验证码失败:', error);
|
|
|
|
|
alert('发送验证码失败,请稍后重试');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 刷新图形验证码
|
|
|
|
|
function refreshCaptcha() {
|
|
|
|
|
// 添加时间戳防止缓存
|
|
|
|
|
captchaUrl.value = `/user/captcha?t=${new Date().getTime()}`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 注册
|
|
|
|
|
async function register() {
|
|
|
|
|
try {
|
|
|
|
|
// 校验图形验证码
|
|
|
|
|
const captchaResponse = await request.post('/user/verify-captcha', {
|
|
|
|
|
captcha: registerForm.value.captcha
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 刷新图形验证码
|
|
|
|
|
function refreshCaptcha() {
|
|
|
|
|
// 添加时间戳防止缓存
|
|
|
|
|
captchaUrl.value = `/user/captcha?t=${new Date().getTime()}`;
|
|
|
|
|
if (captchaResponse.code !== 200) {
|
|
|
|
|
ElMessage({
|
|
|
|
|
message: captchaResponse.msg,
|
|
|
|
|
type: 'error',
|
|
|
|
|
duration: 500
|
|
|
|
|
});
|
|
|
|
|
refreshCaptcha();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//TODO:暂时跳过手机/邮箱验证码验证的注册
|
|
|
|
|
//注册
|
|
|
|
|
async function register() {
|
|
|
|
|
try {
|
|
|
|
|
// 校验图形验证码
|
|
|
|
|
const captchaResponse = await request.post('/user/verify-captcha', {
|
|
|
|
|
captcha: registerForm.value.captcha
|
|
|
|
|
// 密码确认校验
|
|
|
|
|
if (registerForm.value.password !== registerForm.value.confirmPassword) {
|
|
|
|
|
ElMessage({
|
|
|
|
|
message: '两次输入的密码不一致',
|
|
|
|
|
type: 'error',
|
|
|
|
|
duration: 500
|
|
|
|
|
});
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 构建注册数据
|
|
|
|
|
const registerData = {
|
|
|
|
|
username: registerForm.value.username,
|
|
|
|
|
password: registerForm.value.password
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (captchaResponse.code !== 200) {
|
|
|
|
|
ElMessage({
|
|
|
|
|
message: captchaResponse.msg,
|
|
|
|
|
type: 'error',
|
|
|
|
|
duration: 500
|
|
|
|
|
});
|
|
|
|
|
refreshCaptcha();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//密码确认校验
|
|
|
|
|
if (registerForm.value.password !== registerForm.value.confirmPassword) {
|
|
|
|
|
ElMessage({
|
|
|
|
|
message: '两次输入的密码不一致',
|
|
|
|
|
type: 'error',
|
|
|
|
|
duration: 500
|
|
|
|
|
});
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 构建注册数据
|
|
|
|
|
const registerData = {
|
|
|
|
|
username: registerForm.value.username,
|
|
|
|
|
password: registerForm.value.password
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 根据注册类型添加对应字段
|
|
|
|
|
switch (currentType.value) {
|
|
|
|
|
case 'email':
|
|
|
|
|
registerData.email = registerForm.value.email;
|
|
|
|
|
break;
|
|
|
|
|
case 'phone':
|
|
|
|
|
registerData.phone = registerForm.value.phone;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const response = await request.post('/user/register', registerData);
|
|
|
|
|
|
|
|
|
|
if (response.code === 200) {
|
|
|
|
|
ElMessage({
|
|
|
|
|
message: '注册成功',
|
|
|
|
|
type: 'success',
|
|
|
|
|
duration: 500
|
|
|
|
|
});
|
|
|
|
|
//触发切换到登录表单
|
|
|
|
|
emit('toggleForm');
|
|
|
|
|
} else {
|
|
|
|
|
ElMessage({
|
|
|
|
|
message: '注册失败,请稍后重试',
|
|
|
|
|
type: 'error',
|
|
|
|
|
duration: 500
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
catch (error) {
|
|
|
|
|
console.error('注册失败:', error);
|
|
|
|
|
alert(error.response?.message || '注册失败,请稍后重试');
|
|
|
|
|
refreshCaptcha();
|
|
|
|
|
}
|
|
|
|
|
// 根据注册类型添加对应字段
|
|
|
|
|
switch (currentType.value) {
|
|
|
|
|
case 'email':
|
|
|
|
|
registerData.email = registerForm.value.email;
|
|
|
|
|
break;
|
|
|
|
|
case 'phone':
|
|
|
|
|
registerData.phone = registerForm.value.phone;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
// 初始化图形验证码
|
|
|
|
|
refreshCaptcha();
|
|
|
|
|
});
|
|
|
|
|
const response = await request.post('/user/register', registerData);
|
|
|
|
|
|
|
|
|
|
// 返回模板需要使用的数据和方法
|
|
|
|
|
return {
|
|
|
|
|
currentType,
|
|
|
|
|
registerTypes,
|
|
|
|
|
registerForm,
|
|
|
|
|
captchaUrl,
|
|
|
|
|
inputType,
|
|
|
|
|
placeholder,
|
|
|
|
|
showVerifyCode,
|
|
|
|
|
cooldown,
|
|
|
|
|
sendCode,
|
|
|
|
|
refreshCaptcha,
|
|
|
|
|
register,
|
|
|
|
|
isValidInput
|
|
|
|
|
};
|
|
|
|
|
if (response.code === 200) {
|
|
|
|
|
ElMessage({
|
|
|
|
|
message: '注册成功',
|
|
|
|
|
type: 'success',
|
|
|
|
|
duration: 500
|
|
|
|
|
});
|
|
|
|
|
// 触发切换到登录表单
|
|
|
|
|
emit('toggleForm');
|
|
|
|
|
} else {
|
|
|
|
|
ElMessage({
|
|
|
|
|
message: '注册失败,请稍后重试',
|
|
|
|
|
type: 'error',
|
|
|
|
|
duration: 500
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (error) {
|
|
|
|
|
console.error('注册失败:', error);
|
|
|
|
|
alert(error.response?.message || '注册失败,请稍后重试');
|
|
|
|
|
refreshCaptcha();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
// 初始化图形验证码
|
|
|
|
|
refreshCaptcha();
|
|
|
|
|
});
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
|