Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -143,5 +143,13 @@ public ApiResponse<List<RecommendCardResponse>> getRecommendedCards(
return ApiResponse.onSuccess(cardService.getRecommendedCardPreviews(user.getId()));
}

@GetMapping("/profile/{userId}")
@Operation(summary = "프로필 화면 피드 미리보기", description = "공유한 카드의 번호와 이미지 url 조회 API")
public ApiResponse<CardResponse.ProfileCardListDTO> getProfileCardsList(@PathVariable Long userId,
@RequestParam(required = false) Long cursor,
@RequestParam(defaultValue = "15") int size) {
return ApiResponse.onSuccess(cardService.getProfileCardList(userId, size, cursor));
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -157,4 +157,23 @@ public static CardDeleteResponse toCardDeleteResponse(Card card) {
.successMessage("카드 삭제 성공")
.build();
}

public static CardResponse.ProfileCardDTO toProfileCardDto(Card card){
return CardResponse.ProfileCardDTO.builder()
.cardId(card.getId())
.cardImageUrl(card.getCardImageUrl())
.build();
}

public static CardResponse.ProfileCardListDTO toProfileCardList(Long userId, Slice<Card> cardList) {
List<Card> list = cardList.getContent();
return CardResponse.ProfileCardListDTO.builder()
.hasNext(cardList.hasNext())
.nextCursor(cardList.hasNext() ? list.get(list.size() - 1).getId() : null)
.userId(userId)
.cardsList(cardList.getContent().stream()
.map(CardConverter::toProfileCardDto)
.toList())
Comment on lines +174 to +176

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

cardList.getContent()가 중복으로 호출되고 있습니다. 169번째 줄에서 이미 list 변수에 저장했으므로, list.stream()을 사용하여 중복 호출을 피하는 것이 좋습니다. 이렇게 하면 코드가 더 효율적이고 깔끔해집니다.

Suggested change
.cardsList(cardList.getContent().stream()
.map(CardConverter::toProfileCardDto)
.toList())
.cardsList(list.stream()
.map(CardConverter::toProfileCardDto)
.toList())

.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,25 @@ public static class CardDeleteResponse {

}

@Builder
@Getter
@NoArgsConstructor
@AllArgsConstructor
public static class ProfileCardListDTO{
private Long userId;
private boolean hasNext;
private Long nextCursor;
private List<ProfileCardDTO> cardsList;
}

@Builder
@Getter
@NoArgsConstructor
@AllArgsConstructor
public static class ProfileCardDTO {
private Long cardId;
private String cardImageUrl;
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -110,4 +110,17 @@ SELECT ch.hashtag.id, COUNT(ch.card.id)
""")
List<Object[]> countCardsByHashtagIds(@Param("hashtagIds") List<Long> hashtagIds);

Slice<Card> findByUserIdAndIsSharedTrueAndIsDeletedFalseOrderByIdDesc(Long userId, Pageable pageable);
Slice<Card> findByUserIdAndIsSharedTrueAndIsDeletedFalseAndIdLessThanOrderByIdDesc(Long userId, Long cursor, Pageable pageable);

@Query("""
select count(c)
from Card c
where c.isDeleted = false
and c.isShared = true
and c.user.id = :userId
""")
Long countByUserIdAndIsDeletedFalseAndIsSharedTrue(@Param("userId") Long userId);


}
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,5 @@ public interface CardService {
CardDetailResponse updateCard(Long cardId, User user, CardUpdateRequest request);
CardResponse.PagedCardFeedResponseDto getCardFeedByCursor(HttpServletRequest request, Long userId, int size, Long cursor);
List<RecommendCardResponse> getRecommendedCardPreviews(Long userId);
CardResponse.ProfileCardListDTO getProfileCardList(Long userId, int size, Long cursor);
}
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,19 @@ public CardFeedResponse getCardFeed(Long cardId, Long userId) {
);
}

@Override

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

getProfileCardList 메서드는 데이터베이스에서 데이터를 읽기만 하는 조회용 메서드입니다. 성능 향상과 일관성을 위해 @Transactional(readOnly = true) 어노테이션을 추가하는 것을 권장합니다. 클래스 내 다른 조회 메서드들에도 적용되어 있습니다.

    @Override
    @Transactional(readOnly = true)

public CardResponse.ProfileCardListDTO getProfileCardList(Long userId, int size, Long cursor) {
Slice<Card> cardSlice;
Pageable pageable = PageRequest.of(0, size);

if (cursor == null) {
cardSlice = cardRepository.findByUserIdAndIsSharedTrueAndIsDeletedFalseOrderByIdDesc(userId, pageable);
} else {
cardSlice = cardRepository.findByUserIdAndIsSharedTrueAndIsDeletedFalseAndIdLessThanOrderByIdDesc(userId, cursor, pageable);
}
return CardConverter.toProfileCardList(userId, cardSlice);
}

@Override
@Transactional
public CardDeleteResponse deleteCard(Long cardId, Long userId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,11 @@ public ApiResponse<UserResponseDTO.ProfileDto> updateUserIntroduce(
UserResponseDTO.ProfileDto updatedProfile = userService.updateIntroduce(request, introduce, user);
return ApiResponse.onSuccess(updatedProfile);
}

@Operation(summary = "유저 프로필 조회")
@GetMapping("/profile/{userId}")
public ApiResponse<UserResponseDTO.DetailProfileDto> getProfile(HttpServletRequest request,
@PathVariable Long userId) {
return ApiResponse.onSuccess(userService.getProfile(request,userId));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ public static UserResponseDTO.ProfileDto toProfileIconDto(User user){
.isFollowing(true)
.build();
}
// todo: 두개 비슷함 -> 합치기
public static UserResponseDTO.ProfileDto toProfileDto(User user, Boolean isFollowing){
return UserResponseDTO.ProfileDto.builder()
.userId(user.getId())
Expand All @@ -73,6 +72,25 @@ public static UserResponseDTO.ProfileDto toProfileDto(User user, Boolean isFollo
.isFollowing(isFollowing)
.build();
}
public static UserResponseDTO.DetailProfileDto toDetailProfileDto(
User user,
Boolean isFollowing,
Long totalCard,
Long totalFollower,
Long totalFollowing) {

return UserResponseDTO.DetailProfileDto.builder()
.userId(user.getId())
.profileImageUrl(user.getProfileImageUrl())
.nameId(user.getNameId())
.nickname(user.getNickname())
.isFollowing(isFollowing)
.introduce(user.getIntroduce())
.totalCard(totalCard)
.totalFollower(totalFollower)
.totalFollowing(totalFollowing)
.build();
}

public static ReactionResponseDTO.CardReactionUserListDto toCardReactionUsersListDto(Long cardId, ReactionType reactionType, Page<UserResponseDTO.ProfileDto> profileList){
return ReactionResponseDTO.CardReactionUserListDto.builder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,31 @@ public static class UserIconListResponseDto{
private List<ProfileDto> userIconList;
}

@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor
public static class DetailProfileDto {
@NotNull
private Long userId;
@NotNull
private String profileImageUrl;
@NotNull
private String nameId;
@NotNull
private String nickname;
@NotNull
private Boolean isFollowing;
@NotNull
private String introduce;
@NotNull
private Long totalCard;
@NotNull
private Long totalFollower;
@NotNull
private Long totalFollowing;
}

@Getter
@Builder
@AllArgsConstructor
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,7 @@ public interface UserFollowRepository extends JpaRepository<UserFollow,Long> {
List<Long> findFollowingUserIds(@Param("userId") Long userId);

UserFollow findByUserAndTargetUser(User user, User target);

Long countUserFollowByTargetUser(User targetUser);
Long countUserFollowByUser(User user);
Comment on lines +27 to +28

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

메서드 이름이 약간 혼동을 줄 수 있습니다. Spring Data JPA의 명명 규칙에 따라 더 명확하고 간결한 이름으로 변경하는 것을 제안합니다. 예를 들어, countByTargetUser는 팔로워 수를, countByUser는 팔로잉 수를 계산하는 것으로 명확하게 이해될 수 있습니다. 이 변경 사항을 적용할 경우 UserServiceImpl에서의 메서드 호출도 함께 수정해야 합니다.

Suggested change
Long countUserFollowByTargetUser(User targetUser);
Long countUserFollowByUser(User user);
Long countByTargetUser(User targetUser);
Long countByUser(User user);

}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public interface UserService {
UserResponseDTO.UserActionResponseDto followUser(HttpServletRequest request, Long targetUserId);
UserResponseDTO.UserActionResponseDto unfollowUser(HttpServletRequest request, Long targetUserId);
User getLoginUser(HttpServletRequest request);
UserResponseDTO.DetailProfileDto getProfile(HttpServletRequest request,Long userId);

// 마이페이지 업데이트 관련 서비스
UserResponseDTO.ProfileDto updateUserProfileImage(HttpServletRequest request, MultipartFile profileImage, User user);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package EatPic.spring.domain.user.service;

import EatPic.spring.domain.card.repository.CardRepository;
import EatPic.spring.domain.user.converter.UserConverter;
import EatPic.spring.domain.user.dto.*;
import EatPic.spring.domain.user.dto.request.LoginRequestDTO;
Expand Down Expand Up @@ -44,6 +45,7 @@ public class UserServiceImpl implements UserService{
private final UserFollowRepository userFollowRepository;
private final UserBlockRepository userBlockRepository;
private final UserBadgeService userBadgeService;
private final CardRepository cardRepository;
private final PasswordEncoder passwordEncoder;
private final JwtTokenProvider jwtTokenProvider;

Expand Down Expand Up @@ -189,6 +191,19 @@ public User getLoginUser(HttpServletRequest request) {
.orElseThrow(() -> new ExceptionHandler(ErrorStatus.MEMBER_NOT_FOUND));
}

@Override

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

getProfile 메서드는 데이터베이스에서 데이터를 읽기만 하는 조회용 메서드입니다. 성능 향상과 일관성을 위해 @Transactional(readOnly = true) 어노테이션을 추가하는 것을 권장합니다. 클래스 내 다른 조회 메서드들에도 적용되어 있습니다.

    @Override
    @Transactional(readOnly = true)

public UserResponseDTO.DetailProfileDto getProfile(HttpServletRequest request, Long userId) {
User me = getLoginUser(request);

User user = userRepository.findById(userId).orElseThrow(()-> new ExceptionHandler(USER_NOT_FOUND));
Boolean isFollowing = userFollowRepository.existsByUserAndTargetUser(me, user);
Long totalCard = cardRepository.countByUserIdAndIsDeletedFalseAndIsSharedTrue(userId);
Long totalFollower = userFollowRepository.countUserFollowByTargetUser(user);
Long totalFollowing = userFollowRepository.countUserFollowByUser(user);

return UserConverter.toDetailProfileDto(user, isFollowing,totalCard,totalFollower,totalFollowing);
}

@Override
public UserResponseDTO.UserActionResponseDto unfollowUser(HttpServletRequest request, Long targetUserId) {
User user = getLoginUser(request);
Expand All @@ -207,8 +222,13 @@ public UserResponseDTO.UserActionResponseDto unfollowUser(HttpServletRequest req
@Override
public UserResponseDTO.UserActionResponseDto followUser(HttpServletRequest request, Long targetUserId) {
User user = getLoginUser(request);
if(user.getId().equals(targetUserId)) {
throw new ExceptionHandler(FOLLOW_FORBBIDEN);
}

User target = userRepository.findUserById(targetUserId);


UserFollow prev = userFollowRepository.findByUserAndTargetUser(user,target);
UserFollow follow = UserFollow.builder().user(user).targetUser(target).build();
if(prev!=null && prev.getTargetUser().getId().equals(targetUserId)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ public enum ErrorStatus implements BaseErrorCode {
// 팔로우 관련 응답
FOLLOW_ALREADY_EXISTS(HttpStatus.BAD_REQUEST, "FOLLOW_001", "이미 팔로잉 중입니다"),
FOLLOW_NOT_EXISTS(HttpStatus.BAD_REQUEST, "FOLLOW_002", "팔로우 기록이 없습니다"),
FOLLOW_FORBBIDEN(HttpStatus.FORBIDDEN, "FOLLOW_003", "자신을 팔로우 할 수 없습니다."),

// 약관 관련 응답
TERM_NOT_FOUND(HttpStatus.NOT_FOUND, "TERM_001", "해당 약관을 찾을 수 없습니다.");
Expand Down
Loading