保誠-保戶業務員媒合平台
[ADD] 新增約訪紀錄API
[ADD] 修改約訪記錄API
[ADD] 刪除約訪記錄API
[ADD] 取得顧問所有預約單的API新增約訪紀錄資料
修改4個檔案
新增11個檔案
492 ■■■■■ 已變更過的檔案
pamapi/src/doc/約訪紀錄API/修改約訪紀錄.txt 31 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/doc/約訪紀錄API/刪除約訪紀錄.txt 6 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/doc/約訪紀錄API/新增約訪紀錄.txt 27 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/doc/預約單/顧問取得所有自己的預約單API.txt 45 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/main/java/com/pollex/pam/domain/InterviewRecord.java 87 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/main/java/com/pollex/pam/enums/InterviewRecordStatusEnum.java 6 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/main/java/com/pollex/pam/repository/InterviewRecordRepository.java 18 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/main/java/com/pollex/pam/service/AppointmentService.java 20 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/main/java/com/pollex/pam/service/InterviewRecordService.java 82 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/main/java/com/pollex/pam/service/dto/AppointmentCustomerViewDTO.java 8 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/main/java/com/pollex/pam/service/dto/InterviewRecordDTO.java 69 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/main/java/com/pollex/pam/service/mapper/AppointmentCustomerViewMapper.java 6 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/main/java/com/pollex/pam/service/mapper/InterviewRecordMapper.java 37 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/main/java/com/pollex/pam/web/rest/InterviewRecordResource.java 36 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/main/java/com/pollex/pam/web/rest/errors/InterviewRecordNotFoundException.java 14 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
pamapi/src/doc/¬ù³X¬ö¿ýAPI/­×§ï¬ù³X¬ö¿ý.txt
¤ñ¹ï·sÀÉ®×
@@ -0,0 +1,31 @@
http post :
http://localhost:8080/api/interview_record/update
id : interviewRecord id
content : ç´„訪紀錄內容
interviewDate: é è¨ˆç´„訪時間
appointmentId: é ç´„å–®id
request body :
{
    "id":5,
    "content":"test record content2",
    "interviewDate":"2021-01-01T08:00:00.000",
    "appointmentId": 385
}
response body :
{
    "id": 5,
    "content": "test record content2",
    "interviewDate": "2021-01-01T08:00:00.000+00:00",
    "appointmentId": 385
}
pamapi/src/doc/¬ù³X¬ö¿ýAPI/§R°£¬ù³X¬ö¿ý.txt
¤ñ¹ï·sÀÉ®×
@@ -0,0 +1,6 @@
http delete :
http://localhost:8080/api/interview_record/{interviewRecordId}
http://localhost:8080/api/interview_record/5
pamapi/src/doc/¬ù³X¬ö¿ýAPI/·s¼W¬ù³X¬ö¿ý.txt
¤ñ¹ï·sÀÉ®×
@@ -0,0 +1,27 @@
http post :
http://localhost:8080/api/interview_record/create
interviewDate: é è¨ˆç´„訪日期
content : ç´€éŒ„內容
appointmentId: é ç´„å–®id
request body :
{
    "content":"test record content",
    "interviewDate":"2021-01-01T08:00:00.000",
    "appointmentId": 385
}
response body :
{
    "id": 5,
    "content": "test record content",
    "interviewDate": "2021-01-01T08:00:00.000+00:00",
    "appointmentId": 385
}
pamapi/src/doc/¹w¬ù³æ/ÅU°Ý¨ú±o©Ò¦³¦Û¤vªº¹w¬ù³æAPI.txt
@@ -3,30 +3,9 @@
http://localhost:8080/api/consultant/getMyAppointment
appointmentMemoList : å‚™è¨»è³‡æ–™
interviewRecordDTOs : ç´„訪紀錄
[ {
  "id" : 435,
  "phone" : "0973057067",
  "email" : "",
  "contactType" : "phone",
  "gender" : "male",
  "age" : "under_20",
  "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-29T09:33:16.643Z",
  "lastModifiedDate" : "2021-12-29T09:33:16.637Z",
  "agentNo" : "A568420",
  "customerId" : 90,
  "name" : "Jack",
  "consultantViewTime" : "2021-12-29T09:33:49.547Z",
  "consultantReadTime" : null,
  "contactTime" : null,
  "satisfactionScore" : null,
  "appointmentMemoList" : [ ]
}, {
  "id" : 385,
  "phone" : "0911223344",
  "email" : "SDD",
@@ -35,21 +14,27 @@
  "age" : "21-30",
  "job" : "內勤",
  "requirement" : "健康與保障",
  "communicateStatus" : "reserved",
  "communicateStatus" : "contacted",
  "hopeContactTime" : "'星期一,星期二,星期三,星期四,星期五,星期六,星期日、9:00~12:00,12:00~14:00,14:00~18:00,18:00~21:00'",
  "otherRequirement" : null,
  "appointmentDate" : "2021-12-16T07:11:05.400Z",
  "lastModifiedDate" : "2021-12-16T07:11:05.399Z",
  "lastModifiedDate" : "2021-12-28T07:16:37.004Z",
  "agentNo" : "A568420",
  "customerId" : 139,
  "name" : "Angula-test",
  "consultantViewTime" : "2021-12-27T02:02:18.711Z",
  "consultantReadTime" : "2021-12-29T09:14:24.209Z",
  "contactTime" : null,
  "consultantReadTime" : "2021-12-28T07:16:01.295Z",
  "contactTime" : "2021-12-28T07:16:37.004Z",
  "satisfactionScore" : null,
  "appointmentMemoList" : [ {
    "id" : 2,
    "content" : "test4",
  "appointmentMemoList" : [ ],
  "interviewRecordDTOs" : [ {
    "id" : 6,
    "content" : "test record content",
    "createdDate" : "2022-01-07T07:38:05.976Z",
    "lastModifiedDate" : "2022-01-07T07:38:05.976Z",
    "createdBy" : "A568420",
    "lastModifiedBy" : "A568420",
    "interviewDate" : "2021-01-01T08:00:00.000+00:00",
    "appointmentId" : 385
  } ]
} ]
} ]
pamapi/src/main/java/com/pollex/pam/domain/InterviewRecord.java
¤ñ¹ï·sÀÉ®×
@@ -0,0 +1,87 @@
package com.pollex.pam.domain;
import java.io.Serializable;
import java.util.Date;
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 com.pollex.pam.enums.InterviewRecordStatusEnum;
@Entity
@Table(name = "interview_record")
public class InterviewRecord extends AbstractAuditingEntity implements Serializable {
    /**
     *
     */
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(name = "content")
    private String content;
    @Column(name = "interview_date")
    private Date interviewDate;
    @Column(name = "appointment_id")
    private Long appointmentId;
    @Enumerated(EnumType.STRING)
    @Column(name = "status")
    private InterviewRecordStatusEnum status;
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getContent() {
        return content;
    }
    public void setContent(String content) {
        this.content = content;
    }
    public Date getInterviewDate() {
        return interviewDate;
    }
    public void setInterviewDate(Date interviewDate) {
        this.interviewDate = interviewDate;
    }
    public Long getAppointmentId() {
        return appointmentId;
    }
    public void setAppointmentId(Long appointmentId) {
        this.appointmentId = appointmentId;
    }
    public InterviewRecordStatusEnum getStatus() {
        return status;
    }
    public void setStatus(InterviewRecordStatusEnum status) {
        this.status = status;
    }
}
pamapi/src/main/java/com/pollex/pam/enums/InterviewRecordStatusEnum.java
¤ñ¹ï·sÀÉ®×
@@ -0,0 +1,6 @@
package com.pollex.pam.enums;
public enum InterviewRecordStatusEnum {
    AVAILABLE,
    DELETED
}
pamapi/src/main/java/com/pollex/pam/repository/InterviewRecordRepository.java
¤ñ¹ï·sÀÉ®×
@@ -0,0 +1,18 @@
package com.pollex.pam.repository;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.pollex.pam.domain.InterviewRecord;
import com.pollex.pam.enums.InterviewRecordStatusEnum;
@Repository
public interface InterviewRecordRepository extends JpaRepository<InterviewRecord, Long>{
    List<InterviewRecord> findByAppointmentId(Long appointmentId);
    List<InterviewRecord> findByAppointmentIdAndStatus(Long appointmentId, InterviewRecordStatusEnum status);
}
pamapi/src/main/java/com/pollex/pam/service/AppointmentService.java
@@ -8,6 +8,7 @@
import com.pollex.pam.config.ApplicationProperties;
import com.pollex.pam.service.dto.AppointmentUpdateDTO;
import com.pollex.pam.service.dto.InterviewRecordDTO;
import com.pollex.pam.web.rest.errors.SendEmailFailException;
import com.pollex.pam.web.rest.errors.SendSMSFailException;
import io.jsonwebtoken.lang.Assert;
@@ -19,7 +20,9 @@
import com.pollex.pam.domain.Appointment;
import com.pollex.pam.domain.AppointmentCustomerView;
import com.pollex.pam.domain.InterviewRecord;
import com.pollex.pam.enums.ContactStatusEnum;
import com.pollex.pam.enums.InterviewRecordStatusEnum;
import com.pollex.pam.repository.AppointmentCustomerViewRepository;
import com.pollex.pam.repository.AppointmentRepository;
import com.pollex.pam.security.SecurityUtils;
@@ -69,6 +72,9 @@
    @Autowired
    SpringTemplateEngine springTemplateEngine;
    @Autowired
    InterviewRecordService interviewRecordService;
    public Appointment customerCreateAppointment(AppointmentCreateDTO appointmentCreateDTO) {
        Appointment appointment = appointmentDTOMapper.toAppointment(appointmentCreateDTO);
@@ -120,15 +126,22 @@
        AppointmentCustomerViewDTO dto = appointmentCustomerViewMapper.toAppointmentCustomerViewDTO(appointment);
        setSatisfactionScore(dto, appointmentId);
//        setInterviewRecordDTO(dto);
        return dto;
    }
    public List<AppointmentCustomerViewDTO> getConsultantAvailableAppointments(String agentNo) {
    public void setInterviewRecordDTO(AppointmentCustomerViewDTO dto) {
        List<InterviewRecordDTO> interviewRecords = interviewRecordService.findByAppointmentIdAndStatus(dto.getId(), InterviewRecordStatusEnum.AVAILABLE);
        dto.setInterviewRecordDTOs(interviewRecords);
    }
    public List<AppointmentCustomerViewDTO> getConsultantAvailableAppointments(String agentNo) {
        return appointmentCustomerViewRepository.findByAgentNo(agentNo).stream()
            .filter(appointment -> appointment.getStatus() == AVAILABLE)
            .map(appointmentCustomerView -> {
                AppointmentCustomerViewDTO dto = appointmentCustomerViewMapper.toAppointmentCustomerViewDTO(appointmentCustomerView);
                setSatisfactionScore(dto, appointmentCustomerView.getId());
                return dto;
            })
            .collect(Collectors.toList());
@@ -244,4 +257,9 @@
    public String getAppointmentDetailUrl(Long appointmentId) {
        return applicationProperties.getFrontEndDomain() + "/myAppointmentList/contactedList?appointmentId=" + appointmentId;
    }
    public Appointment findById(Long id) {
        return appointmentRepository.findById(id)
                .orElseThrow(AppointmentNotFoundException::new);
    }
}
pamapi/src/main/java/com/pollex/pam/service/InterviewRecordService.java
¤ñ¹ï·sÀÉ®×
@@ -0,0 +1,82 @@
package com.pollex.pam.service;
import java.util.List;
import org.hibernate.boot.model.naming.IllegalIdentifierException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.pollex.pam.domain.Appointment;
import com.pollex.pam.domain.InterviewRecord;
import com.pollex.pam.enums.InterviewRecordStatusEnum;
import com.pollex.pam.repository.InterviewRecordRepository;
import com.pollex.pam.security.SecurityUtils;
import com.pollex.pam.service.dto.InterviewRecordDTO;
import com.pollex.pam.service.mapper.InterviewRecordMapper;
import com.pollex.pam.web.rest.errors.InterviewRecordNotFoundException;
@Service
public class InterviewRecordService {
    @Autowired
    InterviewRecordRepository interviewRecordRepository;
    @Autowired
    InterviewRecordMapper interviewRecordMapper;
    @Autowired
    AppointmentService appointmentService;
    public InterviewRecord create(InterviewRecordDTO dto) {
        if(dto.getId()!=null) {
            throw new IllegalArgumentException();
        }
        InterviewRecord record = interviewRecordMapper.toInterviewRecord(dto);
        checkAuth(record);
        record.setStatus(InterviewRecordStatusEnum.AVAILABLE);
        interviewRecordRepository.save(record);
        return record;
    }
    public InterviewRecord update(InterviewRecordDTO dto) {
        if(dto.getId()==null) {
            throw new IllegalArgumentException();
        }
        InterviewRecord record = findById(dto.getId());
        checkAuth(record);
        interviewRecordMapper.copyToInterviewRecord(dto, record);
        interviewRecordRepository.save(record);
        return record;
    }
    public void checkAuth(InterviewRecord record) {
        Appointment appointment = appointmentService.findById(record.getAppointmentId());
        if(!appointment.getAgentNo().equals(SecurityUtils.getAgentNo())) {
            throw new IllegalAccessError("The account can not edit the appointment");
        }
    }
    public void delete(Long interviewRecordId) {
        InterviewRecord record = findById(interviewRecordId);
        record.setStatus(InterviewRecordStatusEnum.DELETED);
        interviewRecordRepository.save(record);
    }
    public InterviewRecord findById(Long id) {
        return interviewRecordRepository.findById(id)
        .orElseThrow(InterviewRecordNotFoundException::new);
    }
    public List<InterviewRecordDTO> findByAppointmentId(Long appointmentId) {
        List<InterviewRecord> records = interviewRecordRepository.findByAppointmentId(appointmentId);
        return interviewRecordMapper.toInterviewRecordDTO(records);
    }
    public List<InterviewRecordDTO> findByAppointmentIdAndStatus(Long appointmentId, InterviewRecordStatusEnum status) {
        List<InterviewRecord> records = interviewRecordRepository.findByAppointmentIdAndStatus(appointmentId, status);
        return interviewRecordMapper.toInterviewRecordDTO(records);
    }
}
pamapi/src/main/java/com/pollex/pam/service/dto/AppointmentCustomerViewDTO.java
@@ -4,6 +4,7 @@
import java.util.List;
import com.pollex.pam.domain.AppointmentMemo;
import com.pollex.pam.domain.InterviewRecord;
import com.pollex.pam.enums.ContactStatusEnum;
public class AppointmentCustomerViewDTO {
@@ -29,6 +30,7 @@
    private Instant contactTime;
    private Float satisfactionScore;
    private List<AppointmentMemo> appointmentMemoList;
    private List<InterviewRecordDTO> interviewRecordDTOs;
    public Long getId() {
        return id;
@@ -156,6 +158,12 @@
    public void setAppointmentMemoList(List<AppointmentMemo> appointmentMemoList) {
        this.appointmentMemoList = appointmentMemoList;
    }
    public List<InterviewRecordDTO> getInterviewRecordDTOs() {
        return interviewRecordDTOs;
    }
    public void setInterviewRecordDTOs(List<InterviewRecordDTO> interviewRecordDTOs) {
        this.interviewRecordDTOs = interviewRecordDTOs;
    }
    
    
}
pamapi/src/main/java/com/pollex/pam/service/dto/InterviewRecordDTO.java
¤ñ¹ï·sÀÉ®×
@@ -0,0 +1,69 @@
package com.pollex.pam.service.dto;
import java.time.Instant;
import java.util.Date;
public class InterviewRecordDTO {
    private Long id;
    private String content;
    private Instant createdDate;
    private Instant lastModifiedDate;
    private String createdBy;
    private String lastModifiedBy;
    private Date interviewDate;
    private Long appointmentId;
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getContent() {
        return content;
    }
    public void setContent(String content) {
        this.content = content;
    }
    public Instant getCreatedDate() {
        return createdDate;
    }
    public void setCreatedDate(Instant createdDate) {
        this.createdDate = createdDate;
    }
    public Instant getLastModifiedDate() {
        return lastModifiedDate;
    }
    public void setLastModifiedDate(Instant lastModifiedDate) {
        this.lastModifiedDate = lastModifiedDate;
    }
    public String getCreatedBy() {
        return createdBy;
    }
    public void setCreatedBy(String createdBy) {
        this.createdBy = createdBy;
    }
    public String getLastModifiedBy() {
        return lastModifiedBy;
    }
    public void setLastModifiedBy(String lastModifiedBy) {
        this.lastModifiedBy = lastModifiedBy;
    }
    public Date getInterviewDate() {
        return interviewDate;
    }
    public void setInterviewDate(Date interviewDate) {
        this.interviewDate = interviewDate;
    }
    public Long getAppointmentId() {
        return appointmentId;
    }
    public void setAppointmentId(Long appointmentId) {
        this.appointmentId = appointmentId;
    }
}
pamapi/src/main/java/com/pollex/pam/service/mapper/AppointmentCustomerViewMapper.java
@@ -5,20 +5,26 @@
import java.util.List;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.pollex.pam.domain.AppointmentCustomerView;
import com.pollex.pam.service.AppointmentService;
import com.pollex.pam.service.dto.AppointmentCustomerViewDTO;
@Service
public class AppointmentCustomerViewMapper {
    @Autowired
    AppointmentService appointmentService;
    
    @Transactional
    public AppointmentCustomerViewDTO toAppointmentCustomerViewDTO(AppointmentCustomerView source) {
        AppointmentCustomerViewDTO target = new AppointmentCustomerViewDTO();
        BeanUtils.copyProperties(source, target);
        target.setAppointmentMemoList(source.getAppointmentMemoList());
        appointmentService.setInterviewRecordDTO(target);
        return target;
    }
pamapi/src/main/java/com/pollex/pam/service/mapper/InterviewRecordMapper.java
¤ñ¹ï·sÀÉ®×
@@ -0,0 +1,37 @@
package com.pollex.pam.service.mapper;
import static java.util.stream.Collectors.toList;
import java.util.List;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import com.pollex.pam.domain.InterviewRecord;
import com.pollex.pam.service.dto.InterviewRecordDTO;
@Service
public class InterviewRecordMapper {
    public InterviewRecord toInterviewRecord(InterviewRecordDTO source) {
        InterviewRecord target = new InterviewRecord();
        BeanUtils.copyProperties(source, target);
        return target;
    }
    public void copyToInterviewRecord(InterviewRecordDTO source, InterviewRecord target) {
        BeanUtils.copyProperties(source, target);
    }
    public List<InterviewRecordDTO> toInterviewRecordDTO(List<InterviewRecord> records) {
        return records.stream()
                .map(s-> toInterviewRecordDTO(s))
                .collect(toList());
    }
    public InterviewRecordDTO toInterviewRecordDTO(InterviewRecord source) {
        InterviewRecordDTO target = new InterviewRecordDTO();
        BeanUtils.copyProperties(source, target);
        return target;
    }
}
pamapi/src/main/java/com/pollex/pam/web/rest/InterviewRecordResource.java
¤ñ¹ï·sÀÉ®×
@@ -0,0 +1,36 @@
package com.pollex.pam.web.rest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
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 com.pollex.pam.domain.InterviewRecord;
import com.pollex.pam.service.InterviewRecordService;
import com.pollex.pam.service.dto.InterviewRecordDTO;
@RestController
@RequestMapping("/api/interview_record")
public class InterviewRecordResource {
    @Autowired
    InterviewRecordService interviewRecordService;
    @PostMapping("/create")
    public InterviewRecord create(@RequestBody InterviewRecordDTO dto) {
        return interviewRecordService.create(dto);
    }
    @PostMapping("/update")
    public InterviewRecord update(@RequestBody InterviewRecordDTO dto) {
        return interviewRecordService.update(dto);
    }
    @DeleteMapping("/{interviewRecordId}")
    public void delete(@PathVariable Long interviewRecordId) {
        interviewRecordService.delete(interviewRecordId);
    }
}
pamapi/src/main/java/com/pollex/pam/web/rest/errors/InterviewRecordNotFoundException.java
¤ñ¹ï·sÀÉ®×
@@ -0,0 +1,14 @@
package com.pollex.pam.web.rest.errors;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(code = HttpStatus.NOT_FOUND, reason = "InterviewRecord not found")
public class InterviewRecordNotFoundException extends RuntimeException{
    /**
     *
     */
    private static final long serialVersionUID = 1L;
}