Skip to content

Commit

Permalink
Merge branch 'develop' into feat/#1-googleEmailLogin
Browse files Browse the repository at this point in the history
  • Loading branch information
dami0806 authored Jun 4, 2024
2 parents 3885fbb + cd2db31 commit 13041cc
Show file tree
Hide file tree
Showing 19 changed files with 584 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;

@SpringBootApplication
@EnableJpaAuditing
@SpringBootApplication(exclude = {SecurityAutoConfiguration.class})
public class OneAndZeroBestApplication {

public static void main(String[] args) {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package com.sparta.oneandzerobest.follow.controller;

import com.sparta.oneandzerobest.follow.dto.ErrorResponseDTO;
import com.sparta.oneandzerobest.follow.dto.FollowResponseDTO;
import com.sparta.oneandzerobest.follow.service.FollowService;
import com.sparta.oneandzerobest.auth.util.JwtUtil;
import com.sparta.oneandzerobest.auth.entity.User;
import com.sparta.oneandzerobest.auth.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
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;

/**
* FollowController는 팔로우 및 언팔로우 요청을 처리하는 컨트롤러입니다.
*/
@RestController
@RequestMapping("/api/follow")
public class FollowController {

@Autowired
private FollowService followService;

@Autowired
private JwtUtil jwtUtil;

@Autowired
private UserRepository userRepository;

/**
* 팔로우 요청을 처리합니다.
* @param token JWT 토큰
* @param userId 팔로우 당하는 사용자의 ID
* @return 팔로우 응답 데이터를 담은 DTO
*/
@PostMapping
public ResponseEntity<?> follow(@RequestHeader("Authorization") String token,
@PathVariable("user_id") Long userId) {

// JWT 토큰에서 사용자 이름 추출
String username = jwtUtil.getUsernameFromToken(token.replace("Bearer ", ""));

// 사용자 이름으로 사용자 조회
User user = userRepository.findByUsername(username)
.orElseThrow(() -> new RuntimeException("유저를 찾을 수 없습니다."));

// 자신을 팔로우할 수 없음
if (user.getId().equals(userId)) {
return ResponseEntity.badRequest().body(new ErrorResponseDTO("스스로를 팔로우할 수 없습니다."));
}

// 팔로우 서비스 호출
try {
FollowResponseDTO responseDTO = followService.follow(user.getId(), userId);
return new ResponseEntity<>(responseDTO, HttpStatus.OK);
} catch (Exception e) {
return ResponseEntity.badRequest().body(new ErrorResponseDTO("이미 팔로우한 유저입니다."));
}
}

/**
* 언팔로우 요청을 처리합니다.
* @param token JWT 토큰
* @param userId 언팔로우 당하는 사용자의 ID
* @return 언팔로우 응답 데이터를 담은 DTO
*/
@DeleteMapping
public ResponseEntity<?> unfollow(@RequestHeader("Authorization") String token,
@PathVariable("user_id") Long userId) {
// JWT 토큰에서 사용자 이름 추출
String username = jwtUtil.getUsernameFromToken(token.replace("Bearer ", ""));

// 사용자 이름으로 사용자 조회
User user = userRepository.findByUsername(username)
.orElseThrow(() -> new RuntimeException("유저를 찾을 수 없습니다."));

// 언팔로우 서비스 호출
try {
FollowResponseDTO responseDTO = followService.unfollow(user.getId(), userId);
return new ResponseEntity<>(responseDTO, HttpStatus.OK);
} catch (Exception e) {
return ResponseEntity.badRequest().body(new ErrorResponseDTO("팔로우하지 않은 유저를 언팔로우 할 수 없습니다."));
}
}

/**
* 팔로우 상태를 조회합니다.
* @param token JWT 토큰
* @param userId 팔로우 당하는 사용자의 ID
* @return 팔로우 상태
*/
@GetMapping
public ResponseEntity<?> getFollowers(@RequestHeader("Authorization") String token,
@PathVariable("user_id") Long userId) {
// JWT 토큰에서 사용자 이름 추출
String username = jwtUtil.getUsernameFromToken(token.replace("Bearer ", ""));

// 사용자 이름으로 사용자 조회
User user = userRepository.findByUsername(username)
.orElseThrow(() -> new RuntimeException("유저를 찾을 수 없습니다."));

// 팔로워 조회
List<User> followers = followService.getFollowers(userId);
List<FollowResponseDTO> followersDTO = followers.stream()
.map(follower -> new FollowResponseDTO(follower.getId(), follower.getUsername()))
.collect(Collectors.toList());

return ResponseEntity.ok(followersDTO);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.sparta.oneandzerobest.follow.dto;

import lombok.AllArgsConstructor;
import lombok.Getter;

/**
* ErrorResponseDTO는 오류 응답 시 반환되는 데이터를 담는 DTO입니다.
*/
@Getter
@AllArgsConstructor
public class ErrorResponseDTO {
private String error;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.sparta.oneandzerobest.follow.dto;

import lombok.Getter;
import lombok.Setter;

/**
* FollowRequestDTO는 팔로우 요청 시 필요한 데이터를 담는 DTO입니다.
*/
@Getter
@Setter
public class FollowRequestDTO {
private Long followeeId; // 팔로우할 사용자의 ID
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.sparta.oneandzerobest.follow.dto;

import lombok.Getter;
import lombok.Setter;

/**
* FollowResponseDTO는 팔로우 응답 시 반환되는 데이터를 담는 DTO입니다.
*/
@Getter
@Setter
public class FollowResponseDTO {
private Long followerId;
private Long followeeId;
private String message;
private String username;

/**
* 팔로우 응답 DTO를 생성하는 생성자입니다.
*
* @param followerId 팔로워의 ID
* @param username 팔로워의 사용자 이름
*/

public FollowResponseDTO(Long followerId, String username) {
this.followerId = followerId;
this.username = username;
}

public FollowResponseDTO() {
}
}
48 changes: 48 additions & 0 deletions src/main/java/com/sparta/oneandzerobest/follow/entity/Follow.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.sparta.oneandzerobest.follow.entity;

import com.sparta.oneandzerobest.timestamp.TimeStamp;
import jakarta.persistence.*;
import com.sparta.oneandzerobest.auth.entity.User;

/**
* Follow 엔티티는 팔로우 관계를 나타내는 엔티티입니다.
*/
@Entity
public class Follow extends TimeStamp {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@ManyToOne
@JoinColumn(name = "follower_id", nullable = false)
private User follower;

@ManyToOne
@JoinColumn(name = "followee_id", nullable = false)
private User followee;

// Getter, Setter
public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public User getFollower() {
return follower;
}

public void setFollower(User follower) {
this.follower = follower;
}

public User getFollowee() {
return followee;
}

public void setFollowee(User followee) {
this.followee = followee;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.sparta.oneandzerobest.follow.repository;

import com.sparta.oneandzerobest.follow.entity.Follow;
import com.sparta.oneandzerobest.auth.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
import java.util.Optional;

/**
* FollowRepository는 Follow 엔티티에 대한 데이터베이스 작업을 수행하는 리포지토리입니다.
*/
public interface FollowRepository extends JpaRepository<Follow, Long> {
List<Follow> findByFollower(User follower);
List<Follow> findByFollowee(User followee);
Optional<Follow> findByFollowerAndFollowee(User follower, User followee);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package com.sparta.oneandzerobest.follow.service;

import com.sparta.oneandzerobest.follow.dto.FollowResponseDTO;
import com.sparta.oneandzerobest.follow.entity.Follow;
import com.sparta.oneandzerobest.auth.entity.User;
import com.sparta.oneandzerobest.follow.repository.FollowRepository;
import com.sparta.oneandzerobest.auth.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
* FollowService는 팔로우와 언팔로우 기능을 제공하는 서비스입니다.
* 이 서비스는 사용자 간의 팔로우 관계를 관리합니다.
*/
@Service
public class FollowService {

@Autowired
private FollowRepository followRepository;

@Autowired
private UserRepository userRepository;

/**
* 팔로우 기능을 수행합니다.
* @param followerId 팔로우하는 사용자의 ID
* @param followeeId 팔로우 당하는 사용자의 ID
* @return 팔로우 응답 데이터를 담은 DTO
*/
public FollowResponseDTO follow(Long followerId, Long followeeId) {

// 팔로우하는 사용자 조회
User follower = userRepository.findById(followerId)
.orElseThrow(() -> new RuntimeException("팔로워를 찾을 수 없습니다."));

// 팔로우 당하는 사용자 조회
User followee = userRepository.findById(followeeId)
.orElseThrow(() -> new RuntimeException("팔로위를 찾을 수 없습니다."));


// 이미 팔로우한 경우 예외 발생
if (followRepository.findByFollowerAndFollowee(follower, followee).isPresent()) {
throw new RuntimeException("이미 팔로우한 유저입니다.");
}

// 새로운 팔로우 관계 생성 및 저장
Follow follow = new Follow();
follow.setFollower(follower);
follow.setFollowee(followee);
followRepository.save(follow);

// ResponseDTO 생성 및 반환
FollowResponseDTO responseDTO = new FollowResponseDTO();
responseDTO.setFollowerId(follower.getId());
responseDTO.setFolloweeId(followee.getId());
responseDTO.setMessage("유저를 성공적으로 팔로우 했습니다.");

return responseDTO;
}

/**
* 언팔로우 기능을 수행합니다.
* @param followerId 언팔로우하는 사용자의 ID
* @param followeeId 언팔로우 당하는 사용자의 ID
* @return 언팔로우 응답 데이터를 담은 DTO
*/
public FollowResponseDTO unfollow(Long followerId, Long followeeId) {

// 언팔로우하는 사용자 조회
User follower = userRepository.findById(followerId)
.orElseThrow(() -> new RuntimeException("팔로워를 찾을 수 없습니다."));

// 언팔로우 당하는 사용자 조회
User followee = userRepository.findById(followeeId)
.orElseThrow(() -> new RuntimeException("팔로위를 찾을 수 없습니다."));

// 팔로우 관계가 존재하지 않으면 예외 발생
Follow follow = followRepository.findByFollowerAndFollowee(follower, followee)
.orElseThrow(() -> new RuntimeException("팔로우하지 않은 유저를 언팔로우 할 수 없습니다."));

// 팔로우 관계 삭제
followRepository.delete(follow);

// ResponseDTO 생성 및 반환
FollowResponseDTO responseDTO = new FollowResponseDTO();
responseDTO.setFollowerId(follower.getId());
responseDTO.setFolloweeId(followee.getId());
responseDTO.setMessage("유저를 성공적으로 언팔로우 했습니다.");

return responseDTO;
}

/**
* 특정 사용자의 팔로워 목록을 조회합니다.
* @param userId 팔로우 당하는 사용자의 ID
* @return 팔로워 목록
*/
public List<User> getFollowers(Long userId) {
// 팔로우 당하는 사용자 조회
User followee = userRepository.findById(userId)
.orElseThrow(() -> new RuntimeException("유저를 찾을 수 없습니다."));

// 팔로우 관계에서 팔로워 목록 추출
return followRepository.findByFollowee(followee)
.stream()
.map(Follow::getFollower)
.collect(Collectors.toList());
}
}
Loading

0 comments on commit 13041cc

Please sign in to comment.