From d671c283604d805d528e42cca6560a1a271278e6 Mon Sep 17 00:00:00 2001
From: Tomas <tomasysh@gmail.com>
Date: 星期五, 26 八月 2022 10:59:34 +0800
Subject: [PATCH] fix: 背景自動執行 regenerateImgOfVerification 引發的畫面卡死問題

---
 PAMapp/pages/login/index.vue |  782 +++++++++++++++++++++++++++++++------------------------
 1 files changed, 443 insertions(+), 339 deletions(-)

diff --git a/PAMapp/pages/login/index.vue b/PAMapp/pages/login/index.vue
index ce2d0f4..6bada8e 100644
--- a/PAMapp/pages/login/index.vue
+++ b/PAMapp/pages/login/index.vue
@@ -9,10 +9,10 @@
             <el-row type="flex" class="pt-30">
               <el-button
                 :class="{ 'active': connectDevice === 'MOBILE'}"
-                @click="connectDevice = 'MOBILE'">����Ⅳ</el-button>
+                @click="connectDevice = 'MOBILE'; regenerateImgOfVerification()">����Ⅳ</el-button>
               <el-button
                 :class="{ 'active': connectDevice === 'EMAIL'}"
-                @click="connectDevice = 'EMAIL'">Email</el-button>
+                @click="connectDevice = 'EMAIL'; regenerateImgOfVerification()">Email</el-button>
             </el-row>
           </div>
 
@@ -58,13 +58,33 @@
             </div>
           </div>
 
+          <div class="pam-paragraph" v-if="(!showPhoneOtpCodeField && !showEmailVerifyField)">
+            <div class="pam-consultant-login__title">
+              <div>�����Ⅳ <span class="text--dark-blue fs-16">(����之撠神)</span></div>
+              <div class="text--primary fs-16 cursor--pointer fix-chrome-click--issue"
+                style="margin-left: 16px"
+                @click="regenerateImgOfVerification">������</div>
+            </div>
+            <div class="pam-consultant-login__verifyBlock mt-10">
+              <div class="w-55">
+                <input type="text"
+                  v-model="verificationCode"
+                  maxlength="4"
+                  class="pam-consultant-login__input">
+              </div>
+              <div class="pam-consultant-login__verifyImg">
+                <img :src="imgSrc" alt="撽�Ⅳ">
+              </div>
+            </div>
+          </div>
+
           <!-- mobile 撽�Ⅳ -->
           <template v-if="connectDevice === 'MOBILE'">
             <div v-show="showPhoneOtpCodeField">
               <el-row type="flex" justify="space-between">
-                  <div class="mdTxt">頛詨撽�Ⅳ</div>
+                  <div class="mdTxt">頛詨 OTP 撽�Ⅳ</div>
                   <div class="otp-count-timer">
-                    {{phoneCounter}}
+                    {{counterTime(otpCounterSec)}}
                   </div>
               </el-row>
 
@@ -75,11 +95,11 @@
                     'is-invalid': !otpCode
                   }"
                   v-model="otpCode"
-                  placeholder="隢撓�撽�Ⅳ"
+                  placeholder="隢撓� OTP 撽�Ⅳ"
                   >
               </el-row>
               <div class="error mt-5 mb-10">
-                  <span v-show="otpCounterSec === 0">撽�Ⅳ撌脤�����撽�Ⅳ</span>
+                  <span v-show="otpCounterSec === 0">OTP 撽�Ⅳ撌脤����� OTP 撽�Ⅳ</span>
               </div>
 
               <el-row>
@@ -88,22 +108,23 @@
                   @click="resentOtp('MOBILE')"
                   icon="icon-arrow"
                 >
-                  ��撽�Ⅳ<span
+                  �� OTP 撽�Ⅳ<span
                     class="pam-field-title__hint pl-5"
                     v-if="otpResendCounter !== 0"
                   >({{ otpResendCounter }})</span>
                 </el-button>
+
               </el-row>
             </div>
 
             <el-row>
               <el-button
                   v-if="onPhoneVerifyStep === 'APPLY_OTP'"
