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
@@ -1,9 +1,6 @@
package com.example.egobook_be.domain.friend.controller;

import com.example.egobook_be.domain.friend.dto.FriendRequestCreateReqDto;
import com.example.egobook_be.domain.friend.dto.FriendRequestListResDto;
import com.example.egobook_be.domain.friend.dto.FriendResDto;
import com.example.egobook_be.domain.friend.dto.FriendSearchResDto;
import com.example.egobook_be.domain.friend.dto.*;
import com.example.egobook_be.domain.friend.service.FriendService;
import com.example.egobook_be.global.response.GlobalResponse;
import io.swagger.v3.oas.annotations.Operation;
Expand Down Expand Up @@ -52,6 +49,7 @@ public ResponseEntity<GlobalResponse<Void>> requestFriend(
받은 친구 신청을 수락합니다.

- 수락 시 양방향 친구 관계가 생성됩니다.
- 친구는 최대 10명까지만 추가할 수 있으며, 초과 시 수락이 실패합니다.
"""
)
@PostMapping("/requests/{requestId}/accept")
Expand Down Expand Up @@ -129,7 +127,7 @@ public ResponseEntity<GlobalResponse<Void>> deleteFriend(
"""
)
@GetMapping("/requests/incoming")
public ResponseEntity<GlobalResponse<List<FriendRequestListResDto>>> getIncomingRequests(
public ResponseEntity<GlobalResponse<FriendRequestListWithCountResDto>> getIncomingRequests(
@AuthenticationPrincipal(expression = "userAuthDto.userId") Long userId
) {
return ResponseEntity.ok(
Expand Down Expand Up @@ -168,7 +166,7 @@ public ResponseEntity<GlobalResponse<List<FriendRequestListResDto>>> getOutgoing
"""
)
@GetMapping
public ResponseEntity<GlobalResponse<List<FriendResDto>>> getFriends(
public ResponseEntity<GlobalResponse<FriendListResDto>> getFriends(
@AuthenticationPrincipal(expression = "userAuthDto.userId")
@Parameter(hidden = true) Long userId
) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.example.egobook_be.domain.friend.dto;

import lombok.Builder;

import java.util.List;

@Builder
public record FriendListResDto(
int count,
List<FriendResDto> friends
) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ public record FriendRequestListResDto(
Long requestId,
Long userId,
String nickname,
Integer level,
LocalDateTime requestedAt
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.example.egobook_be.domain.friend.dto;

import lombok.Builder;

import java.util.List;

@Builder
public record FriendRequestListWithCountResDto(
int totalCount,
List<FriendRequestListResDto> requests
) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
@Builder
public record FriendResDto(
Long friendId,
String nickname
String nickname,
Integer level
) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public enum FriendErrorCode implements BaseErrorCode {
*/
ALREADY_FRIEND(HttpStatus.CONFLICT, "이미 친구 관계입니다."),
ALREADY_REQUESTED(HttpStatus.CONFLICT, "이미 친구 신청을 보낸 상태입니다."),
FRIEND_LIMIT_EXCEEDED(HttpStatus.CONFLICT, "친구는 최대 10명까지만 추가할 수 있습니다."),

/**
* 400 BAD_REQUEST
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,22 @@ public interface FriendRepository extends JpaRepository<Friend, Long> {

List<Friend> findByUser(User user);

long countByUser(User user);

@Query("""
select f.friend.id
from Friend f
where f.user = :user
""")
List<Long> findFriendIdsByUser(@Param("user") User user);

@Query("""
select f
from Friend f
join fetch f.friend u
where f.user = :user
""")
List<Friend> findByUserWithFriend(
@Param("user") User user
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import com.example.egobook_be.domain.friend.enums.FriendRequestStatus;
import com.example.egobook_be.domain.user.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import java.util.List;
import java.util.Optional;
Expand All @@ -25,4 +27,21 @@ boolean existsBySenderAndReceiverAndStatus(
List<FriendRequest> findByReceiverAndStatus(User receiver, FriendRequestStatus status);

List<FriendRequest> findBySenderAndStatus(User sender, FriendRequestStatus status);

long countByReceiverAndStatus(
User receiver,
FriendRequestStatus status
);

@Query("""
select fr
from FriendRequest fr
join fetch fr.receiver r
where fr.sender = :sender
and fr.status = :status
""")
List<FriendRequest> findBySenderAndStatusWithReceiver(
@Param("sender") User sender,
@Param("status") FriendRequestStatus status
);
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
package com.example.egobook_be.domain.friend.service;

import com.example.egobook_be.domain.friend.dto.FriendRequestCreateReqDto;
import com.example.egobook_be.domain.friend.dto.FriendRequestListResDto;
import com.example.egobook_be.domain.friend.dto.FriendResDto;
import com.example.egobook_be.domain.friend.dto.FriendSearchResDto;
import com.example.egobook_be.domain.friend.dto.*;
import com.example.egobook_be.domain.friend.entity.Friend;
import com.example.egobook_be.domain.friend.entity.FriendRequest;
import com.example.egobook_be.domain.friend.enums.FriendRequestStatus;
Expand Down Expand Up @@ -87,6 +84,14 @@ public void acceptRequest(Long receiverId, Long requestId) {
.findByIdAndReceiver(requestId, receiver)
.orElseThrow(() -> new CustomException(FriendErrorCode.FRIEND_REQUEST_NOT_FOUND));

User sender = request.getSender();

// 친구 수 제한 체크 (양쪽 모두)
if (friendRepository.countByUser(receiver) >= 10
|| friendRepository.countByUser(sender) >= 10) {
throw new CustomException(FriendErrorCode.FRIEND_LIMIT_EXCEEDED);
}

request.accept();

// 양방향 친구 관계 생성
Expand Down Expand Up @@ -149,22 +154,40 @@ public void deleteFriend(Long userId, Long friendId) {

/** 내가 받은 친구 신청 목록 (승인 대기) **/
@Transactional(readOnly = true)
public List<FriendRequestListResDto> getIncomingRequests(Long userId) {
public FriendRequestListWithCountResDto getIncomingRequests(Long userId) {

User receiver = userRepository.findById(userId)
.orElseThrow(() -> new CustomException(FriendErrorCode.USER_NOT_FOUND));

return friendRequestRepository
.findByReceiverAndStatus(receiver, FriendRequestStatus.PENDING)
.stream()
.map(req -> FriendRequestListResDto.builder()
.requestId(req.getId())
.userId(req.getSender().getId())
.nickname(req.getSender().getNickname())
.requestedAt(req.getCreatedAt())
.build()
)
List<FriendRequest> requests =
friendRequestRepository.findByReceiverAndStatus(
receiver,
FriendRequestStatus.PENDING
);

int totalCount = (int) friendRequestRepository.countByReceiverAndStatus(
receiver,
FriendRequestStatus.PENDING
);

List<FriendRequestListResDto> list = requests.stream()
.map(req -> {
User sender = req.getSender();

return FriendRequestListResDto.builder()
.requestId(req.getId())
.userId(sender.getId())
.nickname(sender.getNickname())
.level(sender.getLevel())
.requestedAt(req.getCreatedAt())
.build();
})
.toList();

return FriendRequestListWithCountResDto.builder()
.totalCount(totalCount)
.requests(list)
.build();
}

/** 내가 보낸 친구 신청 목록 **/
Expand All @@ -175,33 +198,46 @@ public List<FriendRequestListResDto> getOutgoingRequests(Long userId) {
.orElseThrow(() -> new CustomException(FriendErrorCode.USER_NOT_FOUND));

return friendRequestRepository
.findBySenderAndStatus(sender, FriendRequestStatus.PENDING)
.findBySenderAndStatusWithReceiver(sender, FriendRequestStatus.PENDING)
.stream()
.map(req -> FriendRequestListResDto.builder()
.requestId(req.getId())
.userId(req.getReceiver().getId())
.nickname(req.getReceiver().getNickname())
.requestedAt(req.getCreatedAt())
.build()
)
.map(req -> {
User receiver = req.getReceiver();

return FriendRequestListResDto.builder()
.requestId(req.getId())
.userId(receiver.getId())
.nickname(receiver.getNickname())
.level(receiver.getLevel())
.requestedAt(req.getCreatedAt())
.build();
})
.toList();
}

/** 친구 리스트 **/
@Transactional(readOnly = true)
public List<FriendResDto> getFriends(Long userId) {
public FriendListResDto getFriends(Long userId) {

User user = userRepository.findById(userId)
.orElseThrow(() -> new CustomException(FriendErrorCode.USER_NOT_FOUND));

return friendRepository.findByUser(user)
List<FriendResDto> friends = friendRepository.findByUserWithFriend(user)
.stream()
.map(friend -> FriendResDto.builder()
.friendId(friend.getFriend().getId())
.nickname(friend.getFriend().getNickname())
.build()
)
.map(friend -> {
User friendUser = friend.getFriend();

return FriendResDto.builder()
.friendId(friendUser.getId())
.nickname(friendUser.getNickname())
.level(friendUser.getLevel())
.build();
})
.toList();

return FriendListResDto.builder()
.count(friends.size())
.friends(friends)
.build();
}

/** 친구 검색 **/
Expand Down
Loading