From 98891d1d1bcaa414f336b9c05ad94d39fe9cb1bc Mon Sep 17 00:00:00 2001
From: Mila <Mila@pollex.com.tw>
Date: 星期一, 29 十一月 2021 15:34:57 +0800
Subject: [PATCH] Merge branch 'master' of https://192.168.0.10:8443/r/pcalife/PAM

---
 PAMapp/pages/login/index.vue                                                      |   57 +++++-
 pamapi/src/main/java/com/pollex/pam/service/mapper/CustomerMapper.java            |   19 ++
 pamapi/src/main/java/com/pollex/pam/domain/Customer.java                          |   30 +--
 pamapi/src/doc/客戶API/更新個人帳號資訊.txt                                                 |   10 +
 pamapi/src/doc/登入API/顧問登入驗證碼流程.txt                                                |   29 +++
 pamapi/src/main/java/com/pollex/pam/security/SecurityUtils.java                   |    5 
 pamapi/src/main/java/com/pollex/pam/config/SecurityConfiguration.java             |    1 
 pamapi/src/main/java/com/pollex/pam/service/dto/CustomerDTO.java                  |   31 +++
 pamapi/src/main/java/com/pollex/pam/web/rest/ConsultantLoginValidateResource.java |   62 +++++++
 pamapi/src/main/java/com/pollex/pam/service/AppointmentService.java               |    3 
 pamapi/src/main/java/com/pollex/pam/service/CustomerService.java                  |   43 ++++-
 pamapi/src/main/java/com/pollex/pam/service/ConsultantService.java                |    6 
 PAMapp/plugins/filters/date.filter.ts                                             |    2 
 pamapi/src/main/java/com/pollex/pam/enums/CustomerDetailEnum.java                 |    6 
 pamapi/src/main/java/com/pollex/pam/service/util/VerifyCodeUtil.java              |   68 ++++++++
 pamapi/src/main/java/com/pollex/pam/web/rest/CustomerInfoResource.java            |   33 ++++
 pamapi/src/main/java/com/pollex/pam/service/CustomerAuthService.java              |   21 +-
 pamapi/src/doc/客戶API/取得個人帳號資訊.txt                                                 |    8 +
 18 files changed, 369 insertions(+), 65 deletions(-)

diff --git a/PAMapp/pages/login/index.vue b/PAMapp/pages/login/index.vue
index 84e02bd..341d3f9 100644
--- a/PAMapp/pages/login/index.vue
+++ b/PAMapp/pages/login/index.vue
@@ -152,7 +152,7 @@
         <el-button
           type="primary"
           v-if="(connectDevice === 'MOBILE' && onPhoneVerifyStep === 'INPUT_OTP') || (connectDevice === 'EMAIL' && onEmailVerifyResendStatus === 'CAN_RESEND')"
-          :disabled="isLoginBtnDisabled"
+          :disabled="isSubmitBtnDisabled"
           @click="login">
           �
         </el-button>
@@ -161,7 +161,7 @@
       <el-dialog
         title="甇∟�雿輻��"
         :custom-class="'pam-register-dialog'"
-        :visible.sync="registerDialogVisable"
+        :visible.sync="registerDialogVisible"
         :fullscreen="true"
         :close-on-click-modal="false"
         :show-close="false"
@@ -185,7 +185,8 @@
           <el-row class="pt-10">
             <div
               class="mdTxt pam-register-dialog__contract"
-              @scroll="detectContructReadStatus">
+              ref="contract"
+              @scroll="detectContractReadStatus">
               <h3>����犖鞈��鈭��</h3>
               <p class="mt-10">
               �摰�犖鞈��風瘜��������犖鞈����������
@@ -248,15 +249,15 @@
           </el-row>
           <el-row class="pt-30">
             <div class="pam-agree-radio">
-              <label for="agreeControct" class="pam-radio"
+              <label for="agreeContract" class="pam-radio"
                 :class="{disabled: !isReadContract}">
                 <input
                   type="radio"