-                  :disabled="!phoneNumber || !phoneValid"
+                  :disabled="!phoneNumber || !phoneValid || verificationCode.length !== 4"
                   @click="applyOtpVerification('MOBILE')"
                   icon="icon-arrow"
                 >
-                  ����Ⅳ
+                  ��� OTP 撽�Ⅳ
                 </el-button>
             </el-row>
 
@@ -113,9 +134,9 @@
           <template v-if="connectDevice === 'EMAIL'">
             <el-row v-show="showEmailVerifyField">
               <el-row type="flex" justify="space-between">
-                  <div class="mdTxt">頛詨撽�Ⅳ</div>
+                  <div class="mdTxt">頛詨 OTP 撽�Ⅳ</div>
                   <div class="otp-count-timer">
-                    {{emailOtpCounter}}
+                    {{counterTime(emailCounterSec)}}
                   </div>
               </el-row>
 
@@ -126,11 +147,11 @@
                     'is-invalid': !emailOtpCode
                   }"
                   v-model="emailOtpCode"
-                  placeholder="隢撓�撽�Ⅳ"
+                  placeholder="隢撓� OTP 撽�Ⅳ"
                   >
               </el-row>
               <div class="error mt-5 mb-10">
-                  <span v-show="emailCounterSec === 0">撽�Ⅳ撌脤�����撽�Ⅳ</span>
+                  <span v-show="emailCounterSec === 0">OTP 撽�Ⅳ撌脤����� OTP 撽�Ⅳ</span>
               </div>
 
               <el-button
@@ -138,25 +159,25 @@
                 icon="icon-arrow"
                 @click="resentOtp('EMAIL')"
               >
-                ��撽�Ⅳ<span
+                �� OTP 撽�Ⅳ<span
                     v-if="emailResendCounter !== 0"
-                    class="pam-field-title__hint pl-5"
+                    class="pam-嚚�field-title__hint pl-5"
                   >({{ emailResendCounter }})</span>
               </el-button>
             </el-row>
 
-            <el-row v-show="!showEmailVerifyField">
+            <el-row>
               <el-button
-                  :disabled="!email || !emailValid"
+                  v-if="onEmailVerifyResendStatus === 'APPLY_OTP'"
+                  :disabled="!email || !emailValid || verificationCode.length !== 4"
                   @click="applyOtpVerification('EMAIL')"
                   icon="icon-arrow"
                 >
-                  ����Ⅳ
+                  ��� OTP 撽�Ⅳ
                 </el-button>
             </el-row>
           </template>
       </div>
-
 
       <el-row type="flex" justify="center" class="pam-login-page__action-bar mt-30">
         <el-button
@@ -168,15 +189,13 @@
         </el-button>
       </el-row>
 
-      <el-dialog
-        title="甇∟�雿輻��"
-        :custom-class="'pam-register-dialog'"
-        :visible.sync="registerDialogVisible"
-        :fullscreen="true"
-        :close-on-click-modal="false"
-        :show-close="false"
-        center>
-        <span>
+      <PopUpFrame
+        :isOpen.sync="registerDialogVisible"
+        :dialogWidth="'90%'"
+        class="pam-register-dialog"
+        @closePopUp="isReadContract = false;agreeContract = false"
+      >
+          <div class="subTitle text--center mb-20">甇∟�雿輻��</div>
           <el-row>
             <input
               class="pam-input"
@@ -194,67 +213,45 @@
           </el-row>
           <el-row class="pt-10">
             <div
+              v-if="registerDialogVisible"
               class="mdTxt pam-register-dialog__contract"
               ref="contract"
               @scroll="detectContractReadStatus">
-              <h3>����犖鞈��鈭��</h3>
+              <h3>靽�犖憯賭��隞賣�������犖鞈��鈭��</h3>
               <p class="mt-10">
