Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEAT] 커뮤니티 게시글 전체 조회 및 상세조회(인터페이스 우선배포) #254

Merged
merged 14 commits into from
Oct 29, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@
import lombok.RequiredArgsConstructor;
import lombok.val;
import org.sopt.makers.internal.domain.InternalMemberDetails;
import org.sopt.makers.internal.dto.community.CommentListResponse;
import org.sopt.makers.internal.dto.community.CommentSaveRequest;
import org.sopt.makers.internal.dto.community.*;
import org.sopt.makers.internal.mapper.CommunityResponseMapper;
import org.sopt.makers.internal.service.CommunityCategoryService;
import org.sopt.makers.internal.service.CommunityCommentService;
import org.sopt.makers.internal.service.CommuntiyPostService;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
Expand All @@ -18,14 +20,58 @@
import javax.validation.Valid;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/community")
@SecurityRequirement(name = "Authorization")
@Tag(name = "Community 관련 API", description = "Community 관련 API List")
public class CommunityController {

private final CommuntiyPostService communtiyPostService;
private final CommunityCategoryService communityCategoryService;
private final CommunityCommentService communityCommentService;
private final CommunityResponseMapper communityResponseMapper;

@Operation(summary = "커뮤니티 전체 카테고리 조회")
@GetMapping("/category")
public ResponseEntity<List<CategoryDto>> getCategoryList() {
val response = communityCategoryService.getAllCategory();
return ResponseEntity.status(HttpStatus.OK).body(response);
}

@Operation(summary = "커뮤니티 글 상세 조회")
@GetMapping("/posts/{postId}")
public ResponseEntity<CategoryPostMemberDao> getCategoryList(@PathVariable("postId") Long postId) {
val response = communtiyPostService.getPostById(postId);
return ResponseEntity.status(HttpStatus.OK).body(response);
}

@Operation(
summary = "커뮤니티 글 전체 조회",
description =
"""
categoryId: 카테고리 전체조회시 id값, 전체일 경우 null\n
cursor: 처음 조회시 null, 이외에 마지막 글 id
"""
)
@GetMapping("/posts")
public ResponseEntity<PostAllResponse> getAllPosts (
@RequestParam(required = false, name = "categoryId") Long categoryId,
@RequestParam(required = false, name = "limit") Integer limit,
@RequestParam(required = false, name = "cursor") Long cursor
) {
val posts = communtiyPostService.getAllPosts(categoryId, limit, cursor);
val hasNextPosts = (limit != null && posts.size() > limit);
if (hasNextPosts) posts.remove(posts.size() - 1);
val postResponse = posts.stream().map(post -> {
val comments = communityCommentService.getCommentLists(post.id());
return communityResponseMapper.toPostResponse(post, comments);
}).collect(Collectors.toList());
val response = new PostAllResponse(categoryId, hasNextPosts, postResponse);
return ResponseEntity.status(HttpStatus.OK).body(response);
}

@Operation(summary = "커뮤니티 댓글 생성 API")
@PostMapping("/{postId}/comment")
Expand All @@ -36,7 +82,6 @@ public ResponseEntity<Map<String, Boolean>> createComment(
) {
val writerId = memberDetails.getId();
communityCommentService.createComment(writerId, postId, request);

return ResponseEntity.status(HttpStatus.CREATED).body(Map.of("success", true));
}

Expand All @@ -54,7 +99,6 @@ public ResponseEntity<Map<String, Boolean>> deleteComment(
) {
val writerId = memberDetails.getId();
communityCommentService.deleteComment(commentId, writerId);

return ResponseEntity.status(HttpStatus.OK).body(Map.of("success", true));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.sopt.makers.internal.dto.community;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.sopt.makers.internal.domain.community.Category;

@AllArgsConstructor
@NoArgsConstructor
@Data
public class CategoryDto {

private Long id;
private String name;
private List<CategoryDto> children;

public static List<CategoryDto> toDtoList(List<Category> categories) {
CategoryHelper helper = CategoryHelper.newInstance(
categories,
c -> new CategoryDto(c.getId(), c.getName(), new ArrayList<>()),
Category::getParent,
Category::getId,
CategoryDto::getChildren);
return helper.convert();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package org.sopt.makers.internal.dto.community;

import org.sopt.makers.internal.exception.CannotConvertHelperException;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
public class CategoryHelper<K, E, D> {

private List<E> entities;
private Function<E, D> toDto;
private Function<E, E> getParent;
private Function<E, K> getKey;
private Function<D, List<D>> getChildren;

public static <K, E, D> CategoryHelper newInstance(List<E> entities, Function<E, D> toDto, Function<E, E> getParent,
Function<E, K> getKey, Function<D, List<D>> getChildren) {
return new CategoryHelper<K, E, D>(entities, toDto, getParent, getKey, getChildren);
}

private CategoryHelper(List<E> entities, Function<E, D> toDto, Function<E, E> getParent, Function<E, K> getKey,
Function<D, List<D>> getChildren) {
this.entities = entities;
this.toDto = toDto;
this.getParent = getParent;
this.getKey = getKey;
this.getChildren = getChildren;
}

public List<D> convert() {
try {
return convertInternal();
} catch (NullPointerException e) {
throw new CannotConvertHelperException(e.getMessage());
}
}

private List<D> convertInternal() {
Map<K, D> map = new HashMap<>();
List<D> roots = new ArrayList<>();

for (E e : entities) {
D dto = toDto(e);
map.put(getKey(e), dto);
if (hasParent(e)) {
E parent = getParent(e);
K parentKey = getKey(parent);
D parentDto = map.get(parentKey);
getChildren(parentDto).add(dto);
} else {
roots.add(dto);
}
}
return roots;
}

private boolean hasParent(E e) {
return getParent(e) != null;
}

private E getParent(E e) {
return getParent.apply(e);
}

private D toDto(E e) {
return toDto.apply(e);
}

private K getKey(E e) {
return getKey.apply(e);
}

private List<D> getChildren(D d) {
return getChildren.apply(d);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package org.sopt.makers.internal.dto.community;

import com.querydsl.core.annotations.QueryProjection;
import org.sopt.makers.internal.domain.MemberCareer;
import org.sopt.makers.internal.domain.MemberSoptActivity;

import java.time.LocalDateTime;
import java.util.List;

public record CategoryPostMemberDao(
Long id,
Long categoryId,
Long userId,
String userName,
String profileImage,
List<MemberSoptActivity> activities,
List<MemberCareer> careers,
String title,
String content,
Integer hits,
Boolean isQuestion,
Boolean isBlindWriter,
String[] images,
LocalDateTime createdAt,
LocalDateTime updatedAt
) {
@QueryProjection
public CategoryPostMemberDao {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package org.sopt.makers.internal.dto.community;

import com.querydsl.core.annotations.QueryProjection;
import org.sopt.makers.internal.domain.MemberCareer;
import org.sopt.makers.internal.domain.MemberSoptActivity;

import java.time.LocalDateTime;
import java.util.List;

public record CommentDao(
Long id,
Long userId,
String userName,
String profileImage,
List<MemberSoptActivity> activities,
List<MemberCareer> careers,
String content,
Boolean isBlindWriter,
LocalDateTime createdAt,
LocalDateTime updatedAt
) {
@QueryProjection
public CommentDao {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.sopt.makers.internal.dto.community;

import org.sopt.makers.internal.domain.MemberCareer;
import org.sopt.makers.internal.domain.MemberSoptActivity;

import java.time.LocalDateTime;
import java.util.List;

public record CommentResponse(
Long id,
Long userId,
String userName,
String profileImage,
List<MemberSoptActivity> activities,
List<MemberCareer> careers,
String content,
Boolean isBlindWriter,
LocalDateTime createdAt,
LocalDateTime updatedAt
){}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package org.sopt.makers.internal.dto.community;

public class CommunityCommentDao {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package org.sopt.makers.internal.dto.community;

import io.swagger.v3.oas.annotations.media.Schema;

import java.time.LocalDate;
import java.util.List;

public record CommunityMemberProfileResponse(
@Schema(required = true)
Long id,
@Schema(required = true)
String name,
String profileImage,
@Schema(required = true)
List<MemberSoptActivityResponse> activities,
List<MemberLinkResponse> links,
List<MemberCareerResponse> careers,
Boolean allowOfficial
) {

public record UserFavorResponse(
Boolean isPourSauceLover,
Boolean isHardPeachLover,
Boolean isMintChocoLover,
Boolean isRedBeanFishBreadLover,
Boolean isSojuLover,
Boolean isRiceTteokLover
){}

public record MemberLinkResponse(
Long id,
String title,
String url
){}

public record MemberSoptActivityResponse(
Long id,
Integer generation,
String part,
String team
){}

public record MemberCareerResponse(
Long id,
String companyName,
String title,
String startDate,
String endDate,
Boolean isCurrent
){}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.sopt.makers.internal.dto.community;

import io.swagger.v3.oas.annotations.media.Schema;
import org.sopt.makers.internal.domain.MemberCareer;
import org.sopt.makers.internal.domain.MemberSoptActivity;

import java.util.List;

public record CommunityMemberResponse(
Long id,
String name,
String image,
@Schema(required = true)
List<MemberSoptActivity> activities,
List<MemberCareer> careers
){}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.sopt.makers.internal.dto.community;

import java.util.List;

public record PostAllResponse(
Long categoryId,
Boolean hasNext,
List<PostResponse> posts
) {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.sopt.makers.internal.dto.community;

import io.swagger.v3.oas.annotations.media.Schema;
import org.sopt.makers.internal.dto.member.MemberProfileResponse;

import java.time.LocalDateTime;
import java.util.List;

public record PostResponse(
@Schema(required = true)
Long id,
CommunityMemberResponse member,
Long writerId,
String title,
String content,
Integer hits,
String[] images,
Boolean isQuestion,
Boolean isBlindWriter,
LocalDateTime createdAt,
List<CommentResponse> comments
) {}
Loading