와이어프레임
erd
컨트롤러
package org.example.snsprojcet.domain.friend.controller;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import lombok.RequiredArgsConstructor;
import org.example.snsprojcet.domain.friend.dto.FriendRequestDto;
import org.example.snsprojcet.domain.friend.dto.FriendResponseDto;
import org.example.snsprojcet.domain.friend.entity.Friend;
import org.example.snsprojcet.domain.friend.service.FriendService;
import org.example.snsprojcet.domain.user.entity.User;
import org.example.snsprojcet.domain.user.service.UserService;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.stream.Collectors;
@RestController
@RequestMapping("/api/friends")
@RequiredArgsConstructor
public class FriendController {
private final FriendService friendService;
private final UserService userService;
// 친구 요청 보내기
@PostMapping("/request")
public ResponseEntity<String> sendFriendRequest(@RequestBody FriendRequestDto dto, User user) {
User request = userService.findByNickname(dto.getRequestNickname());// 송신자 사용자 받아오기
User receiver = userService.findByNickname(dto.getReceiverNickname()); // 수신자 유저 받아오기
//
//
Friend friend = friendService.sendFriendRequest(request, receiver);
return ResponseEntity.ok("친구 요청이 성공적으로 전송되었습니다.");
}
// 친구 수락
@PostMapping("/{friendId}/accept")
public ResponseEntity<String> accept(@PathVariable Long friendId) {
friendService.acceptFriendRequest(friendId);
return ResponseEntity.ok("친구 요청을 수락했습니다.");
}
// 친구 거절
@PostMapping("/{friendId}/reject")
public ResponseEntity<String> reject(@PathVariable Long friendId) {
friendService.rejectFriendRequest(friendId);
return ResponseEntity.ok("친구 요청을 거절했습니다.");
}
// 보낸 요청 목록
@GetMapping("/requestList")
public ResponseEntity<List<FriendResponseDto>> sentRequests(@RequestParam String nickname) {
User loginUser = userService.findByNickname(nickname);
List<FriendResponseDto> list =
friendService
.getSentRequests(loginUser)
.stream()
.map(FriendResponseDto::new)
.collect(Collectors.toList()
);
return ResponseEntity.ok(list);
}
// 받은 요청 목록
@GetMapping("/receivedList")
public ResponseEntity<List<FriendResponseDto>> receivedRequests(String nickname) {
User loginUser = userService.findByNickname(nickname);
List<FriendResponseDto> list = friendService.getReceivedRequests(loginUser)
.stream().map(FriendResponseDto::new).collect(Collectors.toList());
return ResponseEntity.ok(list);
}
//친구목록
@GetMapping("/friendList")
public ResponseEntity<List<String>> FriendList(@RequestParam String nickname) {
// 친구 목록 조회
List<String> friendList = friendService.findAllFriendList(nickname);
return new ResponseEntity<>(friendList, HttpStatus.OK);
}
// 친구 삭제
@DeleteMapping("/delete")
public ResponseEntity<String> deleteFriend(HttpServletRequest request, @RequestParam String nickname) {
// 세션에서 로그인한 사용자 정보 가져오기
HttpSession session = request.getSession();
Long loginUserId = (Long) session.getAttribute("userId");
// 로그인한 사용자와 친구 정보를 가져오기
User loginUser = userService.findById(loginUserId);
User friend = userService.findByNickname(nickname);
// 친구 관계 삭제
boolean success = friendService.deleteFriend(loginUser, friend);
if (success) {
return ResponseEntity.ok("친구가 삭제되었습니다.");
} else {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("친구 삭제에 실패했습니다.");
}
}
}
엔티티
package org.example.snsprojcet.domain.friend.entity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.example.snsprojcet.domain.friend.enums.FriendStatus;
import org.example.snsprojcet.domain.user.entity.User;
@NoArgsConstructor
@Getter
@Entity
@Table(name = "friend")
public class Friend {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
//친구 요청 보내는 사람
@ManyToOne
@JoinColumn(name = "userrequest_id",nullable = false)
private User userrequest;
//받는사람
@ManyToOne
@JoinColumn(name = "userreceiver_id",nullable = false)
private User userreceiver;
public Friend(User userrequest, User userreceiver, FriendStatus status) {
this.userrequest = userrequest;
this.userreceiver = userreceiver;
this.status = status;
}
@Enumerated(EnumType.STRING)
private FriendStatus status;
//친구수락
public void accept() {
this.status = FriendStatus.ACCEPTED;
}
//친구 거절
public void reject() {
this.status = FriendStatus.REJECTED;
}
}
레포지토리
package org.example.snsprojcet.domain.friend.repository;
import org.example.snsprojcet.domain.friend.entity.Friend;
import org.example.snsprojcet.domain.friend.enums.FriendStatus;
import org.example.snsprojcet.domain.user.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import java.util.List;
import java.util.Optional;
public interface FriendRepository extends JpaRepository<Friend,Long> {
//요청 보내는 리스트
List<Friend> findByUserrequest(User userrequest);
//요청 받는 리스트
List<Friend> findByUserreceiver(User userreciever);
//친구 조회
@Query("SELECT f FROM Friend f WHERE (f.userrequest = :user OR f.userreceiver = :user) AND f.status = :status")
List<Friend> findAcceptedFriends(FriendStatus friendStatus, User user);
// userrequest는 친구 요청을 보내는 사람이고, userreceiver는 친구 요청을 받는 사람
Friend findByUserrequestAndUserreceiver(User userrequest, User userreceiver);
// 반대편 관계도 찾기 위해 userreceiver와 userrequest를 반대로 사용
Friend findByUserreceiverAndUserrequest(User userreceiver, User userrequest);
}
서비스
package org.example.snsprojcet.domain.friend.service;
import lombok.RequiredArgsConstructor;
import org.example.snsprojcet.domain.friend.dto.FriendResponseDto;
import org.example.snsprojcet.domain.friend.entity.Friend;
import org.example.snsprojcet.domain.friend.enums.FriendStatus;
import org.example.snsprojcet.domain.friend.repository.FriendRepository;
import org.example.snsprojcet.domain.user.entity.User;
import org.example.snsprojcet.domain.user.repository.UserRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import static org.example.snsprojcet.domain.friend.enums.FriendStatus.ACCEPTED;
@Service
@RequiredArgsConstructor
public class FriendService {
private final FriendRepository friendRepository;
private final UserRepository userRepository;
// 친구 요청 보내기
public Friend sendFriendRequest(User requester, User receiver) {
return friendRepository.save(new Friend(requester, receiver, FriendStatus.PENDING));
}
// 친구 수락
@Transactional
public void acceptFriendRequest(Long friendId) {
Friend friend = friendRepository.findById(friendId)
.orElseThrow(() -> new IllegalArgumentException("친구 요청이 존재하지 않습니다."));
friend.accept();
}
// 친구 거절
@Transactional
public void rejectFriendRequest(Long friendId) {
Friend friend = friendRepository.findById(friendId)
.orElseThrow(() -> new IllegalArgumentException("친구 요청이 존재하지 않습니다."));
friend.reject();
}
// 내가 요청한 친구 목록
public List<Friend> getSentRequests(User user) {
return friendRepository.findByUserrequest(user);
}
// 내가 받은 친구 요청 목록
public List<Friend> getReceivedRequests(User user) {
return friendRepository.findByUserreceiver(user);
}
// 친구 목록 조회
public List<String> findAllFriendList (String nickname) {
// 유저 조회
User userByNicknameOrElseThrow = userRepository.findUserByNicknameOrElseThrow(nickname);
// 친구 요청 리스트 불러오기(친구 요청 목록에서 nickname 뽑아오기위해)
// 수락 한 친구 상태만 보여주기
List<FriendResponseDto> list =
friendRepository.findByUserrequest(userByNicknameOrElseThrow)
.stream()
.filter(friend -> friend.getStatus().equals(ACCEPTED)) // 친구 요청을 수락했는지 확인
.map(friend -> new FriendResponseDto(friend))
.toList();
// nickname 뽑아와 새로운 리스트 생성
List<String> nicknames = list.stream()
.map(friendResponseDto -> friendResponseDto.getReceiverNickname()) // FriendResponseDto에서 nickname 가져오기
.toList();
return nicknames;
}
//친구삭제 및 확인
public boolean deleteFriend(User loginUser, User friend) {
// 로그인한 사용자와 친구 간의 관계를 찾음
Friend relation = friendRepository.findByUserrequestAndUserreceiver(loginUser, friend);
// 만약 첫 번째 관계가 없으면, 반대 관계를 찾음 (친구가 로그인한 사용자에게 보낸 요청을 찾기)
if (relation == null) {
relation = friendRepository.findByUserreceiverAndUserrequest(loginUser, friend);
}
// 친구 관계가 존재하면 삭제
if (relation != null) {
friendRepository.delete(relation);
// 반대편 관계도 삭제 (친구가 로그인한 사용자를 팔로우한 경우)
Friend reverseRelation = friendRepository.findByUserrequestAndUserreceiver(friend, loginUser);
if (reverseRelation == null) {
reverseRelation = friendRepository.findByUserreceiverAndUserrequest(friend, loginUser);
}
if (reverseRelation != null) {
friendRepository.delete(reverseRelation);
}
return true; // 삭제 성공
}
return false; // 친구 관계가 존재하지 않으면 삭제할 수 없음
}
}
'스프링' 카테고리의 다른 글
Spring MVC 내부 구조와 HttpMessageConverter 완전 정복 (0) | 2025.04.15 |
---|---|
kpt (0) | 2025.04.14 |
뉴스피드 프로젝트 예외처리 (0) | 2025.04.08 |
뉴스피드 프로젝트 친구설정 (0) | 2025.04.08 |
뉴스피드 프로젝트 친구 목록 정렬 정리 (0) | 2025.04.08 |