diff --git a/.gitignore b/.gitignore index b94d08a..2f981f2 100644 --- a/.gitignore +++ b/.gitignore @@ -45,4 +45,4 @@ out/ application-mail.properties ### AWS S3 관련 정보 ### -application-S3.properties \ No newline at end of file +application-S3.properties diff --git a/src/main/java/kwthon_1team/kwthon/config/SecurityConfig.java b/src/main/java/kwthon_1team/kwthon/config/SecurityConfig.java index 1d1a069..1f3551c 100644 --- a/src/main/java/kwthon_1team/kwthon/config/SecurityConfig.java +++ b/src/main/java/kwthon_1team/kwthon/config/SecurityConfig.java @@ -15,7 +15,7 @@ @EnableWebSecurity public class SecurityConfig { private final String[] possibleAccess = {"/api/auth/signUp", "/api/auth/emailVerification", "/api/auth/login", - "/api/error", "/api", "/error", "/auth/**"}; + "/api/error", "/api", "/error", "/auth/**", "/friendMail/**"}; @Bean public PasswordEncoder passwordEncoder() { diff --git a/src/main/java/kwthon_1team/kwthon/controller/MailController.java b/src/main/java/kwthon_1team/kwthon/controller/MailController.java new file mode 100644 index 0000000..71b7091 --- /dev/null +++ b/src/main/java/kwthon_1team/kwthon/controller/MailController.java @@ -0,0 +1,31 @@ +package kwthon_1team.kwthon.controller; + +import kwthon_1team.kwthon.common.BaseResponse; +import kwthon_1team.kwthon.domian.dto.response.MailDetailResponse; +import kwthon_1team.kwthon.domian.dto.response.MailPagingResponse; +import kwthon_1team.kwthon.domian.dto.response.MailSummaryResponse; +import kwthon_1team.kwthon.service.MailService; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +public class MailController { + + private final MailService mailService; + + @GetMapping("/friendMail/{memberId}") + public BaseResponse> inquiryMailByMemberId( + @PathVariable("memberId") Long memberId, int page, int size + ){ + return new BaseResponse(HttpStatus.OK.value(), "친구 메일이 검색 되었습니다.",mailService.inquiryMailByFriendId(memberId, page, size)); + } + + @GetMapping("/friendMail/detail/{mailId}") + public BaseResponse inquiryMailByMailId(@PathVariable("mailId") Long mailId){ + return new BaseResponse(HttpStatus.OK.value(), "메일 정보를 불러왔습니다.", mailService.inquiryMailDetailByMailId(mailId)); + } +} diff --git a/src/main/java/kwthon_1team/kwthon/controller/MemberController.java b/src/main/java/kwthon_1team/kwthon/controller/MemberController.java index 60169dc..cd8ab67 100644 --- a/src/main/java/kwthon_1team/kwthon/controller/MemberController.java +++ b/src/main/java/kwthon_1team/kwthon/controller/MemberController.java @@ -1,6 +1,7 @@ package kwthon_1team.kwthon.controller; import kwthon_1team.kwthon.common.BaseResponse; +import kwthon_1team.kwthon.domian.dto.response.SearchResponse; import kwthon_1team.kwthon.domian.dto.request.AuthRequestDto; import kwthon_1team.kwthon.service.MemberService; import lombok.RequiredArgsConstructor; @@ -8,12 +9,19 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import java.util.List; + @RestController @RequiredArgsConstructor public class MemberController { private final MemberService memberService; + @GetMapping("/search") + public BaseResponse> search(@RequestParam String keyword) { + return new BaseResponse(HttpStatus.OK.value(), "검색 결과를 불러왔습니다.",memberService.search(keyword)); @PostMapping("/auth/signUp") public BaseResponse signUp(@RequestBody AuthRequestDto authRequestDto) { memberService.join(authRequestDto); diff --git a/src/main/java/kwthon_1team/kwthon/converter/MailConverter.java b/src/main/java/kwthon_1team/kwthon/converter/MailConverter.java new file mode 100644 index 0000000..c44540e --- /dev/null +++ b/src/main/java/kwthon_1team/kwthon/converter/MailConverter.java @@ -0,0 +1,53 @@ +package kwthon_1team.kwthon.converter; + +import kwthon_1team.kwthon.domian.dto.response.MailDetailResponse; +import kwthon_1team.kwthon.domian.dto.response.MailPagingResponse; +import kwthon_1team.kwthon.domian.dto.response.MailSummaryResponse; +import kwthon_1team.kwthon.domian.entity.Mail; +import kwthon_1team.kwthon.domian.entity.Photo; +import lombok.RequiredArgsConstructor; + +import org.springframework.stereotype.Component; +import org.springframework.data.domain.Page; + +@Component +@RequiredArgsConstructor +public class MailConverter { + + + public MailSummaryResponse toMailSummaryResponse(Mail mail, Photo Photo){ + return MailSummaryResponse.builder() + .mailId(mail.getMailId()) + .mailDate(mail.getMailDate()) + .mailTitle(mail.getMailTitle()) + .senderId(mail.getSender().getStudentId()) + .senderName(mail.getSender().getName()) + .isPublic(mail.getIsPublic()) + .photo(Photo) + .build(); + } + + public MailDetailResponse toMailDetailResponse(Mail mail){ + return MailDetailResponse.builder() + .mailId(mail.getMailId()) + .mailText(mail.getMailText()) + .mainTitle(mail.getMailTitle()) + .senderId(mail.getSender().getStudentId()) + .senderName(mail.getSender().getName()) + .isPublic(mail.getIsPublic()) + .mailDate(mail.getMailDate()) + .build(); + } + + public MailPagingResponse toMailPagingResponse(Page mails){ + return MailPagingResponse.builder() + .emails(mails.getContent()) + .page(mails.getNumber()) + .totalPages(mails.getTotalPages()) + .isFirst(mails.isFirst()) + .isLast(mails.isLast()) + .totalElements(mails.getNumberOfElements()) + .build(); + } + +} diff --git a/src/main/java/kwthon_1team/kwthon/converter/MemberConverter.java b/src/main/java/kwthon_1team/kwthon/converter/MemberConverter.java new file mode 100644 index 0000000..a4d207d --- /dev/null +++ b/src/main/java/kwthon_1team/kwthon/converter/MemberConverter.java @@ -0,0 +1,20 @@ +package kwthon_1team.kwthon.converter; + +import kwthon_1team.kwthon.domian.dto.response.SearchResponse; +import kwthon_1team.kwthon.domian.entity.Member; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class MemberConverter { + + public SearchResponse toSearchResponse(Member member){ + return SearchResponse.builder() + .studentId(member.getStudentId()) + .department(member.getDepartment()) + .name(member.getName()) + .build(); + } + +} diff --git a/src/main/java/kwthon_1team/kwthon/domian/dto/response/MailDetailResponse.java b/src/main/java/kwthon_1team/kwthon/domian/dto/response/MailDetailResponse.java new file mode 100644 index 0000000..b86bf23 --- /dev/null +++ b/src/main/java/kwthon_1team/kwthon/domian/dto/response/MailDetailResponse.java @@ -0,0 +1,24 @@ +package kwthon_1team.kwthon.domian.dto.response; + + +import kwthon_1team.kwthon.domian.entity.Photo; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; + +import java.time.LocalDateTime; +import java.util.List; + +@Getter +@AllArgsConstructor +@Builder +public class MailDetailResponse { + private Long mailId; + private String mainTitle; + private String mailText; + private Boolean isPublic; + private Long senderId; + private String senderName; + private LocalDateTime mailDate; + private List photos; +} diff --git a/src/main/java/kwthon_1team/kwthon/domian/dto/response/MailPagingResponse.java b/src/main/java/kwthon_1team/kwthon/domian/dto/response/MailPagingResponse.java new file mode 100644 index 0000000..3b7acc2 --- /dev/null +++ b/src/main/java/kwthon_1team/kwthon/domian/dto/response/MailPagingResponse.java @@ -0,0 +1,18 @@ +package kwthon_1team.kwthon.domian.dto.response; + +import lombok.*; + +import java.util.List; + +@Getter +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class MailPagingResponse { + private List emails; + private int page; + private int totalPages; + private int totalElements; + private Boolean isFirst; + private Boolean isLast; +} diff --git a/src/main/java/kwthon_1team/kwthon/domian/dto/response/MailSummaryResponse.java b/src/main/java/kwthon_1team/kwthon/domian/dto/response/MailSummaryResponse.java new file mode 100644 index 0000000..ea38fa9 --- /dev/null +++ b/src/main/java/kwthon_1team/kwthon/domian/dto/response/MailSummaryResponse.java @@ -0,0 +1,21 @@ +package kwthon_1team.kwthon.domian.dto.response; + +import kwthon_1team.kwthon.domian.entity.Photo; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; + +import java.time.LocalDateTime; + +@Getter +@AllArgsConstructor +@Builder +public class MailSummaryResponse { + private Long mailId; + private LocalDateTime mailDate; + private String mailTitle; + private Long senderId; + private String senderName; + private Boolean isPublic; + private Photo photo; +} diff --git a/src/main/java/kwthon_1team/kwthon/domian/dto/response/SearchResponse.java b/src/main/java/kwthon_1team/kwthon/domian/dto/response/SearchResponse.java new file mode 100644 index 0000000..ebaefcf --- /dev/null +++ b/src/main/java/kwthon_1team/kwthon/domian/dto/response/SearchResponse.java @@ -0,0 +1,14 @@ +package kwthon_1team.kwthon.domian.dto.response; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +@AllArgsConstructor +public class SearchResponse { + private Long studentId; + private String name; + private String department; +} diff --git a/src/main/java/kwthon_1team/kwthon/domian/entity/Mail.java b/src/main/java/kwthon_1team/kwthon/domian/entity/Mail.java index 48fac11..6139376 100644 --- a/src/main/java/kwthon_1team/kwthon/domian/entity/Mail.java +++ b/src/main/java/kwthon_1team/kwthon/domian/entity/Mail.java @@ -1,8 +1,7 @@ package kwthon_1team.kwthon.domian.entity; import jakarta.persistence.*; -import lombok.Data; -import lombok.NoArgsConstructor; +import lombok.*; import java.time.LocalDateTime; import java.util.ArrayList; @@ -11,6 +10,9 @@ @Data @NoArgsConstructor @Entity +@Getter +@AllArgsConstructor +@Builder public class Mail { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) diff --git a/src/main/java/kwthon_1team/kwthon/repository/MailRepository.java b/src/main/java/kwthon_1team/kwthon/repository/MailRepository.java new file mode 100644 index 0000000..a9477c0 --- /dev/null +++ b/src/main/java/kwthon_1team/kwthon/repository/MailRepository.java @@ -0,0 +1,15 @@ +package kwthon_1team.kwthon.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import kwthon_1team.kwthon.domian.entity.Mail; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Page; + + +public interface MailRepository extends JpaRepository { + + @Query("SELECT m FROM Mail m JOIN m.sender s WHERE m.isPublic = true AND s.studentId = :memberId") + Page findAllByFriendId(@Param("memberId") Long memberId, Pageable pageable); +} diff --git a/src/main/java/kwthon_1team/kwthon/repository/MemberRepository.java b/src/main/java/kwthon_1team/kwthon/repository/MemberRepository.java index 4822d86..78c5c6e 100644 --- a/src/main/java/kwthon_1team/kwthon/repository/MemberRepository.java +++ b/src/main/java/kwthon_1team/kwthon/repository/MemberRepository.java @@ -2,8 +2,16 @@ import kwthon_1team.kwthon.domian.entity.Member; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; +import java.util.List; + @Repository public interface MemberRepository extends JpaRepository { + + @Query("SELECT m FROM Member m WHERE " + + "(m.name LIKE%:keyword% OR m.department LIKE%:keyword% OR CAST(m.studentId AS String) LIKE %:keyword%)") + List findAllByKeyword(@Param("keyword") String keyword); } diff --git a/src/main/java/kwthon_1team/kwthon/service/MailService.java b/src/main/java/kwthon_1team/kwthon/service/MailService.java new file mode 100644 index 0000000..c0cd3d0 --- /dev/null +++ b/src/main/java/kwthon_1team/kwthon/service/MailService.java @@ -0,0 +1,11 @@ +package kwthon_1team.kwthon.service; + +import kwthon_1team.kwthon.domian.dto.response.MailDetailResponse; +import kwthon_1team.kwthon.domian.dto.response.MailPagingResponse; +import kwthon_1team.kwthon.domian.dto.response.MailSummaryResponse; + +public interface MailService { + + MailPagingResponse inquiryMailByFriendId(Long memberId, int page, int size); + MailDetailResponse inquiryMailDetailByMailId(Long mailId); +} diff --git a/src/main/java/kwthon_1team/kwthon/service/MailServiceImpl.java b/src/main/java/kwthon_1team/kwthon/service/MailServiceImpl.java new file mode 100644 index 0000000..4a0750a --- /dev/null +++ b/src/main/java/kwthon_1team/kwthon/service/MailServiceImpl.java @@ -0,0 +1,51 @@ +package kwthon_1team.kwthon.service; + + +import kwthon_1team.kwthon.converter.MailConverter; +import kwthon_1team.kwthon.domian.dto.response.MailDetailResponse; +import kwthon_1team.kwthon.domian.dto.response.MailPagingResponse; +import kwthon_1team.kwthon.domian.dto.response.MailSummaryResponse; +import kwthon_1team.kwthon.domian.entity.Mail; +import kwthon_1team.kwthon.domian.entity.Photo; +import kwthon_1team.kwthon.exception.BadRequestException; +import kwthon_1team.kwthon.repository.MailRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Page; + + +@Service +@RequiredArgsConstructor +public class MailServiceImpl implements MailService { + + private final MailRepository mailRepository; + private final MailConverter mailConverter; + + /* + * 메일 검색 + */ + @Override + public MailPagingResponse inquiryMailByFriendId(Long memberId, int page, int size){ + Pageable pageable = PageRequest.of(page, size); + Page mailPage = mailRepository.findAllByFriendId(memberId, pageable); + + Page mailSummaryResponses = mailPage.map(mail->{ + Photo firstPhoto = mail.getPhotos() != null && !mail.getPhotos().isEmpty() + ? mail.getPhotos().get(0) + : null; + return mailConverter.toMailSummaryResponse(mail,firstPhoto); + }); + + return mailConverter.toMailPagingResponse(mailSummaryResponses); + } + + @Override + public MailDetailResponse inquiryMailDetailByMailId(Long mailId){ + Mail mail = mailRepository.findById(mailId) + .orElseThrow(()-> new BadRequestException("존재하지 않는 메일입니다.")); + return mailConverter.toMailDetailResponse(mail); + } +} diff --git a/src/main/java/kwthon_1team/kwthon/service/MemberService.java b/src/main/java/kwthon_1team/kwthon/service/MemberService.java index 726eb1e..c644785 100644 --- a/src/main/java/kwthon_1team/kwthon/service/MemberService.java +++ b/src/main/java/kwthon_1team/kwthon/service/MemberService.java @@ -1,5 +1,6 @@ package kwthon_1team.kwthon.service; + import kwthon_1team.kwthon.domian.dto.request.AuthRequestDto; import kwthon_1team.kwthon.domian.entity.Member; import kwthon_1team.kwthon.exception.BadRequestException; @@ -7,12 +8,15 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; + import kwthon_1team.kwthon.converter.MemberConverter; + @Service @Transactional @RequiredArgsConstructor public class MemberService { private final MemberRepository memberRepository; + private final MemberConverter memberConverter; private String emailCode; @@ -44,5 +48,9 @@ private void validateDuplicateEmail(String email) { private Member converToMember(AuthRequestDto authRequestDto) { return new Member(authRequestDto); + + public List search(String keyword) { + List memberList = memberRepository.findAllByKeyword(keyword); + return memberList.stream().map(memberConverter::toSearchResponse).toList(); } }