保誠-保戶業務員媒合平台
wayne
2021-11-29 4b1639583efdb417cdf9a999a74d6d17835cc252
[add] 客戶、顧問登入紀錄

刪除1個檔案
修改6個檔案
新增6個檔案
修改1個檔案名稱
356 ■■■■■ 已變更過的檔案
pamapi/src/doc/sql/20211129_w.sql 11 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/doc/顧問API/指定顧問詳細資訊.txt 2 ●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/main/java/com/pollex/pam/domain/Consultant.java 13 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/main/java/com/pollex/pam/domain/LoginRecord.java 94 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/main/java/com/pollex/pam/enums/LoginMethod.java 6 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/main/java/com/pollex/pam/enums/LoginResult.java 6 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/main/java/com/pollex/pam/repository/LoginRecordRepository.java 13 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/main/java/com/pollex/pam/security/provider/EServiceAuthenticationProvider.java 16 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/main/java/com/pollex/pam/service/ConsultantService.java 11 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/main/java/com/pollex/pam/service/LoginRecordService.java 66 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/main/java/com/pollex/pam/service/LoginService.java 90 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/main/java/com/pollex/pam/service/OtpUtilService.java 11 ●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/main/java/com/pollex/pam/service/mapper/ConsultantMapper.java 5 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/main/java/com/pollex/pam/web/rest/TestLoginResource.java 12 ●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/doc/sql/20211129_w.sql
¤ñ¹ï·sÀÉ®×
@@ -0,0 +1,11 @@
ALTER TABLE omo.consultant DROP COLUMN latest_login_time;
CREATE TABLE omo.login_record (
    id bigserial NOT NULL,
    account varchar NOT NULL,
    login_method varchar NOT NULL,
    login_date timestamp NOT NULL,
    "result" varchar NOT NULL,
    failed_reason varchar NULL,
    CONSTRAINT login_record_pk PRIMARY KEY (id)
);
pamapi/src/doc/ÅU°ÝAPI/«ü©wÅU°Ý¸Ô²Ó¸ê°T.txt
File was renamed from pamapi/src/doc/ÅU°ÝAPI/ÅU°Ý²Ó¸`.txt
@@ -11,7 +11,7 @@
    "phoneNumber": "0912345678",
    "serveArea": "台北市地區",
    "companyAddress": "台北市信義區忠孝東路一段1號",
    "latestLoginTime": null,
    "latestLoginTime": "2021-11-29T07:39:22.135Z",      // è‹¥ç„¡æœ€å¾Œç™»å…¥ç´€éŒ„則會帶null
    "seniority": "4å¹´2個月",
    "suitability": 0,
    "evaluation": 0,
pamapi/src/main/java/com/pollex/pam/domain/Consultant.java
@@ -4,7 +4,6 @@
import javax.persistence.*;
import java.io.Serializable;
import java.time.Instant;
@Entity
@Table(name = "consultant")
@@ -50,9 +49,6 @@
    @Column(name = "company_address")
    private String companyAddress;
    @Column(name = "latest_login_time")
    private Instant latestLoginTime;
    @Column(name = "seniority")
    private String seniority;
@@ -168,14 +164,6 @@
        companyAddress = companyAddress;
    }
    public Instant getLatestLoginTime() {
        return latestLoginTime;
    }
    public void setLatestLoginTime(Instant lastLoginTime) {
        this.latestLoginTime = lastLoginTime;
    }
    public String getSeniority() {
        return seniority;
    }
@@ -239,7 +227,6 @@
            ", gender=" + gender +
            ", phoneNumber='" + phoneNumber + '\'' +
            ", companyAddress='" + companyAddress + '\'' +
            ", latestLoginTime=" + latestLoginTime +
            ", seniority='" + seniority + '\'' +
            ", concept='" + concept + '\'' +
            ", experience='" + experience + '\'' +
pamapi/src/main/java/com/pollex/pam/domain/LoginRecord.java
¤ñ¹ï·sÀÉ®×
@@ -0,0 +1,94 @@
package com.pollex.pam.domain;
import com.pollex.pam.enums.LoginMethod;
import com.pollex.pam.enums.LoginResult;
import javax.persistence.*;
import java.io.Serializable;
import java.time.Instant;
@Entity
@Table(name = "login_record")
public class LoginRecord implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(name = "account")
    private String account;
    @Enumerated(EnumType.STRING)
    @Column(name = "login_method")
    private LoginMethod loginMethod;
    @Column(name = "login_date", updatable = false)
    private Instant loginDate = Instant.now();
    @Enumerated(EnumType.STRING)
    @Column(name = "result")
    private LoginResult result;
    @Column(name = "failed_reason")
    private String failedReason;
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getAccount() {
        return account;
    }
    public void setAccount(String account) {
        this.account = account;
    }
    public LoginMethod getLoginMethod() {
        return loginMethod;
    }
    public void setLoginMethod(LoginMethod loginMethod) {
        this.loginMethod = loginMethod;
    }
    public Instant getLoginDate() {
        return loginDate;
    }
    public void setLoginDate(Instant createdDate) {
        this.loginDate = createdDate;
    }
    public LoginResult getResult() {
        return result;
    }
    public void setResult(LoginResult result) {
        this.result = result;
    }
    public String getFailedReason() {
        return failedReason;
    }
    public void setFailedReason(String failedReason) {
        this.failedReason = failedReason;
    }
    @Override
    public String toString() {
        return "LoginRecord{" +
            "id=" + id +
            ", account='" + account + '\'' +
            ", loginMethod=" + loginMethod +
            ", createdDate=" + loginDate +
            ", result=" + result +
            ", failedReason='" + failedReason + '\'' +
            '}';
    }
}
pamapi/src/main/java/com/pollex/pam/enums/LoginMethod.java
¤ñ¹ï·sÀÉ®×
@@ -0,0 +1,6 @@
package com.pollex.pam.enums;
public enum LoginMethod {
    OTP,
    E_SERVICE
}
pamapi/src/main/java/com/pollex/pam/enums/LoginResult.java
¤ñ¹ï·sÀÉ®×
@@ -0,0 +1,6 @@
package com.pollex.pam.enums;
public enum LoginResult {
    SUCCESS,
    FAIL
}
pamapi/src/main/java/com/pollex/pam/repository/LoginRecordRepository.java
¤ñ¹ï·sÀÉ®×
@@ -0,0 +1,13 @@
package com.pollex.pam.repository;
import com.pollex.pam.domain.LoginRecord;
import com.pollex.pam.enums.LoginResult;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.Optional;
@Repository
public interface LoginRecordRepository extends JpaRepository<LoginRecord, Long> {
    Optional<LoginRecord> findTopByAccountAndResultOrderByLoginDate(String account, LoginResult loginResult);
}
pamapi/src/main/java/com/pollex/pam/security/provider/EServiceAuthenticationProvider.java
@@ -1,14 +1,12 @@
package com.pollex.pam.security.provider;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.pollex.pam.config.ApplicationProperties;
import com.pollex.pam.domain.Consultant;
import com.pollex.pam.enums.ConsultantDetailEnum;
import com.pollex.pam.enums.CustomerDetailEnum;
import com.pollex.pam.repository.ConsultantRepository;
import com.pollex.pam.security.token.EServiceAuthenticationToken;
import com.pollex.pam.service.dto.EServiceRequest;
import com.pollex.pam.service.LoginRecordService;
import com.pollex.pam.service.dto.EServiceResponse;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
@@ -22,7 +20,6 @@
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
@@ -54,11 +51,15 @@
    @Autowired
    ConsultantRepository consultantRepository;
    @Autowired
    LoginRecordService loginRecordService;
    public Authentication authenticate(EServiceAuthenticationToken authenticationToken) throws AuthenticationException {
        String account = authenticationToken.getPrincipal();
        String credentials = authenticationToken.getCredentials();
        if(applicationProperty.isMockLogin()){
            loginRecordService.saveEServiceLoginSuccessRecord(account);
            return getConsultantToken(account, credentials);
        }
@@ -68,10 +69,13 @@
                EServiceResponse eServiceResponse = responseEntity.getBody();
                if(E_SERVICE_LOGIN_SUCCESS_CODE.equals(eServiceResponse.getCode())){
                    loginRecordService.saveEServiceLoginSuccessRecord(account);
                    return getConsultantToken(account, credentials);
                }
                throw new RuntimeException("eService login failed, eService response code = " + eServiceResponse.getCode() + ", eService response msg = " + eServiceResponse.getMsg());
                else {
                    loginRecordService.saveEServiceLoginFailRecord(account, eServiceResponse.getMsg());
                    throw new RuntimeException("eService login failed, eService response code = " + eServiceResponse.getCode() + ", eService response msg = " + eServiceResponse.getMsg());
                }
            }
            throw new RuntimeException("eService http error!, response http status code = " + responseEntity.getStatusCode());
pamapi/src/main/java/com/pollex/pam/service/ConsultantService.java
@@ -3,6 +3,7 @@
import com.pollex.pam.domain.AppointmentCustomerView;
import com.pollex.pam.domain.Consultant;
import com.pollex.pam.domain.CustomerFavoriteConsultant;
import com.pollex.pam.enums.LoginResult;
import com.pollex.pam.repository.AppointmentCustomerViewRepository;
import com.pollex.pam.repository.ConsultantRepository;
import com.pollex.pam.repository.CustomerFavoriteConsultantRepository;
@@ -43,6 +44,9 @@
    @Autowired
    AppointmentCustomerViewMapper appointmentCustomerViewMapper;
    @Autowired
    LoginRecordService loginRecordService;
    public List<ConsultantDTO> getMyConsultantList() {
        Long userId = SecurityUtils.getCustomerDBId();
        return customerFavoriteConsultantRepository.findAllByCustomerId(userId)
@@ -74,7 +78,12 @@
    public ConsultantDetailDTO getConsultantDetail(String agentNo) {
        Consultant consultant = consultantRepository.findOneByAgentNo(agentNo).orElseThrow(ConsultantNotFoundException::new);
        return consultantMapper.toDetailDto(consultant);
        ConsultantDetailDTO consultantDetailDTO = consultantMapper.toDetailDto(consultant);
        loginRecordService.findLatestLoginRecord(agentNo, LoginResult.SUCCESS)
                .ifPresent(loginRecord -> consultantDetailDTO.setLatestLoginTime(loginRecord.getLoginDate()));
        return consultantDetailDTO;
    }
    @Transactional
pamapi/src/main/java/com/pollex/pam/service/LoginRecordService.java
¤ñ¹ï·sÀÉ®×
@@ -0,0 +1,66 @@
package com.pollex.pam.service;
import com.pollex.pam.domain.LoginRecord;
import com.pollex.pam.enums.LoginResult;
import com.pollex.pam.repository.LoginRecordRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Optional;
import static com.pollex.pam.enums.LoginMethod.E_SERVICE;
import static com.pollex.pam.enums.LoginMethod.OTP;
import static com.pollex.pam.enums.LoginResult.FAIL;
import static com.pollex.pam.enums.LoginResult.SUCCESS;
@Service
@Transactional
public class LoginRecordService {
    @Autowired
    LoginRecordRepository loginRecordRepository;
    public Optional<LoginRecord> findLatestLoginRecord(String account, LoginResult loginResult) {
        return loginRecordRepository.findTopByAccountAndResultOrderByLoginDate(account, loginResult);
    }
    public void saveOTPLoginSuccessRecord(String account) {
        LoginRecord loginRecord = new LoginRecord();
        loginRecord.setAccount(account);
        loginRecord.setLoginMethod(OTP);
        loginRecord.setResult(SUCCESS);
        loginRecordRepository.save(loginRecord);
    }
    public void saveOTPLoginFailRecord(String account, String failReason) {
        LoginRecord loginRecord = new LoginRecord();
        loginRecord.setAccount(account);
        loginRecord.setLoginMethod(OTP);
        loginRecord.setResult(FAIL);
        loginRecord.setFailedReason(failReason);
        loginRecordRepository.save(loginRecord);
    }
    public void saveEServiceLoginSuccessRecord(String account) {
        LoginRecord loginRecord = new LoginRecord();
        loginRecord.setAccount(account);
        loginRecord.setLoginMethod(E_SERVICE);
        loginRecord.setResult(SUCCESS);
        loginRecordRepository.save(loginRecord);
    }
    public void saveEServiceLoginFailRecord(String account, String failReason) {
        LoginRecord loginRecord = new LoginRecord();
        loginRecord.setAccount(account);
        loginRecord.setLoginMethod(E_SERVICE);
        loginRecord.setResult(FAIL);
        loginRecord.setFailedReason(failReason);
        loginRecordRepository.save(loginRecord);
    }
}
pamapi/src/main/java/com/pollex/pam/service/LoginService.java
Àɮפw§R°£
pamapi/src/main/java/com/pollex/pam/service/OtpUtilService.java
@@ -10,7 +10,6 @@
import org.springframework.stereotype.Service;
import com.pollex.pam.config.ApplicationProperties;
import com.pollex.pam.security.provider.OtpAuthenticationProvider;
import com.pollex.pam.service.dto.OtpResponseDTO;
import org.springframework.transaction.annotation.Transactional;
@@ -28,6 +27,9 @@
    @Autowired
    OtpTmpService otpTmpService;
    @Autowired
    LoginRecordService loginRecordService;
    @Transactional
    public void verifyOtp(VerifyOtpVM verifyOtpParam) {
        verifyOtp(verifyOtpParam.getAccount(), verifyOtpParam.getIndexKey(), verifyOtpParam.getOtpCode());
@@ -37,10 +39,15 @@
    public void verifyOtp(String account, String indexKey, String otpCode) {
        try {
            if(applicationProperty.isMockLogin()){
                loginRecordService.saveOTPLoginSuccessRecord(account);
                log.debug("Do MockLogin");
            } else {  // otp logon
                OtpResponseDTO otpResponseDTO = otpWebService.verifyOTP(indexKey, otpCode);
                if (!otpResponseDTO.isSuccess()) {
                if (otpResponseDTO.isSuccess()) {
                    loginRecordService.saveOTPLoginSuccessRecord(account);
                }
                else {
                    loginRecordService.saveOTPLoginFailRecord(account, otpResponseDTO.getFailReason());
                    throw new AuthenticationCredentialsNotFoundException("");
                }
            }
pamapi/src/main/java/com/pollex/pam/service/mapper/ConsultantMapper.java
@@ -72,17 +72,16 @@
        consultantDetailDTO.setPhoneNumber(source.getPhoneNumber());
        consultantDetailDTO.setServeArea(source.getServeArea());
        consultantDetailDTO.setCompanyAddress(source.getCompanyAddress());
        consultantDetailDTO.setLatestLoginTime(source.getLatestLoginTime());
        consultantDetailDTO.setSeniority(source.getSeniority());
        consultantDetailDTO.setConcept(source.getConcept());
        consultantDetailDTO.setAwards(source.getAward());
        consultantDetailDTO.setImage(source.getPhotoPath());
        consultantDetailDTO.setExpertises(splitStringWithChar(source.getExpertise()));
        consultantDetailDTO.setExperiences(splitStringWithChar(source.getExperience()));
        // todo æ±ºå®šåŒ¹é…ç¨‹åº¦
        consultantDetailDTO.setSuitability(50);
        consultantDetailDTO.setEvaluation(50);
        consultantDetailDTO.setExpertises(splitStringWithChar(source.getExpertise()));
        consultantDetailDTO.setExperiences(splitStringWithChar(source.getExperience()));
        return consultantDetailDTO;
    }
pamapi/src/main/java/com/pollex/pam/web/rest/TestLoginResource.java
@@ -1,17 +1,11 @@
package com.pollex.pam.web.rest;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.pollex.pam.config.ApplicationProperties;
import com.pollex.pam.security.jwt.JWTFilter;
import com.pollex.pam.security.jwt.TokenProvider;
import com.pollex.pam.security.token.EServiceAuthenticationToken;
import com.pollex.pam.security.token.OtpAuthenticationToken;
import com.pollex.pam.service.LoginService;
import com.pollex.pam.service.LoginRecordService;
import com.pollex.pam.service.OtpWebService;
import com.pollex.pam.service.dto.EServiceRequest;
import com.pollex.pam.service.dto.EServiceResponse;
import com.pollex.pam.service.dto.OtpResponseDTO;
import com.pollex.pam.web.rest.vm.OtpAccount;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
@@ -25,8 +19,6 @@
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
@@ -51,7 +43,7 @@
    private final static Logger log = LoggerFactory.getLogger(TestLoginResource.class);
    @Autowired
    LoginService loginService;
    LoginRecordService loginRecordService;
    @Autowired
    ApplicationProperties applicationProperty;