Skip to content

Commit 45371e7

Browse files
authored
Merge pull request #234 from DevKor-github/feat/menu
학식 조회 api 추가
2 parents 5cf14c6 + c39261a commit 45371e7

7 files changed

Lines changed: 121 additions & 8 deletions

File tree

src/main/java/devkor/com/teamcback/domain/operatingtime/service/OperatingService.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ private String findPlaceOperatingTime(Place place, DayOfWeek dayOfWeek) {
146146

147147
// 장소의 운영 시간이 시간 형식이 아니면 건물의 운영 시간을 따라감
148148
if(!isTimeRangePattern(operatingTime)) {
149+
if(place.getBuilding() == null) return DEFAULT_OPERATING_TIME;
149150
operatingTime = place.getBuilding().getOperatingTime();
150151
}
151152

@@ -327,10 +328,10 @@ public void updatePlaceOperatingTime() {
327328
for(Place place : places) {
328329
if(!placesWithCondition.contains(place)) {
329330
// 조건이 없는 장소는 건물의 운영 여부 및 운영 시간과 동일하도록 세팅
330-
place.setSundayOperatingTime(place.getBuilding().getSundayOperatingTime());
331-
place.setSaturdayOperatingTime(place.getBuilding().getSaturdayOperatingTime());
332-
place.setWeekdayOperatingTime(place.getBuilding().getWeekdayOperatingTime());
333-
place.setOperating(place.getBuilding().isOperating());
331+
place.setSundayOperatingTime(place.getBuilding() == null ? DEFAULT_OPERATING_TIME : place.getBuilding().getSundayOperatingTime());
332+
place.setSaturdayOperatingTime(place.getBuilding() == null ? DEFAULT_OPERATING_TIME : place.getBuilding().getSaturdayOperatingTime());
333+
place.setWeekdayOperatingTime(place.getBuilding() == null ? DEFAULT_OPERATING_TIME : place.getBuilding().getWeekdayOperatingTime());
334+
place.setOperating(place.getBuilding() == null ? true : place.getBuilding().isOperating());
334335
}
335336
}
336337
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package devkor.com.teamcback.domain.place.controller;
2+
3+
import devkor.com.teamcback.domain.place.dto.response.GetCafeteriaMenuListRes;
4+
import devkor.com.teamcback.domain.place.service.CafeteriaMenuService;
5+
import devkor.com.teamcback.global.response.CommonResponse;
6+
import io.swagger.v3.oas.annotations.Operation;
7+
import io.swagger.v3.oas.annotations.Parameter;
8+
import io.swagger.v3.oas.annotations.media.Content;
9+
import io.swagger.v3.oas.annotations.media.Schema;
10+
import io.swagger.v3.oas.annotations.responses.ApiResponse;
11+
import io.swagger.v3.oas.annotations.responses.ApiResponses;
12+
import lombok.RequiredArgsConstructor;
13+
import org.springframework.web.bind.annotation.GetMapping;
14+
import org.springframework.web.bind.annotation.RequestMapping;
15+
import org.springframework.web.bind.annotation.RequestParam;
16+
import org.springframework.web.bind.annotation.RestController;
17+
18+
import java.time.LocalDate;
19+
20+
@RestController
21+
@RequiredArgsConstructor
22+
@RequestMapping("/api/places/cafeterias")
23+
public class CafeteriaMenuController {
24+
25+
private final CafeteriaMenuService cafeteriaMenuService;
26+
27+
@Operation(summary = "건물 id와 날짜로 학식 메뉴 검색",
28+
description = "건물 id와 날짜로 학식 메뉴 검색")
29+
@ApiResponses(value = {
30+
@ApiResponse(responseCode = "200", description = "정상 처리 되었습니다."),
31+
@ApiResponse(responseCode = "401", description = "권한이 없습니다.",
32+
content = @Content(schema = @Schema(implementation = CommonResponse.class))),
33+
})
34+
@GetMapping("/menus")
35+
public CommonResponse<GetCafeteriaMenuListRes> getCafeteriaMenu(
36+
@Parameter(name = "placeId", description = "장소 ID") @RequestParam Long placeId,
37+
@Parameter(name = "startDate", description = "2025-12-25 형식의 요청 시작 날짜") @RequestParam LocalDate startDate,
38+
@Parameter(name = "endDate", description = "2025-12-25 형식의 요청 마지막 날짜") @RequestParam LocalDate endDate) {
39+
40+
return CommonResponse.success(cafeteriaMenuService.getCafeteriaMenu(placeId, startDate, endDate));
41+
}
42+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package devkor.com.teamcback.domain.place.dto.response;
2+
3+
import lombok.Getter;
4+
5+
import java.time.LocalDate;
6+
import java.util.HashMap;
7+
import java.util.Map;
8+
9+
@Getter
10+
public class GetCafeteriaMenuListRes {
11+
private Long placeId;
12+
private String placeName;
13+
private String address;
14+
private String operatingTime;
15+
private String contact;
16+
private Map<LocalDate, Map<String, String>> menus = new HashMap<>();
17+
18+
public GetCafeteriaMenuListRes(Long placeId, String name, String address, String operatingTime, String contact, Map<LocalDate, Map<String, String>> menus) {
19+
this.placeId = placeId;
20+
this.placeName = name;
21+
this.address = address;
22+
this.operatingTime = operatingTime;
23+
this.contact = contact;
24+
this.menus = menus;
25+
}
26+
}

src/main/java/devkor/com/teamcback/domain/place/entity/Place.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ public class Place extends BaseEntity {
7070
@Column(nullable = false)
7171
private Integer starNum = 0;
7272

73+
@Column
74+
private String contact; // 연락처 등
75+
7376
@ManyToOne
7477
@JoinColumn(name = "building_id")
7578
private Building building;

src/main/java/devkor/com/teamcback/domain/place/repository/CafeteriaMenuRepository.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44
import org.springframework.data.jpa.repository.JpaRepository;
55

66
import java.time.LocalDate;
7+
import java.util.List;
78

89
public interface CafeteriaMenuRepository extends JpaRepository<CafeteriaMenu, Long> {
910
CafeteriaMenu findByDateAndKindAndPlaceId(LocalDate date, String kind, Long placeId);
11+
12+
List<CafeteriaMenu> findByDateAndPlaceId(LocalDate date, Long placeId);
1013
}

src/main/java/devkor/com/teamcback/domain/place/scheduler/CafeteriaMenuScheduler.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import devkor.com.teamcback.global.redis.RedisLockUtil;
55
import lombok.RequiredArgsConstructor;
66
import lombok.extern.slf4j.Slf4j;
7+
import org.springframework.boot.context.event.ApplicationReadyEvent;
8+
import org.springframework.context.event.EventListener;
79
import org.springframework.scheduling.annotation.Scheduled;
810
import org.springframework.stereotype.Component;
911

@@ -15,15 +17,15 @@ public class CafeteriaMenuScheduler {
1517
private final CafeteriaMenuService cafeteriaMenuService;
1618
private final RedisLockUtil redisLockUtil;
1719

18-
// @EventListener(ApplicationReadyEvent.class)
20+
// @EventListener(ApplicationReadyEvent.class)
1921
@Scheduled(cron = "0 10 0 * * *") // 매일 자정 10분마다
2022
public void updateMenus() {
2123
redisLockUtil.executeWithLock("menu_lock", 1, 300, () -> {
2224

2325
System.out.println("--- 고려대학교 학식메뉴 스크래핑 시작 ---");
2426

2527
// 수당삼양패컬티하우스 송림
26-
// cafeteriaMenuService.scrapeMenu(503, 3103L);
28+
cafeteriaMenuService.scrapeMenu(503, 9757L);
2729
// 자연계 학생식당
2830
cafeteriaMenuService.scrapeMenu(504, 3103L);
2931
// 자연계 교직원 식당
@@ -35,7 +37,7 @@ public void updateMenus() {
3537
// 교우회관 학생식당
3638
cafeteriaMenuService.scrapeMenu(507, 7705L);
3739
// 학생회관 학생식당
38-
// cafeteriaMenuService.scrapeMenu(508, 3103L);
40+
cafeteriaMenuService.scrapeMenu(508, 9758L);
3941

4042
System.out.println("------------------종료-------------------");
4143
return null;

src/main/java/devkor/com/teamcback/domain/place/service/CafeteriaMenuService.java

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package devkor.com.teamcback.domain.place.service;
22

3+
import devkor.com.teamcback.domain.building.entity.Building;
4+
import devkor.com.teamcback.domain.building.repository.BuildingRepository;
5+
import devkor.com.teamcback.domain.place.dto.response.GetCafeteriaMenuListRes;
36
import devkor.com.teamcback.domain.place.entity.CafeteriaMenu;
47
import devkor.com.teamcback.domain.place.entity.Place;
58
import devkor.com.teamcback.domain.place.repository.CafeteriaMenuRepository;
@@ -17,7 +20,9 @@
1720
import java.time.LocalDate;
1821
import java.time.format.DateTimeFormatter;
1922
import java.util.ArrayList;
23+
import java.util.HashMap;
2024
import java.util.List;
25+
import java.util.Map;
2126
import java.util.regex.Matcher;
2227
import java.util.regex.Pattern;
2328

@@ -36,6 +41,37 @@ public class CafeteriaMenuService {
3641
private final CafeteriaMenuRepository cafeteriaMenuRepository;
3742
private final PlaceRepository placeRepository;
3843

44+
/**
45+
* 학생식당 메뉴 조회
46+
*/
47+
@Transactional(readOnly = true)
48+
public GetCafeteriaMenuListRes getCafeteriaMenu(Long placeId, LocalDate startDate, LocalDate endDate) {
49+
Place place = placeRepository.findById(placeId).orElseThrow(() -> new GlobalException(ResultCode.NOT_FOUND_PLACE));
50+
51+
String address = place.getBuilding() == null ? "" : place.getBuilding().getName() + " ";
52+
address += place.getFloor() < 0 ? "B" : "";
53+
address += (int)Math.abs(place.getFloor()) + "층";
54+
55+
Map<LocalDate, Map<String, String>> menuMap = new HashMap<>();
56+
57+
startDate
58+
.datesUntil(endDate)
59+
.forEach(date -> {
60+
List<CafeteriaMenu> cafeteriaMenuList = cafeteriaMenuRepository.findByDateAndPlaceId(date, placeId);
61+
62+
Map<String, String> menuByKind = new HashMap<>();
63+
for (CafeteriaMenu cafeteriaMenu : cafeteriaMenuList) {
64+
menuByKind.put(cafeteriaMenu.getKind(), cafeteriaMenu.getMenu());
65+
}
66+
67+
menuMap.put(date, menuByKind);
68+
});
69+
70+
GetCafeteriaMenuListRes res = new GetCafeteriaMenuListRes(placeId, place.getName(), address, place.getDetail(), place.getContact(), menuMap);
71+
72+
return res;
73+
}
74+
3975
/**
4076
* 웹 페이지에서 식단 정보를 스크래핑하고 리스트로 반환합니다.
4177
*/
@@ -78,7 +114,7 @@ public void scrapeMenu(int page, Long placeId) {
78114

79115
// 5. 데이터를 날짜-요일 패턴을 기준으로 분리하여 블록화
80116
// 패턴: (YYYY.MM.DD (요일))
81-
Pattern dateDayPattern = Pattern.compile("(\\d{4}\\.\\d{2}\\.\\d{2})\\s*\\(\\s*[월화수목금토일]\\s*\\)\\s*");
117+
Pattern dateDayPattern = Pattern.compile("(\\d{4}\\.\\d{2}\\.\\d{2})\\s*");
82118
Matcher dateDayMatcher = dateDayPattern.matcher(cleanedHtmlContent);
83119

84120
List<String> blocks = new ArrayList<>();

0 commit comments

Comments
 (0)