From e8241decc705f9db3e46aed7b3a3f8b3188cf820 Mon Sep 17 00:00:00 2001
From: wayne <wayne8692wayne8692@gmail.com>
Date: 星期四, 10 三月 2022 15:46:46 +0800
Subject: [PATCH] Merge branch 'Phase3' into pollex-dev

---
 PAMapp/pages/agentInfo/_agentNo.vue                                                       |   31 +++-------
 PAMapp/components/Client/ClientCard.vue                                                   |    4 
 PAMapp/components/Interview/InterviewMsg.vue                                              |   17 +++++
 PAMapp/store/localStorage.ts                                                              |    3 +
 PAMapp/pages/agentInfo/edit/_agentNo.vue                                                  |    2 
 pamapi/src/main/resources/config/application-uat.yml                                      |    2 
 pamapi/src/main/java/com/pollex/pam/security/provider/EServiceAuthenticationProvider.java |   85 ++++++++++++++++++++++++++++
 pamapi/src/main/java/com/pollex/pam/security/provider/CustomAuthenticationProvider.java   |    1 
 PAMapp/pages/appointment/_appointmentId/index.vue                                         |    6 +-
 pamapi/src/main/java/com/pollex/pam/web/rest/EServiceResource.java                        |    6 ++
 PAMapp/pages/appointment/_appointmentId/close/index.vue                                   |    8 +-
 11 files changed, 132 insertions(+), 33 deletions(-)

diff --git a/PAMapp/components/Client/ClientCard.vue b/PAMapp/components/Client/ClientCard.vue
index 7cbde5d..9f11d09 100644
--- a/PAMapp/components/Client/ClientCard.vue
+++ b/PAMapp/components/Client/ClientCard.vue
@@ -77,12 +77,12 @@
                   v-else-if="client.communicateStatus === contactStatus.CONTACTED">
                   蝯��
                 </div>
-                <div
+                <!-- <div
                   class="invite-msg smTxt_bold"
                   @click.stop="inviteReview"
                   v-else-if="!client.satisfactionScore">
                   ��遛��漲
-                </div>
+                </div> -->
 
                 <div
                     class="date xsTxt text--black"
