From 3a4522a027aeb0cd8cebb0429be04fb7a26966aa Mon Sep 17 00:00:00 2001 From: YunJaeHoon Date: Sun, 5 Jan 2025 20:40:12 +0900 Subject: [PATCH] =?UTF-8?q?FIX:=20=EA=B0=95=EC=9D=98=20=EC=8B=9C=EA=B0=84?= =?UTF-8?q?=20=EB=B0=8F=20=EC=9E=A5=EC=86=8C=20=EC=97=94=ED=8B=B0=ED=8B=B0?= =?UTF-8?q?=20=EB=B6=84=EB=A6=AC=EC=97=90=20=EB=94=B0=EB=A5=B8=20api=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Devkor_project/dto/CommentDto.java | 56 ++++++++--- .../example/Devkor_project/dto/CourseDto.java | 94 +++++++++++++++---- .../example/Devkor_project/entity/Course.java | 1 - .../repository/TimeLocationRepository.java | 10 +- .../Devkor_project/service/AdminService.java | 81 +++++++++++++++- .../Devkor_project/service/CourseService.java | 36 +++++-- .../Devkor_project/service/MyPageService.java | 7 +- 7 files changed, 239 insertions(+), 46 deletions(-) diff --git a/src/main/java/com/example/Devkor_project/dto/CommentDto.java b/src/main/java/com/example/Devkor_project/dto/CommentDto.java index 7bce420..5bc9267 100644 --- a/src/main/java/com/example/Devkor_project/dto/CommentDto.java +++ b/src/main/java/com/example/Devkor_project/dto/CommentDto.java @@ -1,15 +1,13 @@ package com.example.Devkor_project.dto; -import com.example.Devkor_project.entity.Comment; -import com.example.Devkor_project.entity.CommentRating; -import com.example.Devkor_project.entity.Course; -import com.example.Devkor_project.entity.CourseRating; +import com.example.Devkor_project.entity.*; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import lombok.*; import java.time.LocalDate; +import java.util.List; public class CommentDto { @@ -268,7 +266,7 @@ public static class StartUpdate @Schema(description = "학점") private String credit; @Schema(description = "시간, 장소") - private String time_location; + private List time_locations; @NotNull(message = "COUNT_comments는 null일 수 없습니다.") @Schema(description = "강의평 개수") private int COUNT_comments; @@ -566,7 +564,7 @@ public static class MyPage @Schema(description = "학점") private String credit; @Schema(description = "시간, 장소") - private String time_location; + private List time_locations; @NotBlank(message = "[review] cannot be blank.") @Schema(description = "강의평 내용") @@ -629,10 +627,13 @@ public static class MyPage private boolean learn_t4_industry; } - public static CommentDto.StartUpdate entityToStartUpdate(Course course, - CourseRating courseRating, - com.example.Devkor_project.entity.Comment comment, - CommentRating commentRating) + public static CommentDto.StartUpdate entityToStartUpdate( + Course course, + CourseRating courseRating, + com.example.Devkor_project.entity.Comment comment, + CommentRating commentRating, + List timeLocations + ) { return StartUpdate.builder() .course_id(course.getCourse_id()) @@ -645,7 +646,18 @@ public static CommentDto.StartUpdate entityToStartUpdate(Course course, .name(course.getName()) .professor(course.getProfessor()) .credit(course.getCredit()) - .time_location(course.getTime_location()) + .time_locations( + timeLocations.stream().map( + timeLocation -> { + return CourseDto.TimeLocation.builder() + .day(timeLocation.getDay()) + .startPeriod(timeLocation.getStartPeriod()) + .endPeriod(timeLocation.getEndPeriod()) + .location(timeLocation.getLocation()) + .build(); + }) + .toList() + ) .COUNT_comments(course.getCOUNT_comments()) .AVG_rating(courseRating.getAVG_rating()) .AVG_r1_amount_of_studying(courseRating.getAVG_r1_amount_of_studying()) @@ -680,9 +692,12 @@ public static CommentDto.StartUpdate entityToStartUpdate(Course course, .build(); } - public static CommentDto.MyPage entityToMyPage(com.example.Devkor_project.entity.Comment comment, - Course course, - CommentRating commentRating) + public static CommentDto.MyPage entityToMyPage( + com.example.Devkor_project.entity.Comment comment, + Course course, + CommentRating commentRating, + List timeLocations + ) { return MyPage.builder() .comment_id(comment.getComment_id()) @@ -696,7 +711,18 @@ public static CommentDto.MyPage entityToMyPage(com.example.Devkor_project.entity .name(course.getName()) .professor(course.getProfessor()) .credit(course.getCredit()) - .time_location(course.getTime_location()) + .time_locations( + timeLocations.stream().map( + timeLocation -> { + return CourseDto.TimeLocation.builder() + .day(timeLocation.getDay()) + .startPeriod(timeLocation.getStartPeriod()) + .endPeriod(timeLocation.getEndPeriod()) + .location(timeLocation.getLocation()) + .build(); + }) + .toList() + ) .review(comment.getReview()) .likes(comment.getLikes()) .created_at(comment.getCreated_at()) diff --git a/src/main/java/com/example/Devkor_project/dto/CourseDto.java b/src/main/java/com/example/Devkor_project/dto/CourseDto.java index b8da0a7..3d8198a 100644 --- a/src/main/java/com/example/Devkor_project/dto/CourseDto.java +++ b/src/main/java/com/example/Devkor_project/dto/CourseDto.java @@ -2,6 +2,7 @@ import com.example.Devkor_project.entity.Course; import com.example.Devkor_project.entity.CourseRating; +import com.example.Devkor_project.entity.TimeLocation; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.Email; import jakarta.validation.constraints.NotBlank; @@ -49,7 +50,7 @@ public static class Basic @Schema(description = "학점") private String credit; @Schema(description = "시간, 장소") - private String time_location; + private List time_locations; @NotNull(message = "COUNT_comments는 null일 수 없습니다.") @Schema(description = "강의평 개수") private int COUNT_comments; @@ -138,7 +139,7 @@ public static class ExpiredBasic @Schema(description = "학점") private String credit; @Schema(description = "시간, 장소") - private String time_location; + private List time_locations; @NotNull(message = "COUNT_comments는 null일 수 없습니다.") @Schema(description = "강의평 개수") private int COUNT_comments; @@ -183,7 +184,7 @@ public static class Detail @Schema(description = "학점") private String credit; @Schema(description = "시간, 장소") - private String time_location; + private List time_locations; @NotNull(message = "COUNT_comments는 null일 수 없습니다.") @Schema(description = "강의평 개수") private int COUNT_comments; @@ -275,7 +276,7 @@ public static class ExpiredDetail @Schema(description = "학점") private String credit; @Schema(description = "시간, 장소") - private String time_location; + private List time_locations; @NotNull(message = "COUNT_comments는 null일 수 없습니다.") @Schema(description = "강의평 개수") private int COUNT_comments; @@ -324,7 +325,13 @@ public static class TimeLocation private String location; } - public static CourseDto.Basic entityToBasic(Course course, CourseRating courseRating, Boolean isBookmark) { + public static CourseDto.Basic entityToBasic( + Course course, + CourseRating courseRating, + List timeLocations, + Boolean isBookmark + ) + { return Basic.builder() .course_id(course.getCourse_id()) .course_code(course.getCourse_code()) @@ -336,7 +343,18 @@ public static CourseDto.Basic entityToBasic(Course course, CourseRating courseRa .name(course.getName()) .professor(course.getProfessor()) .credit(course.getCredit()) - .time_location(course.getTime_location()) + .time_locations( + timeLocations.stream().map( + timeLocation -> { + return CourseDto.TimeLocation.builder() + .day(timeLocation.getDay()) + .startPeriod(timeLocation.getStartPeriod()) + .endPeriod(timeLocation.getEndPeriod()) + .location(timeLocation.getLocation()) + .build(); + }) + .toList() + ) .COUNT_comments(course.getCOUNT_comments()) .isBookmark(isBookmark) .AVG_rating(courseRating.getAVG_rating()) @@ -356,7 +374,12 @@ public static CourseDto.Basic entityToBasic(Course course, CourseRating courseRa .build(); } - public static CourseDto.ExpiredBasic entityToExpiredBasic(Course course, Boolean isBookmark) { + public static CourseDto.ExpiredBasic entityToExpiredBasic( + Course course, + List timeLocations, + Boolean isBookmark + ) + { return ExpiredBasic.builder() .course_id(course.getCourse_id()) .course_code(course.getCourse_code()) @@ -368,16 +391,30 @@ public static CourseDto.ExpiredBasic entityToExpiredBasic(Course course, Boolean .name(course.getName()) .professor(course.getProfessor()) .credit(course.getCredit()) - .time_location(course.getTime_location()) + .time_locations( + timeLocations.stream().map( + timeLocation -> { + return CourseDto.TimeLocation.builder() + .day(timeLocation.getDay()) + .startPeriod(timeLocation.getStartPeriod()) + .endPeriod(timeLocation.getEndPeriod()) + .location(timeLocation.getLocation()) + .build(); + }) + .toList() + ) .COUNT_comments(course.getCOUNT_comments()) .isBookmark(isBookmark) .build(); } - public static CourseDto.Detail entityToDetail(Course course, - CourseRating courseRating, - List commentDtos, - Boolean isBookmark) + public static CourseDto.Detail entityToDetail( + Course course, + CourseRating courseRating, + List commentDtos, + List timeLocations, + Boolean isBookmark + ) { return Detail.builder() .course_id(course.getCourse_id()) @@ -390,7 +427,18 @@ public static CourseDto.Detail entityToDetail(Course course, .name(course.getName()) .professor(course.getProfessor()) .credit(course.getCredit()) - .time_location(course.getTime_location()) + .time_locations( + timeLocations.stream().map( + timeLocation -> { + return CourseDto.TimeLocation.builder() + .day(timeLocation.getDay()) + .startPeriod(timeLocation.getStartPeriod()) + .endPeriod(timeLocation.getEndPeriod()) + .location(timeLocation.getLocation()) + .build(); + }) + .toList() + ) .COUNT_comments(course.getCOUNT_comments()) .isBookmark(isBookmark) .AVG_rating(courseRating.getAVG_rating()) @@ -411,8 +459,11 @@ public static CourseDto.Detail entityToDetail(Course course, .build(); } - public static CourseDto.ExpiredDetail entityToExpiredDetail(Course course, - Boolean isBookmark) + public static CourseDto.ExpiredDetail entityToExpiredDetail( + Course course, + List timeLocations, + Boolean isBookmark + ) { return ExpiredDetail.builder() .course_id(course.getCourse_id()) @@ -425,7 +476,18 @@ public static CourseDto.ExpiredDetail entityToExpiredDetail(Course course, .name(course.getName()) .professor(course.getProfessor()) .credit(course.getCredit()) - .time_location(course.getTime_location()) + .time_locations( + timeLocations.stream().map( + timeLocation -> { + return CourseDto.TimeLocation.builder() + .day(timeLocation.getDay()) + .startPeriod(timeLocation.getStartPeriod()) + .endPeriod(timeLocation.getEndPeriod()) + .location(timeLocation.getLocation()) + .build(); + }) + .toList() + ) .COUNT_comments(course.getCOUNT_comments()) .isBookmark(isBookmark) .build(); diff --git a/src/main/java/com/example/Devkor_project/entity/Course.java b/src/main/java/com/example/Devkor_project/entity/Course.java index dd730ef..73f1e81 100644 --- a/src/main/java/com/example/Devkor_project/entity/Course.java +++ b/src/main/java/com/example/Devkor_project/entity/Course.java @@ -35,6 +35,5 @@ public class Course @Column(nullable = false) private String year; @Column(nullable = false) private String semester; @Column private String credit; - @Column private String time_location; @Column(nullable = false) private int COUNT_comments; } diff --git a/src/main/java/com/example/Devkor_project/repository/TimeLocationRepository.java b/src/main/java/com/example/Devkor_project/repository/TimeLocationRepository.java index 3c3e04d..4440ad2 100644 --- a/src/main/java/com/example/Devkor_project/repository/TimeLocationRepository.java +++ b/src/main/java/com/example/Devkor_project/repository/TimeLocationRepository.java @@ -1,7 +1,15 @@ package com.example.Devkor_project.repository; +import com.example.Devkor_project.entity.Course; import com.example.Devkor_project.entity.TimeLocation; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; -public interface TimeLocationRepository extends JpaRepository { +import java.util.List; + +public interface TimeLocationRepository extends JpaRepository +{ + @Query(value = "SELECT * FROM time_location WHERE course_id = :course_id", nativeQuery = true) + List findByCourseId(Long course_id); } diff --git a/src/main/java/com/example/Devkor_project/service/AdminService.java b/src/main/java/com/example/Devkor_project/service/AdminService.java index d6a1975..b466b0e 100644 --- a/src/main/java/com/example/Devkor_project/service/AdminService.java +++ b/src/main/java/com/example/Devkor_project/service/AdminService.java @@ -182,11 +182,25 @@ public CourseDto.CheckSynchronization checkCourseSynchronization(CrawlingDto.Syn .year(course.getYear()) .semester(course.getTerm()) .credit(credit) - .time_location(time_location) .COUNT_comments(0) .build(); courseRepository.save(newCourse); + + // 강의 시간 및 장소 데이터 추가 + List timeLocations = parseTimeLocation(time_location); + if (timeLocations != null && !timeLocations.isEmpty()) { + for (CourseDto.TimeLocation timeLocationDto : timeLocations) { + TimeLocation timeLocation = TimeLocation.builder() + .course_id(newCourse) + .day(timeLocationDto.getDay()) + .startPeriod(timeLocationDto.getStartPeriod()) + .endPeriod(timeLocationDto.getEndPeriod()) + .location(timeLocationDto.getLocation()) + .build(); + timeLocationRepository.save(timeLocation); + } + } } else { @@ -214,8 +228,69 @@ public CourseDto.CheckSynchronization checkCourseSynchronization(CrawlingDto.Syn courseInDatabase.setCredit(course.getTime().isEmpty() ? null : course.getTime().replaceAll("\\(.*?\\)", "")); isUpdate = true; } - if(!Objects.equals(courseInDatabase.getTime_location(), course.getTime_room().isEmpty() ? null : course.getTime_room().replaceAll("<.*?>", ""))) { - courseInDatabase.setTime_location(course.getTime_room().isEmpty() ? null : course.getTime_room().replaceAll("<.*?>", "")); + + // 실제 강의 시간 및 장소 정보 + List realTimeLocations = parseTimeLocation(course.getTime_room().replaceAll("<.*?>", "")); + // 현재 데이터베이스에 저장되어 있는 강의 시간 및 장소 정보 + List savedTimeLocations = timeLocationRepository.findByCourseId(courseInDatabase.getCourse_id()); + boolean timeLocationIsDifferent = false; + + // 실제 강의 시간 및 장소 정보와 현재 데이터베이스에 저장되어 있는 강의 시간 및 장소 정보가 동일한지 확인 + if(realTimeLocations == null && savedTimeLocations == null) + timeLocationIsDifferent = false; + else if(realTimeLocations != null && savedTimeLocations == null) + timeLocationIsDifferent = true; + else if(realTimeLocations == null) + timeLocationIsDifferent = true; + else if(realTimeLocations.size() != savedTimeLocations.size()) + timeLocationIsDifferent = true; + else + { + for(CourseDto.TimeLocation realTimeLocation : realTimeLocations) + { + boolean isDifferent = true; + + for(TimeLocation savedTimeLocation : savedTimeLocations) + { + if(Objects.equals(savedTimeLocation.getDay(), realTimeLocation.getDay()) && + Objects.equals(savedTimeLocation.getStartPeriod(), realTimeLocation.getStartPeriod()) && + Objects.equals(savedTimeLocation.getEndPeriod(), realTimeLocation.getEndPeriod()) && + Objects.equals(savedTimeLocation.getLocation(), realTimeLocation.getLocation())) + { + isDifferent = false; + break; + } + } + + if(isDifferent) + { + timeLocationIsDifferent = true; + break; + } + } + } + + // 실제 강의 시간 및 장소 정보와 현재 데이터베이스에 저장되어 있는 강의 시간 및 장소 정보가 다를 때 + // 현재 데이터베이스에 저장되어 있는 강의 시간 및 장소 정보를 전부 삭제 + // 그 후, 실제 강의 시간 및 장소 정보를 저장 + if(timeLocationIsDifferent) + { + if(savedTimeLocations != null) + timeLocationRepository.deleteAll(savedTimeLocations); + + if(realTimeLocations != null) { + for (CourseDto.TimeLocation timeLocationDto : realTimeLocations) { + TimeLocation timeLocation = TimeLocation.builder() + .course_id(courseInDatabase) + .day(timeLocationDto.getDay()) + .startPeriod(timeLocationDto.getStartPeriod()) + .endPeriod(timeLocationDto.getEndPeriod()) + .location(timeLocationDto.getLocation()) + .build(); + timeLocationRepository.save(timeLocation); + } + } + isUpdate = true; } diff --git a/src/main/java/com/example/Devkor_project/service/CourseService.java b/src/main/java/com/example/Devkor_project/service/CourseService.java index 812f835..47cc5ec 100644 --- a/src/main/java/com/example/Devkor_project/service/CourseService.java +++ b/src/main/java/com/example/Devkor_project/service/CourseService.java @@ -32,6 +32,7 @@ public class CourseService private final CommentRatingRepository commentRatingRepository; private final CommentLikeRepository commentLikeRepository; private final CommentReportRepository commentReportRepository; + private final TimeLocationRepository timeLocationRepository; /* 강의 검색 서비스 */ public List searchCourse(String keyword, String order, int page, Principal principal) @@ -65,7 +66,11 @@ else if(order.equals("RATING_ASC")) // Course 엔티티 리스트 -> courseDto.ExpiredBasic 리스트 List courseDtos = courses.stream() .map(course -> { - return CourseDto.entityToExpiredBasic(course, false); + + // 강의 시간 및 장소 정보 + List timeLocations = timeLocationRepository.findByCourseId(course.getCourse_id()); + + return CourseDto.entityToExpiredBasic(course, timeLocations, false); }) .toList(); @@ -90,10 +95,13 @@ else if(order.equals("RATING_ASC")) // 해당 강의의 평점 데이터 CourseRating courseRating = course.getCourseRating_id(); + // 강의 시간 및 장소 정보 + List timeLocations = timeLocationRepository.findByCourseId(course.getCourse_id()); + // 사용자의 해당 강의 북마크 여부 boolean isBookmark = !bookmarkRepository.searchBookmark(profile_id, course.getCourse_id()).isEmpty(); - return CourseDto.entityToBasic(course, courseRating, isBookmark); + return CourseDto.entityToBasic(course, courseRating, timeLocations, isBookmark); }) .toList(); @@ -105,10 +113,13 @@ else if(order.equals("RATING_ASC")) List courseDtos = courses.stream() .map(course -> { + // 강의 시간 및 장소 정보 + List timeLocations = timeLocationRepository.findByCourseId(course.getCourse_id()); + // 사용자의 해당 강의 북마크 여부 boolean isBookmark = !bookmarkRepository.searchBookmark(profile_id, course.getCourse_id()).isEmpty(); - return CourseDto.entityToExpiredBasic(course, isBookmark); + return CourseDto.entityToExpiredBasic(course, timeLocations, isBookmark); }) .toList(); @@ -141,11 +152,14 @@ public Object courseDetail(Long course_id, String order, int page, Principal pri Course course = courseRepository.findById(course_id) .orElseThrow(() -> new AppException(ErrorCode.COURSE_NOT_FOUND, course_id)); + // 강의 시간 및 장소 정보 + List timeLocations = timeLocationRepository.findByCourseId(course.getCourse_id()); + // 비로그인 시, 평점 데이터와 강의평 리스트를 전달하지 않으며, 북마크 여부가 항상 false if(principal == null) { // CourseDto.ExpiredDetail 반환 - return CourseDto.entityToExpiredDetail(course, false); + return CourseDto.entityToExpiredDetail(course, timeLocations, false); } else { @@ -228,7 +242,7 @@ else if(order.equals("LIKES_ASC")) boolean isBookmark = !bookmarkRepository.searchBookmark(principalProfile_id, course.getCourse_id()).isEmpty(); // course 엔티티와 강의평 dto 리스트로 CourseDto.Detail 만들어서 반환 - return CourseDto.entityToDetail(course, courseRating, commentDtos, isBookmark); + return CourseDto.entityToDetail(course, courseRating, commentDtos, timeLocations, isBookmark); } else { @@ -236,7 +250,7 @@ else if(order.equals("LIKES_ASC")) boolean isBookmark = !bookmarkRepository.searchBookmark(principalProfile_id, course.getCourse_id()).isEmpty(); // CourseDto.ExpiredDetail 반환 - return CourseDto.entityToExpiredDetail(course, isBookmark); + return CourseDto.entityToExpiredDetail(course, timeLocations, isBookmark); } } } @@ -289,6 +303,9 @@ public CourseDto.Basic startInsertComment(Principal principal, Long course_id) Course course = courseRepository.findById(course_id) .orElseThrow(() -> new AppException(ErrorCode.COURSE_NOT_FOUND, course_id)); + // 강의 시간 및 장소 정보 + List timeLocations = timeLocationRepository.findByCourseId(course.getCourse_id()); + // 해당 사용자가 이미 해당 강의에 강의평을 달았다면, 예외 처리 List comment = commentRepository.searchComment(profile.getProfile_id(), course_id); if(!comment.isEmpty()) @@ -300,7 +317,7 @@ public CourseDto.Basic startInsertComment(Principal principal, Long course_id) // 사용자의 해당 강의 북마크 여부 boolean isBookmark = !bookmarkRepository.searchBookmark(profile.getProfile_id(), course.getCourse_id()).isEmpty(); - return CourseDto.entityToBasic(course, courseRating, isBookmark); + return CourseDto.entityToBasic(course, courseRating, timeLocations, isBookmark); } /* 강의평 작성 완료 및 등록 서비스 */ @@ -428,13 +445,16 @@ public CommentDto.StartUpdate startUpdateComment(Principal principal, Long comme // 강의 평점 정보 CourseRating courseRating = course.getCourseRating_id(); + // 강의 시간 및 장소 정보 + List timeLocations = timeLocationRepository.findByCourseId(course.getCourse_id()); + // 해당 강의평이 해당 사용자가 작성한 강의평이 아니라면, 예외 처리 if(!Objects.equals(comment.getProfile_id().getProfile_id(), profile.getProfile_id())) throw new AppException(ErrorCode.NOT_COMMENT_BY_USER, null); CommentRating commentRating = comment.getCommentRating_id(); - return CommentDto.entityToStartUpdate(course, courseRating, comment, commentRating); + return CommentDto.entityToStartUpdate(course, courseRating, comment, commentRating, timeLocations); } /* 강의평 수정 완료 서비스 */ diff --git a/src/main/java/com/example/Devkor_project/service/MyPageService.java b/src/main/java/com/example/Devkor_project/service/MyPageService.java index 9be185e..3d91b3f 100644 --- a/src/main/java/com/example/Devkor_project/service/MyPageService.java +++ b/src/main/java/com/example/Devkor_project/service/MyPageService.java @@ -31,6 +31,7 @@ public class MyPageService private final CommentRepository commentRepository; private final CourseRatingRepository courseRatingRepository; private final CommentRatingRepository commentRatingRepository; + private final TimeLocationRepository timeLocationRepository; private final BCryptPasswordEncoder encoder; /* 마이페이지 기본 정보 서비스 */ @@ -142,8 +143,9 @@ public List myComments(Principal principal, int page) Course course = comment.getCourse_id(); // 강의 정보 CommentRating commentRating = comment.getCommentRating_id(); // 강의평 평점 정보 + List timeLocations = timeLocationRepository.findByCourseId(course.getCourse_id()); // 강의 시간 및 장소 정보 - return CommentDto.entityToMyPage(comment, course, commentRating); + return CommentDto.entityToMyPage(comment, course, commentRating, timeLocations); }) .toList(); @@ -191,11 +193,12 @@ public List myBookmarks(Principal principal, int page) Course course = bookmark.getCourse_id(); // 강의 정보 CourseRating courseRating = course.getCourseRating_id(); // 강의 평점 정보 + List timeLocations = timeLocationRepository.findByCourseId(course.getCourse_id()); // 강의 시간 및 장소 정보 // 사용자의 해당 강의 북마크 여부 boolean isBookmark = !bookmarkRepository.searchBookmark(profile.getProfile_id(), course.getCourse_id()).isEmpty(); - return CourseDto.entityToBasic(course, courseRating, isBookmark); + return CourseDto.entityToBasic(course, courseRating, timeLocations, isBookmark); }) .toList();