保誠-保戶業務員媒合平台
wayne
2021-12-03 82e2a62e7c90cc191f9e2ebc569fe3a3663b68b0
Merge branch '預約單更新與刪除'

修改17個檔案
新增4個檔案
689 ■■■■ 已變更過的檔案
pamapi/src/doc/sql/20211202_w.sql 35 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/doc/預約單/取消預約單API.txt 4 ●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/doc/顧問API/客戶的顧問清單.txt 142 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/main/java/com/pollex/pam/domain/Appointment.java 30 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/main/java/com/pollex/pam/domain/AppointmentCustomerView.java 23 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/main/java/com/pollex/pam/domain/Satisfaction.java 29 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/main/java/com/pollex/pam/enums/AppointmentStatusEnum.java 6 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/main/java/com/pollex/pam/repository/AppointmentCustomerViewRepository.java 3 ●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/main/java/com/pollex/pam/repository/SatisfactionRepository.java 5 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/main/java/com/pollex/pam/service/AppointmentService.java 48 ●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/main/java/com/pollex/pam/service/ConsultantService.java 81 ●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/main/java/com/pollex/pam/service/SatisfactionService.java 17 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/main/java/com/pollex/pam/service/dto/AppointmentCustomerViewDTO.java 13 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/main/java/com/pollex/pam/service/dto/AppointmentDTO.java 9 ●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/main/java/com/pollex/pam/service/dto/CustomerFavoriteConsultantDTO.java 152 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/main/java/com/pollex/pam/service/dto/SatisfactionDTO.java 7 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/main/java/com/pollex/pam/service/mapper/AppointmentDTOMapper.java 9 ●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/main/java/com/pollex/pam/service/mapper/AppointmentMapper.java 7 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/main/java/com/pollex/pam/service/mapper/ConsultantMapper.java 43 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/main/java/com/pollex/pam/web/rest/AppointmentResource.java 22 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/main/java/com/pollex/pam/web/rest/ConsultantResource.java 4 ●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/doc/sql/20211202_w.sql
¤ñ¹ï·sÀÉ®×
@@ -0,0 +1,35 @@
ALTER TABLE omo.appointment ADD status varchar NULL;
ALTER TABLE omo.appointment ADD contact_time timestamp NULL;
ALTER TABLE omo.appointment ADD last_modified_date timestamp NULL;
ALTER TABLE omo.customer ADD agree_personal_information_time timestamp NULL;
UPDATE omo.appointment SET status = 'AVAILABLE';
UPDATE omo.appointment SET last_modified_date = appointment_date;
DROP VIEW omo.appointment_customer_view;
CREATE OR REPLACE VIEW omo.appointment_customer_view
AS SELECT a.id AS appointment_id,
          a.phone,
          a.email,
          a.contact_type,
          a.gender,
          a.age,
          a.job,
          a.requirement,
          a.communicate_status,
          a.hope_contact_time,
          a.other_requirement,
          a.agent_no,
          a.appointment_date,
          a.customer_id,
          a.consultant_view_time,
          a.consultant_read_time,
          a.contact_time,
          a.status,
          a.last_modified_date,
          c.name
   FROM omo.appointment a
            LEFT JOIN omo.customer c ON a.customer_id = c.id;