-                  id="agreeControct"
-                  @click="agreeControct = !agreeControct"
+                  id="agreeContract"
+                  @click="agreeContract = !agreeContract"
                   :disabled="!isReadContract"
-                  value="agreeControct">
-                  <i :class="agreeControct ?'icon-checkbox-1': 'icon-checkbox'"></i>����蒂蝜潛��
+                  value="agreeContract">
+                  <i :class="agreeContract ?'icon-checkbox-1': 'icon-checkbox'"></i>����蒂蝜潛��
               </label>
             </div>
           </el-row>
@@ -264,7 +265,7 @@
         <span slot="footer" class="dialog-footer">
           <el-button
             type="primary"
-            :disabled="!name || !agreeControct || !isReadContract"
+            :disabled="!name || !agreeContract || !isReadContract"
             @click="applyAccount"
             >撱箇�撣唾��
           </el-button>
@@ -320,7 +321,7 @@
 
 <script lang="ts">
 import { namespace } from 'nuxt-property-decorator';
-import { Vue, Component } from 'vue-property-decorator';
+import { Vue, Component, Ref } from 'vue-property-decorator';
 import { LoginRequest, LoginVerify, loginVerify, OtpInfo, register, RegisterInfo, sendOtp } from '~/assets/ts/api/consultant';
 import { Role } from '~/assets/ts/models/enum/Role';
 
@@ -330,6 +331,7 @@
 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';
 
@@ -350,13 +352,13 @@
   emailOtpInfo!: OtpInfo;
 
   name = '';
-  agreeControct = false;
+  agreeContract = false;
   isReadContract = false;
 
   phoneSuccessConfirmVisable = false;
   emailOtpConfirmVisable = false;
 
-  registerDialogVisable = false;
+  registerDialogVisible = false;
   registerSuccessConfirmVisable = false;
 
   applyAccount_onAction = false;
@@ -374,13 +376,19 @@
     }
   }
 
-  detectContructReadStatus(event: any): void {
+  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);
@@ -480,7 +488,13 @@
       this.storagePhoneOrEmail(this.setRegisterInfo());
     }).catch(error => {
       if (error.response.status === 401) {
-        this.registerDialogVisable = true;
+        this.registerDialogVisible = true;
+        setTimeout(() => {
+          const isScrollBarNeedless = this.contract.scrollHeight <= this.contract.clientHeight;
+          if (isScrollBarNeedless) {
+            this.isReadContract = true;
+          }
+        }, 1000);
       }
     })
   }
@@ -648,6 +662,21 @@
     }
   }
 
+.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;
+  @include desktop {
+    height: 335px;
+  }
+}
+
   .pam-register-dialog__contract {
     $DEVICE_EXTRA_HEIGHT: 42px;
     $ALIGN_PADDING: 60px;
diff --git a/PAMapp/plugins/filters/date.filter.ts b/PAMapp/plugins/filters/date.filter.ts
index 9a15a4e..069a7af 100644
--- a/PAMapp/plugins/filters/date.filter.ts
+++ b/PAMapp/plugins/filters/date.filter.ts
@@ -24,7 +24,7 @@
     return compareDate.getFullYear() === today.getFullYear();
   };
 
