From a3716f72066d25d745f4d5103ff23a553c3e102b Mon Sep 17 00:00:00 2001 From: wayne <wayne8692wayne8692@gmail.com> Date: 星期四, 17 二月 2022 11:41:19 +0800 Subject: [PATCH] Merge branch 'sit' into uat --- PAMapp/pages/login/index.vue | 462 ++++++++++++++++++++++++++++----------------------------- 1 files changed, 227 insertions(+), 235 deletions(-) diff --git a/PAMapp/pages/login/index.vue b/PAMapp/pages/login/index.vue index 863d242..2aacaec 100644 --- a/PAMapp/pages/login/index.vue +++ b/PAMapp/pages/login/index.vue @@ -64,7 +64,7 @@ <el-row type="flex" justify="space-between"> <div class="mdTxt">頛詨撽�Ⅳ</div> <div class="otp-count-timer"> - {{phoneCounter}} + {{counterTime(otpCounterSec)}} </div> </el-row> @@ -115,7 +115,7 @@ <el-row type="flex" justify="space-between"> <div class="mdTxt">頛詨撽�Ⅳ</div> <div class="otp-count-timer"> - {{emailOtpCounter}} + {{counterTime(emailCounterSec)}} </div> </el-row> @@ -171,7 +171,7 @@ :isOpen.sync="registerDialogVisible" :dialogWidth="'90%'" class="pam-register-dialog" - @closePopUp="isReadContract = false" + @closePopUp="isReadContract = false;agreeContract = false" > <div class="subTitle text--center mb-20">甇∟�雿輻��</div> <el-row> @@ -197,8 +197,7 @@ @scroll="detectContractReadStatus"> <h3>����犖鞈��鈭��</h3> <p class="mt-10"> - �摰�犖鞈��風瘜��������犖鞈���������� - �銝����� + �摰�犖鞈��風瘜��������犖鞈���������銝����� <p> <p class="mt-10"> @@ -217,13 +216,11 @@ </p> <p class="mt-10"> - �������������平���暑�������銝剛瘞���������犖鞈� - ���� + �������������平���暑�������銝剛瘞���������犖鞈��� </p> <p class="mt-10"> - 鈭���������摰���甈∩誑憭�璆凋�撱��恐撠����誑��隞 - ���������銋����嚗�������犖鞈��� + 鈭���������摰���甈∩誑憭�璆凋�撱��恐撠����誑��隞���������銋����嚗�������犖鞈��� </p> <p class="mt-10"> @@ -338,17 +335,29 @@ <script lang="ts"> 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'; +import { OtpErrorCode } from '~/shared/models/enum/otpErrorCode'; +import { Role } from '~/shared/models/enum/Role'; +import { LoginRequest } from '~/shared/models/loginRequest.model'; +import { LoginVerify } from '~/shared/models/loginVerify.model'; +import { OtpInfo } from '~/shared/models/otpInfo.model'; +import { RegisterInfo } from '~/shared/models/registerInfo'; +import loginService from '~/shared/services/login.service'; +import messageBoxService from '~/shared/services/message-box.service'; +import otpService, { OtpStorageName } from '~/shared/services/otp.service'; const roleStorage = namespace('localStorage'); @Component export default class Login extends Vue { - @roleStorage.Mutation storageIdToken!: (token:string) => void; - @roleStorage.Mutation storageRole!: (role:string) => void; + @roleStorage.Mutation + storageIdToken!: (token:string) => void; + + @roleStorage.Mutation + storageRole!: (role:string) => void; + + @roleStorage.Mutation + storageUserInfo!: (userInfo: RegisterInfo) => void; + @Ref('contract') readonly contract!: any; connectDevice: 'MOBILE' | 'EMAIL' = 'MOBILE'; @@ -356,18 +365,18 @@ phoneNumber = ''; otpCode = ''; onPhoneVerifyStep: 'APPLY_OTP' | 'INPUT_OTP' | 'SUBMIT_OTP' = 'APPLY_OTP'; - otpCounterSec = 900; + otpCounterSec = 300; otpResendCounter = 30; otpInterval: any; - phoneOtpInfo!: OtpInfo; + phoneOtpIndexKey!: string; email = ''; onEmailVerifyResendStatus: 'APPLY_OTP' | 'CAN_RESEND' = 'APPLY_OTP'; - emailCounterSec = 900; + emailCounterSec = 300; emailResendCounter = 30; emailOtpCode = ''; emailResendInterval: any; - emailOtpInfo!: OtpInfo; + emailOtpIndexKey!: string; autoRedirectCounter = 3; autoRedirectInterval: any; @@ -385,100 +394,79 @@ applyAccount_onAction = false; previousPath = ''; + + ///////////////////////////////////////////////////// + + beforeRouteEnter (to, from, next) { + next(vm => { + vm.previousPath = from.path; + }) + } + 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); + this.parsePhoneOtpTimeFromStorage(); + this.parseEmailOtpTimeFromStorage(); + } + + private parsePhoneOtpTimeFromStorage() { + const parsePhoneOtpTime = otpService.parseOtpTime(OtpStorageName.PHONE); + const diffSecs = otpService.diffOtpTime(OtpStorageName.PHONE, this.otpCounterSec); + + if (parsePhoneOtpTime && diffSecs) { + this.otpResendCounter = diffSecs < 30 ? 30 - diffSecs : 0; + this.otpCounterSec -= diffSecs; + this.phoneNumber = parsePhoneOtpTime.phone ? parsePhoneOtpTime.phone : ''; + this.onPhoneVerifyStep = 'INPUT_OTP'; + this.phoneOtpIndexKey = parsePhoneOtpTime.indexKey; + this.startOtpCount('MOBILE'); } } - 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; + private parseEmailOtpTimeFromStorage() { + const parseEmailOtpTime = otpService.parseOtpTime(OtpStorageName.EMAIL); + const diffSecs = otpService.diffOtpTime(OtpStorageName.EMAIL, this.emailCounterSec); + + if (parseEmailOtpTime && diffSecs) { + this.emailResendCounter = diffSecs < 30 ? 30 - diffSecs : 0; + this.emailCounterSec -= diffSecs; + this.email = parseEmailOtpTime.email ? parseEmailOtpTime.email : ''; + this.onEmailVerifyResendStatus = 'CAN_RESEND'; + this.emailOtpIndexKey = parseEmailOtpTime.indexKey; + this.startOtpCount('EMAIL'); } - }; - - 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 = ''; - } + destroyed() { this.removeOtpTime(); + clearInterval(this.otpInterval); + clearInterval(this.emailResendInterval); + clearInterval(this.autoRedirectInterval); } + ////////////////////////////////////////////////////////// + + //////////////////// �� + login() { + const login: LoginVerify = this.setLoginInfo(); + this.removeOtpTime(); + loginService.loginVerify(login).then(res => { + this.storageIdToken(res.id_token); + this.storageRole(Role.USER); + this.phoneSuccessConfirmVisable = true; + this.autoRedirect(); + this.storagePhoneOrEmail(this.setRegisterInfo()); + }).catch(error => { + this.checkHttpErrorStatus(error); + }); + } + + confirmApplySuccess(): void { + this.phoneSuccessConfirmVisable = false; + this.registerSuccessConfirmVisable = false; + this.redirect(); + } + + //////////////////// 閮餃�� applyAccount(): void { if (this.applyAccount_onAction) { return ; @@ -487,8 +475,8 @@ this.applyAccount_onAction = true; const registerInfo = this.setRegisterInfo(); - register(registerInfo).then(res => { - this.storageIdToken(res.data.id_token); + loginService.register(registerInfo).then(res => { + this.storageIdToken(res.id_token); this.storageRole(Role.USER); this.storagePhoneOrEmail(registerInfo); this.autoRedirect(); @@ -497,12 +485,6 @@ this.applyAccount_onAction = false; }); }; - - confirmApplySuccess(): void { - this.phoneSuccessConfirmVisable = false; - this.registerSuccessConfirmVisable = false; - this.redirect(); - } private autoRedirect() { this.autoRedirectInterval = setInterval(() => { @@ -518,120 +500,42 @@ 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; - }) + 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; } + }; - 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; + //////////////////// ���/��/��撽�Ⅳ + + applyOtpVerification(type: string): void { + const isMobile = this.connectDevice === 'MOBILE'; + const loginInfo: LoginRequest = { + loginType: isMobile ? 'SMS' : 'EMAIL', + account: isMobile ? this.phoneNumber : this.email, + } + loginService.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蝟餌絞�隤�'; + messageBoxService.showErrorMessage(errorMsg); } - } - - 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; + type === 'MOBILE' ? this.phoneOtpIndexKey = otpInfo.indexKey : this.emailOtpIndexKey = otpInfo.indexKey; const info = {...this.setRegisterInfo(), time: new Date()} - type === 'MOBILE' ? localStorage.setItem('phoneOtpTime',JSON.stringify(info)) - : localStorage.setItem('emailOtpTime',JSON.stringify(info)); + const storageName = type === 'MOBILE' ? OtpStorageName.PHONE : OtpStorageName.EMAIL; + otpService.setOtpTimeToStorage(storageName, info); } private startOtpSetting(type: string) { @@ -671,41 +575,128 @@ }, 1000) } + 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(); + } + + private resetOtpSetting(type: string) { + if (type === 'MOBILE') { + clearInterval(this.otpInterval); + this.otpResendCounter = 30; + this.otpCounterSec = 300; + } else { + clearInterval(this.emailResendInterval); + this.emailResendCounter = 30; + this.emailCounterSec = 300; + } + } + + counterTime(counterSec) { + let min = Math.floor(counterSec / 60); + let sec = Math.floor(counterSec % 60); + return `${min < 10 ? '0' + min : min}:${sec < 10 ? '0' + sec : sec}`; + } + + ////////////////////////////////////////////////////////////////// + + private checkHttpErrorStatus(error:any):void{ + switch (error.response.status) { + case 401: + const errorMsg = OtpErrorCode[error.response?.data?.detail] ? OtpErrorCode[error.response?.data?.detail]:'OTP蝟餌絞�隤�'; + messageBoxService.showErrorMessage(errorMsg); + break; + case 403: + this.registerDialogVisible = true; + setTimeout(() => { + const isScrollBarNeedless = this.contract.scrollHeight <= this.contract.clientHeight; + if (isScrollBarNeedless) { + this.isReadContract = true; + } + }, 1000); + break; + default: + messageBoxService.showErrorMessage('',error); + break; + } + } + + private storagePhoneOrEmail(registerInfo:RegisterInfo):void{ + const info = {...registerInfo, time: new Date()} + // storageUserInfo!: (userInfo: RegisterInfo) => void; + this.storageUserInfo(info); + // localStorage.setItem('userInfo',JSON.stringify(info)); + } + + private removeOtpTime() { + otpService.removeOtpTimeToStorage(OtpStorageName.PHONE); + otpService.removeOtpTimeToStorage(OtpStorageName.EMAIL); + } + + + private setLoginInfo() { + const isMobile = this.connectDevice === 'MOBILE' + return { + account: isMobile ? this.phoneNumber : this.email, + indexKey: isMobile ? this.phoneOtpIndexKey : this.emailOtpIndexKey, + otpCode: isMobile ? this.otpCode : this.emailOtpCode + } + } + private setRegisterInfo(): RegisterInfo { return this.connectDevice === 'MOBILE' ? { phone: this.phoneNumber, - indexKey: this.phoneOtpInfo.indexKey, + indexKey: this.phoneOtpIndexKey, otpCode: this.otpCode, name: this.name, contactType: 'SMS' } : { email: this.email, - indexKey: this.emailOtpInfo.indexKey, - otpCode: this.otpCode, + indexKey: this.emailOtpIndexKey, + otpCode: this.emailOtpCode, name: this.name, contactType: 'EMAIL' } } - private storagePhoneOrEmail(registerInfo:RegisterInfo):void{ - const info = {...registerInfo, time: new Date()} - localStorage.setItem('userInfo',JSON.stringify(info)); + get isSubmitBtnDisabled(): boolean { + return this.connectDevice === 'MOBILE' + ? (!this.otpCode || !this.phoneNumber || !this.phoneValid || !this.otpCounterSec) + : (!this.emailOtpCode || !this.email || !this.emailValid || !this.emailCounterSec) } - private removeOtpTime() { - localStorage.removeItem('emailOtpTime'); - localStorage.removeItem('phoneOtpTime'); + 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; } - 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 - } + 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; } } </script> @@ -743,10 +734,11 @@ } .pam-register-dialog__contract { - $DEVICE_EXTRA_HEIGHT: 42px; + $DEVICE_EXTRA_HEIGHT: 80px; $ALIGN_PADDING: 60px; - $TOP_CONTENT_HEIGHT: 186px; - $BOTTOM_CONTENT_HEIGHT: 131px; + $TOP_CONTENT_HEIGHT: 211px; + $BOTTOM_CONTENT_HEIGHT: 141px; + // text-align:start; max-height: calc(100vh - $DEVICE_EXTRA_HEIGHT - $ALIGN_PADDING - $TOP_CONTENT_HEIGHT - $BOTTOM_CONTENT_HEIGHT); overflow-y: scroll; border-radius: 6px; -- Gitblit v1.8.0