-              �摰�犖鞈��風瘜��������犖鞈����������
-              �銝�����
+              靽�犖憯賭��隞賣���嚗�迂��������犖鞈��風瘜�誑銝迂����洵�璇洵鈭��洵�璇洵銝�������蝡臬�銝�����蝡航底�嚗�
               <p>
 
               <p class="mt-10">
-              銝����銝��犖鞈��嚗�����僑�����澈���絞銝�蝺刻���批�璆准����
-              ��蝯⊥撘�(��雿���閰梯�Ⅳ�-MAIL����極雿��)蝑��隞�誑��
-              ���霅��犖銋����
+              銝���犖鞈�������市�瘜����������摰����犖鞈汙銋����澈��Ⅱ隤�
+              鈭箄澈靽 (001)��(040)�����平靘�成閬����鴽日�閬���銋���坐���(059)�����撮鴾��隞�������(069)��祥��恥�蝞∴坐�����(090)�雯鴾瑁頃���隞摮�����(148)�矽��絞閮��弦����(157)�隞�����平�閮��������摰�平���(181)��
               <p>
 
               <p class="mt-10">
-              鈭������犖鞈��風瘜����誘銋�������蝘��風�蝑�����
-              ���������犖鞈���
+              鈭�����犖鞈汙嚗�祕憪�����Ⅳ�摮隞嗡縑蝞勗�隞��撟喳慦�“�����垣閰X����閬������犖鞈���
               <p>
 
               <p class="mt-10">
-              銝���������������������犖鞈���
+              銝��犖鞈汙鴽銋�������情�撘��
+              (銝�)������膩����翵平���敹����成閬��靽������
+              (鈭�)���嚗�犖鞈��撠情���銋����
+              (銝�)撠情嚗������矽�甈����������撟喳�����誨��嚗������蝡舫���“����撅砌��嚗��
+              (���)�撘��瘜成閬����撘��
               </p>
 
               <p class="mt-10">
-              �������������平���暑�������銝剛瘞���������犖鞈�
-              ����
+              ��������洵銝�������蝡臬停���靽����蝡臭��犖鞈汙敺�蝙銋���撘��
+              (銝�)敺���翵蝙銋����
+              �����閰U���閬賣���ˊ蝯西�ˊ���
+              ����隢�����迤��
+              ����隢��迫�����坐����������
+              (鈭�)翵蝙甈��撘����蝡臬�������祥摰X������� 0809-0809-68 銵蝙銝膩甈��(撠������ : �曹� ~ �曹�� 08:00-20:00 ���勗����� 09:00-17:30嚗������曹�-�望24撠��)��
               </p>
 
               <p class="mt-10">
-              鈭���������摰���甈∩誑憭�璆凋�撱��恐撠����誑��隞
-              ���������銋����嚗�������犖鞈���
+              鈭�蝡臬�銵捱摰�����犖鞈����嚗���蝡舀������蒂��撟喳����犖鞈����撌脣���膩鈭������蝡臭���������迤蝣箔�������瘜�蝙��撟喳�脰�“�������垣閰Y�����
               </p>
 
-              <p class="mt-10">
-              ���靘�犖鞈��風瘜洵 3 璇���停����犖鞈�����蝙銋���嚗�
-              (銝�) �閰X���閬賬��
-              (鈭�) 隢�ˊ蝯西�ˊ���
-              (銝�) 隢����甇���
-              (���) 隢��迫����������
-              (鈭�) 隢����
-              ����蝙銝膩甈��撠������������������痊隞颯�靘�
-              �犖鞈��風瘜洵 14 璇�������銵雿平鞎餌��
-              </p>
-
-              <p class="mt-10">
-              銝������迤蝣箔��犖鞈�����瘜����摰�����平����
-              </p>
-
-              <p class="mt-10">
-              �����平���閬���隞�������犖鞈����������銋痊��
-              </p>
-
-              <p class="mt-10">
-              銋��閫�甇支����蝚血��犖鞈��風瘜����������������迨���
-              ��嚗�敺��撽��
-              �犖鞈�������
-              銝��鈭箏歇�����眼���膩��鈭���
-              鈭�鈭箏��眼����������鈭箔��犖鞈��誑��隞����������
-              ���������
-              </p>
             </div>
           </el-row>
           <el-row class="pt-30">
