Skip to content

Commit

Permalink
Merge pull request #38 from kakao-tech-campus-2nd-step3/refactor/#37-…
Browse files Browse the repository at this point in the history
…VideoRefactoring1

[Refactor] #37 비디오에 대한 5주차 코드 리뷰 내용을 반영해보아요
  • Loading branch information
sanghee0820 authored Oct 9, 2024
2 parents 5bea7c2 + 853a0aa commit 5017bf4
Show file tree
Hide file tree
Showing 8 changed files with 124 additions and 129 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package team7.inplace.global.exception.code;

import lombok.AllArgsConstructor;
import lombok.Getter;
import org.springframework.http.HttpStatus;

@AllArgsConstructor
@Getter
public enum VideoErrorCode implements ErrorCode{
NO_SUCH_VIDEO(HttpStatus.NOT_FOUND, "V001", "Can't find such video info");

private final HttpStatus httpStatus;
private final String errorCode;
private final String message;

@Override
public HttpStatus httpStatus() {
return httpStatus;
}

@Override
public String code() {
return errorCode;
}

@Override
public String message() {
return message;
}
}
77 changes: 29 additions & 48 deletions src/main/java/team7/inplace/video/application/VideoService.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@

import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import team7.inplace.influencer.domain.Influencer;
import team7.inplace.influencer.persistence.InfluencerRepository;
import team7.inplace.place.domain.Place;
import team7.inplace.global.exception.InplaceException;
import team7.inplace.global.exception.code.AuthorizationErrorCode;
import team7.inplace.place.application.dto.PlaceForVideo;
import team7.inplace.place.domain.Place;
import team7.inplace.place.persistence.PlaceRepository;
import team7.inplace.video.application.dto.VideoInfo;
import team7.inplace.video.domain.Video;
Expand All @@ -22,64 +23,44 @@
public class VideoService {

private final VideoRepository videoRepository;
private final InfluencerRepository influencerRepository;
private final PlaceRepository placeRepository;

public List<VideoInfo> getByVideosInfluencer(List<String> influencers) {
// 인플루언서 정보 처리
List<Long> influencerIds = influencerRepository.findByNameIn(influencers).stream()
.map(Influencer::getId)
.toList();

// 인플루언서 정보로 필터링한 비디오 정보 불러오기
List<Video> savedVideos = videoRepository.findVideosByInfluencerIdIn(influencerIds);

// DTO 형식에 맞게 대입
return videoToInfo(savedVideos);
}

public List<VideoInfo> getAllVideosDesc() {
// id를 기준으로 내림차순 정렬하여 비디오 정보 불러오기
List<Video> savedVideos = videoRepository.findAllByOrderByIdDesc();

// DTO 형식에 맞게 대입
return videoToInfo(savedVideos);
}

public List<VideoInfo> getVideosBySurround(VideoSearchParams videoSearchParams, Pageable pageable) {
Page<Place> placesByDistance = placeRepository.getPlacesByDistance(
public Page<VideoInfo> getVideosBySurround(VideoSearchParams videoSearchParams, Pageable pageable) {
Page<Place> places = placeRepository.getPlacesByDistance(
videoSearchParams.longitude(),
videoSearchParams.latitude(),
pageable
);

List<Place> places = placesByDistance.getContent();
List<Video> videos = new ArrayList<>();
for (Place place : places) {
if(videos.size() == places.size())
for (Place place : places.getContent()) {
if (videos.size() == places.getSize())
break;
videos.add(videoRepository.findTopByPlaceOrderByIdDesc(place));
videos.add(videoRepository.findTopByPlaceOrderByIdDesc(place)
.orElseThrow(()-> InplaceException.of(AuthorizationErrorCode.NO_SUCH_VIDEO)));
}
return videoToInfo(videos);
return new PageImpl<>(videos).map(this::videoToInfo);
}

public Page<VideoInfo> getAllVideosDesc(Pageable pageable) {
// id를 기준으로 내림차순 정렬하여 비디오 정보 불러오기
Page<Video> videos = videoRepository.findAllByOrderByIdDesc(pageable);

// DTO 형식에 맞게 대입
return videos.map(this::videoToInfo);
}

private List<VideoInfo> videoToInfo(List<Video> savedVideos) {
List<VideoInfo> videoInfos = new ArrayList<>();
for (Video savedVideo : savedVideos) {
Place place = savedVideo.getPlace();
String alias = AliasUtil.makeAlias(
private VideoInfo videoToInfo(Video savedVideo) {
Place place = savedVideo.getPlace();
String alias = AliasUtil.makeAlias(
savedVideo.getInfluencer().getName(),
place.getCategory()
);
videoInfos.add(
new VideoInfo(
savedVideo.getId(),
alias,
savedVideo.getVideoUrl(),
PlaceForVideo.of(place.getId(), place.getName())
)
);
}
return videoInfos;
);
return new VideoInfo(
savedVideo.getId(),
alias,
savedVideo.getVideoUrl(),
PlaceForVideo.of(place.getId(), place.getName())
);
}
}
18 changes: 7 additions & 11 deletions src/main/java/team7/inplace/video/domain/Video.java
Original file line number Diff line number Diff line change
@@ -1,22 +1,16 @@
package team7.inplace.video.domain;

import static lombok.AccessLevel.PROTECTED;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import team7.inplace.influencer.domain.Influencer;
import team7.inplace.place.domain.Place;

import static lombok.AccessLevel.PROTECTED;
import static jakarta.persistence.FetchType.EAGER;
import static jakarta.persistence.GenerationType.IDENTITY;
import static lombok.AccessLevel.PROTECTED;

@Entity
@Getter
Expand All @@ -30,11 +24,13 @@ public class Video {
@Column(name = "video_url", nullable = false, columnDefinition = "TEXT")
@NonNull
private String videoUrl;
@ManyToOne
// 즉시 로딩 적용
@ManyToOne(fetch = EAGER)
@JoinColumn(name = "influencer_id", nullable = false)
@NonNull
private Influencer influencer;
@ManyToOne
// 즉시 로딩 적용
@ManyToOne(fetch = EAGER)
@JoinColumn(name = "place_id", nullable = false)
@NonNull
private Place place;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
package team7.inplace.video.persistence;

import java.util.List;
import java.util.Optional;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import team7.inplace.place.domain.Place;
import team7.inplace.video.domain.Video;

public interface VideoRepository extends JpaRepository<Video, Long> {

List<Video> findVideosByInfluencerIdIn(List<Long> influencerIds);
Page<Video> findVideosByInfluencerIdIn(List<Long> influencerIds, Pageable pageable);

List<Video> findAllByOrderByIdDesc();
Page<Video> findAllByOrderByIdDesc(Pageable pageable);

Video findTopByPlaceOrderByIdDesc(Place place);
Optional<Video> findTopByPlaceOrderByIdDesc(Place place);

List<Video> findByPlaceIdIn(List<Long> placeIds);
}
59 changes: 18 additions & 41 deletions src/main/java/team7/inplace/video/presentation/VideoController.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package team7.inplace.video.presentation;

import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import team7.inplace.video.application.dto.VideoInfo;
import team7.inplace.video.presentation.dto.VideoResponse;
import team7.inplace.video.application.VideoService;
import team7.inplace.video.presentation.dto.VideoResponse;
import team7.inplace.video.presentation.dto.VideoSearchParams;

import java.util.ArrayList;
Expand All @@ -18,57 +18,34 @@
@RestController
@RequiredArgsConstructor
@RequestMapping("/videos")
public class VideoController implements VideoControllerApiSpec{
public class VideoController implements VideoControllerApiSpec {
private final VideoService videoService;

// 토큰 필요 메서드
@GetMapping()
public ResponseEntity<List<VideoResponse>> readVideos(
HttpServletRequest request,
@RequestParam(name = "influencer", required = false) List<String> influencers,
public ResponseEntity<Page<VideoResponse>> readVideos(
@ModelAttribute VideoSearchParams searchParams,
@RequestParam(defaultValue = "0", required = false) int page,
@RequestParam(defaultValue = "10", required = false) int size
@PageableDefault(page = 0, size = 10) Pageable pageable
) {
// Authorization 헤더 추출
String authHeader = request.getHeader("Authorization");
// 토큰 존재 여부 검사
if(authHeader != null && authHeader.startsWith("Bearer ")) {
// 토큰 유효성 검사

// 토큰이 있는 경우
return readByInfluencer(influencers);
}

// 토큰이 없는 경우
return readBySurround(searchParams, page, size);
}

private ResponseEntity<List<VideoResponse>> readByInfluencer(List<String> influencers){
List<VideoInfo> videoInfos = videoService.getByVideosInfluencer(influencers);
List<VideoResponse> videoResponses = videoInfos.stream().map(VideoResponse::from).toList();
return new ResponseEntity<>(videoResponses, HttpStatus.OK);
}

private ResponseEntity<List<VideoResponse>> readBySurround(VideoSearchParams searchParams, int page, int size) {
Pageable pageable = PageRequest.of(page, size);
List<VideoInfo> videoInfos = videoService.getVideosBySurround(searchParams, pageable);
List<VideoResponse> videoResponses = videoInfos.stream().map(VideoResponse::from).toList();
Page<VideoResponse> videoResponses = videoService.getVideosBySurround(searchParams, pageable)
.map(VideoResponse::from);
return new ResponseEntity<>(videoResponses, HttpStatus.OK);
}

@GetMapping("/new")
public ResponseEntity<List<VideoResponse>> readByNew() {
List<VideoInfo> videoInfos = videoService.getAllVideosDesc();
List<VideoResponse> videoResponses = videoInfos.stream().map(VideoResponse::from).toList();
public ResponseEntity<Page<VideoResponse>> readByNew(
@PageableDefault(page = 0, size = 10) Pageable pageable
) {
Page<VideoResponse> videoResponses = videoService.getAllVideosDesc(pageable)
.map(VideoResponse::from);
return new ResponseEntity<>(videoResponses, HttpStatus.OK);
}

// 조회수 반환 기능 개발 시 개발
@GetMapping("/cool")
public ResponseEntity<List<VideoResponse>> readByCool() {
public ResponseEntity<Page<VideoResponse>> readByCool(
@PageableDefault(page = 0, size = 10) Pageable pageable
) {
List<VideoResponse> videoResponses = new ArrayList<>();
return new ResponseEntity<>(videoResponses, HttpStatus.OK);
return new ResponseEntity<>(new PageImpl<>(videoResponses), HttpStatus.OK);
}

}
Original file line number Diff line number Diff line change
@@ -1,32 +1,37 @@
package team7.inplace.video.presentation;

import io.swagger.v3.oas.annotations.Operation;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestParam;
import team7.inplace.video.presentation.dto.VideoResponse;
import team7.inplace.video.presentation.dto.VideoSearchParams;

import java.util.List;


public interface VideoControllerApiSpec {
@Operation(
summary = "내 인플루언서가 방문한 or 내 주변 그곳 ",
description = "토큰의 유무에 따라 다른 동작을 수행합니다."
summary = "내 주변 그곳 ",
description = "Parameter로 입력받은 위치의 주변 장소들을 조회합니다."
)
public ResponseEntity<List<VideoResponse>> readVideos(
HttpServletRequest request,
@RequestParam(name = "influencer", required = false) List<String> influencers,
ResponseEntity<Page<VideoResponse>> readVideos(
@ModelAttribute VideoSearchParams searchParams,
@RequestParam(defaultValue = "0", required = false) int page,
@RequestParam(defaultValue = "10", required = false) int size
@PageableDefault(page = 0, size = 10) Pageable pageable
);

@Operation(summary = "새로 등록된 그 곳", description = "id를 기준으로 내림차순 정렬한 Video 정보를 조회합니다.")
public ResponseEntity<List<VideoResponse>> readByNew();
@Operation(
summary = "새로 등록된 그 곳",
description = "id를 기준으로 내림차순 정렬한 Video 정보를 조회합니다."
)
ResponseEntity<Page<VideoResponse>> readByNew(
@PageableDefault(page = 0, size = 10) Pageable pageable
);

@Operation(summary = "쿨한 그 곳", description = "조회수를 기준으로 내림차순 정렬한 Video 정보를 조회합니다.")
public ResponseEntity<List<VideoResponse>> readByCool();
@Operation(
summary = "쿨한 그 곳",
description = "조회수를 기준으로 내림차순 정렬한 Video 정보를 조회합니다."
)
ResponseEntity<Page<VideoResponse>> readByCool(
@PageableDefault(page = 0, size = 10) Pageable pageable
);
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package team7.inplace.video.service;
package team7.inplace.video.application;

import static org.mockito.BDDMockito.given;

Expand Down
Loading

0 comments on commit 5017bf4

Please sign in to comment.