-  const minutes = date.getMinutes() > 10 ?  date.getMinutes() : `0${date.getMinutes()}`;
+  const minutes = date.getMinutes() > 9 ?  date.getMinutes() : `0${date.getMinutes()}`;
 
   if (isThisYear(date)) {
     return isToday(date)
diff --git "a/pamapi/src/doc/\345\256\242\346\210\266API/\345\217\226\345\276\227\345\200\213\344\272\272\345\270\263\350\231\237\350\263\207\350\250\212.txt" "b/pamapi/src/doc/\345\256\242\346\210\266API/\345\217\226\345\276\227\345\200\213\344\272\272\345\270\263\350\231\237\350\263\207\350\250\212.txt"
new file mode 100644
index 0000000..c95a24a
--- /dev/null
+++ "b/pamapi/src/doc/\345\256\242\346\210\266API/\345\217\226\345\276\227\345\200\213\344\272\272\345\270\263\350\231\237\350\263\207\350\250\212.txt"
@@ -0,0 +1,8 @@
+http get: http://localhost:8080/api/customer/info
+
+response body:
+{
+    "email": null,
+    "phone": "0955555555",
+    "name": "test999"
+}
diff --git "a/pamapi/src/doc/\345\256\242\346\210\266API/\346\233\264\346\226\260\345\200\213\344\272\272\345\270\263\350\231\237\350\263\207\350\250\212.txt" "b/pamapi/src/doc/\345\256\242\346\210\266API/\346\233\264\346\226\260\345\200\213\344\272\272\345\270\263\350\231\237\350\263\207\350\250\212.txt"
new file mode 100644
index 0000000..5884854
--- /dev/null
+++ "b/pamapi/src/doc/\345\256\242\346\210\266API/\346\233\264\346\226\260\345\200\213\344\272\272\345\270\263\350\231\237\350\263\207\350\250\212.txt"
@@ -0,0 +1,10 @@
+http put: http://localhost:8080/api/customer/info
+
+request body:
+{
+    "email": null,
+    "phone": "0955555555",
+    "name": "test998"
+}
+
+response http code: 204 (NO_CONTENT)
diff --git "a/pamapi/src/doc/\347\231\273\345\205\245API/\351\241\247\345\225\217\347\231\273\345\205\245\351\251\227\350\255\211\347\242\274\346\265\201\347\250\213.txt" "b/pamapi/src/doc/\347\231\273\345\205\245API/\351\241\247\345\225\217\347\231\273\345\205\245\351\251\227\350\255\211\347\242\274\346\265\201\347\250\213.txt"
new file mode 100644
index 0000000..c132146
--- /dev/null
+++ "b/pamapi/src/doc/\347\231\273\345\205\245API/\351\241\247\345\225\217\347\231\273\345\205\245\351\251\227\350\255\211\347\242\274\346\265\201\347\250\213.txt"
@@ -0,0 +1,29 @@
+* �������Ⅳ����
+http get :
+
+http://localhost:8080/api/login/validate/get_img_code
+
+
+response content type: 
+image/jpeg
+
+
+
+* 撠��Ⅳ�敺垢�脰����
+
+http get :
+
+http://localhost:8080/api/login/validate/verify_img_code/{imgCode}
+
+ex:
+http://localhost:8080/api/login/validate/verify_img_code/4Rrcp
+
+
+
+
+response :
+
+true (撽����), false(撽�仃���)
+
+
+
diff --git a/pamapi/src/main/java/com/pollex/pam/config/SecurityConfiguration.java b/pamapi/src/main/java/com/pollex/pam/config/SecurityConfiguration.java
index 4349448..6fca6d3 100644
--- a/pamapi/src/main/java/com/pollex/pam/config/SecurityConfiguration.java
+++ b/pamapi/src/main/java/com/pollex/pam/config/SecurityConfiguration.java
@@ -83,6 +83,7 @@
             .antMatchers("/api/activate").permitAll()
             .antMatchers("/api/testLogin/**").permitAll()
             .antMatchers("/api/otp/**").permitAll()
+            .antMatchers("/api/login/validate/**").permitAll()
             .antMatchers("/api/eService/authenticate").permitAll()
             .antMatchers("/api/account/reset-password/init").permitAll()
             .antMatchers("/api/account/reset-password/finish").permitAll()
diff --git a/pamapi/src/main/java/com/pollex/pam/domain/Customer.java b/pamapi/src/main/java/com/pollex/pam/domain/Customer.java
index 359d0a3..9a94a8c 100644
--- a/pamapi/src/main/java/com/pollex/pam/domain/Customer.java
+++ b/pamapi/src/main/java/com/pollex/pam/domain/Customer.java
@@ -4,49 +4,43 @@
 import java.time.Instant;
 import java.util.Optional;
 
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.EnumType;
-import javax.persistence.Enumerated;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.Table;
+import javax.persistence.*;
 
 import org.springframework.data.annotation.CreatedDate;
 import org.springframework.data.annotation.LastModifiedDate;
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;
 import org.springframework.util.StringUtils;
 
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.pollex.pam.enums.OtpLoginTypeEnum;
 
+@EntityListeners(AuditingEntityListener.class)
 @Entity
 @Table(name = "customer")
 public class Customer implements Serializable {
-	
-	
+
 	/**
-	 * 
+	 *
 	 */
 	private static final long serialVersionUID = 1L;
-	
+
 	@Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     private Long id;
-	
+
 	@Column(name = "name")
     private String name;
-	
+
 	@Column(name = "phone")
     private String phone;
-	
+
 	@Column(name = "email")
     private String email;
-	
+
 	@Enumerated(value = EnumType.STRING)
 	@Column(name = "contact_type")
     private OtpLoginTypeEnum contactType;
-	
+
 	@CreatedDate
     @Column(name = "created_date", updatable = false)
     @JsonIgnore
@@ -112,7 +106,7 @@
 	public void setContactType(OtpLoginTypeEnum contactType) {
 		this.contactType = contactType;
 	}
-    
+
     public String toAccountString() {
     	return Optional.ofNullable(getPhone())
 				.filter(StringUtils::hasText)
diff --git a/pamapi/src/main/java/com/pollex/pam/enums/CustomerDetailEnum.java b/pamapi/src/main/java/com/pollex/pam/enums/CustomerDetailEnum.java
index f1ccc21..e9209f3 100644
--- a/pamapi/src/main/java/com/pollex/pam/enums/CustomerDetailEnum.java
+++ b/pamapi/src/main/java/com/pollex/pam/enums/CustomerDetailEnum.java
@@ -1,10 +1,8 @@
 package com.pollex.pam.enums;
 
 public enum CustomerDetailEnum {
-    ID("CustomerId"),
-    NAME("CustomerName"),
-    ACCOUNT("CustomerAccount"),
-    CONTACT_TYPE("ContactType");
+    DB_ID("CustomerDBId"),
+    NAME("CustomerName");
 
     private final String value;
 
diff --git a/pamapi/src/main/java/com/pollex/pam/security/SecurityUtils.java b/pamapi/src/main/java/com/pollex/pam/security/SecurityUtils.java
index 5e6c77b..787c1f3 100644
--- a/pamapi/src/main/java/com/pollex/pam/security/SecurityUtils.java
+++ b/pamapi/src/main/java/com/pollex/pam/security/SecurityUtils.java
@@ -107,10 +107,9 @@
         return userDetails.get(ConsultantDetailEnum.AGENT_NO.getValue());
     }
 
-    // todo , should get id from user details
-    public static Long getCustomerId() {
+    public static Long getCustomerDBId() {
     	Map<String, String> userDetails = getCurrentUserDetails();
-    	return Long.parseLong(userDetails.get(CustomerDetailEnum.ID.getValue()));
+    	return Long.parseLong(userDetails.get(CustomerDetailEnum.DB_ID.getValue()));
     }
 
     public static Map<String, String> getCurrentUserDetails() {
diff --git a/pamapi/src/main/java/com/pollex/pam/service/AppointmentService.java b/pamapi/src/main/java/com/pollex/pam/service/AppointmentService.java
index 7b0ebfa..b23f88e 100644
--- a/pamapi/src/main/java/com/pollex/pam/service/AppointmentService.java
+++ b/pamapi/src/main/java/com/pollex/pam/service/AppointmentService.java
@@ -16,7 +16,6 @@
 import com.pollex.pam.service.dto.AppointmentCustomerViewDTO;
 import com.pollex.pam.service.mapper.AppointmentCustomerViewMapper;
 import com.pollex.pam.service.mapper.AppointmentDTOMapper;
-import com.pollex.pam.service.mapper.AppointmentMapper;
 import com.pollex.pam.web.rest.errors.AppointmentNotFoundException;
 
 @Service
@@ -40,7 +39,7 @@
 
 	public void customerCreateAppointment(AppointmentCreateDTO appointmentCreateDTO) {
 		Appointment appointment = appointmentDTOMapper.toAppointment(appointmentCreateDTO);
-		appointment.setCustomerId(SecurityUtils.getCustomerId());
+		appointment.setCustomerId(SecurityUtils.getCustomerDBId());
 		appointment.setCommunicateStatus(ContactStatusEnum.RESERVED);
 		appointmentRepository.save(appointment);
 	}
diff --git a/pamapi/src/main/java/com/pollex/pam/service/ConsultantService.java b/pamapi/src/main/java/com/pollex/pam/service/ConsultantService.java
index af9c247..f59f84b 100644
--- a/pamapi/src/main/java/com/pollex/pam/service/ConsultantService.java
+++ b/pamapi/src/main/java/com/pollex/pam/service/ConsultantService.java
@@ -44,7 +44,7 @@
     AppointmentCustomerViewMapper appointmentCustomerViewMapper;
 
     public List<ConsultantDTO> getMyConsultantList() {
-        Long userId = SecurityUtils.getCustomerId();
+        Long userId = SecurityUtils.getCustomerDBId();
         return customerFavoriteConsultantRepository.findAllByCustomerId(userId)
             .stream()
             .map(consultantMapper::toDto)
@@ -81,7 +81,7 @@
     public void addConsultantToCustomList(AddConsultantParam param) {
         List<String> agentNoList = param.getAgentNoList();
         List<Consultant> consultants = consultantRepository.findAllByAgentNoIn(agentNoList);
-        Long userId = SecurityUtils.getCustomerId();
+        Long userId = SecurityUtils.getCustomerDBId();
 
         consultants.forEach(consultant -> {
             boolean isConsultantInList = customerFavoriteConsultantRepository.findOneByCustomerIdAndConsultant(userId, consultant).isPresent();
@@ -107,7 +107,7 @@
 	}
 
     public void removeConsultantFromCustomList(String agentNo) {
-        Long customId = SecurityUtils.getCustomerId();
+        Long customId = SecurityUtils.getCustomerDBId();
         Consultant consultant = consultantRepository.findOneByAgentNo(agentNo).orElseThrow(ConsultantNotFoundException::new);
         CustomerFavoriteConsultant target = customerFavoriteConsultantRepository.findOneByCustomerIdAndConsultant(customId, consultant).orElse(null);
 
diff --git a/pamapi/src/main/java/com/pollex/pam/service/CustomerAuthService.java b/pamapi/src/main/java/com/pollex/pam/service/CustomerAuthService.java
index aa9b5b4..8929adf 100644
--- a/pamapi/src/main/java/com/pollex/pam/service/CustomerAuthService.java
+++ b/pamapi/src/main/java/com/pollex/pam/service/CustomerAuthService.java
@@ -25,16 +25,16 @@
 @Service
 @Transactional
 public class CustomerAuthService {
-	
+
 	@Autowired
     AuthenticationManagerBuilder authenticationManagerBuilder;
-	
+
 	@Autowired
     CustomerRepository customerRepository;
 
     @Autowired
     TokenProvider tokenProvider;
-    
+
 	public String authorize(Customer account, String indexKey, String otpCode) {
 		OtpAccount otpAccount = OtpAccount.createOtpAccount(account, indexKey);
         OtpAuthenticationToken authenticationToken = new OtpAuthenticationToken(
@@ -43,26 +43,25 @@
         );
 
         SecurityContextHolder.getContext().setAuthentication(authenticationToken);
-        
+
         Authentication authentication = buildCustomerAuthToken(account, otpCode, indexKey);
         String jwt = tokenProvider.createToken(authentication, false);
         return jwt;
 	}
-	
+
 	public UsernamePasswordAuthenticationToken buildCustomerAuthToken(Customer customer
     		, String otpCode, String indexKey) {
-    	
+
         List<GrantedAuthority> grantedAuths = Arrays.asList(new SimpleGrantedAuthority("ROLE_USER"));
-        
+
         final String account = customer.toAccountString();
-        UsernamePasswordAuthenticationToken authenticationToken = 
+        UsernamePasswordAuthenticationToken authenticationToken =
         		new UsernamePasswordAuthenticationToken(account, otpCode, grantedAuths);
 
         Map<String, String> details = new HashMap<>();
-        details.put(CustomerDetailEnum.ID.getValue(), customer.getId().toString());
+        details.put(CustomerDetailEnum.DB_ID.getValue(), customer.getId().toString());
         details.put(CustomerDetailEnum.NAME.getValue(), customer.getName());
-        details.put(CustomerDetailEnum.ACCOUNT.getValue(), account);
-//        details.put(CustomerDetailEnum.CONTACT_TYPE.getValue(), customer.getContactType());
+
         authenticationToken.setDetails(details);
 
         return authenticationToken;
diff --git a/pamapi/src/main/java/com/pollex/pam/service/CustomerService.java b/pamapi/src/main/java/com/pollex/pam/service/CustomerService.java
index fe9a396..79a086d 100644
--- a/pamapi/src/main/java/com/pollex/pam/service/CustomerService.java
+++ b/pamapi/src/main/java/com/pollex/pam/service/CustomerService.java
@@ -2,6 +2,9 @@
 
 import java.util.Optional;
 
+import com.pollex.pam.security.SecurityUtils;
+import com.pollex.pam.service.dto.CustomerDTO;
+import com.pollex.pam.service.mapper.CustomerMapper;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.core.userdetails.UsernameNotFoundException;
 import org.springframework.stereotype.Service;
@@ -18,31 +21,34 @@
 @Service
 @Transactional
 public class CustomerService {
-	
+
 	@Autowired
 	CustomerRepository customerRepository;
-	
+
 	@Autowired
     CustomerDTOMapper customerDTOMapper;
-	
+
 	@Autowired
 	CustomerAuthService customerAuthService;
-	
+
 	@Autowired
 	OtpTmpService otpTmpService;
-	
+
+    @Autowired
+    CustomerMapper customerMapper;
+
 	public Customer save(Customer customer) {
 		return customerRepository.save(customer);
 	}
-	
+
 	public Customer registerCustomer(CustomerRegisterDTO registDTO) {
 		boolean isCustomerExist = checkCustomerExist(registDTO);
 		if(isCustomerExist) {
 			throw new UsernameAlreadyUsedException();
-			
+
 		}else {
 			String account = getCustomerAccount(registDTO);
-			
+
 			OtpTmp otpTmp = otpTmpService.findByAccountAndIndexKey(account, registDTO.getIndexKey());
 	    	if(otpTmp.getStatus() == OtpTmpStatusEnum.VERRIFIED) {
 	    		Customer customer = customerDTOMapper.toCustomer(registDTO);
@@ -54,9 +60,28 @@
 	    				+ " => status: " + otpTmp.getStatus());
 	    	}
 		}
-		
+
 	}
 
+    public void updateLoggedCustomer(CustomerDTO customerDTO) {
+        Long customerId = SecurityUtils.getCustomerDBId();
+        Customer customer = customerRepository.findById(customerId)
+            .orElseThrow(() -> new UsernameNotFoundException("customerId which is from token is not found in customer db table, customer id = " + customerId));
+
+        customer.setEmail(customerDTO.getEmail());
+        customer.setPhone(customerDTO.getPhone());
+        customer.setName(customerDTO.getName());
+        customerRepository.save(customer);
+    }
+
+    public CustomerDTO getLoggedCustomerDTO() {
+        Long customerId = SecurityUtils.getCustomerDBId();
+        Customer customer = customerRepository.findById(customerId)
+            .orElseThrow(() -> new UsernameNotFoundException("customerId which is from token is not found in customer db table, customer id = " + customerId));
+
+        return customerMapper.toDto(customer);
+    }
+
 	private String getCustomerAccount(CustomerRegisterDTO registDTO) {
 		return registDTO.getContactType() == OtpLoginTypeEnum.EMAIL?registDTO.getEmail():registDTO.getPhone();
 	}
diff --git a/pamapi/src/main/java/com/pollex/pam/service/dto/CustomerDTO.java b/pamapi/src/main/java/com/pollex/pam/service/dto/CustomerDTO.java
new file mode 100644
index 0000000..176dc0b
--- /dev/null
+++ b/pamapi/src/main/java/com/pollex/pam/service/dto/CustomerDTO.java
@@ -0,0 +1,31 @@
+package com.pollex.pam.service.dto;
+
+public class CustomerDTO {
+    private String email;
+    private String phone;
+    private String name;
+
+    public String getEmail() {
+        return email;
+    }
+
+    public void setEmail(String email) {
+        this.email = email;
+    }
+
+    public String getPhone() {
+        return phone;
+    }
+
+    public void setPhone(String phone) {
+        this.phone = phone;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+}
diff --git a/pamapi/src/main/java/com/pollex/pam/service/mapper/CustomerMapper.java b/pamapi/src/main/java/com/pollex/pam/service/mapper/CustomerMapper.java
new file mode 100644
index 0000000..757d8c9
--- /dev/null
+++ b/pamapi/src/main/java/com/pollex/pam/service/mapper/CustomerMapper.java
@@ -0,0 +1,19 @@
+package com.pollex.pam.service.mapper;
+
+import com.pollex.pam.domain.Customer;
+import com.pollex.pam.service.dto.CustomerDTO;
+import org.springframework.stereotype.Service;
+
+@Service
+public class CustomerMapper {
+
+    public CustomerDTO toDto(Customer customer) {
+        CustomerDTO dto = new CustomerDTO();
+        dto.setEmail(customer.getEmail());
+        dto.setPhone(customer.getPhone());
+        dto.setName(customer.getName());
+
+        return dto;
+    }
+
+}
diff --git a/pamapi/src/main/java/com/pollex/pam/service/util/VerifyCodeUtil.java b/pamapi/src/main/java/com/pollex/pam/service/util/VerifyCodeUtil.java
new file mode 100644
index 0000000..e42af0b
--- /dev/null
+++ b/pamapi/src/main/java/com/pollex/pam/service/util/VerifyCodeUtil.java
@@ -0,0 +1,68 @@
+package com.pollex.pam.service.util;
+
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.Graphics;
+import java.awt.image.BufferedImage;
+import java.util.Random;
+
+public final class VerifyCodeUtil {
+
+	
+	public static String createcode() {
+		String code = "";
+		code = "";
+		String randomRange = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";// Randomly generated character
+																					// range (0-9, a-z, A-Z)
+
+		// The number of digits for generating the verification code (here 4 digits)
+		for (int i = 0; i < 4; i++) {
+			int index = (int) (Math.random() * 62);// Will produce a [0,62) number, excluding decimals
+			char randomCode = randomRange.charAt(index);
+			code = code + randomCode;
+		}
+		return code;
+	}
+
+	// 3. Generate pictures
+	public static BufferedImage createimage(String code) {
+		// The first 2 parameters are: width, height. The back is the image type
+		// Create a BufferedImage object without transparent color, TYPE_INT_ARGB is
+		// with transparent color
+		BufferedImage bi = new BufferedImage(130, 50, BufferedImage.TYPE_INT_RGB);
+
+		// 1. Get a canvas
+		Graphics g = bi.getGraphics();
+		// 2. Add background color
+		g.setColor(Color.WHITE);
+		g.fillRect(0, 0, 130, 50);
+
+		// 3. Add interference lines
+		for (int i = 0; i < 10; i++) {
+			Random r = new Random();
+			int red = r.nextInt(256);
+			int green = r.nextInt(256);
+			int blue = r.nextInt(256);
+			Color c = new Color(red, green, blue);
+			g.setColor(c);
+			int x1 = r.nextInt(131);
+			int y1 = r.nextInt(51);
+			int x2 = r.nextInt(131);
+			int y2 = r.nextInt(51);
+			g.drawLine(x1, y1, x2, y2);// Draw a line
+			// g.drawOval(x1, y1, x2, y2);//Draw a curve
+		}
+
+		// 3. Add text
+		g.setColor(Color.BLACK);
+		g.setFont(new Font(" ", Font.BOLD, 40));
+
+		// 4. Fill the text into the artboard
+		g.drawString(code, 15, 40);
+
+		// 5. Close the canvas
+		g.dispose();
+		return bi;
+	}
+
+}
\ No newline at end of file
diff --git a/pamapi/src/main/java/com/pollex/pam/web/rest/ConsultantLoginValidateResource.java b/pamapi/src/main/java/com/pollex/pam/web/rest/ConsultantLoginValidateResource.java
new file mode 100644
index 0000000..47b4ffc
--- /dev/null
+++ b/pamapi/src/main/java/com/pollex/pam/web/rest/ConsultantLoginValidateResource.java
@@ -0,0 +1,62 @@
+package com.pollex.pam.web.rest;
+
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.pollex.pam.service.util.VerifyCodeUtil;
+
+@RestController
+@RequestMapping("/api/login/validate")
+public class ConsultantLoginValidateResource {
+	
+	@GetMapping("/get_img_code")
+	public void getVerifyCodeImg(HttpServletResponse response, HttpServletRequest request) {
+		try {
+			String code = VerifyCodeUtil.createcode();
+			BufferedImage image = VerifyCodeUtil.createimage(code);
+			// Return to the client in a stream
+			response.setContentType("image/jpeg");
+			// response.setContentType("image/bmp");
+			ByteArrayOutputStream bt = new ByteArrayOutputStream();
+			// Convert pictures to byte stream
+			ImageIO.write(image, "jpeg", bt);
+			ServletOutputStream outputStream = response.getOutputStream();
+			outputStream.write(bt.toByteArray());
+			HttpSession session = request.getSession();
+			session.setAttribute("img_code", code);
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+
+	}
+
+	@GetMapping("/verify_img_code/{imgCode}")
+	public boolean verifyImgCode(HttpServletResponse response, HttpServletRequest request,
+			@PathVariable String imgCode) {
+		HttpSession session = request.getSession();
+		String sessionImpCode = (String) session.getAttribute("img_code");
+		if (!StringUtils.hasText(sessionImpCode)
+				|| !StringUtils.hasText(imgCode)) {
+			return false;
+		}
+		
+		if (imgCode.equals(sessionImpCode)) {
+			return true;
+		}
+		
+		return false;
+	}
+}
diff --git a/pamapi/src/main/java/com/pollex/pam/web/rest/CustomerInfoResource.java b/pamapi/src/main/java/com/pollex/pam/web/rest/CustomerInfoResource.java
new file mode 100644
index 0000000..df6d70b
--- /dev/null
+++ b/pamapi/src/main/java/com/pollex/pam/web/rest/CustomerInfoResource.java
@@ -0,0 +1,33 @@
+package com.pollex.pam.web.rest;
+
+import com.pollex.pam.service.CustomerService;
+import com.pollex.pam.service.dto.CustomerDTO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.util.Assert;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping("/api/customer/info")
+public class CustomerInfoResource {
+
+    @Autowired
+    CustomerService customerService;
+
+    @GetMapping("")
+    public ResponseEntity<CustomerDTO> getLoggedCustomerInfo() {
+        return new ResponseEntity<>(customerService.getLoggedCustomerDTO(), HttpStatus.OK);
+    }
+
+    @PutMapping("")
+    public ResponseEntity<Void> updateLoggedCustomerInfo(@RequestBody CustomerDTO customerDTO) {
+        boolean hasEmail = StringUtils.hasText(customerDTO.getEmail());
+        boolean hasPhone = StringUtils.hasText(customerDTO.getPhone());
+        Assert.isTrue(hasEmail || hasPhone, "the email and the phone both are empty!");
+
+        customerService.updateLoggedCustomer(customerDTO);
+        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
+    }
+}

--
Gitblit v1.8.0