@@ -271,23 +268,23 @@
               </label>
             </div>
           </el-row>
-        </span>
-        <span slot="footer" class="dialog-footer">
-          <el-button
-            type="primary"
-            :disabled="!name || !agreeContract || !isReadContract"
-            @click="applyAccount"
-            >撱箇�撣唾��
-          </el-button>
-        </span>
-      </el-dialog>
+          <div class="text--center mt-10">
+            <el-button
+              type="primary"
+              :disabled="!name || !agreeContract || !isReadContract"
+              @click="applyAccount"
+              >撱箇�撣唾��
+            </el-button>
+          </div>
+      </PopUpFrame>
 
       <PopUpFrame class="pam-popUpFrame"
-        :isOpen.sync="emailOtpConfirmVisable">
+        :isOpen.sync="emailOtpConfirmVisable"
+      >
         <div class="pam-popUp-title text--center">撌脣������</div>
         <div class="pam-popUp-title text--center">{{email}}</div>
         <div class="pam-popUp-title text--center">隢��摮隞嗡蒂摰������</div>
-        <div class="pam-popUp-confirm-bolck pam-paragraph">
+        <div class="pam-popUp-confirm-bolck mt-30">
           <div class="text--center">
             <el-button
                 type="primary"
@@ -298,29 +295,37 @@
       </PopUpFrame>
 
       <PopUpFrame class="pam-popUpFrame"
-        :isOpen.sync="registerSuccessConfirmVisable">
+        :isOpen.sync="registerSuccessConfirmVisable"
+        @closePopUp="confirmApplySuccess"
+      >
           <div class="pam-popUp-title text--center">
             甇∟�����������垣閰g�“���誑�����{ connectDevice === 'MOBILE' ? '����Ⅳ' : 'Email'}}���蝜�
           </div>
-          <div class="pam-popUp-confirm-bolck pam-paragraph">
+          <div class="pam-popUp-txt text--center mb-10 mt-5"
+          >�撠�歲��...{{autoRedirectCounter}}蝘�</div>
+          <div class="pam-popUp-confirm-bolck mt-30">
             <div class="text--center">
               <el-button
                   type="primary"
-                  @click="confirmApplySuccess"
+                  @click="registerSuccessConfirmVisable = false"
               >������</el-button>
             </div>
           </div>
       </PopUpFrame>
 
       <PopUpFrame class="pam-popUpFrame"
-        :isOpen.sync="phoneSuccessConfirmVisable">
-          <div class="pam-popUp-title text--center mb-50"
+        :isOpen.sync="phoneSuccessConfirmVisable"
+        @closePopUp="confirmApplySuccess"
+      >
+          <div class="pam-popUp-title text--center"
           >甇∟�������</div>
-          <div class="pam-popUp-confirm-bolck pam-paragraph">
+          <div class="pam-popUp-txt text--center mb-30 mt-5 xsTxt"
+          >�撠�歲��...{{autoRedirectCounter}}蝘�</div>
+          <div class="pam-popUp-confirm-bolck mt-30">
             <div class="text--center">
               <el-button
                   type="primary"
-                  @click="confirmApplySuccess"
+                  @click="phoneSuccessConfirmVisable = false"
               >������</el-button>
             </div>
           </div>
@@ -332,16 +337,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 { 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';
@@ -349,18 +367,24 @@
   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;
+
+  verificationCode = '';
+  imgSrc = '';
+
+  autoRedirectCounter = 3;
+  autoRedirectInterval: any;
 
   name = '';
   agreeContract = false;
@@ -374,17 +398,123 @@
 
   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);
+    this.parsePhoneOtpTimeFromStorage();
+    this.parseEmailOtpTimeFromStorage();
+    this.regenerateImgOfVerification();
+  }
+
+  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');
     }