ALTER TABLE omo.satisfaction ADD appointment_id bigserial NOT NULL;
pamapi/src/doc/¹w¬ù³æ/¨ú®ø¹w¬ù³æAPI.txt
¤ñ¹ï·sÀÉ®×
@@ -0,0 +1,4 @@
http delete:
http://localhost:8080/api/appointment/{appointmentId}
response http status: 204 (成功)
pamapi/src/doc/ÅU°ÝAPI/«È¤áªºÅU°Ý²M³æ.txt
@@ -3,19 +3,141 @@
response body:
[
    {
        "agentNo": "12345",
        "name": "測試推薦業務員",
        "img": "",
        "agentNo": "J149388015",
        "name": "宋重機",
        "img": "avatar9.jpg",
        "expertise": [
            "財務規劃",
            "資產轉移"
            "健康與保障",
            "子女教育",
            "資產規劃",
            "樂活退休",
            "保單健檢/規劃",
            "分紅保單"
        ],
        "avgScore": 4.7,
        "avgScore": 4.0,
        "contactStatus": "reserved",        // å¯é€²è¡Œç‹€æ…‹ï¼špicked (進行預約)、reserved (已預約)、contacted (已連繫)
        "createTime": "2021-12-02T10:55:53.939Z",   // åŠ å…¥é¡§å•æ¸…å–®æ™‚é–“
        "updateTime": "2021-12-02T10:56:32.741Z",   // æœ€è¿‘更新時間
        "role": "威盛保險經紀人",
        "seniority": "22 å¹´ 8 æœˆ",
        "latestAppointmentId": 130,                 // æœ€å¾Œä¸€ç­†é ç´„å–®ID
        "latestAppointmentDate": "2021-12-02T10:56:32.741Z",    // æœ€å¾Œä¸€ç­†é ç´„單預約時間
        "latestAppointmentScore": null,                 // æœ€å¾Œä¸€ç­†é ç´„單的分數 (null為尚未評分)
        "appointments": [       // å®¢æˆ¶å·²é ç´„的顧問清單
            {
                "id": 130,
                "phone": "0938520091",
                "email": "",
                "contactType": "phone",
                "gender": "female",
                "age": "21-30",
                "job": "內勤",
                "requirement": "子女教育,分紅保單相關",
                "communicateStatus": "reserved",
                "hopeContactTime": "'禮拜一,禮拜二,禮拜三、12:00~14:00,18:00~21:00'",
                "otherRequirement": null,
                "appointmentDate": "2021-12-02T10:56:32.741Z",
                "lastModifiedDate": "2021-12-02T10:56:32.741Z",
                "agentNo": "J149388015",
                "customerId": 76,
                "name": "李哲維",
                "consultantViewTime": null,
                "consultantReadTime": null
            }
        ],
        "new": true
    },
    {
        "agentNo": "B282677963",
        "name": "喬妹",
        "img": "avatar6.jpg",
        "expertise": [
            "健康與保障",
            "子女教育",
            "資產規劃",
            "樂活退休",
            "保單健檢/規劃",
            "分紅保單"
        ],
        "avgScore": 1.0,
        "contactStatus": "reserved",
        "createTime": "2021-12-02T10:55:57.423Z",
        "updateTime": "2021-12-02T10:56:56.946Z",
        "role": "錠嵂保險經紀人",
        "seniority": "30 å¹´ 8 æœˆ",
        "latestAppointmentId": 131,
        "latestAppointmentDate": "2021-12-02T10:56:56.946Z",
        "latestAppointmentScore": null,
        "appointments": [
            {
                "id": 131,
                "phone": "0938520091",
                "email": "",
                "contactType": "phone",
                "gender": "female",
                "age": "21-30",
                "job": "內勤",
                "requirement": "子女教育,分紅保單相關",
                "communicateStatus": "reserved",
                "hopeContactTime": "'禮拜五、9:00~12:00,12:00~14:00,14:00~18:00,18:00~21:00'",
                "otherRequirement": null,
                "appointmentDate": "2021-12-02T10:56:56.946Z",
                "lastModifiedDate": "2021-12-02T10:56:56.946Z",
                "agentNo": "B282677963",
                "customerId": 76,
                "name": "李哲維",
                "consultantViewTime": null,
                "consultantReadTime": null
            }
        ],
        "new": true
    },
    {
        "agentNo": "R221444250",
        "name": "崔寨",
        "img": "avatar10.jpg",
        "expertise": [
            "健康與保障",
            "子女教育",
            "資產規劃",
            "樂活退休",
            "保單健檢/規劃",
            "分紅保單"
        ],
        "avgScore": 5.0,
        "contactStatus": "picked",
        "updateTime": "2021-11-02T06:46:13.723Z",
        "seniority": "4å¹´2個月",
        "createTime": "2021-12-02T10:56:01.004Z",
        "updateTime": null,
        "role": "台名保險經紀人",
        "new": false,
        "latestAppointmentId": null
        "seniority": "38 å¹´ ",
        "latestAppointmentId": null,
        "latestAppointmentDate": null,
        "latestAppointmentScore": null,
        "appointments": [],
        "new": true
    },
    {
        "agentNo": "Z152717443",
        "name": "伍夠勇",
        "img": "avatar3.jpg",
        "expertise": [
            "健康與保障",
            "子女教育",
            "資產規劃",
            "樂活退休",
            "保單健檢/規劃",
            "分紅保單"
        ],
        "avgScore": 3.0,
        "contactStatus": "picked",
        "createTime": "2021-12-02T10:56:04.620Z",
        "updateTime": null,
        "role": "和泰保險經紀人",
        "seniority": "17 å¹´ 1 æœˆ",
        "latestAppointmentId": null,
        "latestAppointmentDate": null,
        "latestAppointmentScore": null,                 // æœ€å¾Œä¸€ç­†é ç´„單的分數 (null為尚未評分)
        "appointments": [],
        "new": true
    }
]
pamapi/src/main/java/com/pollex/pam/domain/Appointment.java
@@ -5,7 +5,9 @@
import javax.persistence.*;
import com.pollex.pam.enums.AppointmentStatusEnum;
import com.pollex.pam.enums.ContactStatusEnum;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
@@ -54,9 +56,13 @@
    @Column(name = "other_requirement")
    private String otherRequirement;
    @LastModifiedDate
    @Column(name = "appointment_date")
    @CreatedDate
    @Column(name = "appointment_date", updatable = false)
    private Instant appointmentDate;
    @LastModifiedDate
    @Column(name = "last_modified_date")
    private Instant lastModifiedDate;
    @Column(name = "agent_no")
    private String agentNo;
