diff --git a/.github/ISSUE_TEMPLATE/issue-form.yml b/.github/ISSUE_TEMPLATE/issue-form.yml index 046b27f6..59d7969c 100644 --- a/.github/ISSUE_TEMPLATE/issue-form.yml +++ b/.github/ISSUE_TEMPLATE/issue-form.yml @@ -11,7 +11,6 @@ body: placeholder: 'GAJI-00' validations: required: true - - type: input id: description attributes: @@ -19,7 +18,6 @@ body: description: '이슈에 대해서 간략히 설명해주세요' validations: required: true - - type: textarea id: details attributes: @@ -29,7 +27,6 @@ body: - About Details validations: required: true - - type: textarea id: tasks attributes: @@ -40,7 +37,6 @@ body: - [ ] Task2 validations: required: true - - type: textarea id: references attributes: diff --git a/.github/workflows/create-jira-issue.yml b/.github/workflows/create-jira-issue.yml index 95b2587e..428df24c 100644 --- a/.github/workflows/create-jira-issue.yml +++ b/.github/workflows/create-jira-issue.yml @@ -14,22 +14,18 @@ jobs: JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }} JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }} JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }} - - name: Checkout develop code uses: actions/checkout@v4 with: ref: develop - - name: Issue Parser uses: stefanbuck/github-issue-praser@v3 id: issue-parser with: template-path: ./.github/ISSUE_TEMPLATE/issue-form.yml - - name: Log Issue Parser run: | echo '${{ steps.issue-parser.outputs.jsonString }}' - - name: Convert markdown to Jira Syntax uses: peter-evans/jira2md@v1 id: md2jira @@ -40,7 +36,6 @@ jobs: ${{ github.event.issue.body }} mode: md2jira - - name: Create Issue id: create uses: atlassian/gajira-create@v3 @@ -55,23 +50,18 @@ jobs: "key": "${{ steps.issue-parser.outputs.issueparser_parentKey }}" } } - - - name: Log created issue run: echo "Jira Issue ${{ steps.issue-parser.outputs.parentKey }}/${{ steps.create.outputs.issue }} was created" - - name: Checkout develop code uses: actions/checkout@v4 with: ref: develop - - name: Create branch with Ticket number run: | sanitized_branch_name=$(echo '${{ github.event.issue.title }}/${{ steps.create.outputs.issue }}' | sed 's/[^a-zA-Z0-9_/-]/-/g') sanitized_branch_name=$(echo "$sanitized_branch_name" | sed 's/-\+/-/g' | sed 's/-$//g' | sed 's/^-\+//g') git checkout -b "$sanitized_branch_name" git push origin "$sanitized_branch_name" - - name: Update issue title uses: actions-cool/issues-helper@v3 with: diff --git a/src/main/java/gaji/service/domain/enums/PostTypeEnum.java b/src/main/java/gaji/service/domain/enums/PostTypeEnum.java index 74c60b1f..8ac84b43 100644 --- a/src/main/java/gaji/service/domain/enums/PostTypeEnum.java +++ b/src/main/java/gaji/service/domain/enums/PostTypeEnum.java @@ -28,7 +28,7 @@ public static PostTypeEnum from(String param) { } } log.error("PostTypeEnum.from() exception occur param: {}", param); - throw new RestApiException(CommunityPostErrorStatus._INVALID_POST_TYPE); + return null; } } diff --git a/src/main/java/gaji/service/domain/post/converter/CommunityCommentConverter.java b/src/main/java/gaji/service/domain/post/converter/CommunityCommentConverter.java index e430265f..0b0016c2 100644 --- a/src/main/java/gaji/service/domain/post/converter/CommunityCommentConverter.java +++ b/src/main/java/gaji/service/domain/post/converter/CommunityCommentConverter.java @@ -26,7 +26,7 @@ public static CommunityPostCommentResponseDTO.PostCommentDTO toPostCommentDTO(Co return CommunityPostCommentResponseDTO.PostCommentDTO.builder() .commentId(comment.getId()) .userId(comment.getUser().getId()) - .userNickName(comment.getUser().getName()) + .userNickName(comment.getUser().getNickname()) .commentBody(comment.getBody()) .groupNum(comment.getGroupNum()) .depth(comment.getDepth()) diff --git a/src/main/java/gaji/service/domain/post/converter/CommunityPostConverter.java b/src/main/java/gaji/service/domain/post/converter/CommunityPostConverter.java index f86408f0..f06af6bf 100644 --- a/src/main/java/gaji/service/domain/post/converter/CommunityPostConverter.java +++ b/src/main/java/gaji/service/domain/post/converter/CommunityPostConverter.java @@ -29,11 +29,6 @@ @RequiredArgsConstructor @Component public class CommunityPostConverter { - private final HashtagService hashtagService; - private final CategoryService categoryService; - private final CommunityPostBookMarkService postBookMarkService; - private final CommunityPostLikesService postLikesService; - private final CommunityPostQueryService communityPostQueryService; // 초기 PostStatus 지정 public static PostStatusEnum getInitialPostStatus(PostTypeEnum type) { @@ -41,8 +36,8 @@ public static PostStatusEnum getInitialPostStatus(PostTypeEnum type) { (type == PostTypeEnum.PROJECT) ? PostStatusEnum.RECRUITING : PostStatusEnum.BLOGING; } - public static CommunityPostResponseDTO.UploadPostResponseDTO toUploadPostResponseDTO(CommnuityPost post) { - return CommunityPostResponseDTO.UploadPostResponseDTO + public static CommunityPostResponseDTO.PostIdResponseDTO toPostIdResponseDTO(CommnuityPost post) { + return CommunityPostResponseDTO.PostIdResponseDTO .builder() .postId(post.getId()) .build(); @@ -63,14 +58,15 @@ public static CommunityPostResponseDTO.PostLikesIdDTO toPostLikesIdDTO(PostLikes } public static CommnuityPost toPost(CommunityPostRequestDTO.UploadPostRequestDTO request, User user) { + PostTypeEnum postTypeEnum = PostTypeEnum.from(request.getType()); + return CommnuityPost.builder() .user(user) .title(request.getTitle()) .body(request.getBody()) - .thumbnailUrl(/*(request.getThumbnailUrl() == null) ? Post.getDefaultThumbnailUrl() : request.getThumbnailUrl()*/ - request.getThumbnailUrl()) - .type(request.getType()) - .status(getInitialPostStatus(request.getType())) + .thumbnailUrl(request.getThumbnailUrl()) + .type(postTypeEnum) + .status(getInitialPostStatus(postTypeEnum)) .build(); } @@ -97,8 +93,7 @@ public static PostLikes toPostLikes(User user, CommnuityPost post) { .build(); } - public CommunityPostResponseDTO.PostPreviewDTO toPostPreviewDTO(CommnuityPost post) { - List selectHashtagList = hashtagService.findAllFetchJoinWithHashtagByEntityIdAndPostType(post.getId(), post.getType()); + public static CommunityPostResponseDTO.PostPreviewDTO toPostPreviewDTO(CommnuityPost post, List selectHashtagList) { List hashtagList = HashtagConverter.toHashtagNameList(selectHashtagList); return CommunityPostResponseDTO.PostPreviewDTO.builder() @@ -117,10 +112,9 @@ public CommunityPostResponseDTO.PostPreviewDTO toPostPreviewDTO(CommnuityPost po .build(); } - public CommunityPostResponseDTO.PostPreviewListDTO toPostPreviewListDTO(List postList, boolean hasNext) { - CommunityPostConverter postConverter = new CommunityPostConverter(hashtagService, categoryService, postBookMarkService, postLikesService, communityPostQueryService); + public static CommunityPostResponseDTO.PostPreviewListDTO toPostPreviewListDTO(List postList, boolean hasNext, List selectHashtagList) { List postPreviewDTOList = postList.stream() - .map(postConverter::toPostPreviewDTO) + .map(post -> CommunityPostConverter.toPostPreviewDTO(post, selectHashtagList)) .collect(Collectors.toList()); return CommunityPostResponseDTO.PostPreviewListDTO.builder() @@ -129,20 +123,10 @@ public CommunityPostResponseDTO.PostPreviewListDTO toPostPreviewListDTO(List selectHashtagList = hashtagService.findAllFetchJoinWithHashtagByEntityIdAndPostType(post.getId(), post.getType()); + public static CommunityPostResponseDTO.PostDetailDTO toPostDetailDTO(CommnuityPost post, SelectCategory selectCategory, List selectHashtagList, + boolean isBookmarked, boolean isLiked, boolean isWriter) { List hashtagNameAndIdDTOList = HashtagConverter.toHashtagNameAndIdDTOList(selectHashtagList); - // ofNullable 메서드로 NPE 방지 - /*CategoryEnum category = Optional.ofNullable(categoryService.findOneFetchJoinWithCategoryByEntityIdAndPostType(post.getId(), post.getType())) - .map(SelectCategory::getCategory) - .map(Category::getCategory) - .orElse(null);*/ - - boolean isBookmarked = (userId == null) ? false : postBookMarkService.existsByUserAndPost(userId, post); - boolean isLiked = (userId == null) ? false : postLikesService.existsByUserAndPost(userId, post); - boolean isWriter = (userId == null) ? false : communityPostQueryService.isPostWriter(userId, post); - return CommunityPostResponseDTO.PostDetailDTO.builder() .userId(post.getUser().getId()) .type(post.getType()) diff --git a/src/main/java/gaji/service/domain/post/converter/PostTypeConverter.java b/src/main/java/gaji/service/domain/post/converter/PostTypeConverter.java index cb9b6392..9eda4b61 100644 --- a/src/main/java/gaji/service/domain/post/converter/PostTypeConverter.java +++ b/src/main/java/gaji/service/domain/post/converter/PostTypeConverter.java @@ -1,12 +1,18 @@ package gaji.service.domain.post.converter; import gaji.service.domain.enums.PostTypeEnum; +import gaji.service.domain.post.code.CommunityPostErrorStatus; +import gaji.service.global.exception.RestApiException; import org.springframework.core.convert.converter.Converter; public class PostTypeConverter implements Converter { @Override public PostTypeEnum convert(String param) { - return PostTypeEnum.from(param); + PostTypeEnum postType = PostTypeEnum.from(param); + if (postType == null) { + throw new RestApiException(CommunityPostErrorStatus._INVALID_POST_TYPE); + } + return postType; } } diff --git a/src/main/java/gaji/service/domain/post/service/CommunityCommentService.java b/src/main/java/gaji/service/domain/post/service/CommunityCommentService.java index 3f357c77..2d3ac6b1 100644 --- a/src/main/java/gaji/service/domain/post/service/CommunityCommentService.java +++ b/src/main/java/gaji/service/domain/post/service/CommunityCommentService.java @@ -2,6 +2,7 @@ import gaji.service.domain.post.entity.CommnuityPost; import gaji.service.domain.post.entity.CommunityComment; +import gaji.service.domain.post.web.dto.CommunityPostCommentResponseDTO; import gaji.service.domain.post.web.dto.CommunityPostRequestDTO; import gaji.service.domain.user.entity.User; import org.springframework.data.domain.Slice; @@ -13,7 +14,7 @@ public interface CommunityCommentService { CommunityComment createCommentByCheckParentCommentIdIsNull(Long parentCommentId, CommunityPostRequestDTO.WriteCommentRequestDTO request, User findUser, CommnuityPost findPost); void hardDeleteComment(CommunityComment comment); CommunityComment findByCommentId(Long commentId); - Slice getCommentListByPost(Long postId, Integer lastGroupNum, int page, int size); + CommunityPostCommentResponseDTO.PostCommentListDTO getCommentListByPost(Long userId, Long postId, Integer lastGroupNum, int page, int size); boolean isCommentWriter(Long userId, CommunityComment comment); void validCommentWriter(Long userId, CommunityComment comment); diff --git a/src/main/java/gaji/service/domain/post/service/CommunityCommentServiceImpl.java b/src/main/java/gaji/service/domain/post/service/CommunityCommentServiceImpl.java index 9fe9c7c1..9399ba62 100644 --- a/src/main/java/gaji/service/domain/post/service/CommunityCommentServiceImpl.java +++ b/src/main/java/gaji/service/domain/post/service/CommunityCommentServiceImpl.java @@ -1,11 +1,14 @@ package gaji.service.domain.post.service; import gaji.service.domain.post.code.CommunityCommentErrorStatus; +import gaji.service.domain.post.converter.CommunityCommentConverter; import gaji.service.domain.post.converter.CommunityPostConverter; import gaji.service.domain.post.entity.CommnuityPost; import gaji.service.domain.post.entity.CommunityComment; import gaji.service.domain.post.repository.CommunityCommentJpaRepository; +import gaji.service.domain.post.web.dto.CommunityPostCommentResponseDTO; import gaji.service.domain.post.web.dto.CommunityPostRequestDTO; +import gaji.service.domain.post.web.dto.CommunityPostResponseDTO; import gaji.service.domain.user.entity.User; import gaji.service.global.exception.RestApiException; import lombok.RequiredArgsConstructor; @@ -14,6 +17,9 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.ArrayList; +import java.util.List; + @Service @RequiredArgsConstructor @Transactional(readOnly = true) @@ -45,10 +51,22 @@ public void hardDeleteComment(CommunityComment comment) { } @Override - public Slice getCommentListByPost(Long postId, Integer lastGroupNum, int page, int size) { + public CommunityPostCommentResponseDTO.PostCommentListDTO getCommentListByPost(Long userId, Long postId, Integer lastGroupNum, int page, int size) { PageRequest pageRequest = PageRequest.of(page, size); CommnuityPost findPost = communityPostQueryService.findPostByPostId(postId); - return communityCommentJpaRepository.findBySliceAndPostFetchJoinWithUser(lastGroupNum, findPost, pageRequest); + Slice commentSlice = communityCommentJpaRepository.findBySliceAndPostFetchJoinWithUser(lastGroupNum, findPost, pageRequest); + + List postCommentDTOList = new ArrayList<>(); + + for (CommunityComment communityComment : commentSlice.getContent()) { + boolean isWriter = (userId == null) ? false : isCommentWriter(userId, communityComment); + postCommentDTOList.add(CommunityCommentConverter.toPostCommentDTO(communityComment, isWriter)); + } + + return CommunityPostCommentResponseDTO.PostCommentListDTO.builder() + .commentList(postCommentDTOList) + .hasNext(commentSlice.hasNext()) + .build(); } @Override diff --git a/src/main/java/gaji/service/domain/post/service/CommunityPostCommandService.java b/src/main/java/gaji/service/domain/post/service/CommunityPostCommandService.java index ea7ca245..4b6da6b8 100644 --- a/src/main/java/gaji/service/domain/post/service/CommunityPostCommandService.java +++ b/src/main/java/gaji/service/domain/post/service/CommunityPostCommandService.java @@ -4,17 +4,20 @@ import gaji.service.domain.post.entity.CommunityComment; import gaji.service.domain.post.entity.PostBookmark; import gaji.service.domain.post.entity.PostLikes; +import gaji.service.domain.post.web.dto.CommunityPostCommentResponseDTO; import gaji.service.domain.post.web.dto.CommunityPostRequestDTO; +import gaji.service.domain.post.web.dto.CommunityPostResponseDTO; public interface CommunityPostCommandService { - CommnuityPost uploadPost(Long userId, CommunityPostRequestDTO.UploadPostRequestDTO request); - CommunityComment writeCommentOnCommunityPost(Long userId, Long postId, Long parentCommentId, CommunityPostRequestDTO.WriteCommentRequestDTO request); + CommunityPostResponseDTO.PostIdResponseDTO uploadPost(Long userId, CommunityPostRequestDTO.UploadPostRequestDTO request); + CommunityPostResponseDTO.PostIdResponseDTO editPost(Long userId, Long postId, CommunityPostRequestDTO.EditPostRequestDTO request); + CommunityPostCommentResponseDTO.WriteCommentResponseDTO writeCommentOnCommunityPost(Long userId, Long postId, Long parentCommentId, CommunityPostRequestDTO.WriteCommentRequestDTO request); void hardDeleteComment(Long userId, Long commentId); void hardDeleteCommunityPost(Long userId, Long postId); - PostBookmark bookmarkCommunityPost(Long userId, Long postId); + CommunityPostResponseDTO.PostBookmarkIdDTO bookmarkCommunityPost(Long userId, Long postId); void cancelbookmarkCommunityPost(Long userId, Long postId); - PostLikes likeCommunityPost(Long userId, Long postId); + CommunityPostResponseDTO.PostLikesIdDTO likeCommunityPost(Long userId, Long postId); void cancelLikeCommunityPost(Long userId, Long postId); } diff --git a/src/main/java/gaji/service/domain/post/service/CommunityPostCommandServiceImpl.java b/src/main/java/gaji/service/domain/post/service/CommunityPostCommandServiceImpl.java index 3b328d12..3fc2c0e0 100644 --- a/src/main/java/gaji/service/domain/post/service/CommunityPostCommandServiceImpl.java +++ b/src/main/java/gaji/service/domain/post/service/CommunityPostCommandServiceImpl.java @@ -9,6 +9,8 @@ import gaji.service.domain.common.service.CategoryService; import gaji.service.domain.common.service.HashtagService; import gaji.service.domain.enums.CategoryEnum; +import gaji.service.domain.enums.PostTypeEnum; +import gaji.service.domain.post.converter.CommunityCommentConverter; import gaji.service.domain.post.converter.CommunityPostConverter; import gaji.service.domain.post.entity.CommnuityPost; import gaji.service.domain.post.entity.CommunityComment; @@ -17,7 +19,9 @@ import gaji.service.domain.post.repository.CommunityPostBookmarkRepository; import gaji.service.domain.post.repository.CommunityPostJpaRepository; import gaji.service.domain.post.repository.CommunityPostLikesRepository; +import gaji.service.domain.post.web.dto.CommunityPostCommentResponseDTO; import gaji.service.domain.post.web.dto.CommunityPostRequestDTO; +import gaji.service.domain.post.web.dto.CommunityPostResponseDTO; import gaji.service.domain.user.entity.User; import gaji.service.domain.user.service.UserQueryService; import lombok.RequiredArgsConstructor; @@ -42,7 +46,7 @@ public class CommunityPostCommandServiceImpl implements CommunityPostCommandServ @Override - public CommnuityPost uploadPost(Long userId, CommunityPostRequestDTO.UploadPostRequestDTO request) { + public CommunityPostResponseDTO.PostIdResponseDTO uploadPost(Long userId, CommunityPostRequestDTO.UploadPostRequestDTO request) { User findUser = userQueryService.findUserById(userId); CommnuityPost post = CommunityPostConverter.toPost(request, findUser); CommnuityPost newPost = communityPostJpaRepository.save(post); @@ -53,7 +57,7 @@ public CommnuityPost uploadPost(Long userId, CommunityPostRequestDTO.UploadPostR List hashtagStringList = request.getHashtagList(); List hashtagEntityList = hashtagService.createHashtagEntityList(hashtagStringList); - List selectHashtagList = HashtagConverter.toSelectHashtagList(hashtagEntityList, post.getId(), request.getType()); + List selectHashtagList = HashtagConverter.toSelectHashtagList(hashtagEntityList, post.getId(), PostTypeEnum.from(request.getType())); hashtagService.saveAllSelectHashtag(selectHashtagList); } @@ -67,11 +71,24 @@ public CommnuityPost uploadPost(Long userId, CommunityPostRequestDTO.UploadPostR categoryService.saveSelectCategory(selectCategory); } - return newPost; + return CommunityPostConverter.toPostIdResponseDTO(newPost); } @Override - public CommunityComment writeCommentOnCommunityPost(Long userId, Long postId, Long parentCommentId, CommunityPostRequestDTO.WriteCommentRequestDTO request) { + public CommunityPostResponseDTO.PostIdResponseDTO editPost(Long userId, Long postId, CommunityPostRequestDTO.EditPostRequestDTO request) { + // 조회 + CommnuityPost findPost = communityPostQueryService.findPostByPostId(postId); + + // 작성자 검증 + communityPostQueryService.validPostWriter(userId, findPost); + + + + return null; + } + + @Override + public CommunityPostCommentResponseDTO.WriteCommentResponseDTO writeCommentOnCommunityPost(Long userId, Long postId, Long parentCommentId, CommunityPostRequestDTO.WriteCommentRequestDTO request) { User findUser = userQueryService.findUserById(userId); CommnuityPost findPost = communityPostQueryService.findPostByPostId(postId); @@ -82,7 +99,7 @@ public CommunityComment writeCommentOnCommunityPost(Long userId, Long postId, Lo // 게시글의 댓글 수 증가 newComment.getPost().increaseCommentCnt(); - return newComment; + return CommunityCommentConverter.toWriteCommentResponseDTO(newComment); } @Override @@ -113,7 +130,7 @@ public void hardDeleteCommunityPost(Long userId, Long postId) { } @Override - public PostBookmark bookmarkCommunityPost(Long userId, Long postId) { + public CommunityPostResponseDTO.PostBookmarkIdDTO bookmarkCommunityPost(Long userId, Long postId) { User findUser = userQueryService.findUserById(userId); CommnuityPost findPost = communityPostQueryService.findPostByPostId(postId); @@ -125,7 +142,7 @@ public PostBookmark bookmarkCommunityPost(Long userId, Long postId) { // 게시글 북마크 수 증가 newPostBookmark.getPost().increaseBookmarkCnt(); - return newPostBookmark; + return CommunityPostConverter.toPostBookmarkIdDTO(newPostBookmark); } @Override @@ -144,7 +161,7 @@ public void cancelbookmarkCommunityPost(Long userId, Long postId) { } @Override - public PostLikes likeCommunityPost(Long userId, Long postId) { + public CommunityPostResponseDTO.PostLikesIdDTO likeCommunityPost(Long userId, Long postId) { User findUser = userQueryService.findUserById(userId); CommnuityPost findPost = communityPostQueryService.findPostByPostId(postId); @@ -157,7 +174,7 @@ public PostLikes likeCommunityPost(Long userId, Long postId) { // 좋아요 수, 인기점수 증가 findPost.increaseLikeCnt(); findPost.increasePopularityScoreByLike(); - return newPostLikes; + return CommunityPostConverter.toPostLikesIdDTO(newPostLikes); } @Override @@ -165,8 +182,7 @@ public void cancelLikeCommunityPost(Long userId, Long postId) { User findUser = userQueryService.findUserById(userId); CommnuityPost findPost = communityPostQueryService.findPostByPostId(postId); - // 검증 - communityPostQueryService.validPostWriter(findUser.getId(), findPost); + // TODO: like owner인지 검증 // 삭제 postLikesRepository.deleteByUserAndPost(findUser, findPost); diff --git a/src/main/java/gaji/service/domain/post/service/CommunityPostQueryService.java b/src/main/java/gaji/service/domain/post/service/CommunityPostQueryService.java index 3a06924c..07c203f7 100644 --- a/src/main/java/gaji/service/domain/post/service/CommunityPostQueryService.java +++ b/src/main/java/gaji/service/domain/post/service/CommunityPostQueryService.java @@ -4,13 +4,14 @@ import gaji.service.domain.enums.PostTypeEnum; import gaji.service.domain.enums.SortType; import gaji.service.domain.post.entity.CommnuityPost; +import gaji.service.domain.post.web.dto.CommunityPostResponseDTO; import org.springframework.data.domain.Slice; public interface CommunityPostQueryService { CommnuityPost findPostByPostId(Long postId); - Slice getPostList(String keyword, + CommunityPostResponseDTO.PostPreviewListDTO getPostList(String keyword, Integer lastPopularityScore, Long lastPostId, Integer lastLikeCnt, @@ -21,7 +22,7 @@ Slice getPostList(String keyword, PostStatusEnum filter, int page, int size); - CommnuityPost getPostDetail(Long postId); + CommunityPostResponseDTO.PostDetailDTO getPostDetail(Long userId, Long postId); boolean isPostWriter(Long userId, CommnuityPost post); void validPostWriter(Long userId, CommnuityPost post); void validExistsPostLikes(Long userId, CommnuityPost post); diff --git a/src/main/java/gaji/service/domain/post/service/CommunityPostQueryServiceImpl.java b/src/main/java/gaji/service/domain/post/service/CommunityPostQueryServiceImpl.java index 149c5a39..dee965f4 100644 --- a/src/main/java/gaji/service/domain/post/service/CommunityPostQueryServiceImpl.java +++ b/src/main/java/gaji/service/domain/post/service/CommunityPostQueryServiceImpl.java @@ -1,15 +1,20 @@ package gaji.service.domain.post.service; +import gaji.service.domain.common.entity.SelectCategory; +import gaji.service.domain.common.entity.SelectHashtag; import gaji.service.domain.common.service.CategoryService; +import gaji.service.domain.common.service.HashtagService; import gaji.service.domain.enums.CategoryEnum; import gaji.service.domain.enums.PostStatusEnum; import gaji.service.domain.enums.PostTypeEnum; import gaji.service.domain.enums.SortType; import gaji.service.domain.post.code.CommunityPostErrorStatus; +import gaji.service.domain.post.converter.CommunityPostConverter; import gaji.service.domain.post.entity.CommnuityPost; import gaji.service.domain.post.repository.CommunityPostBookmarkRepository; import gaji.service.domain.post.repository.CommunityPostJpaRepository; import gaji.service.domain.post.repository.CommunityPostLikesRepository; +import gaji.service.domain.post.web.dto.CommunityPostResponseDTO; import gaji.service.global.exception.RestApiException; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.PageRequest; @@ -17,6 +22,9 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.ArrayList; +import java.util.List; + @Service @RequiredArgsConstructor @Transactional(readOnly = true) @@ -26,9 +34,14 @@ public class CommunityPostQueryServiceImpl implements CommunityPostQueryService private final CommunityPostBookmarkRepository postBookmarkRepository; private final CategoryService categoryService; + private final HashtagService hashtagService; + private final CommunityPostBookMarkService postBookMarkService; + private final CommunityPostLikesService postLikesService; + + @Override - public Slice getPostList(String keyword, + public CommunityPostResponseDTO.PostPreviewListDTO getPostList(String keyword, Integer lastPopularityScore, Long lastPostId, Integer lastLikeCnt, @@ -48,7 +61,7 @@ public Slice getPostList(String keyword, categoryId=categoryService.findAllByCategory(CategoryEnum.fromValue(category)).get(0).getId(); } - return communityPostJpaRepository.findAllFetchJoinWithUser(keyword, + Slice postSlice = communityPostJpaRepository.findAllFetchJoinWithUser(keyword, lastPopularityScore, lastPostId, lastLikeCnt, @@ -58,17 +71,38 @@ public Slice getPostList(String keyword, categoryId, sortType, pageRequest); + + List postPreviewDTOList = new ArrayList<>(); + + for (CommnuityPost post : postSlice.getContent()) { + List selectHashtagList = hashtagService.findAllFetchJoinWithHashtagByEntityIdAndPostType(post.getId(), post.getType()); + postPreviewDTOList.add(CommunityPostConverter.toPostPreviewDTO(post, selectHashtagList)); + } + + return CommunityPostResponseDTO.PostPreviewListDTO.builder() + .postList(postPreviewDTOList) + .hasNext(postSlice.hasNext()) + .build(); } @Override - public CommnuityPost getPostDetail(Long postId) { + public CommunityPostResponseDTO.PostDetailDTO getPostDetail(Long userId, Long postId) { CommnuityPost findPost = communityPostJpaRepository.findByIdFetchJoinWithUser(postId); if (findPost == null) { throw new RestApiException(CommunityPostErrorStatus._POST_NOT_FOUND); } + + boolean isBookmarked = (userId == null) ? false : postBookMarkService.existsByUserAndPost(userId, findPost); + boolean isLiked = (userId == null) ? false : postLikesService.existsByUserAndPost(userId, findPost); + boolean isWriter = (userId == null) ? false : isPostWriter(userId, findPost); + + SelectCategory category = categoryService.findByEntityIdAndType(findPost.getId(), findPost.getType()); + + List selectHashtagList = hashtagService.findAllFetchJoinWithHashtagByEntityIdAndPostType(findPost.getId(), findPost.getType()); + findPost.increaseHitCnt(); findPost.increasePopularityScoreByHit(); - return findPost; + return CommunityPostConverter.toPostDetailDTO(findPost, category, selectHashtagList, isBookmarked, isLiked, isWriter); } @Override diff --git a/src/main/java/gaji/service/domain/post/validation/PostTypeExistValidator.java b/src/main/java/gaji/service/domain/post/validation/PostTypeExistValidator.java index 58b8ec5c..c112ea9e 100644 --- a/src/main/java/gaji/service/domain/post/validation/PostTypeExistValidator.java +++ b/src/main/java/gaji/service/domain/post/validation/PostTypeExistValidator.java @@ -8,27 +8,16 @@ import org.springframework.stereotype.Component; @Component -public class PostTypeExistValidator implements ConstraintValidator { +public class PostTypeExistValidator implements ConstraintValidator { @Override public void initialize(ExistPostType constraintAnnotation) { ConstraintValidator.super.initialize(constraintAnnotation); } - // TODO: 검증 메시지 적용 안되는 문제 해결하기 @Override - public boolean isValid(PostTypeEnum value, ConstraintValidatorContext context) { - boolean isValid = (value == PostTypeEnum.ROOM) || (value == PostTypeEnum.BLOG) || (value == PostTypeEnum.PROJECT) || (value == PostTypeEnum.QUESTION); -// boolean isValid = false; -// -// for (PostTypeEnum postTypeEnum : PostTypeEnum.values()) { -// if (postTypeEnum.equals(value)) { -// isValid = true; -// } -// } - -// boolean isValid = Arrays.stream(PostTypeEnum.values()) -// .allMatch(postTypeEnum -> postTypeEnum.equals(value)); + public boolean isValid(String value, ConstraintValidatorContext context) { + boolean isValid = PostTypeEnum.from(value) != null; if (!isValid) { context.disableDefaultConstraintViolation(); diff --git a/src/main/java/gaji/service/domain/post/web/dto/CommunityPostRequestDTO.java b/src/main/java/gaji/service/domain/post/web/dto/CommunityPostRequestDTO.java index 7322498c..e64278cd 100644 --- a/src/main/java/gaji/service/domain/post/web/dto/CommunityPostRequestDTO.java +++ b/src/main/java/gaji/service/domain/post/web/dto/CommunityPostRequestDTO.java @@ -32,7 +32,7 @@ public static class UploadPostRequestDTO { @Schema(description = "게시글 유형(프로젝트 모집, 질문, 블로그)") @ExistPostType - private final PostTypeEnum type; + private final String type; @Schema(description = "해시태그 리스트") @CheckHashtagBlank @@ -44,6 +44,25 @@ public static class UploadPostRequestDTO { private final String category; } + @Schema(description = "커뮤니티 게시글 수정 DTO") + @Getter + public static class EditPostRequestDTO { + @Schema(description = "게시글 제목") + private String title; + + @Schema(description = "게시글 본문") + private String body; + + @Schema(description = "카테고리") + @ExistsCategory + private String category; + + @Schema(description = "해시태그 리스트") + @CheckHashtagBlank + @CheckHashtagLength + private final List hashtagList = new ArrayList<>(); + } + @Schema(description = "커뮤니티 게시글 댓글 작성 DTO") @Getter @RequiredArgsConstructor diff --git a/src/main/java/gaji/service/domain/post/web/dto/CommunityPostResponseDTO.java b/src/main/java/gaji/service/domain/post/web/dto/CommunityPostResponseDTO.java index bcd2583c..e0405cff 100644 --- a/src/main/java/gaji/service/domain/post/web/dto/CommunityPostResponseDTO.java +++ b/src/main/java/gaji/service/domain/post/web/dto/CommunityPostResponseDTO.java @@ -18,7 +18,7 @@ public class CommunityPostResponseDTO { @Getter @NoArgsConstructor @AllArgsConstructor - public static class UploadPostResponseDTO { + public static class PostIdResponseDTO { Long postId; } diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index d131c545..0f4bfc41 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -1,5 +1,5 @@ server: - port: 8000 + port: 8080 spring: application: