aigc-h5/src/components/auth/Login.vue

392 lines
11 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div class="loginBox">
<div class="banner">
<h2>您好欢迎使用海兔AIGC</h2>
<p>请输入您的相关信息进行登录</p>
</div>
<ul class="tabBox">
<li :class="{ active: loginType == 'tel' }" @click="loginType = 'tel'"><i class="icon-code"></i>短信验证</li>
<li :class="{ active: loginType == 'email' }" @click="loginType = 'email'"><i class="icon-email"></i>邮箱验证</li>
<li :class="{ active: loginType == 'password' }" @click="loginType = 'password'"><i class="icon-pwd"></i>密码登录
</li>
</ul>
<div class="formBox" v-if="loginType === 'tel'">
<div class="item">
<div class="label">手机号码</div>
<div class="val">
<van-field type="tel" :clearable="true" class="txt" v-model="tel" placeholder="请输入手机号码" />
</div>
</div>
<div class="item">
<div class="label">验证码</div>
<div class="val">
<van-field type="digit" :clearable="true" class="stxt" v-model="msgCode" placeholder="请输入验证码" />
<van-button class="sbtn" type="primary" :disabled="telCountDown !== getCodeTime" @click="getTelCode">{{
telBtnTxt }}</van-button>
</div>
</div>
</div>
<div class="formBox" v-if="loginType === 'email'">
<div class="item">
<div class="label">邮箱</div>
<div class="val">
<van-field :clearable="true" class="txt" v-model="email" placeholder="请输入邮箱" />
</div>
</div>
<div class="item">
<div class="label">验证码</div>
<div class="val">
<van-field :clearable="true" class="stxt" v-model="emailCode" placeholder="请输入验证码" />
<van-button class="sbtn" type="primary" :disabled="emailCountDown !== getCodeTime"
@click="getEmailCode">{{ emailBtnTxt }}</van-button>
</div>
</div>
</div>
<div class="formBox" v-if="loginType === 'password'">
<div class="item">
<div class="label">手机号码/邮箱</div>
<div class="val">
<van-field :clearable="true" class="txt" v-model="account" placeholder="请输入手机号码/邮箱" />
</div>
</div>
<div class="item">
<div class="label">密码</div>
<div class="val">
<van-field type="password" class="pwdInput" v-model="password" placeholder="请输入密码" />
</div>
</div>
</div>
<div class="submitBtn">
<van-button type="primary" @click="onLogin"></van-button>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue';
import { useAuthModal } from '@/stores/authModal';
import { useUserInfo } from '@/stores/userInfo';
import { showToast } from 'vant';
import http from '@/io/http';
import { localCache } from '@/io/cache';
import md5 from 'md5';
const authModal = useAuthModal();
const userInfo = useUserInfo();
const loginType = ref('tel');
const tel = ref();
const msgCode = ref();
const email = ref();
const emailCode = ref();
const account = ref();
const password = ref();
const getCodeTime = 60;
const telBtnTxt = ref('获取验证码');
const telCountDown = ref(getCodeTime);
const telTimer = ref(0);
const emailBtnTxt = ref('获取验证码');
const emailCountDown = ref(getCodeTime);
const emailTimer = ref(0);
const telReg = /^1[3-9]\d{9}$/;
const emailReg = /^[\w\.-]+@[a-zA-Z\d\.-]+\.[a-zA-Z]{2,}$/;
const isGetTelCode = ref(false);
const isGetEmailCode = ref(false);
const getTelCode = () => {
if (!telReg.test(tel.value)) {
showToast('请输入正确的手机号码!');
return false;
}
if(isGetTelCode.value){
return false;
}
isGetTelCode.value = true;
http('/api/sms/phone', { phone: tel.value, type: 'login' }, 'POST').then(res => {
reRenderTelGetcodebtn();
}).catch(err => {
showToast(err.message);
}).finally(()=>{
isGetTelCode.value = false;
});
};
const getEmailCode = () => {
if (!emailReg.test(email.value)) {
showToast('请输入正确的邮箱地址!');
return false;
}
if (isGetEmailCode.value) {
return false;
}
isGetEmailCode.value = true;
http('/api/sms/email', { email: email.value, type: 'login' }).then(res => {
reRenderEmailGetcodebtn();
}).catch(err => {
showToast(err.message);
}).finally(() => {
isGetEmailCode.value = false;
});
};
const reRenderTelGetcodebtn = () => {
let time = --telCountDown.value;
telBtnTxt.value = `${time}s后重新获取`;
if (time == 0) {
clearTimeout(telTimer.value);
telBtnTxt.value = '获取验证码';
telCountDown.value = getCodeTime;
} else {
telTimer.value = setTimeout(reRenderTelGetcodebtn, 1000);
}
}
const reRenderEmailGetcodebtn = () => {
let time = --emailCountDown.value;
emailBtnTxt.value = `${time}s后重新获取`;
if (time == 0) {
clearTimeout(emailTimer.value);
emailBtnTxt.value = '获取验证码';
emailCountDown.value = getCodeTime;
} else {
emailTimer.value = setTimeout(reRenderEmailGetcodebtn, 1000);
}
}
const validate = () => {
if (loginType == 'tel') {
if (!telReg.test(tel.value)) {
showToast('请输入正确的手机号码!');
return false;
}
if (!msgCode.value) {
showToast('请输入短信验证码!');
return false;
}
}
if (loginType == 'email') {
if (!emailReg.test(email.value)) {
showToast('请输入正确的邮箱地址!');
return false;
}
if (!emailCode.value) {
showToast('请输入邮箱验证码!');
return false;
}
}
if (loginType.value == 'password') {
if (!account.value) {
showToast('请输入手机号码或邮箱!');
return false;
}
if (!(telReg.test(account.value) || emailReg.test(account.value))) {
showToast('请输入有效的手机号码或邮箱!');
return false;
}
if (!password.value) {
showToast('请输入密码!');
return false;
}
}
return true;
};
const onLogin = () => {
if (!validate()) {
return false;
}
let formData = {};
switch (loginType.value) {
case 'tel':
formData.username = tel.value;
formData.code = msgCode.value;
break;
case 'email':
formData.username = email.value;
formData.code = emailCode.value;
break;
case 'password':
formData.username = account.value;
formData.password = md5(password.value).toLocaleLowerCase();
break;
}
http('/api/auth/login', formData).then(res => {
let nowTime = Date.now();
let overTime = nowTime + res.data.expires_in * 1000;
let authData = { ...res.data, expires_time: overTime };
localCache.set('auth', authData);
authModal.hideAuthModal();
getUserInfo();
}).catch(err => {
showToast(err.message);
})
};
const getUserInfo = () => {
http('/api/user/profile', {}, 'get').then(res => {
localCache.set('userInfo', res.data);
userInfo.updateUserInfo(res.data);
window.location.reload();
}).catch(err => {
showToast(err.message);
})
};
</script>
<style lang="scss" scoped>
.loginBox {
position: relative;
line-height: 1;
padding: 0 60px 60px 60px;
.banner {
text-align: center;
h2 {
font-size: 30px;
margin-bottom: 10px;
}
p {
line-height: 1.5;
font-size: 23px;
color: #999;
}
}
.tabBox {
height: 50px;
width: 100%;
padding: 30px 0;
box-sizing: content-box;
display: flex;
justify-content: space-between;
align-items: center;
li {
width: 175px;
height: 48px;
border: 1px solid #414548;
opacity: 0.4;
border-radius: 2px;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
font-size: 23px;
&:hover,
&.active {
opacity: 1;
color: #FFF;
border-color: #3662FE;
i.icon-code {
background-image: url('../../assets/images/icon_msg_h.png');
}
i.icon-email {
background-image: url('../../assets/images/icon_email_h.png');
}
i.icon-pwd {
background-image: url('../../assets/images/icon_pwd_h.png');
}
}
i {
display: inline-block;
margin-right: 10px;
background-size: contain;
background-repeat: no-repeat;
background-position: center;
width: 30px;
height: 30px;
&.icon-code {
background-image: url('../../assets/images/icon_msg.png');
}
&.icon-email {
background-image: url('../../assets/images/icon_email.png');
}
&.icon-pwd {
background-image: url('../../assets/images/icon_pwd.png');
}
}
}
}
.formBox {
.item {
margin-top: 15px;
.label {
line-height: 66px;
font-size: 28px;
}
.val {
display: flex;
}
.txt,
.stxt,
.pwdInput {
border: 1px solid rgba($color: #414548, $alpha: 0.4);
border-radius: 2px;
background: none;
color: #FFF;
height: 66px;
padding: 0 10px;
:deep(input) {
background: none;
color: #FFF;
line-height: 66px;
font-size: 23px;
&::placeholder {
color: #999;
}
}
}
:deep(.van-cell:after){
display: none;
}
.sbtn {
width: 400px;
margin-left: 10px;
font-size: 23px;
height: 66px;
&:disabled{
opacity: 1;
color: #FFF;
border: 2px solid #FFF;
background: none;
}
}
}
}
.submitBtn {
margin-top: 65px;
button {
width: 100%;
height: 66px;
font-size: 23px;
}
}
}
</style>