@@ -69,6 +75,10 @@
    @Column(name = "consultant_read_time")
    private Instant consultantReadTime;
    @Enumerated(value = EnumType.STRING)
    @Column(name = "status")
    private AppointmentStatusEnum status;
    public Long getId() {
        return id;
@@ -197,4 +207,20 @@
    public void setConsultantReadTime(Instant consultantReadTime) {
        this.consultantReadTime = consultantReadTime;
    }
    public AppointmentStatusEnum getStatus() {
        return status;
    }
    public void setStatus(AppointmentStatusEnum status) {
        this.status = status;
    }
    public Instant getLastModifiedDate() {
        return lastModifiedDate;
    }
    public void setLastModifiedDate(Instant lastModifiedDate) {
        this.lastModifiedDate = lastModifiedDate;
    }
}
pamapi/src/main/java/com/pollex/pam/domain/AppointmentCustomerView.java
@@ -10,6 +10,7 @@
import javax.persistence.Id;
import javax.persistence.Table;
import com.pollex.pam.enums.AppointmentStatusEnum;
import com.pollex.pam.enums.ContactStatusEnum;
@Entity
@@ -71,8 +72,15 @@
    @Column(name = "consultant_read_time")
    private Instant consultantReadTime;
    @Column(name = "last_modified_date")
    private Instant lastModifiedDate;
    @Column(name = "name")
    private String name;
    @Enumerated(value = EnumType.STRING)
    @Column(name = "status")
    private AppointmentStatusEnum status;
    public Long getId() {
        return id;
@@ -202,6 +210,14 @@
        this.consultantReadTime = consultantReadTime;
    }
    public Instant getLastModifiedDate() {
        return lastModifiedDate;
    }
    public void setLastModifiedDate(Instant lastModifiedDate) {
        this.lastModifiedDate = lastModifiedDate;
    }
    public String getName() {
        return name;
    }
@@ -210,4 +226,11 @@
        this.name = name;
    }
    public AppointmentStatusEnum getStatus() {
        return status;
    }
    public void setStatus(AppointmentStatusEnum status) {
        this.status = status;
    }
}
pamapi/src/main/java/com/pollex/pam/domain/Satisfaction.java
@@ -21,16 +21,16 @@
@Entity
@Table(name = "satisfaction")
public class Satisfaction implements Serializable {
    /**
     *
     *
     */
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @CreatedDate
    @Column(name = "created_date", updatable = false)
    @JsonIgnore
@@ -40,19 +40,22 @@
    @Column(name = "last_modified_date")
    @JsonIgnore
    private Instant lastModifiedDate = Instant.now();
    @Column(name = "customer_id")
    private Long customerId;
    @Column(name = "agent_no")
    private String agentNo;
    @Enumerated(EnumType.STRING)
    @Column(name = "status")
    private SatisfactionStatusEnum status;
    @Column(name = "score")
    private Float score;
    @Column(name = "appointment_id")
    private Long appointmentId;
    public Long getId() {
        return id;
@@ -109,6 +112,12 @@
    public void setScore(Float score) {
        this.score = score;
    }
    public Long getAppointmentId() {
        return appointmentId;
    }
    public void setAppointmentId(Long appointmentId) {
        this.appointmentId = appointmentId;
    }
}
pamapi/src/main/java/com/pollex/pam/enums/AppointmentStatusEnum.java
¤ñ¹ï·sÀÉ®×
@@ -0,0 +1,6 @@
package com.pollex.pam.enums;
public enum AppointmentStatusEnum {
    AVAILABLE,
    DELETED
}
pamapi/src/main/java/com/pollex/pam/repository/AppointmentCustomerViewRepository.java
@@ -9,7 +9,6 @@
@Repository
public interface AppointmentCustomerViewRepository extends JpaRepository<AppointmentCustomerView, Long>{
    List<AppointmentCustomerView> findByAgentNo(String agentNo);
    List<AppointmentCustomerView> findByAgentNoAndCustomerId(String agentNo, Long customerId);
}
pamapi/src/main/java/com/pollex/pam/repository/SatisfactionRepository.java
@@ -1,6 +1,7 @@
package com.pollex.pam.repository;
import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@@ -13,6 +14,6 @@
    List<Satisfaction> findByAgentNo(String agentNo);
    List<Satisfaction> findByCustomerId(Long customerId);
    Optional<Satisfaction> findOneByAppointmentId(Long appointmentId);
}
pamapi/src/main/java/com/pollex/pam/service/AppointmentService.java
@@ -2,7 +2,11 @@
import java.time.Instant;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import com.pollex.pam.enums.AppointmentStatusEnum;
import com.pollex.pam.service.dto.AppointmentDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -20,6 +24,9 @@
import com.pollex.pam.service.mapper.AppointmentCustomerViewMapper;
import com.pollex.pam.service.mapper.AppointmentDTOMapper;
import com.pollex.pam.web.rest.errors.AppointmentNotFoundException;
import static com.pollex.pam.enums.AppointmentStatusEnum.AVAILABLE;
import static com.pollex.pam.enums.AppointmentStatusEnum.DELETED;
@Service
@Transactional
@@ -41,7 +48,7 @@
    @Autowired
    AppointmentCustomerViewRepository appointmentCustomerViewRepository;
    @Autowired
    SatisfactionService satisfactionService;
