Skip to content

Commit

Permalink
Merge branch 'dev' of https://github.com/BugFlix/server into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
1hcoj committed May 5, 2024
2 parents c44f2ab + e429eef commit fa07963
Show file tree
Hide file tree
Showing 12 changed files with 140 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ public class SecurityConfiguration {
"/api/v1/auths/login",
"/api/v1/auths/reissue",
"/api/login/oauth2/code/**",
"/api/v1/healthcheck"
"/api/v1/healthcheck",
"/api/v1/profiles/users/{nickname}",
};

@Bean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@

public interface FollowRepository extends JpaRepository<Follow, Long> {

public List<Follow> findByFollower(User follower);
public List<Follow> findByFollowing(User following);
List<Follow> findByFollower(User follower);
List<Follow> findByFollowing(User following);
@Transactional
public void deleteByFollowerAndFollowing(User follower, User following);
void deleteByFollowerAndFollowing(User follower, User following);

Boolean existsByFollowerAndFollowing(User follower, User following);
}
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,20 @@ public ResponseEntity<List<PostResponse>> getAllPost(@RequestParam String url) {
return ResponseEntity.ok(postServiceImpl.getPosts(url));
}

/**
* 특정 Post의 미리보기를 조회합니다.
*
* @param postId
* @param userDetails
* @return 특정 Post 미리보기
*/
@GetMapping("/v1/posts/{postId}/preview")
@Operation(summary = "단일 Post 미리보기 조회", description = "Post의 미리보기를 반환합니다.")
public ResponseEntity<PostPreviewResponse> getPostPreview(@PathVariable Long postId,
@AuthenticationPrincipal UserDetails userDetails) {
return ResponseEntity.ok(postServiceImpl.getPostPreview(postId, userDetails));
}

/***
* 특정 Page 내의 Post 미리보기 전체를 조회합니다.
*
Expand All @@ -100,8 +114,8 @@ public ResponseEntity<List<PostResponse>> getAllPost(@RequestParam String url) {
@Operation(summary = "Post 미리보기 조회", description = "Page내의 Post 미리보기 전체를 반환합니다.")
public ResponseEntity<List<PostPreviewResponse>> getPostPreview(@RequestParam String url,
@AuthenticationPrincipal UserDetails userDetails) {
if (userDetails == null) return ResponseEntity.ok(postServiceImpl.getPostPreview(url));
return ResponseEntity.ok(postServiceImpl.getPostPreview(url, userDetails));
if (userDetails == null) return ResponseEntity.ok(postServiceImpl.getPostPreviews(url));
return ResponseEntity.ok(postServiceImpl.getPostPreviews(url, userDetails));
}


Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/bugflix/weblog/post/dto/PostRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import java.util.List;

@Getter
@Schema(description = "로그인, 토큰 재발급 요청 DTO", requiredProperties = {"content", "url"})
@Schema(description = "Post 저장/수정 DTO", requiredProperties = {"title", "content"})
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class PostRequest {

Expand Down
61 changes: 23 additions & 38 deletions src/main/java/com/bugflix/weblog/post/service/PostServiceImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,12 @@
import org.springframework.data.domain.Sort;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.Objects;

@Service
@RequiredArgsConstructor
Expand Down Expand Up @@ -154,8 +151,17 @@ public List<PostResponse> getPosts(String url) {
return resultList.stream().map(PostResponse::from).toList();
}

@Transactional(readOnly = true)
public PostPreviewResponse getPostPreview(Long postId, UserDetails userDetails) {
Long userId = ((CustomUserDetails) userDetails).getUser().getUserId();
Post post = postRepository.findById(postId)
.orElseThrow(() -> new ResourceNotFoundException(Errors.POST_NOT_FOUND));
List<String> tags = tagRepository.findTagsByPostPostId(postId).stream().map(Tag::getTagContent).toList();
return PostPreviewResponse.of(post, tags, post.getUser().getNickname(), likeServiceImpl.isLiked(postId, userId));
}

/**
* Name : getPostPreview
* Name : getPostPreviews
* Parameter :
* - String url
* Return :
Expand All @@ -164,52 +170,31 @@ public List<PostResponse> getPosts(String url) {
* Explanation :
* - 페이지 내의 모든 post 미리 보기 목록 반환
*/
public List<PostPreviewResponse> getPostPreview(String url, UserDetails userDetails) {
public List<PostPreviewResponse> getPostPreviews(String url) {
List<PostPreviewResponse> postPreviews = new ArrayList<>();
List<Post> posts = postRepository.findByPageUrl(url);

List<Post> postList = postRepository.findByPageUrl(url);

Long userId = ((CustomUserDetails) userDetails).getUser().getUserId();

for (Post post : postList) {
for (Post post : posts) {
Long postId = post.getPostId();

PostPreviewResponse postPreview = new PostPreviewResponse(
post,
postPreviews.add(PostPreviewResponse.of(post,
tagRepository.findTagsByPostPostId(postId).stream().map(Tag::getTagContent).toList(),
userService.findNicknameByPostId(postId),
likeServiceImpl.isLiked(postId, userId),
post.getCreatedDate(),
post.getModifiedDate(),
likeServiceImpl.countLikes(postId));

// Todo postId 가 다른 여러 개의 Entity가 입력되었을 때, like Count 가 정상 작동하는지 확인.

postPreviews.add(postPreview); // List 에 postPreview Entity 추가
userService.findNicknameByPostId(postId), false));
}
return postPreviews;
}

public List<PostPreviewResponse> getPostPreview(String url) {
public List<PostPreviewResponse> getPostPreviews(String url, UserDetails userDetails) {
List<PostPreviewResponse> postPreviews = new ArrayList<>();
List<Post> posts = postRepository.findByPageUrl(url);
Long userId = ((CustomUserDetails) userDetails).getUser().getUserId();

List<Post> postList = postRepository.findByPageUrl(url);

for (Post post : postList) {
for (Post post : posts) {
Long postId = post.getPostId();

PostPreviewResponse postPreview = new PostPreviewResponse(
post,
postPreviews.add(PostPreviewResponse.of(post,
tagRepository.findTagsByPostPostId(postId).stream().map(Tag::getTagContent).toList(),
userService.findNicknameByPostId(postId),
false,
post.getCreatedDate(),
post.getModifiedDate(),
likeServiceImpl.countLikes(postId));

// Todo postId 가 다른 여러 개의 Entity가 입력되었을 때, like Count 가 정상 작동하는지 확인.

postPreviews.add(postPreview); // List 에 postPreview Entity 추가
userService.findNicknameByPostId(postId), likeServiceImpl.isLiked(postId, userId)));
}
return postPreviews;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.bugflix.weblog.profile.controller;

import com.bugflix.weblog.profile.dto.ProfileResponse;
import com.bugflix.weblog.profile.dto.ProfileUpdateRequest;
import com.bugflix.weblog.profile.service.ProfileServiceImpl;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
Expand All @@ -9,10 +10,7 @@
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.userdetails.UserDetails;
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 org.springframework.web.bind.annotation.*;

@Slf4j
@Tag(name = "Profile API", description = "Profile 관련 API")
Expand Down Expand Up @@ -43,8 +41,24 @@ public ResponseEntity<ProfileResponse> getMyProfile(@AuthenticationPrincipal Use
*/
@GetMapping("/v1/profiles/users/{nickname}")
@Operation(summary = "다른 사람 프로필 조회", description = "다른 사람의 프로필을 조회합니다.")
public ResponseEntity<ProfileResponse> getOthersProfile(@PathVariable String nickname) {
return ResponseEntity.ok(profileService.getOthersProfile(nickname));
public ResponseEntity<ProfileResponse> getOthersProfile(@PathVariable String nickname,
@AuthenticationPrincipal UserDetails userDetails) {
if (userDetails == null)
return ResponseEntity.ok(profileService.getOthersProfile(nickname));
return ResponseEntity.ok(profileService.getOthersProfile(nickname, userDetails));
}


/***
* 사용자 Profile 수정
*
* @param userDetails - 사용자 정보
*/
@PutMapping("/v1/profile")
@Operation(summary = "프로필 수정", description = "프로필 정보를 수정합니다.")
public ResponseEntity<Void> updateProfile(@RequestBody ProfileUpdateRequest request,
@AuthenticationPrincipal UserDetails userDetails) {
profileService.updateProfile(request, userDetails);
return ResponseEntity.ok().build();
}
}
5 changes: 5 additions & 0 deletions src/main/java/com/bugflix/weblog/profile/domain/Profile.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ public void changeProfileImage(String imageUrl) {
this.imageUrl = imageUrl;
}

public void update(String imageUrl, String phoneNumber) {
this.imageUrl = imageUrl;
this.phoneNumber = phoneNumber;
}

public void assignUser(User user) {
this.user = user;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,21 @@ public class ProfileResponse {
private String imageUrl;
@Schema(description = "사용자의 email 주소", example = "[email protected]")
private String email;
private Boolean followed;

private ProfileResponse(User user, Profile profile) {
private ProfileResponse(User user, Profile profile, Boolean followed) {
nickname = user.getNickname();
email = user.getEmail();
if (profile.getImageUrl() != null) {
this.imageUrl = profile.getImageUrl();
}
this.followed = followed;
}

public static ProfileResponse of(User user, Profile profile) {
return new ProfileResponse(user, profile);
return new ProfileResponse(user, profile, false);
}
public static ProfileResponse of(User user, Profile profile, Boolean followed) {
return new ProfileResponse(user, profile, followed);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.bugflix.weblog.profile.dto;


import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Schema(description = "프로필 수정 요청",
requiredProperties = {"nickname", "imageUrl", "phoneNumber"})
@Getter
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class ProfileUpdateRequest {

@Schema(description = "별명", example = "namu")
@Size(min = 2, max = 25)
@NotNull
private String nickname;

@NotNull
@Schema(description = "프로필 이미지")
private String imageUrl;

@NotNull
@Schema(description = "전화번호", example = "01012341234")
private String phoneNumber;

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

import com.bugflix.weblog.common.Errors;
import com.bugflix.weblog.common.exception.ResourceNotFoundException;
import com.bugflix.weblog.follow.repository.FollowRepository;
import com.bugflix.weblog.profile.domain.Profile;
import com.bugflix.weblog.profile.dto.ProfileResponse;
import com.bugflix.weblog.profile.dto.ProfileUpdateRequest;
import com.bugflix.weblog.profile.repository.ProfileRepository;
import com.bugflix.weblog.security.domain.CustomUserDetails;
import com.bugflix.weblog.user.domain.User;
Expand All @@ -12,13 +14,15 @@
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
@Slf4j
public class ProfileServiceImpl {
private final ProfileRepository profileRepository;
private final UserRepository userRepository;
private final FollowRepository followRepository;

/**
* 나의 Profile 반환
Expand All @@ -35,6 +39,25 @@ public ProfileResponse getOthersProfile(String nickname) {
.orElseThrow(() -> new ResourceNotFoundException(Errors.USER_NOT_FOUND));
Profile profile = profileRepository.findByUserUserId(user.getUserId())
.orElseThrow(() -> new ResourceNotFoundException(Errors.PROFILE_NOT_FOUND));

return ProfileResponse.of(user, profile);
}

public ProfileResponse getOthersProfile(String nickname, UserDetails userDetails) {
User user = ((CustomUserDetails) userDetails).getUser();
User targetUser = userRepository.findByNickname(nickname)
.orElseThrow(() -> new ResourceNotFoundException(Errors.USER_NOT_FOUND));
Profile profile = profileRepository.findByUserUserId(user.getUserId())
.orElseThrow(() -> new ResourceNotFoundException(Errors.PROFILE_NOT_FOUND));
boolean followed = followRepository.existsByFollowerAndFollowing(user, targetUser);

return ProfileResponse.of(targetUser, profile, followed);
}

@Transactional
public void updateProfile(ProfileUpdateRequest request, UserDetails userDetails) {
User user = ((CustomUserDetails) userDetails).getUser();
user.updateProfile(request);
userRepository.save(user);
}
}
7 changes: 7 additions & 0 deletions src/main/java/com/bugflix/weblog/user/domain/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.bugflix.weblog.common.BaseTimeEntity;
import com.bugflix.weblog.post.domain.Post;
import com.bugflix.weblog.profile.domain.Profile;
import com.bugflix.weblog.profile.dto.ProfileUpdateRequest;
import jakarta.persistence.*;
import lombok.AccessLevel;
import lombok.Builder;
Expand Down Expand Up @@ -70,6 +71,12 @@ public User update(String nickname, String picture) {
return this;
}

public User updateProfile(ProfileUpdateRequest request) {
this.nickname = request.getNickname();
this.profile.update(request.getImageUrl(), request.getPhoneNumber());
return this;
}

public void assignProfile(Profile profile) {
this.profile = profile;
}
Expand Down
6 changes: 2 additions & 4 deletions src/main/java/com/bugflix/weblog/user/dto/SignUpRequest.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
package com.bugflix.weblog.user.dto;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.*;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
Expand All @@ -27,6 +24,7 @@ public class SignUpRequest {
private String password;

@Schema(description = "별명", example = "namu")
@Size(min = 2, max = 25)
@NotNull
private String nickname;

Expand Down

0 comments on commit fa07963

Please sign in to comment.