-    if (parseEmailOtpTime && parseEmailOtpTime.contactType === 'EMAIL') {
-      this.emailDiffTime(parseEmailOtpTime);
+  }
+
+  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');
     }
+  }
+
+  destroyed() {
+    this.removeOtpTime();
+    clearInterval(this.otpInterval);
+    clearInterval(this.emailResendInterval);
+    clearInterval(this.autoRedirectInterval);
+  }
+
+  //////////////////////////////////////////////////////////
+
+  regenerateImgOfVerification(): void {
+    loginService.getImgOfVerification().then( imgOfBase64 => {
+        this.imgSrc = imgOfBase64;
+        this.verificationCode = '';
+      }
+    );
+  };
+
+  //////////////////// ��
+  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 ;
+    }
+
+    this.applyAccount_onAction = true;
+    const registerInfo = this.setRegisterInfo();
+
+    loginService.register(registerInfo).then(res => {
+      this.storageIdToken(res.id_token);
+      this.storageRole(Role.USER);
+      this.storagePhoneOrEmail(registerInfo);
+      this.autoRedirect();
+      this.registerSuccessConfirmVisable = true;
+    }).catch(() => {
+      this.applyAccount_onAction = false;
+    });
+  };
+
+  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));
+    find > -1 ? this.$router.go(-1) : this.$router.push('/');
   }
 
   detectContractReadStatus(event: any): void {
@@ -395,41 +525,7 @@
     }
   };
 
-  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';
@@ -437,159 +533,23 @@
       loginType: isMobile ? 'SMS' : 'EMAIL',
       account: isMobile ? this.phoneNumber : this.email,
     }
-    sendOtp(loginInfo).then(otpInfo => {
+    loginService.sendOtp(loginInfo, this.verificationCode).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);
       }
     });
   };
-
-  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.registerSuccessConfirmVisable = true;
-    }).catch(() => {
-      this.applyAccount_onAction = false;
-    });
-  };
-
-  confirmApplySuccess(): void {
-    this.phoneSuccessConfirmVisable = false;
-    this.registerSuccessConfirmVisable = false;
-    this.$router.go(-1);
-  }
-
-  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.storagePhoneOrEmail(this.setRegisterInfo());
-    }).catch(error => {
-      this.checkHttpErrorStatus(error);
-    });
-  }
-  private checkHttpErrorStatus(error:any):void{
-    switch (error.response.status) {
-        case 401:
-          const errorMsg = error.response.data.detail;
-          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();
-          break;
-      }
-  }
-
-  destroyed() {
-    this.removeOtpTime();
-    clearInterval(this.otpInterval);
-    clearInterval(this.emailResendInterval);
-  }
-
-  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) {
@@ -610,6 +570,9 @@
       this.emailCounterSec -= 1;
       if (this.emailResendCounter !== 0) {
         this.emailResendCounter -= 1;
+        if (this.emailResendCounter === 0) {
+          // this.regenerateImgOfVerification();
+        }
       }
       if (this.emailCounterSec === 0) {
         clearInterval(this.emailResendInterval);
@@ -622,48 +585,141 @@
       this.otpCounterSec -= 1;
       if (this.otpResendCounter !== 0) {
         this.otpResendCounter -= 1;
+        if (this.otpResendCounter === 0) {
+          // this.regenerateImgOfVerification();
+        }
       }
       if (this.otpCounterSec === 0) {
-        clearInterval(this.otpInterval)
+        clearInterval(this.otpInterval);
       }
     }, 1000)
+  }
+
+  resentOtp(type: string) {
+    this.resetOtpSetting(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();
+    this.regenerateImgOfVerification();
+  }
+
+  private resetOtpSetting(type: string) {
+    if (type === 'MOBILE') {
+      clearInterval(this.otpInterval);
+      this.otpResendCounter = 30;
+      this.otpCounterSec = 300;
+      this.onPhoneVerifyStep = 'APPLY_OTP';
+    } else {
+      clearInterval(this.emailResendInterval);
+      this.emailResendCounter = 30;
+      this.emailCounterSec = 300;
+      this.onEmailVerifyResendStatus = 'APPLY_OTP';
+    }
+  }
+
+  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:
+          const defaultErrorMsg = OtpErrorCode[error.response?.data?.title]
+          messageBoxService.showErrorMessage('',defaultErrorMsg);
+          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>
@@ -701,10 +757,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;
@@ -714,18 +771,6 @@
     height: 335px;
   }
 }
