|
import { namespace } from 'nuxt-property-decorator';
|
import { Vue, Component, Ref } from 'vue-property-decorator';
|
import { LoginRequest, LoginVerify, loginVerify, OtpInfo, register, RegisterInfo, sendOtp } from '~/assets/ts/api/consultant';
|
import ErrorMessageBox from '~/assets/ts/errorService';
|
import { OtpErrorCode } from '~/assets/ts/models/enum/otpErrorCode';
|
import { Role } from '~/assets/ts/models/enum/role.enum';
|
|
const roleStorage = namespace('localStorage');
|
|
@Component
|
export default class Login extends Vue {
|
@roleStorage.Mutation storageIdToken!: (token:string) => void;
|
@roleStorage.Mutation storageRole!: (role:string) => void;
|
@Ref('contract') readonly contract!: any;
|
|
connectDevice: 'MOBILE' | 'EMAIL' = 'MOBILE';
|
|
phoneNumber = '';
|
otpCode = '';
|
onPhoneVerifyStep: 'APPLY_OTP' | 'INPUT_OTP' | 'SUBMIT_OTP' = 'APPLY_OTP';
|
otpCounterSec = 900;
|
otpResendCounter = 30;
|
otpInterval: any;
|
phoneOtpInfo!: OtpInfo;
|
|
email = '';
|
onEmailVerifyResendStatus: 'APPLY_OTP' | 'CAN_RESEND' = 'APPLY_OTP';
|
emailCounterSec = 900;
|
emailResendCounter = 30;
|
emailOtpCode = '';
|
emailResendInterval: any;
|
emailOtpInfo!: OtpInfo;
|
|
autoRedirectCounter = 3;
|
autoRedirectInterval: any;
|
|
name = '';
|
agreeContract = false;
|
isReadContract = false;
|
|
phoneSuccessConfirmVisable = false;
|
emailOtpConfirmVisable = false;
|
|
registerDialogVisible = false;
|
registerSuccessConfirmVisable = false;
|
|
applyAccount_onAction = false;
|
|
previousPath = '';
|
mounted() {
|
const phoneOtpTime = localStorage.getItem('phoneOtpTime');
|
const emailOtpTime = localStorage.getItem('emailOtpTime');
|
const parsePhoneOtpTime = phoneOtpTime ? JSON.parse(phoneOtpTime) : '';
|
const parseEmailOtpTime = emailOtpTime ? JSON.parse(emailOtpTime) : '';
|
if (parsePhoneOtpTime && parsePhoneOtpTime.contactType === 'SMS') {
|
this.phoneDiffTime(parsePhoneOtpTime);
|
}
|
if (parseEmailOtpTime && parseEmailOtpTime.contactType === 'EMAIL') {
|
this.emailDiffTime(parseEmailOtpTime);
|
}
|
}
|
|
detectContractReadStatus(event: any): void {
|
const scrollTop = Math.round(event.target.scrollTop);
|
const height = event.target.scrollHeight - event.target.clientHeight;
|
if (Math.floor(scrollTop/10) === (Math.floor(height/10))) {
|
this.isReadContract = true;
|
}
|
};
|
|
get isSubmitBtnDisabled(): boolean {
|
return this.connectDevice === 'MOBILE'
|
? (!this.otpCode || !this.phoneNumber || !this.phoneValid || !this.otpCounterSec)
|
: (!this.emailOtpCode || !this.email || !this.emailValid || !this.emailCounterSec)
|
}
|
|
get phoneCounter() {
|
let min = Math.floor(this.otpCounterSec / 60);
|
let sec = Math.floor(this.otpCounterSec % 60);
|
return `${min < 10 ? '0' + min : min}:${sec < 10 ? '0' + sec : sec}`;
|
}
|
|
get emailOtpCounter() {
|
let min = Math.floor(this.emailCounterSec / 60);
|
let sec = Math.floor(this.emailCounterSec % 60);
|
return `${min < 10 ? '0' + min : min}:${sec < 10 ? '0' + sec : sec}`;
|
}
|
|
get showPhoneOtpCodeField(): boolean {
|
return this.connectDevice === 'MOBILE' && this.onPhoneVerifyStep === 'INPUT_OTP';
|
};
|
|
get showEmailVerifyField(): boolean {
|
return this.connectDevice === 'EMAIL' && this.onEmailVerifyResendStatus === 'CAN_RESEND';
|
};
|
|
get phoneValid() {
|
const rule = /^09[0-9]{8}$/;
|
return this.phoneNumber ? rule.test(this.phoneNumber) : true;
|
}
|
|
get emailValid() {
|
const rule = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;
|
return this.email ? rule.test(this.email) : true;
|
}
|
|
applyOtpVerification(type: string): void {
|
const isMobile = this.connectDevice === 'MOBILE';
|
const loginInfo: LoginRequest = {
|
loginType: isMobile ? 'SMS' : 'EMAIL',
|
account: isMobile ? this.phoneNumber : this.email,
|
}
|
sendOtp(loginInfo).then(otpInfo => {
|
if (otpInfo.success) {
|
this.storageOtpTime(type, otpInfo);
|
this.startOtpSetting(type);
|
this.startOtpCount(type);
|
} else {
|
const errorMsg = OtpErrorCode[otpInfo.failCode] ? OtpErrorCode[otpInfo.failCode]:'OTP系統錯誤';
|
ErrorMessageBox(errorMsg);
|
}
|
});
|
};
|
|
resentOtp(type: string) {
|
this.resetOtpSetting(type);
|
this.applyOtpVerification(type);
|
}
|
|
deleteOtpInfo(type: string) {
|
this.resetOtpSetting(type);
|
if (type === 'MOBILE') {
|
this.onPhoneVerifyStep = 'APPLY_OTP';
|
this.phoneNumber = '';
|
this.otpCode = '';
|
} else {
|
this.onEmailVerifyResendStatus = 'APPLY_OTP';
|
this.email = '';
|
this.emailOtpCode = '';
|
}
|
this.removeOtpTime();
|
}
|
|
applyAccount(): void {
|
if (this.applyAccount_onAction) {
|
return ;
|
}
|
|
this.applyAccount_onAction = true;
|
const registerInfo = this.setRegisterInfo();
|
|
register(registerInfo).then(res => {
|
this.storageIdToken(res.data.id_token);
|
this.storageRole(Role.USER);
|
this.storagePhoneOrEmail(registerInfo);
|
this.autoRedirect();
|
this.registerSuccessConfirmVisable = true;
|
}).catch(() => {
|
this.applyAccount_onAction = false;
|
});
|
};
|
|
confirmApplySuccess(): void {
|
this.phoneSuccessConfirmVisable = false;
|
this.registerSuccessConfirmVisable = false;
|
this.redirect();
|
}
|
|
private autoRedirect() {
|
this.autoRedirectInterval = setInterval(() => {
|
this.autoRedirectCounter -= 1;
|
|
if (this.autoRedirectCounter === 0) {
|
clearInterval(this.autoRedirectInterval);
|
this.redirect();
|
}
|
}, 1000)
|
}
|
|
private redirect() {
|
const backToPrevious = ['questionnaire', 'myConsultantList'];
|
const find = backToPrevious.findIndex(item => this.previousPath.includes(item));
|
console.log(this.previousPath, find, 'redirect');
|
find > -1 ? this.$router.go(-1) : this.$router.push('/');
|
}
|
|
beforeRouteEnter (to, from, next) {
|
next(vm => {
|
console.log(from.path, 'beforeRouteEnter');
|
vm.previousPath = from.path;
|
})
|
}
|
|
login() {
|
const login: LoginVerify = this.setLoginInfo();
|
this.removeOtpTime();
|
loginVerify(login).then(res => {
|
this.storageIdToken(res.data.id_token);
|
this.storageRole(Role.USER);
|
this.phoneSuccessConfirmVisable = true;
|
this.autoRedirect();
|
this.storagePhoneOrEmail(this.setRegisterInfo());
|
}).catch(error => {
|
this.checkHttpErrorStatus(error);
|
});
|
}
|
private checkHttpErrorStatus(error:any):void{
|
switch (error.response.status) {
|
case 401:
|
const errorMsg = OtpErrorCode[error.response?.data?.detail] ? OtpErrorCode[error.response?.data?.detail]:'OTP系統錯誤';
|
ErrorMessageBox(errorMsg);
|
break;
|
case 403:
|
this.registerDialogVisible = true;
|
setTimeout(() => {
|
const isScrollBarNeedless = this.contract.scrollHeight <= this.contract.clientHeight;
|
if (isScrollBarNeedless) {
|
this.isReadContract = true;
|
}
|
}, 1000);
|
break;
|
default:
|
ErrorMessageBox('',error);
|
break;
|
}
|
}
|
|
destroyed() {
|
this.removeOtpTime();
|
clearInterval(this.otpInterval);
|
clearInterval(this.emailResendInterval);
|
clearInterval(this.autoRedirectInterval);
|
}
|
|
private phoneDiffTime(parseOtpTime: any) {
|
const diffSecs = this.calcDiffSecs(parseOtpTime.time);
|
|
if (diffSecs < this.otpCounterSec) {
|
this.otpResendCounter = diffSecs < 30 ? 30 - diffSecs : 0;
|
this.otpCounterSec -= diffSecs;
|
this.phoneNumber = parseOtpTime.phone;
|
this.onPhoneVerifyStep = 'INPUT_OTP';
|
this.phoneOtpInfo = this.setOtpInfo(parseOtpTime);
|
this.startOtpCount('MOBILE');
|
} else {
|
localStorage.removeItem('phoneOtpTime');
|
}
|
}
|
|
private emailDiffTime(parseOtpTime: any) {
|
const diffSecs = this.calcDiffSecs(parseOtpTime.time);
|
|
if (diffSecs < this.emailCounterSec) {
|
this.emailResendCounter = diffSecs < 30 ? 30 - diffSecs : 0;
|
this.emailCounterSec -= diffSecs;
|
this.email = parseOtpTime.email;
|
this.onEmailVerifyResendStatus = 'CAN_RESEND';
|
this.emailOtpInfo = this.setOtpInfo(parseOtpTime);
|
this.startOtpCount('EMAIL');
|
} else {
|
localStorage.removeItem('emailOtpTime');
|
}
|
}
|
|
private calcDiffSecs(parseOtpTime) {
|
const currentTime = new Date().getTime();
|
const storageTime = new Date(parseOtpTime).getTime();
|
return Math.floor((currentTime - storageTime) / 1000);
|
}
|
|
private resetOtpSetting(type: string) {
|
if (type === 'MOBILE') {
|
clearInterval(this.otpInterval);
|
this.otpResendCounter = 30;
|
this.otpCounterSec = 900;
|
} else {
|
clearInterval(this.emailResendInterval);
|
this.emailResendCounter = 30;
|
this.emailCounterSec = 900;
|
}
|
}
|
|
private setOtpInfo(parseOtpTime) {
|
return {
|
indexKey: parseOtpTime.indexKey,
|
success: true,
|
failCode: '',
|
failReason: '',
|
}
|
}
|
|
private storageOtpTime(type: string, otpInfo: OtpInfo) {
|
type === 'MOBILE' ? this.phoneOtpInfo = otpInfo : this.emailOtpInfo = otpInfo;
|
const info = {...this.setRegisterInfo(), time: new Date()}
|
type === 'MOBILE' ? localStorage.setItem('phoneOtpTime',JSON.stringify(info))
|
: localStorage.setItem('emailOtpTime',JSON.stringify(info));
|
}
|
|
private startOtpSetting(type: string) {
|
if (type === 'MOBILE') {
|
this.onPhoneVerifyStep = 'INPUT_OTP';
|
} else {
|
this.onEmailVerifyResendStatus = 'CAN_RESEND';
|
this.emailOtpConfirmVisable = true;
|
}
|
}
|
|
private startOtpCount(type: string) {
|
type === 'MOBILE' ? this.startPhoneCounter() : this.startEmailCounter();;
|
}
|
|
private startEmailCounter() {
|
this.emailResendInterval = setInterval(() => {
|
this.emailCounterSec -= 1;
|
if (this.emailResendCounter !== 0) {
|
this.emailResendCounter -= 1;
|
}
|
if (this.emailCounterSec === 0) {
|
clearInterval(this.emailResendInterval);
|
}
|
}, 1000)
|
}
|
|
private startPhoneCounter() {
|
this.otpInterval = setInterval(() => {
|
this.otpCounterSec -= 1;
|
if (this.otpResendCounter !== 0) {
|
this.otpResendCounter -= 1;
|
}
|
if (this.otpCounterSec === 0) {
|
clearInterval(this.otpInterval)
|
}
|
}, 1000)
|
}
|
|
private setRegisterInfo(): RegisterInfo {
|
return this.connectDevice === 'MOBILE'
|
? {
|
phone: this.phoneNumber,
|
indexKey: this.phoneOtpInfo.indexKey,
|
otpCode: this.otpCode,
|
name: this.name,
|
contactType: 'SMS'
|
}
|
: {
|
email: this.email,
|
indexKey: this.emailOtpInfo.indexKey,
|
otpCode: this.otpCode,
|
name: this.name,
|
contactType: 'EMAIL'
|
}
|
}
|
|
private storagePhoneOrEmail(registerInfo:RegisterInfo):void{
|
const info = {...registerInfo, time: new Date()}
|
localStorage.setItem('userInfo',JSON.stringify(info));
|
}
|
|
private removeOtpTime() {
|
localStorage.removeItem('emailOtpTime');
|
localStorage.removeItem('phoneOtpTime');
|
}
|
|
private setLoginInfo() {
|
const isMobile = this.connectDevice === 'MOBILE'
|
return {
|
account: isMobile ? this.phoneNumber : this.email,
|
indexKey: isMobile ? this.phoneOtpInfo.indexKey : this.emailOtpInfo.indexKey,
|
otpCode: isMobile ? this.otpCode : this.emailOtpCode
|
}
|
}
|
}
|