Skip to content

Commit

Permalink
Merge pull request #30 from Team-Shaka/feature/29
Browse files Browse the repository at this point in the history
Feature/29 게시글 상세조회 API 구현
  • Loading branch information
CYY1007 authored May 21, 2024
2 parents 1319090 + 9d0a26e commit 68a14d7
Show file tree
Hide file tree
Showing 18 changed files with 237 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,22 @@ public class InvitationApi {
private final InvitationService invitationService;

@GetMapping("/invitation")
@Operation(summary = "초대장 조회 \uD83D\uDD11", description = "내가 받은 초대장을 조회합니다.")
@Operation(summary = "초대장 조회 \uD83D\uDD11", description = "내가 받은 초대장을 조회합니다.")
public CommonResponse<InvitationResponseDTO.getInvitations> getInvitations(
@AuthMember @Parameter(hidden = true) User user
) {
return CommonResponse.onSuccess(invitationService.getInvitations(user));
}

@GetMapping("/availableInvitation")
@Operation(summary = "소유한 초대장 개수 및 게이지 조회 \uD83D\uDD11", description = "소유한 초대장 개수 및 게이지를 조회합니다.")
@Operation(summary = "소유한 초대장 개수 및 게이지 조회 \uD83D\uDD11", description = "소유한 초대장 개수 및 게이지를 조회합니다.")
public CommonResponse<InvitationResponseDTO.myInvitationInfo> getAvailableInvitation(@AuthMember @Parameter(hidden = true) User user){

return CommonResponse.onSuccess(invitationService.getMyInvitationInfo(user));
}

@PostMapping("/invitations/accept")
@Operation(summary = "초대장을 수락할지 거절할지 결정 \uD83D\uDD11", description = "초대장을 수락할지 거절할지 결정하는 API 입니다.")
@Operation(summary = "초대장을 수락할지 거절할지 결정 \uD83D\uDD11", description = "초대장을 수락할지 거절할지 결정하는 API 입니다.")
public CommonResponse<InvitationResponseDTO.invitationAccept> acceptInvitation(
@AuthMember @Parameter(hidden = true) User user, @RequestBody InvitationRequestDTO.invitationAcceptDecision request) {
return CommonResponse.onSuccess(invitationService.decisionInvitation(user, request));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,13 @@ public static MemberResponseDTO.registerMember toRegister(Long treehouseId, Memb
.treehouseId(treehouseId) // treehouseId는 관련 기능 구현 후 변경 예정
.build();
}

public static MemberResponseDTO.getMemberProfile toGetMemberProfile(Member member) {
return MemberResponseDTO.getMemberProfile.builder()
.memberId(member.getId())
.memberName(member.getName())
.memberProfileImageUrl(member.getProfileImageUrl())
.memberBranch(3) // Branch 기능 개발 이후 변경 예정
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public class MemberApi {
private final MemberService memberService;

@PostMapping("/register")
@Operation(summary = "회원가입", description = "트리하우스 멤버로 가입합니다.")
@Operation(summary = "트리하우스 회원가입 \uD83D\uDD11", description = "트리하우스 멤버로 가입합니다.")
public CommonResponse<MemberResponseDTO.registerMember> registerTreehouseMember(
@RequestBody final MemberRequestDTO.registerMember request,
@AuthMember @Parameter(hidden = true) User user
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,15 @@ public static class registerMember {
private Long userId;
private Long treehouseId;
}

@Builder
@Getter
@NoArgsConstructor
@AllArgsConstructor
public static class getMemberProfile {
private Long memberId;
private String memberName;
private String memberProfileImageUrl;
private Integer memberBranch;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public class NotificationApi {
private final NotificationService notificationService;

@GetMapping("/users/notifications")
@Operation(summary = "알림 조회 \uD83D\uDD11", description = "사용자의 알림을 조회합니다.")
@Operation(summary = "알림 조회 \uD83D\uDD11", description = "사용자의 알림을 조회합니다.")
public CommonResponse<NotificationResponseDTO.getNotifications> getNotifications(
@AuthMember @Parameter(hidden = true) User user
){
Expand Down
26 changes: 26 additions & 0 deletions src/main/java/treehouse/server/api/post/business/PostMapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package treehouse.server.api.post.business;

import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import treehouse.server.api.post.presentation.dto.PostResponseDTO;
import treehouse.server.api.member.business.MemberMapper;
import treehouse.server.global.common.TimeFormatter;
import treehouse.server.global.entity.post.Post;
import treehouse.server.global.entity.post.PostImage;

@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class PostMapper {

public static PostResponseDTO.getPostDetails toGetPostDetails(Post post) {
return PostResponseDTO.getPostDetails.builder()
.memberProfile(MemberMapper.toGetMemberProfile(post.getWriter()))
.postId(post.getId())
.context(post.getContent())
.pictureUrlList(post.getPostImageList().stream()
.map(PostImage::getImageUrl).toList()
)
// .reactionList() // Reaction 기능 개발 이후 수정
.postedAt(TimeFormatter.format(post.getCreatedAt()))
.build();
}
}
33 changes: 33 additions & 0 deletions src/main/java/treehouse/server/api/post/business/PostService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package treehouse.server.api.post.business;

import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import treehouse.server.api.post.implement.PostCommandAdapter;
import treehouse.server.api.post.implement.PostQueryAdapter;
import treehouse.server.api.post.presentation.dto.PostResponseDTO;
import treehouse.server.global.entity.User.User;
import treehouse.server.global.entity.post.Post;

@Service
@AllArgsConstructor
@Slf4j
public class PostService {

private final PostCommandAdapter postCommandAdapter;
private final PostQueryAdapter postQueryAdapter;

/**
* 게시글 상세조회
* @param user
* @param postId
* @param treehouseId - 게시글 정보에 표시할 memberBranch을 계산하고 감정표현의 isPushed 상태를 반환하기 위해 user와 treehouseId 사용
* @return PostResponseDTO.getPostDetails
*/
@Transactional(readOnly = true)
public PostResponseDTO.getPostDetails getPostDetails(User user, Long postId, Long treehouseId){
Post post = postQueryAdapter.findById(postId);
return PostMapper.toGetPostDetails(post);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package treehouse.server.api.post.implement;

import lombok.RequiredArgsConstructor;
import treehouse.server.global.annotations.Adapter;

@Adapter
@RequiredArgsConstructor
public class PostCommandAdapter {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package treehouse.server.api.post.implement;

import lombok.RequiredArgsConstructor;
import treehouse.server.api.post.persistence.PostRepository;
import treehouse.server.global.annotations.Adapter;
import treehouse.server.global.entity.post.Post;
import treehouse.server.global.exception.GlobalErrorCode;
import treehouse.server.global.exception.ThrowClass.PostException;

@Adapter
@RequiredArgsConstructor
public class PostQueryAdapter {

private final PostRepository postRepository;

public Post findById(Long postId) {
return postRepository.findById(postId).orElseThrow(() -> new PostException(GlobalErrorCode.POST_NOT_FOUND));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package treehouse.server.api.post.persistence;

import org.springframework.data.jpa.repository.JpaRepository;
import treehouse.server.global.entity.post.Post;

public interface PostRepository extends JpaRepository<Post, Long> {
}
38 changes: 38 additions & 0 deletions src/main/java/treehouse/server/api/post/presentation/PostApi.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package treehouse.server.api.post.presentation;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import treehouse.server.api.post.business.PostService;
import treehouse.server.api.post.presentation.dto.PostResponseDTO;
import treehouse.server.global.common.CommonResponse;
import treehouse.server.global.entity.User.User;
import treehouse.server.global.security.handler.annotation.AuthMember;

@RestController
@RequiredArgsConstructor
@Slf4j
@Validated
@Tag(name = "\uD83D\uDCF0 Feed API", description = "트리하우스 피드 관련 API 입니다. 게시글 작성, 피드 조회 등의 API가 포함됩니다.")
@RequestMapping("/treehouses/{treehouseId}/feeds")
public class PostApi {

private final PostService postService;

@GetMapping("/posts/{postId}")
@Operation(summary = "게시글 상세조회 \uD83D\uDD11✅", description = "특정 게시글의 상세정보를 조회합니다.")
public CommonResponse<PostResponseDTO.getPostDetails> getPostDetails(
@PathVariable Long treehouseId,
@PathVariable Long postId,
@AuthMember @Parameter(hidden = true) User user
){
return CommonResponse.onSuccess(postService.getPostDetails(user, postId, treehouseId));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package treehouse.server.api.post.presentation.dto;

import lombok.*;
import treehouse.server.api.member.presentation.dto.MemberResponseDTO;

import java.util.List;

@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class PostResponseDTO {

@Builder
@Getter
@NoArgsConstructor
@AllArgsConstructor
public static class getPostDetails {

private MemberResponseDTO.getMemberProfile memberProfile;
private Long postId;
private String context;
private List<String> pictureUrlList;
// private List<ReactionResponseDto.getReaction> reactionList; Reaction 기능 개발 이후 적용
private String postedAt;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,23 +25,23 @@ public class UserApi {
private final UserService userService;

@PostMapping("/checkName")
@Operation(summary = "아이디 중복 체크", description = "서비스에서 사용할 유저이름을 중복 체크합니다.")
@Operation(summary = "아이디 중복 체크", description = "서비스에서 사용할 유저이름을 중복 체크합니다.")
public CommonResponse<UserResponseDTO.checkName> checkName(
@RequestBody final UserRequestDTO.checkName request
){
return CommonResponse.onSuccess(userService.checkName(request));
}

@PostMapping("/register")
@Operation(summary = "회원가입", description = "회원가입을 진행합니다.")
@Operation(summary = "회원가입", description = "회원가입을 진행합니다.")
public CommonResponse<UserResponseDTO.registerUser> registerMember(
@RequestBody final UserRequestDTO.registerUser request
){
return CommonResponse.onSuccess(userService.register(request));
}

@PostMapping("/reissue")
@Operation(summary = "토큰 재발급", description = "토큰을 재발급 합니다.")
@Operation(summary = "토큰 재발급", description = "토큰을 재발급 합니다.")
public CommonResponse<UserResponseDTO.reissue> reissue(
@RequestBody final UserRequestDTO.reissue request
){
Expand Down
31 changes: 31 additions & 0 deletions src/main/java/treehouse/server/global/common/TimeFormatter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package treehouse.server.global.common;

import java.time.Duration;
import java.time.LocalDateTime;

// 특정 게시글/댓글의 작성 시간을 현재 시간과 비교하여 문자열로 변환하는 유틸리티 클래스
public class TimeFormatter {

private TimeFormatter() {
}

public static String format(LocalDateTime createdAt) {
LocalDateTime now = LocalDateTime.now();
Duration duration = Duration.between(createdAt, now);

long seconds = duration.getSeconds();
long minutes = duration.toMinutes();
long hours = duration.toHours();
long days = duration.toDays();

if (seconds < 60) {
return seconds + "초 전";
} else if (minutes < 60) {
return minutes + "분 전";
} else if (hours < 24) {
return hours + "시간 전";
} else {
return days + "일 전";
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import jakarta.persistence.*;
import lombok.*;
import treehouse.server.global.entity.common.BaseDateTimeEntity;
import treehouse.server.global.entity.feed.Feed;
import treehouse.server.global.entity.post.Post;
import treehouse.server.global.entity.member.Member;

@Entity
Expand All @@ -22,5 +22,5 @@ public class Comment extends BaseDateTimeEntity {

@JoinColumn(name = "feedId")
@ManyToOne(fetch = FetchType.LAZY)
private Feed feed;
private Post post;
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package treehouse.server.global.entity.feed;
package treehouse.server.global.entity.post;

import jakarta.persistence.*;
import lombok.*;
Expand All @@ -7,15 +7,14 @@
import treehouse.server.global.entity.member.Member;
import treehouse.server.global.entity.treeHouse.TreeHouse;

import java.util.Comparator;
import java.util.List;

@Entity
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Feed extends BaseDateTimeEntity {
public class Post extends BaseDateTimeEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
Expand All @@ -24,15 +23,15 @@ public class Feed extends BaseDateTimeEntity {
@ManyToOne(fetch = FetchType.LAZY)
private Member writer;

@JoinColumn(name = "userId")
@JoinColumn(name = "treehouseId")
@ManyToOne(fetch = FetchType.LAZY)
private TreeHouse treeHouse;

private String content;

@OneToMany(mappedBy = "feed")
@OneToMany(mappedBy = "post")
private List<Comment> commentList;

@OneToMany(mappedBy = "feed")
private List<FeedImage> feedImageList;
@OneToMany(mappedBy = "post")
private List<PostImage> postImageList;
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package treehouse.server.global.entity.feed;
package treehouse.server.global.entity.post;

import jakarta.persistence.*;
import lombok.*;
Expand All @@ -9,15 +9,15 @@
@Builder
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class FeedImage extends BaseDateTimeEntity {
public class PostImage extends BaseDateTimeEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

private String imageUrl;

@JoinColumn(name = "feedId")
@JoinColumn(name = "postId")
@ManyToOne(fetch = FetchType.LAZY)
private Feed feed;
private Post post;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package treehouse.server.global.exception.ThrowClass;

import treehouse.server.global.exception.BaseErrorCode;

public class PostException extends GeneralException{

public PostException(BaseErrorCode errorCode) {
super(errorCode);
}
}

0 comments on commit 68a14d7

Please sign in to comment.