diff --git a/PAMapp/components/Interview/InterviewMsg.vue b/PAMapp/components/Interview/InterviewMsg.vue
index bc76c75..61aaa8d 100644
--- a/PAMapp/components/Interview/InterviewMsg.vue
+++ b/PAMapp/components/Interview/InterviewMsg.vue
@@ -102,11 +102,12 @@
     }
 
     addInterview() {
+      const message = this.getMessage();
       const appointmentInformation: ToInformAppointment = {
         appointmentId: this.client.id,
         email        : this.client?.email,
         interviewDate: this.interviewTime,
-        message      : this.interviewTxt,
+        message,
         phone        : this.client?.phone,
       };
       appointmentService.informAppointment(appointmentInformation).then((_) => {
@@ -121,6 +122,20 @@
       this.getMyAppointmentList();
     }
 
+    private getMessage(): string {
+      const targetDate = new Date(this.interviewTime);
+      const interviewTime = `${targetDate.getFullYear()}撟�${targetDate.getMonth() + 1}���${targetDate.getDate()}� ${targetDate.getHours()}���${targetDate.getMinutes()}��;
+      let result = '';
+      if(this.loginConsultant.phoneNumber && this.loginConsultant.email) {
+        result = "�憟踝��靽���像����憿批��" + this.loginConsultant.name + "嚗�����������銝膩������蝜�"+"\n" + interviewTime + "\n" +"隞乩����閰梯�Ⅳ/Email嚗�"+"\n" + this.loginConsultant.phoneNumber + "\n" + this.loginConsultant.email + "\n"+"�甇斗���靘選����蝜恬�����"}
+        else if (!this.loginConsultant.phoneNumber && this.loginConsultant.email) {
+            result = "�憟踝��靽���像����憿批��" + this.loginConsultant.name + "嚗�����������銝膩������蝜�"+"\n" + interviewTime + "\n" +"隞乩����mail嚗�"+"\n" + this.loginConsultant.email + "\n"+"�甇斗���靘選����蝜恬�����"
+        } else {
+          result = "�憟踝��靽���像����憿批��" + this.loginConsultant.name + "嚗�����������銝膩������蝜�"+"\n" + interviewTime + "\n" +"隞乩����閰梯�Ⅳ嚗�"+"\n" + this.loginConsultant.phoneNumber + "\n"+"�甇斗���靘選����蝜恬�����"
+        }
+        return result;
+    }
+
     get isBtnDisabled() :Boolean {
       const isFormValid = this.client.phone ? this.interviewTxt && this.interviewTime :this.interviewTxt
       return !isFormValid
diff --git a/PAMapp/pages/agentInfo/_agentNo.vue b/PAMapp/pages/agentInfo/_agentNo.vue
index 05d4d62..972609c 100644
--- a/PAMapp/pages/agentInfo/_agentNo.vue
+++ b/PAMapp/pages/agentInfo/_agentNo.vue
@@ -1,5 +1,5 @@
 <template>
-    <div>
+    <div v-if="!!agentInfo">
       <el-row
         type="flex"
         justify="center">
@@ -110,26 +110,13 @@
         </el-col>
       </el-row> -->
 
-      <!-- <el-row
+      <el-row
         type="flex"
         class="pam-paragraph">
-        <el-col :span="24" class="pam-field">
-          <div class="pam-field__label pam-progress__label">
-            <div>
-              <div class="pam-field__title">
-                <i class="pam-icon icon-thumbs-up"
-                  ></i>隢株岷摨西”� <i class="pl-5 text--primary icon-information" @click="alertFieldInfo('evaluation')"></i>
-              </div>
-            </div>
-            <div class="xsTxt">
-              {{ agentInfo.evaluation }}/50 (餈����/蝝航��)
-            </div>
-          </div>
-          <div class="pam-field__content pam-field-evaluation pt-10">
-            <el-progress :show-text="false" :stroke-width="15" :percentage="agentInfo.evaluation * 2"></el-progress>
-          </div>
-        </el-col>
-      </el-row> -->
+        <UiField icon="thumbs-up" label="隢株岷摨西”�">
+            {{ agentInfo.nearlyMonthAppointmentCount || 0 }} / {{ agentInfo.allAppointmentCount || 0 }} (餈����/蝝航��)
+        </UiField>
+      </el-row>
 
       <div class="consultant-edit-btn">
         <UiField icon="flag" label="皞�◢�">
@@ -273,11 +260,13 @@
   }
 
   get agentName(): string {
-    return `${this.agentInfo.name}(${this.agentInfo.role})`;
+    if (!this.agentInfo) return '';
+    return `${this.agentInfo?.name}(${this.agentInfo?.role})`;
   }
 
   get displayCommunicationStyleList(): string[] {
-    return this.agentInfo.communicationStyle.split('��').filter((item) => item);
+    if (!this.agentInfo) return [];
+    return this.agentInfo?.communicationStyle.split('��').filter((item) => item);
   }
 
 }
diff --git a/PAMapp/pages/agentInfo/edit/_agentNo.vue b/PAMapp/pages/agentInfo/edit/_agentNo.vue
index eb95946..0d961b4 100644
--- a/PAMapp/pages/agentInfo/edit/_agentNo.vue
+++ b/PAMapp/pages/agentInfo/edit/_agentNo.vue
@@ -1,5 +1,5 @@
 <template>
-    <div class="edit-agent-info-page">
+    <div class="edit-agent-info-page" v-if="!!agentInfo">
 
       <el-row
         type="flex"
diff --git a/PAMapp/pages/appointment/_appointmentId/close/index.vue b/PAMapp/pages/appointment/_appointmentId/close/index.vue
index 3fe2dae..222f6b3 100644
--- a/PAMapp/pages/appointment/_appointmentId/close/index.vue
+++ b/PAMapp/pages/appointment/_appointmentId/close/index.vue
@@ -17,7 +17,7 @@
           class="pam-paragraph" style="flex-direction: column">
           <UiField label="頨怠�����/撅�����" :labelSize="20" class="required">
             <input
-              class="appointment-client-detail-close__input"
+              class="appointment-client-detail-close__input mt-10"
               :class="{'is-invalid':!identityIdValid}"
               v-model="appointmentCloseInfo.policyholderIdentityId"
               placeholder="隢撓�"
@@ -33,7 +33,7 @@
           class="pam-paragraph">
           <UiField label="���誨蝣噗lan Code" :labelSize="20" class="required">
             <input
-              class="appointment-client-detail-close__input"
+              class="appointment-client-detail-close__input mt-10"
               v-model="appointmentCloseInfo.planCode"
               placeholder="隢撓�"
               type="text">
@@ -46,6 +46,7 @@
           <UiField label="�脖辣����" :labelSize="20" class="required">
             <DateTimePicker
               :defaultValue="appointmentCloseInfo.policyEntryDate"
+              class="mt-10"
               @changeDateTime="appointmentCloseDate = $event"></DateTimePicker>
           </UiField>
         </el-row>
@@ -56,7 +57,7 @@
           class="pam-paragraph">
           <UiField label="���漱����" :labelSize="20" class="required">
             <UiSelect :closeReason.sync="appointmentCloseInfo.closedReason"
-              :options="appointmentFailReason"/>
+              :options="appointmentFailReason" class="mt-10"/>
           </UiField>
           <input
             v-if="appointmentCloseInfo.closedReason === 'other'
@@ -73,6 +74,7 @@
         class="pam-paragraph">
         <UiField label="��酉" :labelSize="20">
           <el-input
+          class="mt-10"
             type="textarea"
             :rows="3"
             placeholder="隢撓�"
diff --git a/PAMapp/pages/appointment/_appointmentId/index.vue b/PAMapp/pages/appointment/_appointmentId/index.vue
index ec303f0..7b49df1 100644
--- a/PAMapp/pages/appointment/_appointmentId/index.vue
+++ b/PAMapp/pages/appointment/_appointmentId/index.vue
@@ -1,5 +1,5 @@
 <template>
-  <div class="appointment-client-detail-page">
+  <div class="appointment-client-detail-page" v-if="!!appointmentDetail">
     <div class="date-detail">
       <div>{{ appointmentDetail.appointmentDate | formatDate }}����</div>
       <div>{{ appointmentDetail.consultantReadTime | formatDate }}
@@ -55,9 +55,9 @@
         </div>
       </div>
 
-      <div class=" btn-center" v-if="showWhenAppointmentHasClosed">
+      <!-- <div class=" btn-center" v-if="showWhenAppointmentHasClosed">
         <el-button @click="inviteReview">��遛��漲</el-button>
-      </div>
+      </div> -->
 
       <div class="client-detail-action" v-if="showWhenAppointmentHasContacted">
         <el-button @click="closeAppointment" class="desktop-client-detail-action-btn" >蝯��</el-button>
diff --git a/PAMapp/store/localStorage.ts b/PAMapp/store/localStorage.ts
index 6fd79e3..d1fd32c 100644
--- a/PAMapp/store/localStorage.ts
+++ b/PAMapp/store/localStorage.ts
@@ -110,6 +110,9 @@
     localStorage.removeItem('consultant_id');
     localStorage.removeItem('appointment');
     localStorage.removeItem('login_consultant');
+    localStorage.removeItem('notContactAppointmentIdFromMsg');
+    localStorage.removeItem('satisfactionIdFromMsg');
+    localStorage.removeItem('appointmentIdFromMsg');
     this.id_token = localStorage.getItem('id_token');
     this.current_role = localStorage.getItem('current_role');
     this.consultant_id = localStorage.getItem('consultant_id');
diff --git a/pamapi/src/main/java/com/pollex/pam/security/provider/CustomAuthenticationProvider.java b/pamapi/src/main/java/com/pollex/pam/security/provider/CustomAuthenticationProvider.java
index d4cea92..4bbdd6b 100644
--- a/pamapi/src/main/java/com/pollex/pam/security/provider/CustomAuthenticationProvider.java
+++ b/pamapi/src/main/java/com/pollex/pam/security/provider/CustomAuthenticationProvider.java
@@ -1,6 +1,5 @@
 package com.pollex.pam.security.provider;
 
-import com.pollex.pam.business.security.provider.EServiceAuthenticationProvider;
 import com.pollex.pam.config.ApplicationProperties;
 import com.pollex.pam.business.security.token.EServiceAuthenticationToken;
 import com.pollex.pam.security.token.OtpAuthenticationToken;
diff --git a/pamapi/src/main/java/com/pollex/pam/security/provider/EServiceAuthenticationProvider.java b/pamapi/src/main/java/com/pollex/pam/security/provider/EServiceAuthenticationProvider.java
new file mode 100644
index 0000000..f157b02
--- /dev/null
+++ b/pamapi/src/main/java/com/pollex/pam/security/provider/EServiceAuthenticationProvider.java
@@ -0,0 +1,85 @@
+package com.pollex.pam.security.provider;
+
+import com.pollex.pam.business.domain.Consultant;
+import com.pollex.pam.business.enums.ConsultantDetailEnum;
+import com.pollex.pam.business.repository.ConsultantRepository;
+import com.pollex.pam.business.service.EServiceConnectService;
+import com.pollex.pam.business.service.dto.EServiceResponse;
+import com.pollex.pam.business.web.errors.ConsultantDisableException;
+import com.pollex.pam.business.config.AppProperties;
+import com.pollex.pam.business.security.token.EServiceAuthenticationToken;
+import com.pollex.pam.business.web.errors.EServiceErrorException;
+import com.pollex.pam.config.ApplicationProperties;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.*;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import org.springframework.stereotype.Component;
+
+import java.security.GeneralSecurityException;
+import java.util.*;
+
+@Component
+public class EServiceAuthenticationProvider {
+
+    private static final String E_SERVICE_LOGIN_SUCCESS_CODE = "true";
+    private static final Logger log = LoggerFactory.getLogger(EServiceAuthenticationProvider.class);
+
+    @Autowired
+    ApplicationProperties applicationProperties;
+
+    @Autowired
+    ConsultantRepository consultantRepository;
+
+    @Autowired
+    EServiceConnectService eServiceConnectService;
+
+    public Authentication authenticate(EServiceAuthenticationToken authenticationToken) throws AuthenticationException {
+        String account = authenticationToken.getPrincipal();
+        String credentials = authenticationToken.getCredentials();
+
+        if(applicationProperties.isMockLogin()){
+            return getConsultantTokenAndRecordLoginTime(account, credentials);
+        }
+
+        try {
+            ResponseEntity<EServiceResponse> responseEntity = eServiceConnectService.loginByEService(account, credentials);
+            if(HttpStatus.OK.equals(responseEntity.getStatusCode())) {
+                EServiceResponse eServiceResponse = responseEntity.getBody();
+                log.debug("eService response = {}", eServiceResponse);
+
+                if(E_SERVICE_LOGIN_SUCCESS_CODE.equals(eServiceResponse.getIssuccess())){
+                    return getConsultantTokenAndRecordLoginTime(account, credentials);
+                }
+                else {
+                    throw new EServiceErrorException(eServiceResponse.getMsg());
+                }
+            }
+
+            throw new RuntimeException("eService http error!, response http status code = " + responseEntity.getStatusCode());
+        } catch (GeneralSecurityException e) {
+            throw new RuntimeException("General Security SSL error!");
+        }
+    }
+
+    private UsernamePasswordAuthenticationToken getConsultantTokenAndRecordLoginTime(String account, String credential) throws ConsultantDisableException {
+        Consultant consultant = consultantRepository.findOneByAgentNo(account).orElseThrow(() -> new UsernameNotFoundException("閰脤“����蒂銝��慦�像�蝟餌絞銝�"));
+
+        List<GrantedAuthority> grantedAuths = Arrays.asList(new SimpleGrantedAuthority("ROLE_USER"));
+        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(account, credential, grantedAuths);
+
+        Map<String, String> details = new HashMap<>();
+        details.put(ConsultantDetailEnum.ID.getValue(), consultant.getId().toString());
+        details.put(ConsultantDetailEnum.NAME.getValue(), consultant.getName());
+        details.put(ConsultantDetailEnum.AGENT_NO.getValue(), account);
+        authenticationToken.setDetails(details);
+
+        return authenticationToken;
+    }
+}
diff --git a/pamapi/src/main/java/com/pollex/pam/web/rest/EServiceResource.java b/pamapi/src/main/java/com/pollex/pam/web/rest/EServiceResource.java
index c25ca03..06a1eab 100644
--- a/pamapi/src/main/java/com/pollex/pam/web/rest/EServiceResource.java
+++ b/pamapi/src/main/java/com/pollex/pam/web/rest/EServiceResource.java
@@ -1,6 +1,7 @@
 package com.pollex.pam.web.rest;
 
 import com.pollex.pam.business.aop.logging.audit.AuditLoggingInject;
+import com.pollex.pam.business.service.ConsultantService;
 import com.pollex.pam.security.jwt.JWTFilter;
 import com.pollex.pam.security.jwt.TokenProvider;
 import com.pollex.pam.business.security.token.EServiceAuthenticationToken;
@@ -29,6 +30,9 @@
     @Autowired
     TokenProvider tokenProvider;
 
+    @Autowired
+    ConsultantService consultantService;
+
     @AuditLoggingInject(type = CONSULTANT_LOGIN)
     @PostMapping("/authenticate")
     public ResponseEntity<UserJWTController.JWTToken> authorize(@RequestBody EServiceLoginVM eServiceLoginVM) {
@@ -38,7 +42,9 @@
         );
 
         Authentication authentication = authenticationManagerBuilder.getObject().authenticate(authenticationToken);
+        consultantService.updateLoginTime(eServiceLoginVM.getUsername());
         SecurityContextHolder.getContext().setAuthentication(authenticationToken);
+
         String jwt = tokenProvider.createToken(authentication, false);
         HttpHeaders httpHeaders = new HttpHeaders();
         httpHeaders.add(JWTFilter.AUTHORIZATION_HEADER, "Bearer" + jwt);
diff --git a/pamapi/src/main/resources/config/application-uat.yml b/pamapi/src/main/resources/config/application-uat.yml
index e97aa15..d3b767a 100644
--- a/pamapi/src/main/resources/config/application-uat.yml
+++ b/pamapi/src/main/resources/config/application-uat.yml
@@ -117,7 +117,7 @@
   e-service-login-url: https://eserviceuat.pcalife.com.tw/sso/chatbotValidate
   e-service-login-func: ValidateUsrLogin
   e-service-login-sys: epos
-  front-end-domain: https://vtwlifeopensysuat.pru.intranet.asia/pam
+  front-end-domain: https://onlineuat.pcalife.com.tw/pam
   sms:
     send-notify-msg: true
     url: https://vtwlifeopensysuat.pru.intranet.asia/MesgQueueMgmnt/rest/smsSendMsgResource

--
Gitblit v1.8.0