From b775174e2bbb3e7ef9bb9e5c04c760bce1173ccc Mon Sep 17 00:00:00 2001 From: enjay27 Date: Sat, 12 Jun 2021 00:02:04 +0900 Subject: [PATCH 01/16] =?UTF-8?q?fix:=20Response=20StatusCode=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/devin/dev/model/DefaultResponse.java | 6 +-- .../com/devin/dev/sample/HelloService.java | 2 +- .../com/devin/dev/service/PostService.java | 41 ++++++++++--------- .../com/devin/dev/service/ReplyService.java | 32 +++++++-------- .../com/devin/dev/service/SubjectService.java | 8 ++-- .../com/devin/dev/service/UserService.java | 22 +++++----- .../java/com/devin/dev/utils/StatusCode.java | 21 ++++------ .../devin/dev/service/PostServiceTest.java | 18 ++++---- .../devin/dev/service/ReplyServiceTest.java | 16 ++++---- .../devin/dev/service/UserServiceTest.java | 10 ++--- 10 files changed, 90 insertions(+), 86 deletions(-) diff --git a/src/main/java/com/devin/dev/model/DefaultResponse.java b/src/main/java/com/devin/dev/model/DefaultResponse.java index 1bc4fde..affcbf6 100644 --- a/src/main/java/com/devin/dev/model/DefaultResponse.java +++ b/src/main/java/com/devin/dev/model/DefaultResponse.java @@ -10,18 +10,18 @@ @Getter public class DefaultResponse { - private final StatusCode statusCode; + private final int statusCode; private final ResponseMessage responseMessage; private final T data; public DefaultResponse(StatusCode statusCode, ResponseMessage responseMessage) { - this.statusCode = statusCode; + this.statusCode = statusCode.getCode(); this.responseMessage = responseMessage; this.data = null; } public DefaultResponse(StatusCode statusCode, ResponseMessage responseMessage, T data) { - this.statusCode = statusCode; + this.statusCode = statusCode.getCode(); this.responseMessage = responseMessage; this.data = data; } diff --git a/src/main/java/com/devin/dev/sample/HelloService.java b/src/main/java/com/devin/dev/sample/HelloService.java index 2dce9a9..1345296 100644 --- a/src/main/java/com/devin/dev/sample/HelloService.java +++ b/src/main/java/com/devin/dev/sample/HelloService.java @@ -34,7 +34,7 @@ public DefaultResponse signUp(String data, String password) { HelloDto helloDto = new HelloDto(hello); - return new DefaultResponse<>(StatusCode.OK, ResponseMessage.CREATED_USER, helloDto); + return new DefaultResponse<>(StatusCode.SUCCESS, ResponseMessage.CREATED_USER, helloDto); } } diff --git a/src/main/java/com/devin/dev/service/PostService.java b/src/main/java/com/devin/dev/service/PostService.java index 71bd39a..d92de63 100644 --- a/src/main/java/com/devin/dev/service/PostService.java +++ b/src/main/java/com/devin/dev/service/PostService.java @@ -5,7 +5,9 @@ import com.devin.dev.controller.reply.ReplyOrderCondition; import com.devin.dev.dto.post.PostDetailsDto; import com.devin.dev.dto.post.PostInfoDto; +import com.devin.dev.dto.reply.ReplyLikeDto; import com.devin.dev.entity.post.*; +import com.devin.dev.entity.reply.ReplyLike; import com.devin.dev.entity.user.User; import com.devin.dev.model.DefaultResponse; import com.devin.dev.repository.post.PostImageRepository; @@ -49,19 +51,19 @@ public class PostService { private final JwtAuthTokenProvider tokenProvider; @Transactional - public DefaultResponse post(HttpServletRequest request, PostForm form) { + public DefaultResponse post(PostForm form, HttpServletRequest request) { String token = tokenProvider.parseToken(request); Long userId; if (tokenProvider.validateToken(token)) { userId = tokenProvider.getUserId(token); } else { - return new DefaultResponse<>(StatusCode.BAD_REQUEST, ResponseMessage.NOT_FOUND_USER); + return new DefaultResponse<>(StatusCode.FAIL_AUTH, ResponseMessage.NOT_FOUND_USER); } // 엔티티 조회. 실패시 에러코드 반환 Optional userOptional = userRepository.findById(userId); if (userOptional.isEmpty()) { - return new DefaultResponse<>(StatusCode.BAD_REQUEST, ResponseMessage.NOT_FOUND_USER); + return new DefaultResponse<>(StatusCode.NOT_EXIST, ResponseMessage.NOT_FOUND_USER); } User user = userOptional.get(); List postSubjects = subjectRepository.findByNameIn(form.getPost_tags()); @@ -82,7 +84,7 @@ public DefaultResponse post(HttpServletRequest request, PostForm form) { PostDetailsDto postDetailsDto = new PostDetailsDto(post); // 성공 메시지 및 코드 반환 - return new DefaultResponse<>(StatusCode.OK, ResponseMessage.POST_UPLOAD_SUCCESS, postDetailsDto); + return new DefaultResponse<>(StatusCode.SUCCESS, ResponseMessage.POST_UPLOAD_SUCCESS, postDetailsDto); } @Transactional @@ -90,7 +92,7 @@ public DefaultResponse post(Long userId, String title, String co // 엔티티 조회. 실패시 에러코드 반환 Optional userOptional = userRepository.findById(userId); if (userOptional.isEmpty()) { - return new DefaultResponse<>(StatusCode.BAD_REQUEST, ResponseMessage.NOT_FOUND_USER); + return new DefaultResponse<>(StatusCode.NOT_EXIST, ResponseMessage.NOT_FOUND_USER); } User user = userOptional.get(); List postSubjects = subjectRepository.findByNameIn(tags); @@ -111,7 +113,7 @@ public DefaultResponse post(Long userId, String title, String co PostDetailsDto postDto = new PostDetailsDto(post); // 성공 메시지 및 코드 반환 - return new DefaultResponse<>(StatusCode.OK, ResponseMessage.POST_UPLOAD_SUCCESS, postDto); + return new DefaultResponse<>(StatusCode.SUCCESS, ResponseMessage.POST_UPLOAD_SUCCESS, postDto); } // 게시글 수정 @@ -120,11 +122,11 @@ public DefaultResponse editPost(Long userId, Long postId, String title, Strin // 엔티티 조회. 실패시 에러코드 반환 Optional userOptional = userRepository.findById(userId); if (userOptional.isEmpty()) { - return new DefaultResponse<>(StatusCode.BAD_REQUEST, ResponseMessage.NOT_FOUND_USER); + return new DefaultResponse<>(StatusCode.NOT_EXIST, ResponseMessage.NOT_FOUND_USER); } Optional postOptional = postRepository.findById(postId); if (postOptional.isEmpty()) { - return new DefaultResponse<>(StatusCode.BAD_REQUEST, ResponseMessage.NOT_FOUND_POST); + return new DefaultResponse<>(StatusCode.NOT_EXIST, ResponseMessage.NOT_FOUND_POST); } Post post = postOptional.get(); List postSubjects = subjectRepository.findByNameIn(tags); @@ -158,54 +160,55 @@ public DefaultResponse editPost(Long userId, Long postId, String title, Strin postTagRepository.saveAll(newPostTags); // 성공 메시지 및 코드 반환 - return new DefaultResponse<>(StatusCode.OK, ResponseMessage.POST_EDIT_SUCCESS); + return new DefaultResponse<>(StatusCode.SUCCESS, ResponseMessage.POST_EDIT_SUCCESS); } - @Transactional + @Transactional(readOnly = true) public DefaultResponse getPost(Long postId, ReplyOrderCondition replyOrderCondition) { Optional postOptional = postRepository.findPostDetailsById(postId, replyOrderCondition); if (postOptional.isEmpty()) { - return new DefaultResponse<>(StatusCode.BAD_REQUEST, ResponseMessage.NOT_FOUND_POST); + return new DefaultResponse<>(StatusCode.NOT_EXIST, ResponseMessage.NOT_FOUND_POST); } PostDetailsDto postDetailsDto = postOptional.get(); - return new DefaultResponse<>(StatusCode.OK, ResponseMessage.FOUND_POST, postDetailsDto); + return new DefaultResponse<>(StatusCode.SUCCESS, ResponseMessage.FOUND_POST, postDetailsDto); } // 게시글 검색 - @Transactional + @Transactional(readOnly = true) public DefaultResponse> getPostInfoListByCondition(PostSearchCondition condition, Pageable pageable) { Page postDtos = postRepository.findPostInfoDtoPageByCondition(condition, pageable); PageImpl page = new PageImpl<>(postDtos.toList(), pageable, postDtos.getTotalElements()); - return new DefaultResponse<>(StatusCode.OK, ResponseMessage.FOUND_POST, page); + return new DefaultResponse<>(StatusCode.SUCCESS, ResponseMessage.FOUND_POST, page); } - @Transactional + @Transactional(readOnly = true) public DefaultResponse> getPostInfoList(Long id, Pageable pageable) { Page posts = (id > 0)? postRepository.findAllByTagId(id, pageable) : postRepository.findAll(pageable); Page postInfoDtos = posts.map(PostInfoDto::new); PageImpl postInfoDtosImpl = new PageImpl<>(postInfoDtos.toList(), pageable, postInfoDtos.getTotalElements()); - return new DefaultResponse<>(StatusCode.OK, ResponseMessage.FOUND_POST, postInfoDtosImpl); + return new DefaultResponse<>(StatusCode.SUCCESS, ResponseMessage.FOUND_POST, postInfoDtosImpl); } + @Transactional public DefaultResponse deletePost(Long postId) { Optional postOptional = postRepository.findById(postId); if (postOptional.isEmpty()) { - return new DefaultResponse<>(StatusCode.BAD_REQUEST, ResponseMessage.NOT_FOUND_POST); + return new DefaultResponse<>(StatusCode.NOT_EXIST, ResponseMessage.NOT_FOUND_POST); } Post post = postOptional.get(); postImageRepository.deleteAll(post.getImages()); postTagRepository.deleteAll(post.getTags()); - postLikeRepository.deleteAll(post.getPostLikes()); + postLikeRepository.deleteAll(post.getLikes()); replyImageRepository.deleteAll(post.getReplies().stream().flatMap(reply -> reply.getImages().stream()).collect(Collectors.toList())); replyLikeRepository.deleteAll(post.getReplies().stream().flatMap(reply -> reply.getLikes().stream()).collect(Collectors.toList())); replyRepository.deleteAll(post.getReplies()); postRepository.delete(post); - return new DefaultResponse<>(StatusCode.OK, ResponseMessage.DELETED_POST); + return new DefaultResponse<>(StatusCode.SUCCESS, ResponseMessage.DELETED_POST); } } diff --git a/src/main/java/com/devin/dev/service/ReplyService.java b/src/main/java/com/devin/dev/service/ReplyService.java index 4df521f..6ebad84 100644 --- a/src/main/java/com/devin/dev/service/ReplyService.java +++ b/src/main/java/com/devin/dev/service/ReplyService.java @@ -43,13 +43,13 @@ public DefaultResponse reply(Long userId, Long postId, String content, // 엔티티 조회. 실패시 response 인스턴스 반환 Optional userOptional = userRepository.findById(userId); if (userOptional.isEmpty()) { - return new DefaultResponse<>(StatusCode.BAD_REQUEST, ResponseMessage.NOT_FOUND_USER); + return new DefaultResponse<>(StatusCode.NOT_EXIST, ResponseMessage.NOT_FOUND_USER); } User user = userOptional.get(); Optional postOptional = postRepository.findById(postId); if (postOptional.isEmpty()) { - return new DefaultResponse<>(StatusCode.BAD_REQUEST, ResponseMessage.NOT_FOUND_POST); + return new DefaultResponse<>(StatusCode.NOT_EXIST, ResponseMessage.NOT_FOUND_POST); } Post post = postOptional.get(); @@ -70,7 +70,7 @@ public DefaultResponse reply(Long userId, Long postId, String content, ReplyDto replyDto = ReplyMapper.replyToReplyDto(reply); // response 객체 리턴 - return new DefaultResponse<>(StatusCode.OK, ResponseMessage.REPLY_UPLOAD_SUCCESS, replyDto); + return new DefaultResponse<>(StatusCode.SUCCESS, ResponseMessage.REPLY_UPLOAD_SUCCESS, replyDto); } // 답변 수정 @@ -79,18 +79,18 @@ public DefaultResponse editReply(Long userId, Long replyId, String con // 엔티티 조회. 실패시 response 인스턴스 반환 Optional userOptional = userRepository.findById(userId); if (userOptional.isEmpty()) { - return new DefaultResponse<>(StatusCode.BAD_REQUEST, ResponseMessage.NOT_FOUND_USER); + return new DefaultResponse<>(StatusCode.NOT_EXIST, ResponseMessage.NOT_FOUND_USER); } User user = userOptional.get(); Optional replyOptional = replyRepository.findById(replyId); if (replyOptional.isEmpty()) { - return new DefaultResponse<>(StatusCode.BAD_REQUEST, ResponseMessage.NOT_FOUND_REPLY); + return new DefaultResponse<>(StatusCode.NOT_EXIST, ResponseMessage.NOT_FOUND_REPLY); } Reply reply = replyOptional.get(); if (isNotSameUser(user, reply.getUser())) { - return new DefaultResponse<>(StatusCode.BAD_REQUEST, ResponseMessage.NOT_SAME_USER); + return new DefaultResponse<>(StatusCode.CONDITION_FAIL, ResponseMessage.NOT_SAME_USER); } // 기존 이미지 경로 삭제 @@ -110,7 +110,7 @@ public DefaultResponse editReply(Long userId, Long replyId, String con ReplyDto replyDto = ReplyMapper.replyToReplyDto(reply); // response 객체 리턴 - return new DefaultResponse<>(StatusCode.OK, ResponseMessage.REPLY_EDIT_SUCCESS, replyDto); + return new DefaultResponse<>(StatusCode.SUCCESS, ResponseMessage.REPLY_EDIT_SUCCESS, replyDto); } // 좋아요 상태변경 @@ -119,13 +119,13 @@ public DefaultResponse changeReplyLike(Long userId, Long replyId) // 엔티티 조회. 실패시 response 인스턴스 반환 Optional userOptional = userRepository.findById(userId); if (userOptional.isEmpty()) { - return new DefaultResponse<>(StatusCode.BAD_REQUEST, ResponseMessage.NOT_FOUND_USER); + return new DefaultResponse<>(StatusCode.NOT_EXIST, ResponseMessage.NOT_FOUND_USER); } User user = userOptional.get(); Optional replyOptional = replyRepository.findById(replyId); if (replyOptional.isEmpty()) { - return new DefaultResponse<>(StatusCode.BAD_REQUEST, ResponseMessage.NOT_FOUND_REPLY); + return new DefaultResponse<>(StatusCode.NOT_EXIST, ResponseMessage.NOT_FOUND_REPLY); } Reply reply = replyOptional.get(); @@ -156,7 +156,7 @@ public DefaultResponse changeReplyLike(Long userId, Long replyId) ReplyLikeDto replyLikeDto = new ReplyLikeDto(replyLike.getId(), user.getName()); - return new DefaultResponse<>(StatusCode.OK, ResponseMessage.REPLY_LIKE_CHANGE_SUCCESS, replyLikeDto); + return new DefaultResponse<>(StatusCode.SUCCESS, ResponseMessage.REPLY_LIKE_CHANGE_SUCCESS, replyLikeDto); } @Transactional @@ -164,24 +164,24 @@ public DefaultResponse deleteReply(Long userId, Long replyId) { // 엔티티 조회. 실패시 response 인스턴스 반환 Optional userOptional = userRepository.findById(userId); if (userOptional.isEmpty()) { - return new DefaultResponse<>(StatusCode.BAD_REQUEST, ResponseMessage.NOT_FOUND_USER); + return new DefaultResponse<>(StatusCode.NOT_EXIST, ResponseMessage.NOT_FOUND_USER); } User user = userOptional.get(); Optional replyOptional = replyRepository.findById(replyId); if (replyOptional.isEmpty()) { - return new DefaultResponse<>(StatusCode.BAD_REQUEST, ResponseMessage.NOT_FOUND_REPLY); + return new DefaultResponse<>(StatusCode.NOT_EXIST, ResponseMessage.NOT_FOUND_REPLY); } Reply reply = replyOptional.get(); // 작성자 확인 if (isNotSameUser(user, reply.getUser())) { - return new DefaultResponse<>(StatusCode.BAD_REQUEST, ResponseMessage.NOT_SAME_USER); + return new DefaultResponse<>(StatusCode.CONDITION_FAIL, ResponseMessage.NOT_SAME_USER); } // 채택된 답변인지 확인 if (reply.getStatus() == ReplyStatus.SELECTED) { - return new DefaultResponse<>(StatusCode.BAD_REQUEST, ResponseMessage.CANNOT_DELETE_SELECTED); + return new DefaultResponse<>(StatusCode.CONDITION_FAIL, ResponseMessage.CANNOT_DELETE_SELECTED); } // 리플 작성자 경험치 삭제 @@ -191,7 +191,7 @@ public DefaultResponse deleteReply(Long userId, Long replyId) { reply.setStatus(ReplyStatus.DELETED); replyRepository.save(reply); - return new DefaultResponse<>(StatusCode.OK, ResponseMessage.REPLY_DELETE_SUCCESS); + return new DefaultResponse<>(StatusCode.SUCCESS, ResponseMessage.REPLY_DELETE_SUCCESS); } @Transactional(readOnly = true) @@ -200,7 +200,7 @@ public DefaultResponse> findRepliesInPost(Long postId, Pageable p List replyDtos = ReplyMapper.toDtos(replies.toList()); PageImpl page = new PageImpl<>(replyDtos, pageable, replies.getTotalElements()); - return new DefaultResponse<>(StatusCode.OK, ResponseMessage.FOUND_POST, page); + return new DefaultResponse<>(StatusCode.SUCCESS, ResponseMessage.FOUND_POST, page); } private boolean isNotSameUser(User firstUser, User secondUser) { diff --git a/src/main/java/com/devin/dev/service/SubjectService.java b/src/main/java/com/devin/dev/service/SubjectService.java index 70913a3..a7937ba 100644 --- a/src/main/java/com/devin/dev/service/SubjectService.java +++ b/src/main/java/com/devin/dev/service/SubjectService.java @@ -21,23 +21,23 @@ public class SubjectService { public DefaultResponse addSubject(String name) { Optional subjectOptional = subjectRepository.findByName(name); if (subjectOptional.isPresent()) { - return new DefaultResponse<>(StatusCode.BAD_REQUEST, ResponseMessage.EXIST_SUBJECT); + return new DefaultResponse<>(StatusCode.CONDITION_FAIL, ResponseMessage.EXIST_SUBJECT); } Subject subject = new Subject(name); subjectRepository.save(subject); - return new DefaultResponse<>(StatusCode.OK, ResponseMessage.CREATED_SUBJECT); + return new DefaultResponse<>(StatusCode.SUCCESS, ResponseMessage.CREATED_SUBJECT); } @Transactional public DefaultResponse removeSubject(String name) { Optional subjectOptional = subjectRepository.findByName(name); if (subjectOptional.isEmpty()) { - return new DefaultResponse<>(StatusCode.BAD_REQUEST, ResponseMessage.NOT_FOUND_SUBJECT); + return new DefaultResponse<>(StatusCode.NOT_EXIST, ResponseMessage.NOT_FOUND_SUBJECT); } subjectRepository.delete(subjectOptional.get()); - return new DefaultResponse<>(StatusCode.OK, ResponseMessage.DELETE_SUBJECT); + return new DefaultResponse<>(StatusCode.SUCCESS, ResponseMessage.DELETE_SUBJECT); } } diff --git a/src/main/java/com/devin/dev/service/UserService.java b/src/main/java/com/devin/dev/service/UserService.java index fa0595c..ee99778 100644 --- a/src/main/java/com/devin/dev/service/UserService.java +++ b/src/main/java/com/devin/dev/service/UserService.java @@ -33,7 +33,7 @@ public DefaultResponse signUp(UserSimpleDto userDto) { // 엔티티 조회 Optional foundUser = userRepository.findByEmailEquals(userDto.getUserEmail()); if (foundUser.isPresent()) { - return new DefaultResponse<>(StatusCode.BAD_REQUEST, ResponseMessage.EXIST_USER_EMAIL); + return new DefaultResponse<>(StatusCode.CONDITION_FAIL, ResponseMessage.EXIST_USER_EMAIL); } // 비밀번호 암호화 @@ -47,7 +47,7 @@ public DefaultResponse signUp(UserSimpleDto userDto) { UserDetailsDto userDetailsDto = new UserDetailsDto(user); - return new DefaultResponse<>(StatusCode.OK, ResponseMessage.CREATED_USER, userDetailsDto); + return new DefaultResponse<>(StatusCode.SUCCESS, ResponseMessage.CREATED_USER, userDetailsDto); } @Transactional(readOnly = true) @@ -55,22 +55,22 @@ public DefaultResponse signIn(UserSimpleDto userDto) { // DTO email 로 조회 Optional userOptional = userRepository.findUserDetailsByEmail(userDto.getUserEmail()); if (userOptional.isEmpty()) { - return new DefaultResponse<>(StatusCode.BAD_REQUEST, ResponseMessage.NOT_FOUND_EMAIL); + return new DefaultResponse<>(StatusCode.NOT_EXIST, ResponseMessage.NOT_FOUND_EMAIL); } UserDetailsDto userDetailsDto = userOptional.get(); // 비밀번호 체크 boolean passwordCheck = passwordEncoder.matches(userDto.getUserPassword(), userDetailsDto.getPassword()); if (!passwordCheck) { - return new DefaultResponse<>(StatusCode.BAD_REQUEST, ResponseMessage.INCORRECT_PASSWORD); + return new DefaultResponse<>(StatusCode.FAIL_AUTH, ResponseMessage.INCORRECT_PASSWORD); } // 활성 유저 체크 if (userDetailsDto.getStatus() != UserStatus.ACTIVE) { - return new DefaultResponse<>(StatusCode.BAD_REQUEST, ResponseMessage.INACTIVE_USER); + return new DefaultResponse<>(StatusCode.CONDITION_FAIL, ResponseMessage.INACTIVE_USER); } - return new DefaultResponse<>(StatusCode.OK, ResponseMessage.LOGIN_SUCCESS); + return new DefaultResponse<>(StatusCode.SUCCESS, ResponseMessage.LOGIN_SUCCESS); } @Transactional @@ -78,14 +78,14 @@ public DefaultResponse changeStatus(UserSimpleDto userDto, UserS // 엔티티 조회 Optional userOptional = userRepository.findByEmailEquals(userDto.getUserEmail()); if (userOptional.isEmpty()) { - return new DefaultResponse<>(StatusCode.BAD_REQUEST, ResponseMessage.NOT_FOUND_USER); + return new DefaultResponse<>(StatusCode.NOT_EXIST, ResponseMessage.NOT_FOUND_USER); } User user = userOptional.get(); // 비밀번호 체크 boolean passwordCheck = passwordEncoder.matches(userDto.getUserPassword(), user.getPassword()); if (!passwordCheck) { - return new DefaultResponse<>(StatusCode.BAD_REQUEST, ResponseMessage.INCORRECT_PASSWORD); + return new DefaultResponse<>(StatusCode.FAIL_AUTH, ResponseMessage.INCORRECT_PASSWORD); } // 상태 변경 @@ -93,7 +93,7 @@ public DefaultResponse changeStatus(UserSimpleDto userDto, UserS UserDetailsDto userDetailsDto = new UserDetailsDto(user); - return new DefaultResponse<>(StatusCode.BAD_REQUEST, ResponseMessage.CHANGE_USER_STATUS, userDetailsDto); + return new DefaultResponse<>(StatusCode.SUCCESS, ResponseMessage.CHANGE_USER_STATUS, userDetailsDto); } @Transactional @@ -109,7 +109,7 @@ public User findUserById(Long userId) { public DefaultResponse join(UserSimpleDto userSimpleDto) { userSimpleDto.setUserPassword(passwordEncoder.encode(userSimpleDto.getUserPassword())); User user = userRepository.save(new User(userSimpleDto)); - return new DefaultResponse<>(StatusCode.CREATED, ResponseMessage.CREATED_USER, user.getId()); + return new DefaultResponse<>(StatusCode.SUCCESS, ResponseMessage.CREATED_USER, user.getId()); } @Transactional @@ -123,6 +123,6 @@ public DefaultResponse login(UserLoginRequestDto userLoginRequestDto) { } JwtAuthToken token = jwtAuthTokenProvider.publishToken(user.getId()); UserLoginResponseDto responseDto = new UserLoginResponseDto(user, token); - return new DefaultResponse<>(StatusCode.OK, ResponseMessage.LOGIN_SUCCESS, responseDto); + return new DefaultResponse<>(StatusCode.SUCCESS, ResponseMessage.LOGIN_SUCCESS, responseDto); } } diff --git a/src/main/java/com/devin/dev/utils/StatusCode.java b/src/main/java/com/devin/dev/utils/StatusCode.java index 95bd0d3..27195e0 100644 --- a/src/main/java/com/devin/dev/utils/StatusCode.java +++ b/src/main/java/com/devin/dev/utils/StatusCode.java @@ -1,23 +1,20 @@ package com.devin.dev.utils; public enum StatusCode { - OK(200), - CREATED(201), - NO_CONTENT(204), - BAD_REQUEST(400), - UNAUTHORIZED(401), - FORBIDDEN(403), - NOT_FOUND(404), // 페이지가 없는 경우 - INTERNAL_SERVER_ERROR(500), - SERVICE_UNAVAILABLE(503), - DB_ERROR(600), SUCCESS(0), - FAIL_AUTH(400001), + FAIL_AUTH(40001), NOT_ENOUGH_PARM(40002), - NOT_EXIST(400003), // 찾으려는 정보가 없는 경우 + NOT_EXIST(40003), // 찾으려는 정보가 없는 경우 CONDITION_FAIL(40004), ; + private final int code; + StatusCode(int code) { + this.code = code; + } + + public int getCode() { + return code; } } diff --git a/src/test/java/com/devin/dev/service/PostServiceTest.java b/src/test/java/com/devin/dev/service/PostServiceTest.java index 6e7cf0b..8d0d37b 100644 --- a/src/test/java/com/devin/dev/service/PostServiceTest.java +++ b/src/test/java/com/devin/dev/service/PostServiceTest.java @@ -2,10 +2,7 @@ import com.devin.dev.controller.reply.ReplyOrderCondition; import com.devin.dev.dto.post.PostDetailsDto; -import com.devin.dev.entity.post.Post; -import com.devin.dev.entity.post.PostImage; -import com.devin.dev.entity.post.PostTag; -import com.devin.dev.entity.post.Subject; +import com.devin.dev.entity.post.*; import com.devin.dev.entity.user.User; import com.devin.dev.entity.user.UserStatus; import com.devin.dev.model.DefaultResponse; @@ -16,6 +13,9 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.test.annotation.Rollback; +import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; import org.springframework.transaction.annotation.Transactional; import javax.persistence.EntityManager; @@ -58,7 +58,7 @@ void createSampleData() { @Test void postSucceeded() { DefaultResponse response = postService.post(postUser.getId(), "titleA1", "postA1", List.of("s1", "s2"), List.of("p1", "p2", "p3")); - assertThat(response.getStatusCode()).isEqualTo(StatusCode.OK); + assertThat(response.getStatusCode()).isEqualTo(StatusCode.SUCCESS.getCode()); assertThat(response.getResponseMessage()).isEqualTo(ResponseMessage.POST_UPLOAD_SUCCESS); List posts = postRepository.findByTitle("titleA1"); @@ -72,7 +72,7 @@ void postSucceeded() { @Test void postFailed() { DefaultResponse response = postService.post(9999L, "titleA1", "postA1", List.of("s1", "s2"), List.of("p1", "p2", "p3")); - assertThat(response.getStatusCode()).isEqualTo(StatusCode.BAD_REQUEST); + assertThat(response.getStatusCode()).isEqualTo(StatusCode.NOT_EXIST.getCode()); assertThat(response.getResponseMessage()).isEqualTo(ResponseMessage.NOT_FOUND_USER); } @@ -120,15 +120,18 @@ void getPostSucceeded() { post1.setPostTags(postTags); List postImages = PostImage.createPostImages(List.of("p1", "p2", "p3")); post1.setPostImages(postImages); + post1.setStatus(PostStatus.NOT_SELECTED); postTags.forEach(em::persist); postImages.forEach(em::persist); em.persist(post1); + em.flush(); + em.clear(); ReplyOrderCondition replyOrderCondition = new ReplyOrderCondition(); replyOrderCondition.setLatestDate(true); DefaultResponse response = postService.getPost(post1.getId(), replyOrderCondition); - assertThat(response.getStatusCode()).isEqualTo(StatusCode.OK); + assertThat(response.getStatusCode()).isEqualTo(StatusCode.SUCCESS.getCode()); assertThat(response.getResponseMessage()).isEqualTo(ResponseMessage.FOUND_POST); PostDetailsDto postDto = response.getData(); @@ -153,4 +156,5 @@ void deleteSucceeded() { Post post = em.find(Post.class, post1.getId()); assertThat(post).isNull(); } + } \ No newline at end of file diff --git a/src/test/java/com/devin/dev/service/ReplyServiceTest.java b/src/test/java/com/devin/dev/service/ReplyServiceTest.java index 1735a60..894657f 100644 --- a/src/test/java/com/devin/dev/service/ReplyServiceTest.java +++ b/src/test/java/com/devin/dev/service/ReplyServiceTest.java @@ -53,7 +53,7 @@ void replySuccess() { DefaultResponse response = replyService.reply(replyUser.getId(), post1.getId(), "reply_content", List.of("i1", "i2", "i3")); - assertThat(response.getStatusCode()).isEqualTo(StatusCode.OK); + assertThat(response.getStatusCode()).isEqualTo(StatusCode.SUCCESS.getCode()); assertThat(response.getResponseMessage()).isEqualTo(ResponseMessage.REPLY_UPLOAD_SUCCESS); Reply foundReply = em.find(Reply.class, response.getData().getId()); @@ -81,7 +81,7 @@ void replyWrongUserFailed() { DefaultResponse response = replyService.reply(-1L, post1.getId(), "reply_content", List.of("i1", "i2", "i3")); - assertThat(response.getStatusCode()).isEqualTo(StatusCode.BAD_REQUEST); + assertThat(response.getStatusCode()).isEqualTo(StatusCode.NOT_EXIST.getCode()); assertThat(response.getResponseMessage()).isEqualTo(ResponseMessage.NOT_FOUND_USER); assertThat(response.getData()).isNull(); @@ -98,7 +98,7 @@ void replyWrongPostFailed() { DefaultResponse response = replyService.reply(replyUser.getId(), -1L, "reply_content", List.of("i1", "i2", "i3")); - assertThat(response.getStatusCode()).isEqualTo(StatusCode.BAD_REQUEST); + assertThat(response.getStatusCode()).isEqualTo(StatusCode.NOT_EXIST.getCode()); assertThat(response.getResponseMessage()).isEqualTo(ResponseMessage.NOT_FOUND_POST); assertThat(response.getData()).isNull(); @@ -119,7 +119,7 @@ void replyLikeSuccess() { em.persist(reply); DefaultResponse response = replyService.changeReplyLike(likeUser.getId(), reply.getId()); - assertThat(response.getStatusCode()).isEqualTo(StatusCode.OK); + assertThat(response.getStatusCode()).isEqualTo(StatusCode.SUCCESS.getCode()); assertThat(response.getResponseMessage()).isEqualTo(ResponseMessage.REPLY_LIKE_CHANGE_SUCCESS); ReplyLike replyLike = em.find(ReplyLike.class, response.getData().getId()); @@ -162,7 +162,7 @@ void replyCancelLikeSuccess() { // 좋아요 취소 검증 DefaultResponse response = replyService.changeReplyLike(likeUser.getId(), reply.getId()); - assertThat(response.getStatusCode()).isEqualTo(StatusCode.OK); + assertThat(response.getStatusCode()).isEqualTo(StatusCode.SUCCESS.getCode()); assertThat(response.getResponseMessage()).isEqualTo(ResponseMessage.REPLY_LIKE_CHANGE_SUCCESS); assertThat(replyLike.getId()).isEqualTo(response.getData().getId()); @@ -203,7 +203,7 @@ void editReplySuccess() { DefaultResponse response = replyService.editReply(replyUser.getId(), reply.getId(), "edited_content", List.of("i3", "i1", "i2")); - assertThat(response.getStatusCode()).isEqualTo(StatusCode.OK); + assertThat(response.getStatusCode()).isEqualTo(StatusCode.SUCCESS.getCode()); assertThat(response.getResponseMessage()).isEqualTo(ResponseMessage.REPLY_EDIT_SUCCESS); Reply foundReply = em.find(Reply.class, response.getData().getId()); @@ -241,7 +241,7 @@ void editReplyWrongUserFailed() { // 다른 유저로 댓글 수정 요청, 실패 response 객체 확인 DefaultResponse response = replyService.editReply(postUser.getId(), reply.getId(), "edited_content", List.of("i3", "i1", "i2")); - assertThat(response.getStatusCode()).isEqualTo(StatusCode.BAD_REQUEST); + assertThat(response.getStatusCode()).isEqualTo(StatusCode.CONDITION_FAIL.getCode()); assertThat(response.getResponseMessage()).isEqualTo(ResponseMessage.NOT_SAME_USER); // 안바뀐거 확인 @@ -276,7 +276,7 @@ void deleteReplySuccess() { assertThat(reply.getStatus()).isEqualTo(ReplyStatus.NOT_SELECTED); DefaultResponse response = replyService.deleteReply(replyUser.getId(), reply.getId()); - assertThat(response.getStatusCode()).isEqualTo(StatusCode.OK); + assertThat(response.getStatusCode()).isEqualTo(StatusCode.SUCCESS.getCode()); assertThat(response.getResponseMessage()).isEqualTo(ResponseMessage.REPLY_DELETE_SUCCESS); Reply foundReply = replyRepository.findById(reply.getId()).get(); diff --git a/src/test/java/com/devin/dev/service/UserServiceTest.java b/src/test/java/com/devin/dev/service/UserServiceTest.java index 7e6c8d5..7d4804c 100644 --- a/src/test/java/com/devin/dev/service/UserServiceTest.java +++ b/src/test/java/com/devin/dev/service/UserServiceTest.java @@ -42,7 +42,7 @@ void signUpSucceed() { // 성공 response 객체 확인 assertThat(response.getResponseMessage()).isEqualTo(ResponseMessage.CREATED_USER); - assertThat(response.getStatusCode()).isEqualTo(StatusCode.OK); + assertThat(response.getStatusCode()).isEqualTo(StatusCode.SUCCESS.getCode()); // 저장된 유저 엔티티 확인 Optional foundUser = userRepository.findByEmailEquals("a@b.com"); @@ -71,7 +71,7 @@ void signUpFailed() { // 실패 response 객체 확인 assertThat(response.getResponseMessage()).isEqualTo(ResponseMessage.EXIST_USER_EMAIL); - assertThat(response.getStatusCode()).isEqualTo(StatusCode.BAD_REQUEST); + assertThat(response.getStatusCode()).isEqualTo(StatusCode.CONDITION_FAIL.getCode()); Optional foundUser = userRepository.findByName("B"); assertThat(foundUser.isEmpty()).isTrue(); @@ -95,7 +95,7 @@ void signInSucceed() { System.out.println("response = " + response.getResponseMessage()); // 성공 response 객체 확인 assertThat(response.getResponseMessage()).isEqualTo(ResponseMessage.LOGIN_SUCCESS); - assertThat(response.getStatusCode()).isEqualTo(StatusCode.OK); + assertThat(response.getStatusCode()).isEqualTo(StatusCode.SUCCESS.getCode()); } @Test @@ -116,7 +116,7 @@ void signInFailedWrongEmail() { // 실패 response 객체 확인 assertThat(response.getResponseMessage()).isEqualTo(ResponseMessage.NOT_FOUND_EMAIL); - assertThat(response.getStatusCode()).isEqualTo(StatusCode.BAD_REQUEST); + assertThat(response.getStatusCode()).isEqualTo(StatusCode.NOT_EXIST.getCode()); } @Test @@ -136,6 +136,6 @@ void signInFailedWrongPassword() { // 실패 response 객체 확인 assertThat(response.getResponseMessage()).isEqualTo(ResponseMessage.INCORRECT_PASSWORD); - assertThat(response.getStatusCode()).isEqualTo(StatusCode.BAD_REQUEST); + assertThat(response.getStatusCode()).isEqualTo(StatusCode.FAIL_AUTH.getCode()); } } \ No newline at end of file From d9050390ced7794a62160ac178b2de2c5fbe5f5f Mon Sep 17 00:00:00 2001 From: enjay27 Date: Sat, 12 Jun 2021 00:04:06 +0900 Subject: [PATCH 02/16] =?UTF-8?q?refactor:=20postLikes=20=ED=95=84?= =?UTF-8?q?=EB=93=9C=20=EC=9D=B4=EB=A6=84=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/devin/dev/dto/post/PostInfoDto.java | 4 ++-- src/main/java/com/devin/dev/entity/post/Post.java | 9 ++++++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/devin/dev/dto/post/PostInfoDto.java b/src/main/java/com/devin/dev/dto/post/PostInfoDto.java index 98250f2..df57fcc 100644 --- a/src/main/java/com/devin/dev/dto/post/PostInfoDto.java +++ b/src/main/java/com/devin/dev/dto/post/PostInfoDto.java @@ -44,9 +44,9 @@ public PostInfoDto(Post post) { this.title = post.getTitle(); this.tags = post.getPostTags(); this.statusAccept = post.getStatus() == PostStatus.SELECTED; - this.statusLike = post.getPostLikes().size() > 0; + this.statusLike = post.getLikes().size() > 0; this.replyNum = post.getReplies().size(); - this.likeNum = post.getPostLikes().size(); + this.likeNum = post.getLikes().size(); this.createdDate = post.getCreatedDate(); this.userId = post.getUser().getId(); this.username = post.getUser().getName(); diff --git a/src/main/java/com/devin/dev/entity/post/Post.java b/src/main/java/com/devin/dev/entity/post/Post.java index 7ea18ad..e828ce9 100644 --- a/src/main/java/com/devin/dev/entity/post/Post.java +++ b/src/main/java/com/devin/dev/entity/post/Post.java @@ -2,6 +2,7 @@ import com.devin.dev.entity.base.ModifiedCreated; import com.devin.dev.entity.reply.Reply; +import com.devin.dev.entity.reply.ReplyLike; import com.devin.dev.entity.user.User; import lombok.AccessLevel; import lombok.Getter; @@ -36,7 +37,7 @@ public class Post extends ModifiedCreated { private final List tags = new ArrayList<>(); @OneToMany(mappedBy = "post") - private final List postLikes = new ArrayList<>(); + private final List likes = new ArrayList<>(); @OneToMany(mappedBy = "post") private final List images = new ArrayList<>(); @@ -106,4 +107,10 @@ public void setPostImages(List postImages) { public List getPostTags() { return this.tags.stream().map(tag -> tag.getTag().getName()).collect(Collectors.toList()); } + + public PostLike like(User user, PostLike postLike) { + postLike.changePost(this); + postLike.setUser(user); + return postLike; + } } From efef23339463d97b17938ffca4edb5b0111faf29 Mon Sep 17 00:00:00 2001 From: enjay27 Date: Sat, 12 Jun 2021 00:05:22 +0900 Subject: [PATCH 03/16] =?UTF-8?q?[#6]feat:=20=EA=B2=8C=EC=8B=9C=EA=B8=80?= =?UTF-8?q?=20Like=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dev/controller/post/PostController.java | 9 +++- .../com/devin/dev/entity/post/PostLike.java | 17 +++++- .../repository/post/PostLikeRepository.java | 7 +++ .../post/PostRepositoryQueryImpl.java | 6 +-- .../com/devin/dev/service/PostService.java | 54 +++++++++++++++++++ 5 files changed, 87 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/devin/dev/controller/post/PostController.java b/src/main/java/com/devin/dev/controller/post/PostController.java index df9a272..68a9a18 100644 --- a/src/main/java/com/devin/dev/controller/post/PostController.java +++ b/src/main/java/com/devin/dev/controller/post/PostController.java @@ -3,7 +3,6 @@ import com.devin.dev.controller.reply.ReplyOrderCondition; import com.devin.dev.dto.post.PostDetailsDto; import com.devin.dev.model.DefaultResponse; -import com.devin.dev.security.JwtAuthTokenProvider; import com.devin.dev.service.PostService; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Sort; @@ -52,6 +51,12 @@ public DefaultResponse deletePost(@PathVariable("id") Long postI @PostMapping("/post") public DefaultResponse post(@RequestBody PostForm form, HttpServletRequest request) { - return postService.post(request, form); + return postService.post(form, request); } + + @PatchMapping("/post/{id}/like") + public DefaultResponse changePostLike(@PathVariable("id") Long postId, HttpServletRequest request) { + return postService.changePostLike(postId, request); + } + } diff --git a/src/main/java/com/devin/dev/entity/post/PostLike.java b/src/main/java/com/devin/dev/entity/post/PostLike.java index bd3d1f0..89459a7 100644 --- a/src/main/java/com/devin/dev/entity/post/PostLike.java +++ b/src/main/java/com/devin/dev/entity/post/PostLike.java @@ -1,14 +1,16 @@ package com.devin.dev.entity.post; import com.devin.dev.entity.base.Created; +import com.devin.dev.entity.user.User; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; +import lombok.Setter; import javax.persistence.*; @Entity -@NoArgsConstructor(access = AccessLevel.PROTECTED) +@NoArgsConstructor @Getter public class PostLike extends Created { @@ -21,4 +23,17 @@ public class PostLike extends Created { @JoinColumn(name = "post_id") private Post post; + @Setter + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "user_id") + private User user; + + public void changePost(Post post) { + if(this.post != null) { + this.post.getLikes().remove(this); + } else { + this.post = post; + post.getLikes().add(this); + } + } } diff --git a/src/main/java/com/devin/dev/repository/post/PostLikeRepository.java b/src/main/java/com/devin/dev/repository/post/PostLikeRepository.java index 7d9fcf0..203dd39 100644 --- a/src/main/java/com/devin/dev/repository/post/PostLikeRepository.java +++ b/src/main/java/com/devin/dev/repository/post/PostLikeRepository.java @@ -1,7 +1,14 @@ package com.devin.dev.repository.post; +import com.devin.dev.entity.post.Post; import com.devin.dev.entity.post.PostLike; +import com.devin.dev.entity.user.User; import org.springframework.data.jpa.repository.JpaRepository; +import java.util.List; +import java.util.Optional; + public interface PostLikeRepository extends JpaRepository { + + Optional findByPostAndUser(Post post, User user); } diff --git a/src/main/java/com/devin/dev/repository/post/PostRepositoryQueryImpl.java b/src/main/java/com/devin/dev/repository/post/PostRepositoryQueryImpl.java index 2027333..8ab6408 100644 --- a/src/main/java/com/devin/dev/repository/post/PostRepositoryQueryImpl.java +++ b/src/main/java/com/devin/dev/repository/post/PostRepositoryQueryImpl.java @@ -125,9 +125,9 @@ public Optional findPostDetailsById(Long id, ReplyOrderCondition Post result = queryFactory .select(post) .from(post) - .innerJoin(post.replies, reply).fetchJoin() - .innerJoin(post.user, user).fetchJoin() - .innerJoin(reply.user, user).fetchJoin() + .leftJoin(post.replies, reply).fetchJoin() + .leftJoin(post.user, user).fetchJoin() + .leftJoin(reply.user, user).fetchJoin() .where(post.id.eq(id)) .orderBy( replyOrder(condition) diff --git a/src/main/java/com/devin/dev/service/PostService.java b/src/main/java/com/devin/dev/service/PostService.java index d92de63..5bd7484 100644 --- a/src/main/java/com/devin/dev/service/PostService.java +++ b/src/main/java/com/devin/dev/service/PostService.java @@ -210,6 +210,60 @@ public DefaultResponse deletePost(Long postId) { return new DefaultResponse<>(StatusCode.SUCCESS, ResponseMessage.DELETED_POST); } + + public DefaultResponse changePostLike(Long postId, HttpServletRequest request) { + String token = tokenProvider.parseToken(request); + Long userId; + if (tokenProvider.validateToken(token)) { + userId = tokenProvider.getUserId(token); + } else { + return new DefaultResponse<>(StatusCode.FAIL_AUTH, ResponseMessage.NOT_FOUND_USER); + } + Optional userOptional = userRepository.findById(userId); + if (userOptional.isEmpty()) { + return new DefaultResponse<>(StatusCode.NOT_EXIST, ResponseMessage.NOT_FOUND_USER); + } + User user = userOptional.get(); + + Optional postOptional = postRepository.findById(postId); + if (postOptional.isEmpty()) { + return new DefaultResponse<>(StatusCode.NOT_EXIST, ResponseMessage.NOT_FOUND_POST); + } + Post post = postOptional.get(); + + Optional likeOptional = postLikeRepository.findByPostAndUser(post, user); + + PostLike postLike; + // 추천 유무에 따라 실행 + if (likeOptional.isPresent()) { + postLike = likeOptional.get(); + postLikeRepository.delete(postLike); + if (isNotSameUser(user, post.getUser())) { + // 좋아요 누른 사람 경험치 감소 + user.changeExp(User.ExpChangeType.REPLY_CANCEL_LIKE); + // 답변 작성자 경험치 감소 + post.getUser().changeExp(User.ExpChangeType.REPLY_NOT_BE_LIKED); + } + } else { + postLike = post.like(user, new PostLike()); + if (isNotSameUser(user, post.getUser())) { + // 좋아요 누른 사람 경험치 증가 + user.changeExp(User.ExpChangeType.REPLY_LIKE); + // 답변 작성자 경험치 증가 + post.getUser().changeExp(User.ExpChangeType.REPLY_BE_LIKED); + } + postLikeRepository.save(postLike); + } + + ReplyLikeDto replyLikeDto = new ReplyLikeDto(postLike.getId(), user.getName()); + + return new DefaultResponse<>(StatusCode.SUCCESS, ResponseMessage.REPLY_LIKE_CHANGE_SUCCESS, replyLikeDto); + + } + + private boolean isNotSameUser(User firstUser, User secondUser) { + return !firstUser.getId().equals(secondUser.getId()); + } } From 7a3ae039a798404da12eec2dd423c79618ddf35f Mon Sep 17 00:00:00 2001 From: enjay27 Date: Sat, 12 Jun 2021 00:08:07 +0900 Subject: [PATCH 04/16] =?UTF-8?q?[#19]feat:=20=EB=8B=B5=EB=B3=80=20?= =?UTF-8?q?=EB=93=B1=EB=A1=9D=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dev/controller/post/ReplyUpdateForm.java | 14 ++++++ .../dev/controller/reply/ReplyController.java | 6 +-- .../devin/dev/controller/reply/ReplyForm.java | 16 +++++++ .../com/devin/dev/service/ReplyService.java | 47 +++++++++++++++++++ 4 files changed, 80 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/devin/dev/controller/post/ReplyUpdateForm.java create mode 100644 src/main/java/com/devin/dev/controller/reply/ReplyForm.java diff --git a/src/main/java/com/devin/dev/controller/post/ReplyUpdateForm.java b/src/main/java/com/devin/dev/controller/post/ReplyUpdateForm.java new file mode 100644 index 0000000..88f2d58 --- /dev/null +++ b/src/main/java/com/devin/dev/controller/post/ReplyUpdateForm.java @@ -0,0 +1,14 @@ +package com.devin.dev.controller.post; + +import lombok.Data; + +import javax.validation.constraints.NotEmpty; +import java.util.List; + +@Data +public class ReplyUpdateForm { + @NotEmpty + private String content; + + private List reply_image; +} diff --git a/src/main/java/com/devin/dev/controller/reply/ReplyController.java b/src/main/java/com/devin/dev/controller/reply/ReplyController.java index 837b14a..54ac8d8 100644 --- a/src/main/java/com/devin/dev/controller/reply/ReplyController.java +++ b/src/main/java/com/devin/dev/controller/reply/ReplyController.java @@ -20,9 +20,9 @@ public class ReplyController { private final ReplyService replyService; - @PostMapping("/replies") - public DefaultResponse saveReply(@RequestBody @Valid CreateReplyRequest request) { - return replyService.reply(request.getUserId(), request.getPostId(), request.getContent(), request.getReplyImages()); + @PostMapping("/reply") + public DefaultResponse reply(@RequestBody @Valid ReplyForm form, HttpServletRequest request) { + return replyService.reply(form, request); } @GetMapping("/reply/{id}") diff --git a/src/main/java/com/devin/dev/controller/reply/ReplyForm.java b/src/main/java/com/devin/dev/controller/reply/ReplyForm.java new file mode 100644 index 0000000..3085e88 --- /dev/null +++ b/src/main/java/com/devin/dev/controller/reply/ReplyForm.java @@ -0,0 +1,16 @@ +package com.devin.dev.controller.reply; + +import lombok.Data; + +import javax.validation.constraints.NotEmpty; +import java.util.List; + +@Data +public class ReplyForm { + @NotEmpty + private Long id; + @NotEmpty + private String content; + + private List reply_image; +} \ No newline at end of file diff --git a/src/main/java/com/devin/dev/service/ReplyService.java b/src/main/java/com/devin/dev/service/ReplyService.java index 6ebad84..8b23fb3 100644 --- a/src/main/java/com/devin/dev/service/ReplyService.java +++ b/src/main/java/com/devin/dev/service/ReplyService.java @@ -1,5 +1,7 @@ package com.devin.dev.service; +import com.devin.dev.controller.post.ReplyUpdateForm; +import com.devin.dev.controller.reply.ReplyForm; import com.devin.dev.dto.reply.ReplyDto; import com.devin.dev.dto.reply.ReplyLikeDto; import com.devin.dev.dto.reply.ReplyMapper; @@ -15,6 +17,7 @@ import com.devin.dev.repository.reply.ReplyImageRepository; import com.devin.dev.repository.reply.ReplyLikeRepository; import com.devin.dev.repository.user.UserRepository; +import com.devin.dev.security.JwtAuthTokenProvider; import com.devin.dev.utils.ResponseMessage; import com.devin.dev.utils.StatusCode; import lombok.RequiredArgsConstructor; @@ -24,6 +27,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import javax.servlet.http.HttpServletRequest; import java.util.List; import java.util.Optional; @@ -36,6 +40,7 @@ public class ReplyService { private final ReplyRepository replyRepository; private final ReplyImageRepository replyImageRepository; private final ReplyLikeRepository replyLikeRepository; + private final JwtAuthTokenProvider tokenProvider; // 답변 작성 @Transactional @@ -207,4 +212,46 @@ private boolean isNotSameUser(User firstUser, User secondUser) { return !firstUser.getId().equals(secondUser.getId()); } + @Transactional + public DefaultResponse reply(ReplyForm form, HttpServletRequest request) { + String token = tokenProvider.parseToken(request); + Long userId; + if (tokenProvider.validateToken(token)) { + userId = tokenProvider.getUserId(token); + } else { + return new DefaultResponse<>(StatusCode.FAIL_AUTH, ResponseMessage.NOT_FOUND_USER); + } + Optional userOptional = userRepository.findById(userId); + if (userOptional.isEmpty()) { + return new DefaultResponse<>(StatusCode.NOT_EXIST, ResponseMessage.NOT_FOUND_USER); + } + User user = userOptional.get(); + + Optional postOptional = postRepository.findById(form.getId()); + if (postOptional.isEmpty()) { + return new DefaultResponse<>(StatusCode.NOT_EXIST, ResponseMessage.NOT_FOUND_POST); + } + Post post = postOptional.get(); + + // 엔티티 생성 + List replyImages = ReplyImage.createReplyImages(form.getReply_image()); + Reply reply = Reply.createReplyWithImages(post, user, replyImages, form.getContent()); + + // 리플 작성자 경험치증가 (게시글작성자 != 리플작성자 인 경우) + if (isNotSameUser(post.getUser(), reply.getUser())) { + user.changeExp(User.ExpChangeType.CREATE_REPLY); + } + + // 저장 + replyRepository.save(reply); + replyImageRepository.saveAll(replyImages); + + // DTO 변환 + ReplyDto replyDto = ReplyMapper.replyToReplyDto(reply); + + // response 객체 리턴 + return new DefaultResponse<>(StatusCode.SUCCESS, ResponseMessage.REPLY_UPLOAD_SUCCESS, replyDto); + } + + } From 216746a3bcd500c2af57e9b522622fad0f190666 Mon Sep 17 00:00:00 2001 From: enjay27 Date: Sat, 12 Jun 2021 00:09:11 +0900 Subject: [PATCH 05/16] =?UTF-8?q?[#20]feat:=20=EB=8B=B5=EB=B3=80=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dev/controller/reply/ReplyController.java | 8 ++-- .../com/devin/dev/service/ReplyService.java | 48 +++++++++++++++++++ 2 files changed, 51 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/devin/dev/controller/reply/ReplyController.java b/src/main/java/com/devin/dev/controller/reply/ReplyController.java index 54ac8d8..efa36b7 100644 --- a/src/main/java/com/devin/dev/controller/reply/ReplyController.java +++ b/src/main/java/com/devin/dev/controller/reply/ReplyController.java @@ -25,11 +25,9 @@ public DefaultResponse reply(@RequestBody @Valid ReplyForm form, HttpServletR return replyService.reply(form, request); } - @GetMapping("/reply/{id}") - public Page findReplies( - @PathVariable("id") Long postId, Pageable pageable) { - DefaultResponse> response = replyService.findRepliesInPost(postId, pageable); - return response.getData(); + @PutMapping("/reply/{id}/update") + public DefaultResponse reply(@PathVariable("id") Long replyId, @RequestBody @Valid ReplyUpdateForm form, HttpServletRequest request) { + return replyService.editReply(replyId, form, request); } @Data diff --git a/src/main/java/com/devin/dev/service/ReplyService.java b/src/main/java/com/devin/dev/service/ReplyService.java index 8b23fb3..437db13 100644 --- a/src/main/java/com/devin/dev/service/ReplyService.java +++ b/src/main/java/com/devin/dev/service/ReplyService.java @@ -253,5 +253,53 @@ public DefaultResponse reply(ReplyForm form, HttpServletRequest request) { return new DefaultResponse<>(StatusCode.SUCCESS, ResponseMessage.REPLY_UPLOAD_SUCCESS, replyDto); } + @Transactional + public DefaultResponse editReply(Long replyId, ReplyUpdateForm form, HttpServletRequest request) { + String token = tokenProvider.parseToken(request); + Long userId; + if (tokenProvider.validateToken(token)) { + userId = tokenProvider.getUserId(token); + } else { + return new DefaultResponse<>(StatusCode.FAIL_AUTH, ResponseMessage.NOT_FOUND_USER); + } + Optional userOptional = userRepository.findById(userId); + if (userOptional.isEmpty()) { + return new DefaultResponse<>(StatusCode.NOT_EXIST, ResponseMessage.NOT_FOUND_USER); + } + User user = userOptional.get(); + + Optional replyOptional = replyRepository.findById(replyId); + if (replyOptional.isEmpty()) { + return new DefaultResponse<>(StatusCode.NOT_EXIST, ResponseMessage.NOT_FOUND_REPLY); + } + Reply reply = replyOptional.get(); + + if (isNotSameUser(user, reply.getUser())) { + return new DefaultResponse<>(StatusCode.CONDITION_FAIL, ResponseMessage.NOT_SAME_USER); + } + + if (reply.getStatus() == ReplyStatus.SELECTED) { + return new DefaultResponse<>(StatusCode.CONDITION_FAIL, ResponseMessage.NOT_SAME_USER); + } + + // 기존 이미지 경로 삭제 + List replyImages = replyImageRepository.findByReply(reply); + replyImageRepository.deleteInBatch(replyImages); + + // 수정된 내용 반영 + List newReplyImages = ReplyImage.createReplyImages(form.getReply_image()); + reply.setContent(form.getContent()); + reply.setReplyImages(newReplyImages); + + // 저장 + replyImageRepository.saveAll(newReplyImages); + replyRepository.save(reply); + + // DTO 변환 + ReplyDto replyDto = ReplyMapper.replyToReplyDto(reply); + + // response 객체 리턴 + return new DefaultResponse<>(StatusCode.SUCCESS, ResponseMessage.REPLY_EDIT_SUCCESS, replyDto); + } } From 538d4587d77e153dcd44864bc9b99a00dff69f77 Mon Sep 17 00:00:00 2001 From: enjay27 Date: Sat, 12 Jun 2021 00:09:51 +0900 Subject: [PATCH 06/16] =?UTF-8?q?[#21]feat:=20=EB=8B=B5=EB=B3=80=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dev/controller/reply/ReplyController.java | 19 ++++----- .../com/devin/dev/service/ReplyService.java | 40 +++++++++++++++++++ 2 files changed, 47 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/devin/dev/controller/reply/ReplyController.java b/src/main/java/com/devin/dev/controller/reply/ReplyController.java index efa36b7..b01e530 100644 --- a/src/main/java/com/devin/dev/controller/reply/ReplyController.java +++ b/src/main/java/com/devin/dev/controller/reply/ReplyController.java @@ -1,5 +1,6 @@ package com.devin.dev.controller.reply; +import com.devin.dev.controller.post.ReplyUpdateForm; import com.devin.dev.dto.reply.ReplyDto; import com.devin.dev.model.DefaultResponse; import com.devin.dev.service.ReplyService; @@ -10,6 +11,7 @@ import org.springframework.data.domain.Pageable; import org.springframework.web.bind.annotation.*; +import javax.servlet.http.HttpServletRequest; import javax.validation.Valid; import javax.validation.constraints.NotEmpty; import java.util.List; @@ -30,6 +32,11 @@ public DefaultResponse reply(@PathVariable("id") Long replyId, @RequestBody @ return replyService.editReply(replyId, form, request); } + @DeleteMapping("/reply/{id}") + public DefaultResponse reply(@PathVariable("id") Long replyId, HttpServletRequest request) { + return replyService.deleteReply(replyId, request); + } + @Data private static class CreateReplyResponse { private Long id; @@ -39,18 +46,6 @@ public CreateReplyResponse(Long id) { } } - @Data - private static class CreateReplyRequest { - @NotEmpty - private Long postId; - @NotEmpty - private Long userId; - @NotEmpty - private String content; - @NotEmpty - private List replyImages; - } - @Data @AllArgsConstructor static class Result { diff --git a/src/main/java/com/devin/dev/service/ReplyService.java b/src/main/java/com/devin/dev/service/ReplyService.java index 437db13..82afcb0 100644 --- a/src/main/java/com/devin/dev/service/ReplyService.java +++ b/src/main/java/com/devin/dev/service/ReplyService.java @@ -302,4 +302,44 @@ public DefaultResponse editReply(Long replyId, ReplyUpdateForm form, HttpServ return new DefaultResponse<>(StatusCode.SUCCESS, ResponseMessage.REPLY_EDIT_SUCCESS, replyDto); } + @Transactional + public DefaultResponse deleteReply(Long replyId, HttpServletRequest request) { + String token = tokenProvider.parseToken(request); + Long userId; + if (tokenProvider.validateToken(token)) { + userId = tokenProvider.getUserId(token); + } else { + return new DefaultResponse<>(StatusCode.FAIL_AUTH, ResponseMessage.NOT_FOUND_USER); + } + Optional userOptional = userRepository.findById(userId); + if (userOptional.isEmpty()) { + return new DefaultResponse<>(StatusCode.NOT_EXIST, ResponseMessage.NOT_FOUND_USER); + } + User user = userOptional.get(); + + Optional replyOptional = replyRepository.findById(replyId); + if (replyOptional.isEmpty()) { + return new DefaultResponse<>(StatusCode.NOT_EXIST, ResponseMessage.NOT_FOUND_REPLY); + } + Reply reply = replyOptional.get(); + + // 작성자 확인 + if (isNotSameUser(user, reply.getUser())) { + return new DefaultResponse<>(StatusCode.CONDITION_FAIL, ResponseMessage.NOT_SAME_USER); + } + + // 채택된 답변인지 확인 + if (reply.getStatus() == ReplyStatus.SELECTED) { + return new DefaultResponse<>(StatusCode.CONDITION_FAIL, ResponseMessage.CANNOT_DELETE_SELECTED); + } + + // 리플 작성자 경험치 삭제 + user.changeExp(User.ExpChangeType.DELETE_REPLY); + + // 댓글 상태변경 DELETED 후 저장 + reply.setStatus(ReplyStatus.DELETED); + replyRepository.save(reply); + + return new DefaultResponse<>(StatusCode.SUCCESS, ResponseMessage.REPLY_DELETE_SUCCESS); + } } From 420c9b6ee0a1777c410154e7ab52d682f9560639 Mon Sep 17 00:00:00 2001 From: enjay27 Date: Sat, 12 Jun 2021 00:19:59 +0900 Subject: [PATCH 07/16] =?UTF-8?q?[#22]feat:=20=EB=8B=B5=EB=B3=80=20Like=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dev/controller/reply/ReplyController.java | 5 ++ .../com/devin/dev/dto/reply/ReplyDto.java | 8 +++ .../com/devin/dev/service/ReplyService.java | 51 +++++++++++++++++++ 3 files changed, 64 insertions(+) diff --git a/src/main/java/com/devin/dev/controller/reply/ReplyController.java b/src/main/java/com/devin/dev/controller/reply/ReplyController.java index b01e530..5d7992c 100644 --- a/src/main/java/com/devin/dev/controller/reply/ReplyController.java +++ b/src/main/java/com/devin/dev/controller/reply/ReplyController.java @@ -37,6 +37,11 @@ public DefaultResponse reply(@PathVariable("id") Long replyId, HttpServletReq return replyService.deleteReply(replyId, request); } + @PatchMapping("/reply/{id}/like") + public DefaultResponse changePostLike(@PathVariable("id") Long replyId, HttpServletRequest request) { + return replyService.changeReplyLike(replyId, request); + } + @Data private static class CreateReplyResponse { private Long id; diff --git a/src/main/java/com/devin/dev/dto/reply/ReplyDto.java b/src/main/java/com/devin/dev/dto/reply/ReplyDto.java index d96083b..1de6306 100644 --- a/src/main/java/com/devin/dev/dto/reply/ReplyDto.java +++ b/src/main/java/com/devin/dev/dto/reply/ReplyDto.java @@ -1,5 +1,6 @@ package com.devin.dev.dto.reply; +import com.devin.dev.entity.reply.Reply; import com.devin.dev.entity.reply.ReplyImage; import com.devin.dev.entity.reply.ReplyStatus; import com.devin.dev.entity.user.UserStatus; @@ -33,4 +34,11 @@ public ReplyDto(Long id, String name, String content, ReplyStatus status, Intege this.like = like; } + public ReplyDto(Reply reply) { + this.id = reply.getId(); + this.name = reply.getUser().getName(); + this.content = reply.getContent(); + this.status = reply.getStatus(); + this.like = reply.getLikes().size(); + } } diff --git a/src/main/java/com/devin/dev/service/ReplyService.java b/src/main/java/com/devin/dev/service/ReplyService.java index 82afcb0..a90cd62 100644 --- a/src/main/java/com/devin/dev/service/ReplyService.java +++ b/src/main/java/com/devin/dev/service/ReplyService.java @@ -342,4 +342,55 @@ public DefaultResponse deleteReply(Long replyId, HttpServletRequest request) return new DefaultResponse<>(StatusCode.SUCCESS, ResponseMessage.REPLY_DELETE_SUCCESS); } + + @Transactional + public DefaultResponse changeReplyLike(Long replyId, HttpServletRequest request) { + String token = tokenProvider.parseToken(request); + Long userId; + if (tokenProvider.validateToken(token)) { + userId = tokenProvider.getUserId(token); + } else { + return new DefaultResponse<>(StatusCode.FAIL_AUTH, ResponseMessage.NOT_FOUND_USER); + } + Optional userOptional = userRepository.findById(userId); + if (userOptional.isEmpty()) { + return new DefaultResponse<>(StatusCode.NOT_EXIST, ResponseMessage.NOT_FOUND_USER); + } + User user = userOptional.get(); + + Optional replyOptional = replyRepository.findById(replyId); + if (replyOptional.isEmpty()) { + return new DefaultResponse<>(StatusCode.NOT_EXIST, ResponseMessage.NOT_FOUND_REPLY); + } + Reply reply = replyOptional.get(); + + // 추천 조회 + Optional likeOptional = replyRepository.findLikeByUser(reply, user); + + ReplyLike replyLike; + // 추천 유무에 따라 실행 + if (likeOptional.isPresent()) { + replyLike = likeOptional.get(); + replyLikeRepository.delete(replyLike); + if (isNotSameUser(user, reply.getUser())) { + // 좋아요 누른 사람 경험치 감소 + user.changeExp(User.ExpChangeType.REPLY_CANCEL_LIKE); + // 답변 작성자 경험치 감소 + reply.getUser().changeExp(User.ExpChangeType.REPLY_NOT_BE_LIKED); + } + } else { + replyLike = reply.like(user, new ReplyLike()); + if (isNotSameUser(user, reply.getUser())) { + // 좋아요 누른 사람 경험치 증가 + user.changeExp(User.ExpChangeType.REPLY_LIKE); + // 답변 작성자 경험치 증가 + reply.getUser().changeExp(User.ExpChangeType.REPLY_BE_LIKED); + } + replyLikeRepository.save(replyLike); + } + + ReplyDto replyDto = new ReplyDto(reply); + + return new DefaultResponse<>(StatusCode.SUCCESS, ResponseMessage.REPLY_LIKE_CHANGE_SUCCESS, replyDto); + } } From ced6254f39746c78f70d9930574536c7fd6666f0 Mon Sep 17 00:00:00 2001 From: enjay27 Date: Sat, 12 Jun 2021 00:34:14 +0900 Subject: [PATCH 08/16] =?UTF-8?q?[#23]feat:=20=EB=8B=B5=EB=B3=80=20?= =?UTF-8?q?=EC=B1=84=ED=83=9D=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dev/controller/reply/ReplyController.java | 5 +++ .../com/devin/dev/service/ReplyService.java | 45 +++++++++++++++++++ .../com/devin/dev/utils/ResponseMessage.java | 1 + 3 files changed, 51 insertions(+) diff --git a/src/main/java/com/devin/dev/controller/reply/ReplyController.java b/src/main/java/com/devin/dev/controller/reply/ReplyController.java index 5d7992c..395d12e 100644 --- a/src/main/java/com/devin/dev/controller/reply/ReplyController.java +++ b/src/main/java/com/devin/dev/controller/reply/ReplyController.java @@ -42,6 +42,11 @@ public DefaultResponse changePostLike(@PathVariable("id") Long replyId, HttpS return replyService.changeReplyLike(replyId, request); } + @PatchMapping("/reply/{id}/select") + public DefaultResponse selectReply(@PathVariable("id") Long replyId, HttpServletRequest request) { + return replyService.selectReply(replyId, request); + } + @Data private static class CreateReplyResponse { private Long id; diff --git a/src/main/java/com/devin/dev/service/ReplyService.java b/src/main/java/com/devin/dev/service/ReplyService.java index a90cd62..cd4e558 100644 --- a/src/main/java/com/devin/dev/service/ReplyService.java +++ b/src/main/java/com/devin/dev/service/ReplyService.java @@ -6,6 +6,7 @@ import com.devin.dev.dto.reply.ReplyLikeDto; import com.devin.dev.dto.reply.ReplyMapper; import com.devin.dev.entity.post.Post; +import com.devin.dev.entity.post.PostStatus; import com.devin.dev.entity.reply.Reply; import com.devin.dev.entity.reply.ReplyImage; import com.devin.dev.entity.reply.ReplyLike; @@ -393,4 +394,48 @@ public DefaultResponse changeReplyLike(Long replyId, HttpServletReques return new DefaultResponse<>(StatusCode.SUCCESS, ResponseMessage.REPLY_LIKE_CHANGE_SUCCESS, replyDto); } + + public DefaultResponse selectReply(Long replyId, HttpServletRequest request) { + String token = tokenProvider.parseToken(request); + Long userId; + if (tokenProvider.validateToken(token)) { + userId = tokenProvider.getUserId(token); + } else { + return new DefaultResponse<>(StatusCode.FAIL_AUTH, ResponseMessage.NOT_FOUND_USER); + } + Optional userOptional = userRepository.findById(userId); + if (userOptional.isEmpty()) { + return new DefaultResponse<>(StatusCode.NOT_EXIST, ResponseMessage.NOT_FOUND_USER); + } + User user = userOptional.get(); + + Optional replyOptional = replyRepository.findById(replyId); + if (replyOptional.isEmpty()) { + return new DefaultResponse<>(StatusCode.NOT_EXIST, ResponseMessage.NOT_FOUND_REPLY); + } + Reply reply = replyOptional.get(); + + if (isNotSameUser(user, reply.getPost().getUser())) { + return new DefaultResponse<>(StatusCode.CONDITION_FAIL, ResponseMessage.NOT_SAME_USER); + } + + if (user.getId().equals(reply.getUser().getId())) { + return new DefaultResponse<>(StatusCode.CONDITION_FAIL, ResponseMessage.SAME_USER); + } + + user.changeExp(User.ExpChangeType.REPLY_SELECT); + reply.getUser().changeExp(User.ExpChangeType.REPLY_BE_SELECTED); + + reply.setStatus(ReplyStatus.SELECTED); + reply.getPost().setStatus(PostStatus.SELECTED); + + replyRepository.save(reply); + userRepository.save(user); + userRepository.save(reply.getUser()); + postRepository.save(reply.getPost()); + + ReplyDto replyDto = new ReplyDto(reply); + + return new DefaultResponse<>(StatusCode.SUCCESS, ResponseMessage.REPLY_LIKE_CHANGE_SUCCESS, replyDto); + } } diff --git a/src/main/java/com/devin/dev/utils/ResponseMessage.java b/src/main/java/com/devin/dev/utils/ResponseMessage.java index 024bb69..05ebaf0 100644 --- a/src/main/java/com/devin/dev/utils/ResponseMessage.java +++ b/src/main/java/com/devin/dev/utils/ResponseMessage.java @@ -12,6 +12,7 @@ public enum ResponseMessage { NOT_FOUND_REPLY("답변을 찾을 수 없습니다."), NOT_FOUND_SUBJECT("주제를 찾을 수 없습니다."), NOT_SAME_USER("작성자가 아닙니다."), + SAME_USER("작성자 입니다."), CANNOT_DELETE_SELECTED("채택된 답변은 삭제할 수 없습니다."), CREATED_USER("회원 가입 성공"), UPDATE_USER("회원 정보 수정 성공"), From 888e70bc99f8ec5aacd274c4bfaba30267f0bcdc Mon Sep 17 00:00:00 2001 From: enjay27 Date: Sat, 12 Jun 2021 01:50:18 +0900 Subject: [PATCH 09/16] =?UTF-8?q?[#13]feat:=20=EA=B2=8C=EC=8B=9C=EA=B8=80?= =?UTF-8?q?=20=EC=A1=B0=ED=9A=8C=EC=8B=9C=20=EB=B9=84=ED=9A=8C=EC=9B=90=20?= =?UTF-8?q?=EC=B1=84=ED=83=9D=EA=B8=80=20=EC=A0=9C=ED=95=9C=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dev/controller/post/PostController.java | 5 +-- .../devin/dev/dto/post/PostDetailsDto.java | 34 +++++++++++++++++-- .../com/devin/dev/entity/user/UserStatus.java | 2 +- .../repository/post/PostRepositoryQuery.java | 5 ++- .../post/PostRepositoryQueryImpl.java | 22 ++++++++++++ .../com/devin/dev/service/PostService.java | 23 +++++++++++-- .../devin/dev/service/PostServiceTest.java | 3 -- 7 files changed, 83 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/devin/dev/controller/post/PostController.java b/src/main/java/com/devin/dev/controller/post/PostController.java index 68a9a18..b559b18 100644 --- a/src/main/java/com/devin/dev/controller/post/PostController.java +++ b/src/main/java/com/devin/dev/controller/post/PostController.java @@ -27,14 +27,15 @@ public DefaultResponse getPostList(@RequestParam(defaultValue = "-1") Long id @GetMapping("/postlist/{id}") public DefaultResponse getPostDetails( @PathVariable("id") Long postId, - @RequestParam(defaultValue = "true", name = "sort_reply") boolean sort_reply) { + @RequestParam(defaultValue = "true", name = "sort_reply") boolean sort_reply, + HttpServletRequest request) { ReplyOrderCondition replyOrderCondition = new ReplyOrderCondition(); if (!sort_reply) { replyOrderCondition.setLatestDate(true); } else { replyOrderCondition.setLikeCount(true); } - return postService.getPost(postId, replyOrderCondition); + return postService.getPost(postId, replyOrderCondition, request); } @GetMapping("/postlist") diff --git a/src/main/java/com/devin/dev/dto/post/PostDetailsDto.java b/src/main/java/com/devin/dev/dto/post/PostDetailsDto.java index 31edc22..97a048d 100644 --- a/src/main/java/com/devin/dev/dto/post/PostDetailsDto.java +++ b/src/main/java/com/devin/dev/dto/post/PostDetailsDto.java @@ -3,6 +3,8 @@ import com.devin.dev.entity.post.Post; import com.devin.dev.entity.post.PostImage; import com.devin.dev.entity.post.PostStatus; +import com.devin.dev.entity.reply.ReplyStatus; +import com.devin.dev.entity.user.UserStatus; import com.querydsl.core.annotations.QueryProjection; import lombok.Data; @@ -24,13 +26,14 @@ public class PostDetailsDto { private List post_images; private List post_tags; private boolean status_accept; + private boolean like_post; private LocalDateTime date_create; private LocalDateTime date_update; private Integer reply_num; private List reply; @QueryProjection - public PostDetailsDto(Long post_id, Long publisher_id, String publisher_name, String publisher_profile, Long publisher_exp, String title, String content, List post_images, List post_tags, boolean status_accept, boolean like_post, LocalDateTime date_create, LocalDateTime date_update, Integer reply_num, List replyDtos) { + public PostDetailsDto(Long post_id, Long publisher_id, String publisher_name, String publisher_profile, Long publisher_exp, String title, String content, List post_images, List post_tags, boolean status_accept, boolean like_post, LocalDateTime date_create, LocalDateTime date_update, Integer reply_num, List reply) { this.post_id = post_id; this.publisher_id = publisher_id; this.publisher_name = publisher_name; @@ -41,10 +44,11 @@ public PostDetailsDto(Long post_id, Long publisher_id, String publisher_name, St this.post_images = post_images; this.post_tags = post_tags; this.status_accept = status_accept; + this.like_post = like_post; this.date_create = date_create; this.date_update = date_update; this.reply_num = reply_num; - this.reply = replyDtos; + this.reply = reply; } public PostDetailsDto(Post post) { @@ -58,9 +62,35 @@ public PostDetailsDto(Post post) { this.post_images = post.getImages().stream().map(PostImage::getPath).collect(Collectors.toList()); this.post_tags = post.getPostTags(); this.status_accept = post.getStatus() == PostStatus.SELECTED; + this.like_post = post.getLikes().size() > 0; this.date_create = post.getCreatedDate(); this.date_update = post.getLastModifiedDate(); this.reply_num = post.getReplies().size(); this.reply = post.getReplies().stream().map(PostReplyDto::new).collect(Collectors.toList()); } + + public PostDetailsDto(Post post, UserStatus status) { + this.post_id = post.getId(); + this.publisher_id = post.getUser().getId(); + this.publisher_name = post.getUser().getName(); + this.publisher_profile = post.getUser().getProfile(); + this.publisher_exp = post.getUser().getExp(); + this.title = post.getTitle(); + this.content = post.getContent(); + this.post_images = post.getImages().stream().map(PostImage::getPath).collect(Collectors.toList()); + this.post_tags = post.getPostTags(); + this.status_accept = post.getStatus() == PostStatus.SELECTED; + this.like_post = post.getLikes().size() > 0; + this.date_create = post.getCreatedDate(); + this.date_update = post.getLastModifiedDate(); + this.reply_num = post.getReplies().size(); + this.reply = status == UserStatus.ACTIVE || status == UserStatus.ADMIN ? + post.getReplies().stream().map(PostReplyDto::new).collect(Collectors.toList()) : + post.getReplies().stream().map(PostReplyDto::new).peek(dto -> { + if (dto.isStatus_accept()) { + dto.setContent("비회원은 볼 수 없습니다."); + dto.getReply_images().clear(); + } + }).collect(Collectors.toList()); + } } diff --git a/src/main/java/com/devin/dev/entity/user/UserStatus.java b/src/main/java/com/devin/dev/entity/user/UserStatus.java index 698c066..625cbe1 100644 --- a/src/main/java/com/devin/dev/entity/user/UserStatus.java +++ b/src/main/java/com/devin/dev/entity/user/UserStatus.java @@ -1,5 +1,5 @@ package com.devin.dev.entity.user; public enum UserStatus { - ADMIN, ACTIVE, DORMANT, SUSPENDED, DELETED + ADMIN, ACTIVE, DORMANT, SUSPENDED, DELETED, NON_MEMBERS } diff --git a/src/main/java/com/devin/dev/repository/post/PostRepositoryQuery.java b/src/main/java/com/devin/dev/repository/post/PostRepositoryQuery.java index 803e156..abc9ef8 100644 --- a/src/main/java/com/devin/dev/repository/post/PostRepositoryQuery.java +++ b/src/main/java/com/devin/dev/repository/post/PostRepositoryQuery.java @@ -7,6 +7,7 @@ import com.devin.dev.dto.post.PostSimpleDto; import com.devin.dev.entity.post.Post; import com.devin.dev.entity.user.User; +import com.devin.dev.entity.user.UserStatus; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -23,5 +24,7 @@ public interface PostRepositoryQuery { Page findAllByTagId(Long id, Pageable pageable); - Optional findPostDetailsById(Long id, ReplyOrderCondition condition); + Optional findPostDetailsByIdWithUserType(Long id, UserStatus status, ReplyOrderCondition condition); + + Optional findPostDetailsByIdWithUserType(Long id, ReplyOrderCondition condition); } diff --git a/src/main/java/com/devin/dev/repository/post/PostRepositoryQueryImpl.java b/src/main/java/com/devin/dev/repository/post/PostRepositoryQueryImpl.java index 8ab6408..28cf4b5 100644 --- a/src/main/java/com/devin/dev/repository/post/PostRepositoryQueryImpl.java +++ b/src/main/java/com/devin/dev/repository/post/PostRepositoryQueryImpl.java @@ -8,6 +8,7 @@ import com.devin.dev.entity.reply.QReplyImage; import com.devin.dev.entity.reply.QReplyLike; import com.devin.dev.entity.user.User; +import com.devin.dev.entity.user.UserStatus; import com.querydsl.core.QueryResults; import com.querydsl.core.types.OrderSpecifier; import com.querydsl.core.types.dsl.BooleanExpression; @@ -136,6 +137,27 @@ public Optional findPostDetailsById(Long id, ReplyOrderCondition Optional postDetailsDtoOptional; + postDetailsDtoOptional = result != null ? Optional.of(new PostDetailsDto(result, status)) : Optional.empty(); + + return postDetailsDtoOptional; + } + + @Override + public Optional findPostDetailsByIdWithUserType(Long id, ReplyOrderCondition condition) { + Post result = queryFactory + .select(post) + .from(post) + .leftJoin(post.replies, reply).fetchJoin() + .leftJoin(post.user, user).fetchJoin() + .leftJoin(reply.user, user).fetchJoin() + .where(post.id.eq(id)) + .orderBy( + replyOrder(condition) + ) + .fetchOne(); + + Optional postDetailsDtoOptional; + postDetailsDtoOptional = result != null ? Optional.of(new PostDetailsDto(result)) : Optional.empty(); return postDetailsDtoOptional; diff --git a/src/main/java/com/devin/dev/service/PostService.java b/src/main/java/com/devin/dev/service/PostService.java index 5bd7484..f2c1853 100644 --- a/src/main/java/com/devin/dev/service/PostService.java +++ b/src/main/java/com/devin/dev/service/PostService.java @@ -7,8 +7,8 @@ import com.devin.dev.dto.post.PostInfoDto; import com.devin.dev.dto.reply.ReplyLikeDto; import com.devin.dev.entity.post.*; -import com.devin.dev.entity.reply.ReplyLike; import com.devin.dev.entity.user.User; +import com.devin.dev.entity.user.UserStatus; import com.devin.dev.model.DefaultResponse; import com.devin.dev.repository.post.PostImageRepository; import com.devin.dev.repository.post.PostLikeRepository; @@ -165,7 +165,26 @@ public DefaultResponse editPost(Long userId, Long postId, String title, Strin @Transactional(readOnly = true) public DefaultResponse getPost(Long postId, ReplyOrderCondition replyOrderCondition) { - Optional postOptional = postRepository.findPostDetailsById(postId, replyOrderCondition); + Optional postOptional = postRepository.findPostDetailsByIdWithUserType(postId, replyOrderCondition); + if (postOptional.isEmpty()) { + return new DefaultResponse<>(StatusCode.NOT_EXIST, ResponseMessage.NOT_FOUND_POST); + } + PostDetailsDto postDetailsDto = postOptional.get(); + + return new DefaultResponse<>(StatusCode.SUCCESS, ResponseMessage.FOUND_POST, postDetailsDto); + } + + @Transactional(readOnly = true) + public DefaultResponse getPost(Long postId, ReplyOrderCondition replyOrderCondition, HttpServletRequest request) { + String token = tokenProvider.parseToken(request); + UserStatus userStatus; + if (tokenProvider.validateToken(token)) { + userStatus = UserStatus.ACTIVE; + } else { + userStatus = UserStatus.NON_MEMBERS; + } + + Optional postOptional = postRepository.findPostDetailsByIdWithUserType(postId, userStatus, replyOrderCondition); if (postOptional.isEmpty()) { return new DefaultResponse<>(StatusCode.NOT_EXIST, ResponseMessage.NOT_FOUND_POST); } diff --git a/src/test/java/com/devin/dev/service/PostServiceTest.java b/src/test/java/com/devin/dev/service/PostServiceTest.java index 8d0d37b..d50c11f 100644 --- a/src/test/java/com/devin/dev/service/PostServiceTest.java +++ b/src/test/java/com/devin/dev/service/PostServiceTest.java @@ -13,9 +13,6 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.test.annotation.Rollback; -import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; import org.springframework.transaction.annotation.Transactional; import javax.persistence.EntityManager; From 7b06509dce468e693308a7f295fc307d81833c7f Mon Sep 17 00:00:00 2001 From: enjay27 Date: Sat, 12 Jun 2021 01:50:58 +0900 Subject: [PATCH 10/16] =?UTF-8?q?[#25]feat:=20=EA=B2=8C=EC=8B=9C=EA=B8=80?= =?UTF-8?q?=20=EC=88=98=EC=A0=95=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dev/controller/post/PostController.java | 5 ++ .../dev/controller/post/PostUpdateForm.java | 25 +++++++++ .../post/PostRepositoryQueryImpl.java | 2 +- .../com/devin/dev/service/PostService.java | 54 +++++++++++++++++++ 4 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/devin/dev/controller/post/PostUpdateForm.java diff --git a/src/main/java/com/devin/dev/controller/post/PostController.java b/src/main/java/com/devin/dev/controller/post/PostController.java index b559b18..ef8fbc5 100644 --- a/src/main/java/com/devin/dev/controller/post/PostController.java +++ b/src/main/java/com/devin/dev/controller/post/PostController.java @@ -60,4 +60,9 @@ public DefaultResponse changePostLike(@PathVariable("id") Long postId, HttpSe return postService.changePostLike(postId, request); } + @PutMapping("/post/{id}/update") + public DefaultResponse reply(@PathVariable("id") Long replyId, @RequestBody PostUpdateForm form, HttpServletRequest request) { + return postService.editPost(replyId, form, request); + } + } diff --git a/src/main/java/com/devin/dev/controller/post/PostUpdateForm.java b/src/main/java/com/devin/dev/controller/post/PostUpdateForm.java new file mode 100644 index 0000000..61641d5 --- /dev/null +++ b/src/main/java/com/devin/dev/controller/post/PostUpdateForm.java @@ -0,0 +1,25 @@ +package com.devin.dev.controller.post; + +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.ArrayList; +import java.util.List; + +@Data +@NoArgsConstructor +public class PostUpdateForm { + private Long id; + private String title; + private String content; + private List post_images = new ArrayList<>(); + private List post_tags = new ArrayList<>(); + + public PostUpdateForm(Long id, String title, String content, List post_images, List post_tags) { + this.id = id; + this.title = title; + this.content = content; + this.post_images = post_images; + this.post_tags = post_tags; + } +} diff --git a/src/main/java/com/devin/dev/repository/post/PostRepositoryQueryImpl.java b/src/main/java/com/devin/dev/repository/post/PostRepositoryQueryImpl.java index 28cf4b5..9596365 100644 --- a/src/main/java/com/devin/dev/repository/post/PostRepositoryQueryImpl.java +++ b/src/main/java/com/devin/dev/repository/post/PostRepositoryQueryImpl.java @@ -122,7 +122,7 @@ public Page findAllByTagId(Long id, Pageable pageable) { } @Override - public Optional findPostDetailsById(Long id, ReplyOrderCondition condition) { + public Optional findPostDetailsByIdWithUserType(Long id, UserStatus status, ReplyOrderCondition condition) { Post result = queryFactory .select(post) .from(post) diff --git a/src/main/java/com/devin/dev/service/PostService.java b/src/main/java/com/devin/dev/service/PostService.java index f2c1853..157adc8 100644 --- a/src/main/java/com/devin/dev/service/PostService.java +++ b/src/main/java/com/devin/dev/service/PostService.java @@ -2,6 +2,8 @@ import com.devin.dev.controller.post.PostForm; import com.devin.dev.controller.post.PostSearchCondition; +import com.devin.dev.controller.post.PostUpdateForm; +import com.devin.dev.controller.post.ReplyUpdateForm; import com.devin.dev.controller.reply.ReplyOrderCondition; import com.devin.dev.dto.post.PostDetailsDto; import com.devin.dev.dto.post.PostInfoDto; @@ -283,6 +285,58 @@ public DefaultResponse changePostLike(Long postId, HttpServletRequest request private boolean isNotSameUser(User firstUser, User secondUser) { return !firstUser.getId().equals(secondUser.getId()); } + + @Transactional + public DefaultResponse editPost(Long postId, PostUpdateForm form, HttpServletRequest request) { + String token = tokenProvider.parseToken(request); + Long userId; + if (tokenProvider.validateToken(token)) { + userId = tokenProvider.getUserId(token); + } else { + return new DefaultResponse<>(StatusCode.FAIL_AUTH, ResponseMessage.NOT_FOUND_USER); + } + Optional userOptional = userRepository.findById(userId); + if (userOptional.isEmpty()) { + return new DefaultResponse<>(StatusCode.NOT_EXIST, ResponseMessage.NOT_FOUND_USER); + } + Optional postOptional = postRepository.findById(postId); + if (postOptional.isEmpty()) { + return new DefaultResponse<>(StatusCode.NOT_EXIST, ResponseMessage.NOT_FOUND_POST); + } + Post post = postOptional.get(); + List postSubjects = subjectRepository.findByNameIn(form.getPost_tags()); + + // 기존 태그 및 이미지 경로 삭제 + List postImages = postImageRepository.findByPost(post); + postImageRepository.deleteInBatch(postImages); + + // 수정된 내용 반영 + List newPostImages = PostImage.createPostImages(form.getPost_images()); + post.setTitle(form.getTitle()); + post.setContent(form.getContent()); + List deleteList = new ArrayList<>(); + + for (PostTag tag : post.getTags()) { + if (!postSubjects.contains(tag.getTag())) { + deleteList.add(tag); + } else { + postSubjects.remove(tag.getTag()); + } + } + List newPostTags = PostTag.createPostTags(postSubjects); + postTagRepository.deleteInBatch(deleteList); + + post.setPostTags(newPostTags); + post.setPostImages(newPostImages); + + // 저장 + postImageRepository.saveAll(newPostImages); + postRepository.save(post); + postTagRepository.saveAll(newPostTags); + + // 성공 메시지 및 코드 반환 + return new DefaultResponse<>(StatusCode.SUCCESS, ResponseMessage.POST_EDIT_SUCCESS); + } } From 7249396121cacc018f97dee8a148db14526a492c Mon Sep 17 00:00:00 2001 From: enjay27 Date: Sat, 12 Jun 2021 02:04:42 +0900 Subject: [PATCH 11/16] =?UTF-8?q?[#25]feat:=20=EC=B1=84=ED=83=9D=EB=90=9C?= =?UTF-8?q?=20=EA=B2=8C=EC=8B=9C=EA=B8=80=20=EB=B3=80=EA=B2=BD=20=EB=B6=88?= =?UTF-8?q?=EA=B0=80=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/devin/dev/controller/post/PostUpdateForm.java | 6 ++---- src/main/java/com/devin/dev/service/PostService.java | 9 +++++++++ src/main/java/com/devin/dev/utils/ResponseMessage.java | 1 + 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/devin/dev/controller/post/PostUpdateForm.java b/src/main/java/com/devin/dev/controller/post/PostUpdateForm.java index 61641d5..a39ef97 100644 --- a/src/main/java/com/devin/dev/controller/post/PostUpdateForm.java +++ b/src/main/java/com/devin/dev/controller/post/PostUpdateForm.java @@ -9,14 +9,12 @@ @Data @NoArgsConstructor public class PostUpdateForm { - private Long id; private String title; private String content; - private List post_images = new ArrayList<>(); - private List post_tags = new ArrayList<>(); + private List post_images; + private List post_tags; public PostUpdateForm(Long id, String title, String content, List post_images, List post_tags) { - this.id = id; this.title = title; this.content = content; this.post_images = post_images; diff --git a/src/main/java/com/devin/dev/service/PostService.java b/src/main/java/com/devin/dev/service/PostService.java index 157adc8..11b1191 100644 --- a/src/main/java/com/devin/dev/service/PostService.java +++ b/src/main/java/com/devin/dev/service/PostService.java @@ -221,6 +221,10 @@ public DefaultResponse deletePost(Long postId) { } Post post = postOptional.get(); + if (post.getStatus() == PostStatus.SELECTED) { + return new DefaultResponse<>(StatusCode.CONDITION_FAIL, ResponseMessage.SELECTED_POST); + } + postImageRepository.deleteAll(post.getImages()); postTagRepository.deleteAll(post.getTags()); postLikeRepository.deleteAll(post.getLikes()); @@ -304,6 +308,11 @@ public DefaultResponse editPost(Long postId, PostUpdateForm form, HttpServlet return new DefaultResponse<>(StatusCode.NOT_EXIST, ResponseMessage.NOT_FOUND_POST); } Post post = postOptional.get(); + + if (post.getStatus() == PostStatus.SELECTED) { + return new DefaultResponse<>(StatusCode.CONDITION_FAIL, ResponseMessage.SELECTED_POST); + } + List postSubjects = subjectRepository.findByNameIn(form.getPost_tags()); // 기존 태그 및 이미지 경로 삭제 diff --git a/src/main/java/com/devin/dev/utils/ResponseMessage.java b/src/main/java/com/devin/dev/utils/ResponseMessage.java index 05ebaf0..3992794 100644 --- a/src/main/java/com/devin/dev/utils/ResponseMessage.java +++ b/src/main/java/com/devin/dev/utils/ResponseMessage.java @@ -22,6 +22,7 @@ public enum ResponseMessage { POST_UPLOAD_SUCCESS("게시글 등록 성공"), POST_EDIT_SUCCESS("게시글 수정 성공"), DELETED_POST("게시글 삭제 성공"), + SELECTED_POST("채택된 게시글"), REPLY_UPLOAD_SUCCESS("답변 등록 성공"), REPLY_EDIT_SUCCESS("답변 수정 성공"), REPLY_DELETE_SUCCESS("답변 삭제 성공"), From 9b8aabc6059c57c69e0d264bfb6bedecd8f70b19 Mon Sep 17 00:00:00 2001 From: enjay27 Date: Sat, 12 Jun 2021 02:57:22 +0900 Subject: [PATCH 12/16] =?UTF-8?q?fix:=20ReplyController=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=20=EC=9D=B4=EB=A6=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/devin/dev/controller/reply/ReplyController.java | 6 +++--- src/main/java/com/devin/dev/service/ReplyService.java | 8 ++++---- src/main/java/com/devin/dev/utils/ResponseMessage.java | 6 ++++-- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/devin/dev/controller/reply/ReplyController.java b/src/main/java/com/devin/dev/controller/reply/ReplyController.java index 395d12e..ac24398 100644 --- a/src/main/java/com/devin/dev/controller/reply/ReplyController.java +++ b/src/main/java/com/devin/dev/controller/reply/ReplyController.java @@ -28,17 +28,17 @@ public DefaultResponse reply(@RequestBody @Valid ReplyForm form, HttpServletR } @PutMapping("/reply/{id}/update") - public DefaultResponse reply(@PathVariable("id") Long replyId, @RequestBody @Valid ReplyUpdateForm form, HttpServletRequest request) { + public DefaultResponse editReply(@PathVariable("id") Long replyId, @RequestBody @Valid ReplyUpdateForm form, HttpServletRequest request) { return replyService.editReply(replyId, form, request); } @DeleteMapping("/reply/{id}") - public DefaultResponse reply(@PathVariable("id") Long replyId, HttpServletRequest request) { + public DefaultResponse deleteReply(@PathVariable("id") Long replyId, HttpServletRequest request) { return replyService.deleteReply(replyId, request); } @PatchMapping("/reply/{id}/like") - public DefaultResponse changePostLike(@PathVariable("id") Long replyId, HttpServletRequest request) { + public DefaultResponse changeReplyLike(@PathVariable("id") Long replyId, HttpServletRequest request) { return replyService.changeReplyLike(replyId, request); } diff --git a/src/main/java/com/devin/dev/service/ReplyService.java b/src/main/java/com/devin/dev/service/ReplyService.java index cd4e558..19f9f04 100644 --- a/src/main/java/com/devin/dev/service/ReplyService.java +++ b/src/main/java/com/devin/dev/service/ReplyService.java @@ -187,7 +187,7 @@ public DefaultResponse deleteReply(Long userId, Long replyId) { // 채택된 답변인지 확인 if (reply.getStatus() == ReplyStatus.SELECTED) { - return new DefaultResponse<>(StatusCode.CONDITION_FAIL, ResponseMessage.CANNOT_DELETE_SELECTED); + return new DefaultResponse<>(StatusCode.CONDITION_FAIL, ResponseMessage.SELECTED_REPLY); } // 리플 작성자 경험치 삭제 @@ -280,7 +280,7 @@ public DefaultResponse editReply(Long replyId, ReplyUpdateForm form, HttpServ } if (reply.getStatus() == ReplyStatus.SELECTED) { - return new DefaultResponse<>(StatusCode.CONDITION_FAIL, ResponseMessage.NOT_SAME_USER); + return new DefaultResponse<>(StatusCode.CONDITION_FAIL, ResponseMessage.SELECTED_REPLY); } // 기존 이미지 경로 삭제 @@ -310,7 +310,7 @@ public DefaultResponse deleteReply(Long replyId, HttpServletRequest request) if (tokenProvider.validateToken(token)) { userId = tokenProvider.getUserId(token); } else { - return new DefaultResponse<>(StatusCode.FAIL_AUTH, ResponseMessage.NOT_FOUND_USER); + return new DefaultResponse<>(StatusCode.FAIL_AUTH, ResponseMessage.LOGIN_FAIL); } Optional userOptional = userRepository.findById(userId); if (userOptional.isEmpty()) { @@ -331,7 +331,7 @@ public DefaultResponse deleteReply(Long replyId, HttpServletRequest request) // 채택된 답변인지 확인 if (reply.getStatus() == ReplyStatus.SELECTED) { - return new DefaultResponse<>(StatusCode.CONDITION_FAIL, ResponseMessage.CANNOT_DELETE_SELECTED); + return new DefaultResponse<>(StatusCode.CONDITION_FAIL, ResponseMessage.SELECTED_REPLY); } // 리플 작성자 경험치 삭제 diff --git a/src/main/java/com/devin/dev/utils/ResponseMessage.java b/src/main/java/com/devin/dev/utils/ResponseMessage.java index 3992794..2e021fb 100644 --- a/src/main/java/com/devin/dev/utils/ResponseMessage.java +++ b/src/main/java/com/devin/dev/utils/ResponseMessage.java @@ -12,8 +12,9 @@ public enum ResponseMessage { NOT_FOUND_REPLY("답변을 찾을 수 없습니다."), NOT_FOUND_SUBJECT("주제를 찾을 수 없습니다."), NOT_SAME_USER("작성자가 아닙니다."), + NO_AUTHORITY("권한이 없습니다."), SAME_USER("작성자 입니다."), - CANNOT_DELETE_SELECTED("채택된 답변은 삭제할 수 없습니다."), + SELECTED_REPLY("채택된 답변 입니다."), CREATED_USER("회원 가입 성공"), UPDATE_USER("회원 정보 수정 성공"), DELETE_USER("회원 탈퇴 성공"), @@ -32,7 +33,8 @@ public enum ResponseMessage { EXIST_USER_EMAIL("이미 존재하는 회원 메일"), EXIST_SUBJECT("이미 존재하는 주제"), DELETE_SUBJECT("관심 주제 삭제 성공"), - DB_ERROR("데이터베이스 에러"); + DB_ERROR("데이터베이스 에러"), + FOUND_SUBJECT("관심 주제 조회 성공"); ResponseMessage(String message) { } From 1c815d50c29cd1be647f604b0d71c8c24daff795 Mon Sep 17 00:00:00 2001 From: enjay27 Date: Sat, 12 Jun 2021 03:01:44 +0900 Subject: [PATCH 13/16] =?UTF-8?q?[#26]feat:=20=EA=B4=80=EC=8B=AC=EC=82=AC?= =?UTF-8?q?=20=EC=83=9D=EC=84=B1=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/subject/SubjectController.java | 25 ++++++++++++ .../dev/controller/subject/SubjectForm.java | 11 ++++++ .../com/devin/dev/service/SubjectService.java | 39 +++++++++++++++++++ 3 files changed, 75 insertions(+) create mode 100644 src/main/java/com/devin/dev/controller/subject/SubjectController.java create mode 100644 src/main/java/com/devin/dev/controller/subject/SubjectForm.java diff --git a/src/main/java/com/devin/dev/controller/subject/SubjectController.java b/src/main/java/com/devin/dev/controller/subject/SubjectController.java new file mode 100644 index 0000000..dd6281f --- /dev/null +++ b/src/main/java/com/devin/dev/controller/subject/SubjectController.java @@ -0,0 +1,25 @@ +package com.devin.dev.controller.subject; + +import com.devin.dev.model.DefaultResponse; +import com.devin.dev.service.SubjectService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +import javax.servlet.http.HttpServletRequest; + +@Controller +@RequiredArgsConstructor +public class SubjectController { + + private final SubjectService subjectService; + + @PostMapping("/tags") + public DefaultResponse addSubject(@RequestBody SubjectForm form, HttpServletRequest request) { + return subjectService.addSubject(form, request); + } + +} diff --git a/src/main/java/com/devin/dev/controller/subject/SubjectForm.java b/src/main/java/com/devin/dev/controller/subject/SubjectForm.java new file mode 100644 index 0000000..7a32afa --- /dev/null +++ b/src/main/java/com/devin/dev/controller/subject/SubjectForm.java @@ -0,0 +1,11 @@ +package com.devin.dev.controller.subject; + +import lombok.Data; + +import java.util.List; + +@Data +public class SubjectForm { + + private List subjects; +} diff --git a/src/main/java/com/devin/dev/service/SubjectService.java b/src/main/java/com/devin/dev/service/SubjectService.java index a7937ba..29300f1 100644 --- a/src/main/java/com/devin/dev/service/SubjectService.java +++ b/src/main/java/com/devin/dev/service/SubjectService.java @@ -1,21 +1,60 @@ package com.devin.dev.service; +import com.devin.dev.controller.subject.SubjectForm; import com.devin.dev.entity.post.Subject; +import com.devin.dev.entity.user.User; +import com.devin.dev.entity.user.UserStatus; import com.devin.dev.model.DefaultResponse; +import com.devin.dev.repository.post.PostTagRepository; import com.devin.dev.repository.subject.SubjectRepository; +import com.devin.dev.repository.user.UserInterestRepository; +import com.devin.dev.repository.user.UserRepository; +import com.devin.dev.security.JwtAuthTokenProvider; import com.devin.dev.utils.ResponseMessage; import com.devin.dev.utils.StatusCode; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import javax.servlet.http.HttpServletRequest; +import java.util.List; import java.util.Optional; +import java.util.stream.Collectors; @Service @RequiredArgsConstructor public class SubjectService { private final SubjectRepository subjectRepository; + private final PostTagRepository postTagRepository; + private final UserRepository userRepository; + private final UserInterestRepository userInterestRepository; + private final JwtAuthTokenProvider tokenProvider; + + @Transactional + public DefaultResponse addSubject(SubjectForm form, HttpServletRequest request) { + String token = tokenProvider.parseToken(request); + Long userId; + if (tokenProvider.validateToken(token)) { + userId = tokenProvider.getUserId(token); + } else { + return new DefaultResponse<>(StatusCode.FAIL_AUTH, ResponseMessage.NOT_FOUND_USER); + } + Optional userOptional = userRepository.findById(userId); + if (userOptional.isEmpty()) { + return new DefaultResponse<>(StatusCode.NOT_EXIST, ResponseMessage.NOT_FOUND_USER); + } + User user = userOptional.get(); + + if (user.getStatus() != UserStatus.ADMIN) { + return new DefaultResponse<>(StatusCode.CONDITION_FAIL, ResponseMessage.NO_AUTHORITY); + } + + List subjects = form.getSubjects().stream().map(Subject::new).collect(Collectors.toList()); + subjectRepository.saveAll(subjects); + + return new DefaultResponse<>(StatusCode.SUCCESS, ResponseMessage.CREATED_SUBJECT); + } @Transactional public DefaultResponse addSubject(String name) { From 064cbb6722120252ad578cfe0f0fa18c4702ce31 Mon Sep 17 00:00:00 2001 From: enjay27 Date: Sat, 12 Jun 2021 03:03:00 +0900 Subject: [PATCH 14/16] =?UTF-8?q?[#27]feat:=20=EA=B4=80=EC=8B=AC=EC=82=AC?= =?UTF-8?q?=20=EC=82=AD=EC=A0=9C=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/subject/SubjectController.java | 4 +++ .../com/devin/dev/service/SubjectService.java | 28 +++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/src/main/java/com/devin/dev/controller/subject/SubjectController.java b/src/main/java/com/devin/dev/controller/subject/SubjectController.java index dd6281f..89dd50d 100644 --- a/src/main/java/com/devin/dev/controller/subject/SubjectController.java +++ b/src/main/java/com/devin/dev/controller/subject/SubjectController.java @@ -22,4 +22,8 @@ public DefaultResponse addSubject(@RequestBody SubjectForm form, HttpServletR return subjectService.addSubject(form, request); } + @DeleteMapping("/tags") + public DefaultResponse deleteSubject(@RequestBody SubjectForm form, HttpServletRequest request) { + return subjectService.removeSubject(form, request); + } } diff --git a/src/main/java/com/devin/dev/service/SubjectService.java b/src/main/java/com/devin/dev/service/SubjectService.java index 29300f1..900f1a0 100644 --- a/src/main/java/com/devin/dev/service/SubjectService.java +++ b/src/main/java/com/devin/dev/service/SubjectService.java @@ -79,4 +79,32 @@ public DefaultResponse removeSubject(String name) { return new DefaultResponse<>(StatusCode.SUCCESS, ResponseMessage.DELETE_SUBJECT); } + + @Transactional + public DefaultResponse removeSubject(SubjectForm form, HttpServletRequest request) { + String token = tokenProvider.parseToken(request); + Long userId; + if (tokenProvider.validateToken(token)) { + userId = tokenProvider.getUserId(token); + } else { + return new DefaultResponse<>(StatusCode.FAIL_AUTH, ResponseMessage.NOT_FOUND_USER); + } + Optional userOptional = userRepository.findById(userId); + if (userOptional.isEmpty()) { + return new DefaultResponse<>(StatusCode.NOT_EXIST, ResponseMessage.NOT_FOUND_USER); + } + User user = userOptional.get(); + + if (user.getStatus() != UserStatus.ADMIN) { + return new DefaultResponse<>(StatusCode.CONDITION_FAIL, ResponseMessage.NO_AUTHORITY); + } + + List subjects = subjectRepository.findByNameIn(form.getSubjects()); + if (subjects.isEmpty()) { + return new DefaultResponse<>(StatusCode.NOT_EXIST, ResponseMessage.NOT_FOUND_SUBJECT); + } + subjectRepository.deleteAll(subjects); + + return new DefaultResponse<>(StatusCode.SUCCESS, ResponseMessage.DELETE_SUBJECT); + } } From a2f1ad7d46e860cf10a3c1265e0f64d581961fce Mon Sep 17 00:00:00 2001 From: enjay27 Date: Sat, 12 Jun 2021 03:03:27 +0900 Subject: [PATCH 15/16] =?UTF-8?q?[#28]feat:=20=EA=B4=80=EC=8B=AC=EC=82=AC?= =?UTF-8?q?=20=EC=A0=84=EC=B2=B4=20=EC=A1=B0=ED=9A=8C=20=EA=B8=B0=EB=8A=A5?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/devin/dev/controller/subject/SubjectController.java | 6 ++++++ src/main/java/com/devin/dev/service/SubjectService.java | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/src/main/java/com/devin/dev/controller/subject/SubjectController.java b/src/main/java/com/devin/dev/controller/subject/SubjectController.java index 89dd50d..ee9d5f5 100644 --- a/src/main/java/com/devin/dev/controller/subject/SubjectController.java +++ b/src/main/java/com/devin/dev/controller/subject/SubjectController.java @@ -26,4 +26,10 @@ public DefaultResponse addSubject(@RequestBody SubjectForm form, HttpServletR public DefaultResponse deleteSubject(@RequestBody SubjectForm form, HttpServletRequest request) { return subjectService.removeSubject(form, request); } + + @GetMapping("/tags") + public DefaultResponse getSubject() { + return subjectService.getSubject(); + } + } diff --git a/src/main/java/com/devin/dev/service/SubjectService.java b/src/main/java/com/devin/dev/service/SubjectService.java index 900f1a0..07e80d5 100644 --- a/src/main/java/com/devin/dev/service/SubjectService.java +++ b/src/main/java/com/devin/dev/service/SubjectService.java @@ -69,6 +69,12 @@ public DefaultResponse addSubject(String name) { return new DefaultResponse<>(StatusCode.SUCCESS, ResponseMessage.CREATED_SUBJECT); } + @Transactional(readOnly = true) + public DefaultResponse> getSubject() { + List subjects = subjectRepository.findAll().stream().map(Subject::getName).collect(Collectors.toList()); + return new DefaultResponse<>(StatusCode.SUCCESS, ResponseMessage.FOUND_SUBJECT, subjects); + } + @Transactional public DefaultResponse removeSubject(String name) { Optional subjectOptional = subjectRepository.findByName(name); From 9e53ee8421e0f7cc3f90308fb4abe9b4246b6fa4 Mon Sep 17 00:00:00 2001 From: enjay27 Date: Sat, 12 Jun 2021 03:32:11 +0900 Subject: [PATCH 16/16] =?UTF-8?q?fix:=20=EA=B4=80=EC=8B=AC=20=EC=A3=BC?= =?UTF-8?q?=EC=A0=9C=20=EC=A0=84=EC=B2=B4=20=EC=A1=B0=ED=9A=8C=20=EC=8B=9C?= =?UTF-8?q?=20SubjectDto=20=EB=A5=BC=20=EB=B0=98=ED=99=98=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/devin/dev/dto/subject/SubjectDto.java | 16 ++++++++++++++++ .../com/devin/dev/service/SubjectService.java | 7 ++++--- 2 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/devin/dev/dto/subject/SubjectDto.java diff --git a/src/main/java/com/devin/dev/dto/subject/SubjectDto.java b/src/main/java/com/devin/dev/dto/subject/SubjectDto.java new file mode 100644 index 0000000..eb7f7e8 --- /dev/null +++ b/src/main/java/com/devin/dev/dto/subject/SubjectDto.java @@ -0,0 +1,16 @@ +package com.devin.dev.dto.subject; + +import com.devin.dev.entity.post.Subject; +import lombok.Data; + +@Data +public class SubjectDto { + + private Long tag_id; + private String tag_name; + + public SubjectDto(Subject subject) { + this.tag_id = subject.getId(); + this.tag_name = subject.getName(); + } +} diff --git a/src/main/java/com/devin/dev/service/SubjectService.java b/src/main/java/com/devin/dev/service/SubjectService.java index 07e80d5..750d805 100644 --- a/src/main/java/com/devin/dev/service/SubjectService.java +++ b/src/main/java/com/devin/dev/service/SubjectService.java @@ -1,6 +1,7 @@ package com.devin.dev.service; import com.devin.dev.controller.subject.SubjectForm; +import com.devin.dev.dto.subject.SubjectDto; import com.devin.dev.entity.post.Subject; import com.devin.dev.entity.user.User; import com.devin.dev.entity.user.UserStatus; @@ -70,9 +71,9 @@ public DefaultResponse addSubject(String name) { } @Transactional(readOnly = true) - public DefaultResponse> getSubject() { - List subjects = subjectRepository.findAll().stream().map(Subject::getName).collect(Collectors.toList()); - return new DefaultResponse<>(StatusCode.SUCCESS, ResponseMessage.FOUND_SUBJECT, subjects); + public DefaultResponse> getSubject() { + List subjectDtos = subjectRepository.findAll().stream().map(SubjectDto::new).collect(Collectors.toList()); + return new DefaultResponse<>(StatusCode.SUCCESS, ResponseMessage.FOUND_SUBJECT, subjectDtos); } @Transactional