Skip to content

Commit 89bd976

Browse files
authored
Merge pull request #244 from DevKor-github/feat/course
강의실별 강의 정보 조회 기능
2 parents 800e491 + f57c31b commit 89bd976

18 files changed

Lines changed: 425 additions & 2 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package devkor.com.teamcback.domain.common.entity;
2+
3+
public enum Weekday {
4+
MON, TUE, WED, THU, FRI, SAT, SUN
5+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package devkor.com.teamcback.domain.course.controller;
2+
3+
import devkor.com.teamcback.domain.course.dto.response.GetCourseListRes;
4+
import devkor.com.teamcback.domain.course.service.CourseService;
5+
import devkor.com.teamcback.domain.place.dto.response.GetPlaceListRes;
6+
import devkor.com.teamcback.global.response.CommonResponse;
7+
import io.swagger.v3.oas.annotations.Operation;
8+
import io.swagger.v3.oas.annotations.Parameter;
9+
import io.swagger.v3.oas.annotations.media.Content;
10+
import io.swagger.v3.oas.annotations.media.Schema;
11+
import io.swagger.v3.oas.annotations.responses.ApiResponse;
12+
import io.swagger.v3.oas.annotations.responses.ApiResponses;
13+
import lombok.RequiredArgsConstructor;
14+
import org.springframework.web.bind.annotation.*;
15+
16+
@RestController
17+
@RequiredArgsConstructor
18+
@RequestMapping("/api/places")
19+
public class CourseController {
20+
private final CourseService courseService;
21+
22+
@GetMapping("/{placeId}/courses")
23+
@Operation(summary = "장소 id로 강의 리스트 검색",
24+
description = "강의 list 반환")
25+
@ApiResponses(value = {
26+
@ApiResponse(responseCode = "200", description = "정상 처리 되었습니다."),
27+
@ApiResponse(responseCode = "404", description = "장소를 찾을 수 없습니다.",
28+
content = @Content(schema = @Schema(implementation = CommonResponse.class))),
29+
@ApiResponse(responseCode = "401", description = "권한이 없습니다.",
30+
content = @Content(schema = @Schema(implementation = CommonResponse.class))),
31+
})
32+
public CommonResponse<GetCourseListRes> getCourseList(@Parameter(name = "placeId", description = "장소 ID", example = "4424", required = true) @PathVariable Long placeId) {
33+
return CommonResponse.success(courseService.getCourseList(placeId));
34+
}
35+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package devkor.com.teamcback.domain.course.dto.response;
2+
3+
import devkor.com.teamcback.domain.common.entity.Weekday;
4+
import io.swagger.v3.oas.annotations.media.Schema;
5+
import lombok.Getter;
6+
7+
import java.util.List;
8+
import java.util.Map;
9+
10+
@Schema(description = "강의 List 조회 응답 dto")
11+
@Getter
12+
public class GetCourseListRes {
13+
private Long placeId;
14+
private String placeName;
15+
private Map<Weekday, List<GetCourseRes>> courses;
16+
17+
public GetCourseListRes(Long placeId, String placeName, Map<Weekday, List<GetCourseRes>> courses) {
18+
this.placeId = placeId;
19+
this.placeName = placeName;
20+
this.courses = courses;
21+
}
22+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package devkor.com.teamcback.domain.course.dto.response;
2+
3+
import devkor.com.teamcback.domain.course.entity.Course;
4+
import io.swagger.v3.oas.annotations.media.Schema;
5+
import lombok.Getter;
6+
7+
@Schema(description = "강의 응답 dto")
8+
@Getter
9+
public class GetCourseRes {
10+
private Long courseId;
11+
private int year;
12+
private String term;
13+
private String subject;
14+
private int unit;
15+
private String code;
16+
private String section;
17+
private String type;
18+
private String department;
19+
private String professor;
20+
private String weekday;
21+
private int classTime;
22+
23+
public GetCourseRes(Course course, String weekday, int classTime) {
24+
this.courseId = course.getId();
25+
this.year = course.getYear();
26+
this.term = course.getTerm().toString();
27+
this.subject = course.getSubject();
28+
this.unit = course.getUnit();
29+
this.code = course.getCode();
30+
this.section = course.getSection();
31+
this.type = course.getType();
32+
this.department = course.getDepartment();
33+
this.professor = course.getProfessor();
34+
this.weekday = weekday;
35+
this.classTime = classTime;
36+
}
37+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package devkor.com.teamcback.domain.course.entity;
2+
3+
import devkor.com.teamcback.domain.common.entity.BaseEntity;
4+
import jakarta.persistence.*;
5+
import lombok.Getter;
6+
import lombok.NoArgsConstructor;
7+
8+
@Entity
9+
@Getter
10+
@Table(name = "tb_course")
11+
@NoArgsConstructor
12+
public class Course extends BaseEntity {
13+
@Id
14+
@GeneratedValue(strategy = GenerationType.IDENTITY)
15+
private Long id;
16+
17+
@Column(nullable = false)
18+
private int year;
19+
20+
@Column(nullable = false)
21+
@Enumerated(EnumType.STRING)
22+
private Term term;
23+
24+
@Column(nullable = false)
25+
private String subject;
26+
27+
@Column(nullable = false)
28+
private int unit;
29+
30+
@Column(nullable = false)
31+
private String code;
32+
33+
@Column(nullable = false)
34+
private String section;
35+
36+
@Column(nullable = false)
37+
private String type;
38+
39+
@Column(nullable = false)
40+
private String department;
41+
42+
@Column(nullable = false)
43+
private String professor;
44+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package devkor.com.teamcback.domain.course.entity;
2+
3+
import devkor.com.teamcback.domain.common.entity.BaseEntity;
4+
import devkor.com.teamcback.domain.common.entity.Weekday;
5+
import devkor.com.teamcback.domain.place.entity.Place;
6+
import jakarta.persistence.*;
7+
import lombok.Getter;
8+
import lombok.NoArgsConstructor;
9+
import lombok.Setter;
10+
11+
@Entity
12+
@Getter
13+
@Table(name = "tb_course_detail")
14+
@NoArgsConstructor
15+
public class CourseDetail extends BaseEntity {
16+
@Id
17+
@GeneratedValue(strategy = GenerationType.IDENTITY)
18+
private Long id;
19+
20+
@Column
21+
@Enumerated(EnumType.STRING)
22+
private Weekday weekday;
23+
24+
@Column(nullable = false)
25+
private int start;
26+
27+
@Column(nullable = false)
28+
private int end;
29+
30+
@Column
31+
private String placeName;
32+
33+
@ManyToOne
34+
@JoinColumn(name = "course_id")
35+
private Course course;
36+
37+
@Setter
38+
@OneToOne
39+
@JoinColumn(name = "place_id")
40+
private Place place;
41+
42+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package devkor.com.teamcback.domain.course.entity;
2+
3+
public enum Term {
4+
SPRING, SUMMER, FALL, WINTER
5+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package devkor.com.teamcback.domain.course.repository;
2+
3+
import devkor.com.teamcback.domain.course.entity.CourseDetail;
4+
import org.springframework.data.jpa.repository.JpaRepository;
5+
import org.springframework.data.jpa.repository.Query;
6+
7+
import java.util.List;
8+
9+
public interface CourseDetailRepository extends JpaRepository<CourseDetail, Long> {
10+
@Query(value = "SELECT c FROM CourseDetail c WHERE c.place IS NULL ORDER BY c.id asc LIMIT :count")
11+
List<CourseDetail> findLimitByPlaceIdIsNull(int count);
12+
13+
List<CourseDetail> findByPlaceId(Long placeId);
14+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package devkor.com.teamcback.domain.course.repository;
2+
3+
import devkor.com.teamcback.domain.course.entity.Course;
4+
import org.springframework.data.jpa.repository.JpaRepository;
5+
6+
public interface CourseRepository extends JpaRepository<Course, Long> {
7+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package devkor.com.teamcback.domain.course.scheduler;
2+
3+
import devkor.com.teamcback.domain.common.LocationType;
4+
import devkor.com.teamcback.domain.course.entity.CourseDetail;
5+
import devkor.com.teamcback.domain.course.repository.CourseDetailRepository;
6+
import devkor.com.teamcback.domain.place.entity.Place;
7+
import devkor.com.teamcback.domain.place.repository.PlaceRepository;
8+
import devkor.com.teamcback.domain.search.dto.response.GlobalSearchListRes;
9+
import devkor.com.teamcback.domain.search.service.SearchService;
10+
import devkor.com.teamcback.global.redis.RedisLockUtil;
11+
import lombok.RequiredArgsConstructor;
12+
import lombok.extern.slf4j.Slf4j;
13+
import org.springframework.boot.context.event.ApplicationReadyEvent;
14+
import org.springframework.context.event.EventListener;
15+
import org.springframework.stereotype.Component;
16+
import org.springframework.transaction.annotation.Transactional;
17+
18+
import java.util.List;
19+
20+
@Slf4j(topic = "Course Scheduler")
21+
@Component
22+
@RequiredArgsConstructor
23+
public class CourseScheduler {
24+
private final RedisLockUtil redisLockUtil;
25+
private final CourseDetailRepository courseDetailRepository;
26+
private final PlaceRepository placeRepository;
27+
private final SearchService searchService;
28+
29+
//@EventListener(ApplicationReadyEvent.class)
30+
//@Transactional
31+
public void updateCourseDetails() {
32+
redisLockUtil.executeWithLock("course_lock", 1, 300, () -> {
33+
34+
log.info("강의 장소 업데이트");
35+
36+
List<CourseDetail> courseDetails = courseDetailRepository.findLimitByPlaceIdIsNull(500);
37+
38+
for (CourseDetail courseDetail : courseDetails) {
39+
String placeName = courseDetail.getPlaceName();
40+
if(placeName.equals("장소정보없음")) continue;
41+
42+
GlobalSearchListRes resList = searchService.globalSearch(placeName, null);
43+
44+
if(!resList.getList().isEmpty() && resList.getList().get(0).getLocationType() == LocationType.PLACE) {
45+
Place place = placeRepository.findById(resList.getList().get(0).getId()).orElseThrow();
46+
courseDetail.setPlace(place);
47+
}
48+
49+
}
50+
return null;
51+
});
52+
53+
}
54+
}

0 commit comments

Comments
 (0)