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