@@ -50,7 +57,7 @@
        appointment.setCustomerId(SecurityUtils.getCustomerDBId());
        appointment.setCommunicateStatus(ContactStatusEnum.RESERVED);
        appointmentRepository.save(appointment);
    }
    public List<Appointment> findByAgentNo(String agentNo) {
@@ -64,16 +71,17 @@
        return appointmentRepository.save(appointment);
    }
    public AppointmentCustomerViewDTO getAppointmentDetail(Long appointmentId) {
        AppointmentCustomerView appointment = appointmentCustomerViewRepository.findById(appointmentId)
                .orElseThrow(AppointmentNotFoundException::new);
        return appointmentCustomerViewMapper.toAppointmentCustomerViewDTO(appointment);
    }
    public List<Appointment> findByAgentNoAndCustomerId(String agentNo, Long customerId) {
        return appointmentRepository.findByAgentNoAndCustomerId(agentNo, customerId);
    public List<AppointmentCustomerView> findAvailableByAgentNoAndCustomerId(String agentNo, Long customerId) {
        return appointmentCustomerViewRepository.findByAgentNoAndCustomerId(agentNo, customerId)
            .stream()
            .filter(appointmentCustomerView -> appointmentCustomerView.getStatus() == AVAILABLE)
            .collect(Collectors.toList());
    }
    public void recordConsultantReadTime(Long appointmentId) {
@@ -87,4 +95,32 @@
            log.debug("this appointment was read, read time = {}", appointment.getConsultantReadTime());
        }
    }
    public void updateAppointment(AppointmentDTO appointmentDTO) {
        Appointment appointment = appointmentDTOMapper.toAppointment(appointmentDTO);
        appointmentRepository.save(appointment);
    }
    public void markAppointmentDeleted(Long appointmentId) {
        Appointment appointment = appointmentRepository.findById(appointmentId).get();
        appointment.setStatus(DELETED);
        appointmentRepository.save(appointment);
    }
    public void recordAllAppointmentsView(String agentNo) {
        List<Appointment> consultantNotViewAppointments = findByAgentNo(agentNo)
            .stream()
            .filter(appointment -> Objects.isNull(appointment.getConsultantViewTime()))
            .collect(Collectors.toList());
        consultantNotViewAppointments.forEach(appointment -> appointment.setConsultantViewTime(Instant.now()));
        appointmentRepository.saveAll(consultantNotViewAppointments);
    }
    public List<AppointmentCustomerViewDTO> getConsultantAppointments(String agentNo) {
        return appointmentCustomerViewRepository.findByAgentNo(agentNo).stream()
            .filter(appointment -> appointment.getStatus() != DELETED)
            .map(appointmentCustomerViewMapper::toAppointmentCustomerViewDTO)
            .collect(Collectors.toList());
    }
}
pamapi/src/main/java/com/pollex/pam/service/ConsultantService.java
@@ -1,12 +1,11 @@
package com.pollex.pam.service;
import com.pollex.pam.domain.Appointment;
import com.pollex.pam.domain.AppointmentCustomerView;
import com.pollex.pam.domain.Consultant;
import com.pollex.pam.domain.CustomerFavoriteConsultant;
import com.pollex.pam.domain.Satisfaction;
import com.pollex.pam.enums.ContactStatusEnum;
import com.pollex.pam.enums.LoginResult;
import com.pollex.pam.repository.AppointmentCustomerViewRepository;
import com.pollex.pam.repository.AppointmentRepository;
import com.pollex.pam.repository.ConsultantRepository;
import com.pollex.pam.repository.CustomerFavoriteConsultantRepository;
import com.pollex.pam.security.SecurityUtils;
@@ -20,9 +19,9 @@
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.Instant;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
@Service
@@ -43,23 +42,66 @@
    AppointmentService appointmentService;
    @Autowired
    AppointmentRepository appointmentRepository;
    @Autowired
    AppointmentCustomerViewRepository appointmentCustomerViewRepository;
    LoginRecordService loginRecordService;
    @Autowired
    AppointmentCustomerViewMapper appointmentCustomerViewMapper;
    @Autowired
    LoginRecordService loginRecordService;
    SatisfactionService satisfactionService;
    public List<ConsultantDTO> getMyConsultantList() {
        Long userId = SecurityUtils.getCustomerDBId();
        return customerFavoriteConsultantRepository.findAllByCustomerId(userId)
    public List<CustomerFavoriteConsultantDTO> getMyConsultantList() {
        Long customerId = SecurityUtils.getCustomerDBId();
        return customerFavoriteConsultantRepository.findAllByCustomerId(customerId)
            .stream()
            .map(consultantMapper::toDto)
            .map(customerFavoriteConsultantRelation -> {
                Consultant consultant = customerFavoriteConsultantRelation.getConsultant();
                CustomerFavoriteConsultantDTO dto = consultantMapper.toCustomerFavoriteConsultantDto(consultant);
                dto.setContactStatus(ContactStatusEnum.PICKED);
                dto.setLatestAppointmentId(null);
                dto.setLatestAppointmentDate(null);
                dto.setLatestAppointmentScore(null);
                dto.setCreateTime(customerFavoriteConsultantRelation.getLastModifiedDate());
                setAppointmentInfo(
                    dto,
                    appointmentService.findAvailableByAgentNoAndCustomerId(consultant.getAgentNo(), customerId)
                );
                return dto;
            }).collect(Collectors.toList());
    }
    private void setAppointmentInfo(CustomerFavoriteConsultantDTO dto, List<AppointmentCustomerView> appointmentList) {
        List<AppointmentCustomerView> appointments = appointmentList.stream()
            .sorted(Comparator.comparing(AppointmentCustomerView::getAppointmentDate).reversed())
            .collect(Collectors.toList());
        dto.setAppointments(appointmentCustomerViewMapper.toAppointmentCustomerViewDTO(appointments));
        if (!appointments.isEmpty()) {
            AppointmentCustomerView latestAppointment = appointments.get(0);
            dto.setContactStatus(latestAppointment.getCommunicateStatus());
            dto.setLatestAppointmentId(latestAppointment.getId());
            dto.setLatestAppointmentDate(latestAppointment.getAppointmentDate());
            dto.setUpdateTime(latestAppointment.getLastModifiedDate());
            setLatestAppointmentScore(dto, latestAppointment);
        }
    }
    private void setLatestAppointmentScore(CustomerFavoriteConsultantDTO dto, AppointmentCustomerView latestAppointment) {
        Optional<Satisfaction> satisfactionOptional = satisfactionService.getByAppointmentId(latestAppointment.getId());
        if(satisfactionOptional.isPresent()) {
            Satisfaction satisfaction = satisfactionOptional.get();
            dto.setLatestAppointmentScore(satisfaction.getScore());
        }
        else {
            dto.setLatestAppointmentScore(null);
        }
    }
    public List<ConsultantDTO> getRecommendConsultantList() {
@@ -118,8 +160,7 @@
    public List<AppointmentCustomerViewDTO> getMyAppointment() {
        String agentNo = SecurityUtils.getAgentNo();
        List<AppointmentCustomerView> appointmentList = appointmentCustomerViewRepository.findByAgentNo(agentNo);
        return appointmentCustomerViewMapper.toAppointmentCustomerViewDTO(appointmentList);
        return appointmentService.getConsultantAppointments(agentNo);
    }
    public void removeConsultantFromCustomList(String agentNo) {
@@ -137,12 +178,6 @@
    public void recordAllAppointmentsView() {
        String agentNo = SecurityUtils.getAgentNo();
        List<Appointment> consultantNotViewAppointments = appointmentService.findByAgentNo(agentNo)
            .stream()
            .filter(appointment -> Objects.isNull(appointment.getConsultantViewTime()))
            .collect(Collectors.toList());
        consultantNotViewAppointments.forEach(appointment -> appointment.setConsultantViewTime(Instant.now()));
        appointmentRepository.saveAll(consultantNotViewAppointments);
        appointmentService.recordAllAppointmentsView(agentNo);
    }
}
pamapi/src/main/java/com/pollex/pam/service/SatisfactionService.java
@@ -9,7 +9,6 @@
import com.pollex.pam.domain.Appointment;
import com.pollex.pam.domain.Satisfaction;
import com.pollex.pam.enums.SatisfactionStatusEnum;
import com.pollex.pam.repository.CustomerRepository;
import com.pollex.pam.repository.SatisfactionRepository;
import com.pollex.pam.service.dto.SatisfactionCustomerCreateDTO;
@@ -21,22 +20,22 @@
@Service
@Transactional
public class SatisfactionService {
    @Autowired
    SatisfactionRepository satisfactionRepository;
    @Autowired
    AppointmentMapper appointmentMapper;
    @Autowired
    SatisfactionDTOMapper satisfactionDTOMapper;
    @Autowired
    SatisfactionMapper satisfactionMapper;
    @Autowired
    CustomerRepository customerRepository;
    public Satisfaction createSatisfaction(Satisfaction satisfaction) {
        return satisfactionRepository.save(satisfaction);
    }
@@ -62,4 +61,8 @@
        List<Satisfaction> satisfactionList = satisfactionRepository.findByCustomerId(customerDBId);
        return satisfactionMapper.toDTO(satisfactionList);
    }
    public Optional<Satisfaction> getByAppointmentId(Long appointmentId) {
        return satisfactionRepository.findOneByAppointmentId(appointmentId);
    }
}
pamapi/src/main/java/com/pollex/pam/service/dto/AppointmentCustomerViewDTO.java
@@ -2,10 +2,6 @@
import java.time.Instant;
import javax.persistence.Column;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import com.pollex.pam.enums.ContactStatusEnum;
public class AppointmentCustomerViewDTO {
@@ -22,6 +18,7 @@
    private String hopeContactTime;
    private String otherRequirement;
    private Instant appointmentDate;
    private Instant lastModifiedDate;
    private String agentNo;
    private Long customerId;
    private String name;
@@ -99,7 +96,13 @@
    public void setAppointmentDate(Instant appointmentDate) {
        this.appointmentDate = appointmentDate;
    }
    public String getAgentNo() {
    public Instant getLastModifiedDate() {
        return lastModifiedDate;
    }
    public void setLastModifiedDate(Instant lastModifiedDate) {
        this.lastModifiedDate = lastModifiedDate;
    }
    public String getAgentNo() {
        return agentNo;
    }
    public void setAgentNo(String agentNo) {
pamapi/src/main/java/com/pollex/pam/service/dto/AppointmentDTO.java
@@ -6,7 +6,6 @@
import com.pollex.pam.enums.ContactStatusEnum;
@Service
public class AppointmentDTO {
    private Long id;
@@ -21,6 +20,7 @@
    private String hopeContactTime;
    private String otherRequirement;
    private Instant appointmentDate;
    private Instant lastModifiedDate;
    private String agentNo;
    private Long customerId;
    private Instant consultantViewTime;
@@ -122,4 +122,11 @@
    public void setConsultantReadTime(Instant consultantReadTime) {
        this.consultantReadTime = consultantReadTime;
    }
    public Instant getLastModifiedDate() {
        return lastModifiedDate;
    }
    public void setLastModifiedDate(Instant lastModifiedDate) {
        this.lastModifiedDate = lastModifiedDate;
    }
}
pamapi/src/main/java/com/pollex/pam/service/dto/CustomerFavoriteConsultantDTO.java
¤ñ¹ï·sÀÉ®×
@@ -0,0 +1,152 @@
package com.pollex.pam.service.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.pollex.pam.enums.ContactStatusEnum;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.List;
public class CustomerFavoriteConsultantDTO {
    @JsonProperty("new")
    private boolean newConsultant;
    private String agentNo;
    private String name;
    private String img;
    private List<String> expertise;
    private Float avgScore;
    private ContactStatusEnum contactStatus;
    private Instant createTime;
    private Instant updateTime;
    private String role;
    private String seniority;
    private Long latestAppointmentId;
    private Instant latestAppointmentDate;
    private Float latestAppointmentScore;
    private List<AppointmentCustomerViewDTO> appointments;
    public boolean isNewConsultant() {
        if(createTime != null){
            Instant nowTimestamp = Instant.now();
            return ChronoUnit.DAYS.between(createTime, nowTimestamp) < 3;
        }
        return false;
    }
    public String getAgentNo() {
        return agentNo;
    }
    public void setAgentNo(String agentNo) {
        this.agentNo = agentNo;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getImg() {
        return img;
    }
    public void setImg(String img) {
        this.img = img;
    }
    public List<String> getExpertise() {
        return expertise;
    }
    public void setExpertise(List<String> expertise) {
        this.expertise = expertise;
    }
    public Float getLatestAppointmentScore() {
        return latestAppointmentScore;
    }
    public void setLatestAppointmentScore(Float latestAppointmentScore) {
        this.latestAppointmentScore = latestAppointmentScore;
    }
    public Float getAvgScore() {
        return avgScore;
    }
    public void setAvgScore(Float avgScore) {
        this.avgScore = avgScore;
    }
    public ContactStatusEnum getContactStatus() {
        return contactStatus;
    }
    public void setContactStatus(ContactStatusEnum contactStatus) {
        this.contactStatus = contactStatus;
    }
    public Instant getLatestAppointmentDate() {
        return latestAppointmentDate;
    }
    public void setLatestAppointmentDate(Instant latestAppointmentDate) {
        this.latestAppointmentDate = latestAppointmentDate;
    }
    public Instant getCreateTime() {
        return createTime;
    }
    public Instant getUpdateTime() {
        return updateTime;
    }
    public void setCreateTime(Instant createTime) {
        this.createTime = createTime;
    }
    public void setUpdateTime(Instant updateTime) {
        this.updateTime = updateTime;
    }
    public String getRole() {
        return role;
    }
    public void setRole(String role) {
        this.role = role;
    }
    public String getSeniority() {
        return seniority;
    }
    public void setSeniority(String seniority) {
        this.seniority = seniority;
    }
    public void setNewConsultant(boolean newConsultant) {
        this.newConsultant = newConsultant;
    }
    public Long getLatestAppointmentId() {
        return latestAppointmentId;
    }
    public void setLatestAppointmentId(Long latestAppointmentId) {
        this.latestAppointmentId = latestAppointmentId;
    }
    public List<AppointmentCustomerViewDTO> getAppointments() {
        return appointments;
    }
    public void setAppointments(List<AppointmentCustomerViewDTO> appointments) {
        this.appointments = appointments;
    }
}
pamapi/src/main/java/com/pollex/pam/service/dto/SatisfactionDTO.java
@@ -5,7 +5,7 @@
import com.pollex.pam.enums.SatisfactionStatusEnum;
public class SatisfactionDTO {
    private Long id;
    private Instant createdDate;
    private Instant lastModifiedDate;
@@ -13,6 +13,7 @@
    private String agentNo;
    private SatisfactionStatusEnum status;
    private Float score;
    private Long appointmentId;
    public Long getId() {
        return id;
    }
@@ -55,6 +56,6 @@
    public void setScore(Float score) {
        this.score = score;
    }
}
pamapi/src/main/java/com/pollex/pam/service/mapper/AppointmentDTOMapper.java
@@ -1,5 +1,6 @@
package com.pollex.pam.service.mapper;
import com.pollex.pam.service.dto.AppointmentDTO;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
@@ -9,10 +10,16 @@
@Service
public class AppointmentDTOMapper {
    public Appointment toAppointment(AppointmentCreateDTO source) {
        Appointment target = new Appointment();
        BeanUtils.copyProperties(source, target);
        return target;
    }
    public Appointment toAppointment(AppointmentDTO source) {
        Appointment target = new Appointment();
        BeanUtils.copyProperties(source, target);
        return target;
    }
}
pamapi/src/main/java/com/pollex/pam/service/mapper/AppointmentMapper.java
@@ -17,7 +17,7 @@
@Service
public class AppointmentMapper {
    @Autowired
    AppointmentRepository appointmentRepository;
@@ -34,16 +34,17 @@
    public Satisfaction toSatisfaction(Appointment appointment) {
        Satisfaction target = new Satisfaction();
        target.setAppointmentId(appointment.getId());
        target.setAgentNo(appointment.getAgentNo());
        target.setCustomerId(appointment.getCustomerId());
        return target;
    }
    public Satisfaction toSatisfaction(Long appointmentId) {
        Appointment appointment = appointmentRepository.findById(appointmentId).get();
        return toSatisfaction(appointment);
    }
}
pamapi/src/main/java/com/pollex/pam/service/mapper/ConsultantMapper.java
@@ -7,7 +7,9 @@
import com.pollex.pam.service.AppointmentService;
import com.pollex.pam.service.dto.ConsultantDTO;
import com.pollex.pam.service.dto.ConsultantDetailDTO;
import com.pollex.pam.service.dto.CustomerFavoriteConsultantDTO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -19,8 +21,22 @@
    private static final Character SPLIT_MASK = ',';
    @Autowired
    AppointmentService appointmentService;
    public CustomerFavoriteConsultantDTO toCustomerFavoriteConsultantDto(Consultant source) {
        CustomerFavoriteConsultantDTO consultantDTO = new CustomerFavoriteConsultantDTO();
        consultantDTO.setAgentNo(source.getAgentNo());
        consultantDTO.setName(source.getName());
        consultantDTO.setAvgScore(source.getAvgScore());
        consultantDTO.setSeniority(source.getSeniorityDTOString());
        consultantDTO.setExpertise(splitStringWithChar(source.getExpertise()));
        consultantDTO.setImg(source.getPhotoPath());
        consultantDTO.setRole(source.getRole());
        consultantDTO.setContactStatus(null);
        consultantDTO.setUpdateTime(null);
        consultantDTO.setLatestAppointmentId(null);
        return consultantDTO;
    }
    public ConsultantDTO toDto(Consultant source) {
        ConsultantDTO consultantDTO = new ConsultantDTO();
@@ -37,29 +53,6 @@
        consultantDTO.setLatestAppointmentId(null);
        return consultantDTO;
    }
    public ConsultantDTO toDto(CustomerFavoriteConsultant customerFavoriteConsultant) {
        Consultant consultant = customerFavoriteConsultant.getConsultant();
        ConsultantDTO dto = toDto(consultant);
        final Optional<Appointment> latestAppointmentOptional = appointmentService.findByAgentNoAndCustomerId(consultant.getAgentNo(), customerFavoriteConsultant.getCustomerId())
            .stream()
            .max(Comparator.comparing(Appointment::getAppointmentDate));
        if(latestAppointmentOptional.isPresent()) {
            Appointment latestAppointment = latestAppointmentOptional.get();
            dto.setContactStatus(latestAppointment.getCommunicateStatus());
            dto.setLatestAppointmentId(latestAppointment.getId());
            dto.setUpdateTime(latestAppointment.getAppointmentDate());
        }
        else {
            dto.setContactStatus(ContactStatusEnum.PICKED);
            dto.setLatestAppointmentId(null);
            dto.setUpdateTime(customerFavoriteConsultant.getLastModifiedDate());
        }
        return dto;
    }
    public ConsultantDetailDTO toDetailDto(Consultant source) {
pamapi/src/main/java/com/pollex/pam/web/rest/AppointmentResource.java
@@ -1,13 +1,9 @@
package com.pollex.pam.web.rest;
import com.pollex.pam.service.dto.AppointmentDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import com.pollex.pam.service.AppointmentService;
import com.pollex.pam.service.SatisfactionService;
@@ -20,10 +16,22 @@
    @Autowired
    AppointmentService appointmentService;
    @Autowired
    SatisfactionService satisfactionService;
    @PutMapping("")
    public ResponseEntity<Void> updateAppointment(@RequestBody AppointmentDTO appointment) {
        appointmentService.updateAppointment(appointment);
        return ResponseEntity.noContent().build();
    }
    @DeleteMapping("/{appointmentId}")
    public ResponseEntity<Void> markAppointmentDeleted(@PathVariable Long appointmentId) {
        appointmentService.markAppointmentDeleted(appointmentId);
        return ResponseEntity.noContent().build();
    }
    @PostMapping("/customer/create")
    public void clientCreateAppointment(@RequestBody AppointmentCreateDTO appointmentCreateDTO) {
        appointmentService.customerCreateAppointment(appointmentCreateDTO);
pamapi/src/main/java/com/pollex/pam/web/rest/ConsultantResource.java
@@ -25,8 +25,8 @@
    ConsultantService consultantService;
    @GetMapping("/favorite")
    public ResponseEntity<List<ConsultantDTO>> getMyConsultantList() {
        List<ConsultantDTO> myConsultants = consultantService.getMyConsultantList();
    public ResponseEntity<List<CustomerFavoriteConsultantDTO>> getMyConsultantList() {
        List<CustomerFavoriteConsultantDTO> myConsultants = consultantService.getMyConsultantList();
        return new ResponseEntity<>(myConsultants, HttpStatus.OK);
    }