-
-  .pam-register-dialog__contract {
-    $DEVICE_EXTRA_HEIGHT: 42px;
-    $ALIGN_PADDING: 60px;
-    $TOP_CONTENT_HEIGHT: 186px;
-    $BOTTOM_CONTENT_HEIGHT: 131px;
-    max-height: calc(100vh - $DEVICE_EXTRA_HEIGHT - $ALIGN_PADDING - $TOP_CONTENT_HEIGHT - $BOTTOM_CONTENT_HEIGHT);
-    overflow-y: scroll;
-    border-radius: 6px;
-    border: 1px solid #707070;
-    padding: 20px;
-  }
 
   .pam-radio {
     color: $PRIMARY_RED;
@@ -739,31 +784,6 @@
     i {
       font-size: 27px;
       padding-right: 5px;
-    }
-  }
-
-  .pam-register-dialog {
-    padding: 30px 20px;
-    display: flex;
-    flex-direction: column;
-    border-radius: 0;
-    &.el-dialog {
-      border-radius: 0;
-    }
-    .el-dialog__header {
-      padding: 0;
-      margin-bottom: 30px;
-      .el-dialog__title {
-        @extend .subTitle;
-      }
-    }
-    .el-dialog__body {
-      flex: 1;
-      padding: 0;
-      margin-bottom: 30px;
-    }
-    .el-dialog__footer {
-      padding: 0 !important;
     }
   }
 
@@ -782,6 +802,12 @@
       font-size: 20px;
       line-height: 27px;
   }
+
+  .pam-popUp-txt {
+    font-size: 18px;
+    color: $MID_GREY;
+  }
+
   .disabled {
     color: #A7A8AA;
   }
@@ -796,4 +822,82 @@
       font-size: 16px;
     }
   }
+    .pam-consultant-login {
+    margin: auto;
+    width: 336px;
+    font-size: 20px;
+    color: $PRIMARY_BLACK;
+
+    &__header {
+      text-align: center;
+      font-size: 24px;
+      font-weight: bold;
+      letter-spacing: 1.2;
+      color: $PRIMARY_BLACK;
+    }
+
+    &__title {
+      display: flex;
+      // justify-content: space-between;
+      align-items: center;
+    }
+
+    &__input {
+      width: 100%;
+      outline: 0;
+      border: 1px solid #CCCCCC;
+      border-radius: 10px;
+      font-size: 20px;
+      height: 50px;
+      padding: 10px 90px 10px 15px;
+      overflow: auto;
+      box-sizing: border-box;
+      -webkit-box-sizing: border-box;
+      -moz-box-sizing: border-box;
+
+      &Icon {
+        position: absolute;
+        display: flex;
+        align-items: center;
+        top: 15px;
+        right: 15px;
+      }
+    }
+
+    &__forgot-password {
+      color: $PRIMARY_RED;
+      text-decoration: none;
+      font-size: 16px;
+    }
+
+    &__verifyBlock {
+      display: flex;
+      // justify-content: space-between;
+    }
+
+    &__verifyImg {
+      margin-left: 8px;
+      width: 126px;
+      height: 50px;
+      border:1px #cccccc solid;
+      img {
+        width: 100%;
+        height: 100%;
+      }
+    }
+
+    &__confirmBlock {
+      display: flex;
+      justify-content: center;
+    }
+
+    &__confirm {
+      color: $PRIMARY_WHITE;
+      width: 80px;
+      height: 50px;
+      border-radius: 30px;
+      border: 1px solid $LIGHT_GREY;
+      background-color: $PRIMARY_RED;
+    }
+  }
 </style>

--
Gitblit v1.9.3