diff --git a/gradlew b/gradlew old mode 100644 new mode 100755 diff --git a/src/main/java/org/ioteatime/meonghanyangserver/common/type/VideoSuccessType.java b/src/main/java/org/ioteatime/meonghanyangserver/common/type/VideoSuccessType.java index 21dd13f1..f172c5bd 100644 --- a/src/main/java/org/ioteatime/meonghanyangserver/common/type/VideoSuccessType.java +++ b/src/main/java/org/ioteatime/meonghanyangserver/common/type/VideoSuccessType.java @@ -1,7 +1,8 @@ package org.ioteatime.meonghanyangserver.common.type; public enum VideoSuccessType implements SuccessTypeCode { - GET_PRESIGNED_URL(200, "OK", "Presigned Url 조회에 성공하였습니다."); + GET_PRESIGNED_URL(200, "OK", "Presigned Url 조회에 성공하였습니다."), + GET_VIDEO_INFO(200, "OK", "동영상 정보 조회에 성공하였습니다."); private final Integer code; private final String message; diff --git a/src/main/java/org/ioteatime/meonghanyangserver/video/controller/VideoApi.java b/src/main/java/org/ioteatime/meonghanyangserver/video/controller/VideoApi.java index 369c58be..7a3cd159 100644 --- a/src/main/java/org/ioteatime/meonghanyangserver/video/controller/VideoApi.java +++ b/src/main/java/org/ioteatime/meonghanyangserver/video/controller/VideoApi.java @@ -2,10 +2,13 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import java.time.LocalDate; import org.ioteatime.meonghanyangserver.common.api.Api; import org.ioteatime.meonghanyangserver.common.utils.LoginMember; import org.ioteatime.meonghanyangserver.video.dto.response.VideoPresignedUrlResponse; +import org.springframework.format.annotation.DateTimeFormat; import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestParam; @Tag(name = "Video Api", description = "Video 관련 API 목록입니다.") public interface VideoApi { @@ -15,5 +18,7 @@ public Api getVideoPresignedUrl( @Operation(summary = "날짜를 사용한 동영상 정보 조회 발급받습니다.", description = "담당자: 최민석") public Api searchToDate( - @LoginMember Long memberId, @PathVariable Long groupId, @PathVariable String date); + @LoginMember Long memberId, + @PathVariable Long groupId, + @RequestParam("date") @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate date); } diff --git a/src/main/java/org/ioteatime/meonghanyangserver/video/controller/VideoController.java b/src/main/java/org/ioteatime/meonghanyangserver/video/controller/VideoController.java index b95bfa4d..786d9dac 100644 --- a/src/main/java/org/ioteatime/meonghanyangserver/video/controller/VideoController.java +++ b/src/main/java/org/ioteatime/meonghanyangserver/video/controller/VideoController.java @@ -1,15 +1,15 @@ package org.ioteatime.meonghanyangserver.video.controller; +import java.time.LocalDate; import lombok.RequiredArgsConstructor; import org.ioteatime.meonghanyangserver.common.api.Api; import org.ioteatime.meonghanyangserver.common.type.VideoSuccessType; import org.ioteatime.meonghanyangserver.common.utils.LoginMember; +import org.ioteatime.meonghanyangserver.video.dto.response.VideoInfoListResponse; import org.ioteatime.meonghanyangserver.video.dto.response.VideoPresignedUrlResponse; import org.ioteatime.meonghanyangserver.video.service.VideoService; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.format.annotation.DateTimeFormat; +import org.springframework.web.bind.annotation.*; @RestController @RequiredArgsConstructor @@ -25,8 +25,13 @@ public Api getVideoPresignedUrl( return Api.success(VideoSuccessType.GET_PRESIGNED_URL, videoPresignedUrlResponse); } - @Override - public Api searchToDate(Long memberId, Long groupId, String date) { - return null; + @GetMapping("/group/{groupId}") + public Api searchToDate( + @LoginMember Long memberId, + @PathVariable("groupId") Long groupId, + @RequestParam("date") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate date) { + VideoInfoListResponse videoInfoListResponse = + videoService.searchToDate(memberId, groupId, date); + return Api.success(VideoSuccessType.GET_VIDEO_INFO, videoInfoListResponse); } } diff --git a/src/main/java/org/ioteatime/meonghanyangserver/video/domain/VideoEntity.java b/src/main/java/org/ioteatime/meonghanyangserver/video/domain/VideoEntity.java index a2f19320..294c4a8b 100644 --- a/src/main/java/org/ioteatime/meonghanyangserver/video/domain/VideoEntity.java +++ b/src/main/java/org/ioteatime/meonghanyangserver/video/domain/VideoEntity.java @@ -23,6 +23,9 @@ public class VideoEntity { @Column(nullable = false, length = 100) private String videoPath; + @Column(nullable = false, length = 100) + private String thumbnailPath; + @Column(nullable = false) private LocalDateTime createdAt; } diff --git a/src/main/java/org/ioteatime/meonghanyangserver/video/dto/response/VideoInfoListResponse.java b/src/main/java/org/ioteatime/meonghanyangserver/video/dto/response/VideoInfoListResponse.java new file mode 100644 index 00000000..8d8895b5 --- /dev/null +++ b/src/main/java/org/ioteatime/meonghanyangserver/video/dto/response/VideoInfoListResponse.java @@ -0,0 +1,13 @@ +package org.ioteatime.meonghanyangserver.video.dto.response; + +import io.swagger.v3.oas.annotations.media.Schema; +import java.util.List; +import lombok.Builder; + +@Schema(description = "동영상 정보 목록 조회 응답") +public record VideoInfoListResponse(@Schema(description = "비디오 정보") List video) { + @Builder + public VideoInfoListResponse(List video) { + this.video = video; + } +} diff --git a/src/main/java/org/ioteatime/meonghanyangserver/video/dto/response/VideoInfoResponse.java b/src/main/java/org/ioteatime/meonghanyangserver/video/dto/response/VideoInfoResponse.java index c55c63e9..e67a3c87 100644 --- a/src/main/java/org/ioteatime/meonghanyangserver/video/dto/response/VideoInfoResponse.java +++ b/src/main/java/org/ioteatime/meonghanyangserver/video/dto/response/VideoInfoResponse.java @@ -2,9 +2,16 @@ import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import java.time.LocalDateTime; @Schema(description = "동영상 정보 조회 응답") -public record VideoInfoResponse ( - @NotBlank @Schema() Long videoId -){ -} +public record VideoInfoResponse( + @NotNull @Schema(description = "동영상 ID", example = "1") Long videoId, + @NotBlank + @Schema( + description = "썸네일 presigned url", + example = "https://bucket.s3.ap-northeast-2.amazonaws.com/test?") + String thumbnailPresignedUrl, + @NotBlank @Schema(description = "동영상 생성 날짜", example = "2024-11-26 12:57:45") + LocalDateTime createdAt) {} diff --git a/src/main/java/org/ioteatime/meonghanyangserver/video/mapper/VideoResponseMapper.java b/src/main/java/org/ioteatime/meonghanyangserver/video/mapper/VideoResponseMapper.java index 8da964a4..3b2fe58c 100644 --- a/src/main/java/org/ioteatime/meonghanyangserver/video/mapper/VideoResponseMapper.java +++ b/src/main/java/org/ioteatime/meonghanyangserver/video/mapper/VideoResponseMapper.java @@ -1,9 +1,15 @@ package org.ioteatime.meonghanyangserver.video.mapper; +import org.ioteatime.meonghanyangserver.video.domain.VideoEntity; +import org.ioteatime.meonghanyangserver.video.dto.response.VideoInfoResponse; import org.ioteatime.meonghanyangserver.video.dto.response.VideoPresignedUrlResponse; public class VideoResponseMapper { public static VideoPresignedUrlResponse form(String presignedURL) { return new VideoPresignedUrlResponse(presignedURL); } + + public static VideoInfoResponse form(VideoEntity videoEntity, String presignedURL) { + return new VideoInfoResponse(videoEntity.getId(), presignedURL, videoEntity.getCreatedAt()); + } } diff --git a/src/main/java/org/ioteatime/meonghanyangserver/video/repository/VideoRepository.java b/src/main/java/org/ioteatime/meonghanyangserver/video/repository/VideoRepository.java index d217a5c7..80d5bae5 100644 --- a/src/main/java/org/ioteatime/meonghanyangserver/video/repository/VideoRepository.java +++ b/src/main/java/org/ioteatime/meonghanyangserver/video/repository/VideoRepository.java @@ -1,5 +1,7 @@ package org.ioteatime.meonghanyangserver.video.repository; +import java.time.LocalDate; +import java.util.List; import java.util.Optional; import org.ioteatime.meonghanyangserver.video.domain.VideoEntity; @@ -7,4 +9,6 @@ public interface VideoRepository { Optional findById(Long videoId); void deleteAllByGroupId(Long groupId); + + List findByGroupIdAndCreatedAtContains(Long groupId, LocalDate date); } diff --git a/src/main/java/org/ioteatime/meonghanyangserver/video/repository/VideoRepositoryImpl.java b/src/main/java/org/ioteatime/meonghanyangserver/video/repository/VideoRepositoryImpl.java index db5b6b60..e997574d 100644 --- a/src/main/java/org/ioteatime/meonghanyangserver/video/repository/VideoRepositoryImpl.java +++ b/src/main/java/org/ioteatime/meonghanyangserver/video/repository/VideoRepositoryImpl.java @@ -1,6 +1,11 @@ package org.ioteatime.meonghanyangserver.video.repository; +import static org.ioteatime.meonghanyangserver.video.domain.QVideoEntity.videoEntity; + import com.querydsl.jpa.impl.JPAQueryFactory; +import java.time.LocalDate; +import java.time.LocalTime; +import java.util.List; import java.util.Optional; import lombok.RequiredArgsConstructor; import org.ioteatime.meonghanyangserver.video.domain.VideoEntity; @@ -21,4 +26,20 @@ public Optional findById(Long videoId) { public void deleteAllByGroupId(Long groupId) { jpaVideoRepository.deleteAllByGroupId(groupId); } + + @Override + public List findByGroupIdAndCreatedAtContains(Long groupId, LocalDate date) { + return jpaQueryFactory + .select(videoEntity) + .from(videoEntity) + .where( + videoEntity + .group + .id + .eq(groupId) + .and( + videoEntity.createdAt.between( + date.atStartOfDay(), date.atTime(LocalTime.MAX)))) + .fetch(); + } } diff --git a/src/main/java/org/ioteatime/meonghanyangserver/video/service/VideoService.java b/src/main/java/org/ioteatime/meonghanyangserver/video/service/VideoService.java index 140d97a0..319d4bf9 100644 --- a/src/main/java/org/ioteatime/meonghanyangserver/video/service/VideoService.java +++ b/src/main/java/org/ioteatime/meonghanyangserver/video/service/VideoService.java @@ -1,6 +1,8 @@ package org.ioteatime.meonghanyangserver.video.service; import com.amazonaws.HttpMethod; +import java.time.LocalDate; +import java.util.List; import lombok.RequiredArgsConstructor; import org.ioteatime.meonghanyangserver.clients.s3.S3Client; import org.ioteatime.meonghanyangserver.common.exception.NotFoundException; @@ -8,6 +10,8 @@ import org.ioteatime.meonghanyangserver.common.type.VideoErrorType; import org.ioteatime.meonghanyangserver.groupmember.repository.GroupMemberRepository; import org.ioteatime.meonghanyangserver.video.domain.VideoEntity; +import org.ioteatime.meonghanyangserver.video.dto.response.VideoInfoListResponse; +import org.ioteatime.meonghanyangserver.video.dto.response.VideoInfoResponse; import org.ioteatime.meonghanyangserver.video.dto.response.VideoPresignedUrlResponse; import org.ioteatime.meonghanyangserver.video.mapper.VideoResponseMapper; import org.ioteatime.meonghanyangserver.video.repository.VideoRepository; @@ -30,7 +34,29 @@ public VideoPresignedUrlResponse getVideoPresignedUrl( .findById(videoId) .orElseThrow(() -> new NotFoundException(VideoErrorType.VIDEO_NOT_FOUND)); String presignedURL = - s3Client.generatePreSignUrl(videoEntity.getVideoName(), HttpMethod.GET); + s3Client.generatePreSignUrl(videoEntity.getVideoPath(), HttpMethod.GET); return VideoResponseMapper.form(presignedURL); } + + public VideoInfoListResponse searchToDate(Long memberId, Long groupId, LocalDate date) { + if (!groupMemberRepository.existsByMemberIdAndGroupId(memberId, groupId)) { + throw new NotFoundException(GroupErrorType.GROUP_MEMBER_NOT_FOUND); + } + + List videoEntityList = + videoRepository.findByGroupIdAndCreatedAtContains(groupId, date); + + List videoInfoResponseList = + videoEntityList.stream() + .map( + it -> { + String presignedURL = + s3Client.generatePreSignUrl( + it.getThumbnailPath(), HttpMethod.GET); + return VideoResponseMapper.form(it, presignedURL); + }) + .toList(); + + return VideoInfoListResponse.builder().video(videoInfoResponseList).build(); + } } diff --git a/src/main/java/org/ioteatime/meonghanyangserver/videothumbnail/domain/VideoThumbnailEntity.java b/src/main/java/org/ioteatime/meonghanyangserver/videothumbnail/domain/VideoThumbnailEntity.java index 29ffa01c..cbf54dd7 100644 --- a/src/main/java/org/ioteatime/meonghanyangserver/videothumbnail/domain/VideoThumbnailEntity.java +++ b/src/main/java/org/ioteatime/meonghanyangserver/videothumbnail/domain/VideoThumbnailEntity.java @@ -1,11 +1,10 @@ package org.ioteatime.meonghanyangserver.videothumbnail.domain; import jakarta.persistence.*; +import java.time.LocalDateTime; import lombok.Data; import org.ioteatime.meonghanyangserver.video.domain.VideoEntity; -import java.time.LocalDateTime; - @Data @Entity @Table(name = "video_thumbnail") diff --git a/src/main/java/org/ioteatime/meonghanyangserver/videothumbnail/repository/JpaVideoThumbnailRepository.java b/src/main/java/org/ioteatime/meonghanyangserver/videothumbnail/repository/JpaVideoThumbnailRepository.java index 5e50d8fe..b16bf74a 100644 --- a/src/main/java/org/ioteatime/meonghanyangserver/videothumbnail/repository/JpaVideoThumbnailRepository.java +++ b/src/main/java/org/ioteatime/meonghanyangserver/videothumbnail/repository/JpaVideoThumbnailRepository.java @@ -1,4 +1,3 @@ package org.ioteatime.meonghanyangserver.videothumbnail.repository; -public interface JpaVideoThumbnailRepository { -} +public interface JpaVideoThumbnailRepository {} diff --git a/src/main/java/org/ioteatime/meonghanyangserver/videothumbnail/repository/VideoThumbnailRepository.java b/src/main/java/org/ioteatime/meonghanyangserver/videothumbnail/repository/VideoThumbnailRepository.java index c38f5c31..b03582e1 100644 --- a/src/main/java/org/ioteatime/meonghanyangserver/videothumbnail/repository/VideoThumbnailRepository.java +++ b/src/main/java/org/ioteatime/meonghanyangserver/videothumbnail/repository/VideoThumbnailRepository.java @@ -3,5 +3,4 @@ import org.ioteatime.meonghanyangserver.videothumbnail.domain.VideoThumbnailEntity; import org.springframework.data.jpa.repository.JpaRepository; -public interface VideoThumbnailRepository extends JpaRepository { -} +public interface VideoThumbnailRepository extends JpaRepository {} diff --git a/src/main/java/org/ioteatime/meonghanyangserver/videothumbnail/repository/VideoThumbnailRepositoryImpl.java b/src/main/java/org/ioteatime/meonghanyangserver/videothumbnail/repository/VideoThumbnailRepositoryImpl.java index 2d8f59c9..95f3f640 100644 --- a/src/main/java/org/ioteatime/meonghanyangserver/videothumbnail/repository/VideoThumbnailRepositoryImpl.java +++ b/src/main/java/org/ioteatime/meonghanyangserver/videothumbnail/repository/VideoThumbnailRepositoryImpl.java @@ -1,4 +1,3 @@ package org.ioteatime.meonghanyangserver.videothumbnail.repository; -public class VideoThumbnailRepositoryImpl implements JpaVideoThumbnailRepository{ -} +public class VideoThumbnailRepositoryImpl implements JpaVideoThumbnailRepository {}