diff --git a/backend/src/main/java/com/isp/backend/domain/country/controller/CountryController.java b/backend/src/main/java/com/isp/backend/domain/country/controller/CountryController.java index f37df048..67e585dd 100644 --- a/backend/src/main/java/com/isp/backend/domain/country/controller/CountryController.java +++ b/backend/src/main/java/com/isp/backend/domain/country/controller/CountryController.java @@ -5,14 +5,17 @@ import com.isp.backend.domain.country.dto.response.LocationResponse; import com.isp.backend.domain.country.dto.response.WeatherResponse; import com.isp.backend.domain.country.service.CountryService; +import com.isp.backend.domain.country.service.ExchangeRateService; import lombok.RequiredArgsConstructor; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import java.io.IOException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.time.LocalTime; import java.util.List; +import java.util.Map; import java.util.Optional; @RestController @@ -20,8 +23,8 @@ @RequiredArgsConstructor public class CountryController { - @Autowired - private CountryService countryService; + private final CountryService countryService; + private final ExchangeRateService exchangeRateService ; /** 여행지 좌표 찾기 **/ @PostMapping("/locations") @@ -37,7 +40,7 @@ public ResponseEntity findLocation(@RequestBody LocationReques /** 현재 날씨 정보 가져오기 **/ - @GetMapping("/weather/current") + @PostMapping("/weather/current") public ResponseEntity getCurrentWeather(@RequestBody LocationRequest requestDTO) { String city = requestDTO.getCountry(); WeatherResponse weatherResponse = countryService.getCurrentWeather(city); @@ -46,7 +49,7 @@ public ResponseEntity getCurrentWeather(@RequestBody LocationRe /** 한 주 날씨 정보 조회 **/ - @GetMapping("/weather/weekly") + @PostMapping("/weather/weekly") public ResponseEntity> getWeeklyWeather(@RequestBody LocationRequest requestDTO) { String city = requestDTO.getCountry(); LocalTime requestedTime = LocalTime.of(12, 0); @@ -55,5 +58,24 @@ public ResponseEntity> getWeeklyWeather(@RequestBody } + /** 특정 기준 통화에 대한 모든 환율 정보 API **/ +// @GetMapping("/exchange-rates") +// public ResponseEntity getExchangeRates(@RequestParam String baseCurrency) { +// logger.info("Received request for exchange rates with base currency: {}", baseCurrency); +// +// try { +// Map exchangeRates = exchangeRateService.getExchangeRates(baseCurrency); +// return ResponseEntity.ok(exchangeRates); +// } catch (Exception e) { +// logger.error("Error fetching exchange rates", e); +// return ResponseEntity.badRequest().body(Map.of( +// "errorMessage", "환율 정보를 가져오는데 실패했습니다.", +// "httpStatus", "BAD_REQUEST", +// "code", null +// )); +// } +// } + + } \ No newline at end of file diff --git a/backend/src/main/java/com/isp/backend/domain/country/dto/response/DailyWeatherResponse.java b/backend/src/main/java/com/isp/backend/domain/country/dto/response/DailyWeatherResponse.java index 8e373de9..f2e96331 100644 --- a/backend/src/main/java/com/isp/backend/domain/country/dto/response/DailyWeatherResponse.java +++ b/backend/src/main/java/com/isp/backend/domain/country/dto/response/DailyWeatherResponse.java @@ -1,6 +1,5 @@ package com.isp.backend.domain.country.dto.response; -import com.fasterxml.jackson.annotation.JsonProperty; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/backend/src/main/java/com/isp/backend/domain/country/repository/ExchageRateRespository.java b/backend/src/main/java/com/isp/backend/domain/country/repository/ExchageRateRespository.java new file mode 100644 index 00000000..5dab5ba3 --- /dev/null +++ b/backend/src/main/java/com/isp/backend/domain/country/repository/ExchageRateRespository.java @@ -0,0 +1,2 @@ +package com.isp.backend.domain.country.repository;public class ExchageRateRespository { +} diff --git a/backend/src/main/java/com/isp/backend/domain/country/service/CountryService.java b/backend/src/main/java/com/isp/backend/domain/country/service/CountryService.java index 156fc845..ffe467dd 100644 --- a/backend/src/main/java/com/isp/backend/domain/country/service/CountryService.java +++ b/backend/src/main/java/com/isp/backend/domain/country/service/CountryService.java @@ -1,6 +1,5 @@ package com.isp.backend.domain.country.service; - import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.isp.backend.domain.country.dto.response.DailyWeatherResponse; @@ -33,7 +32,7 @@ public class CountryService { private CountryRepository countryRepository; @Value("${api-key.open-weather}") - private String apiKey; + private String weatherApiKey; private final RestTemplate restTemplate = new RestTemplate(); @@ -58,6 +57,7 @@ public Optional findLocationByCity(String city) { } + /** 여행지의 날씨 정보 가져오기 **/ public WeatherResponse getCurrentWeather(String city) { Optional findCountry = findCountryByCity(city); @@ -65,7 +65,7 @@ public WeatherResponse getCurrentWeather(String city) { double latitude = country.getLatitude(); double longitude = country.getLongitude(); - String url = String.format("http://api.openweathermap.org/data/2.5/weather?lat=%f&lon=%f&appid=%s", latitude, longitude, apiKey); + String url = String.format("http://api.openweathermap.org/data/2.5/weather?lat=%f&lon=%f&appid=%s", latitude, longitude, weatherApiKey); String jsonResponse = restTemplate.getForObject(url, String.class); ObjectMapper objectMapper = new ObjectMapper(); @@ -100,7 +100,8 @@ public WeatherResponse getCurrentWeather(String city) { } - /** 한주의 날씨 정보 조회 **/ + + /** 한 주의 날씨 정보 조회 **/ public List getWeeklyWeather(String city, LocalTime requestedTime) { Optional findCountry = findCountryByCity(city); Country country = findCountry.get(); @@ -108,7 +109,7 @@ public List getWeeklyWeather(String city, LocalTime reques double longitude = country.getLongitude(); List weeklyWeather = new ArrayList<>(); - String url = String.format("http://api.openweathermap.org/data/2.5/forecast?lat=%f&lon=%f&appid=%s", latitude, longitude, apiKey); + String url = String.format("http://api.openweathermap.org/data/2.5/forecast?lat=%f&lon=%f&appid=%s", latitude, longitude, weatherApiKey); String jsonResponse = restTemplate.getForObject(url, String.class); try { @@ -116,7 +117,7 @@ public List getWeeklyWeather(String city, LocalTime reques JsonNode rootNode = objectMapper.readTree(jsonResponse); JsonNode forecastList = rootNode.path("list"); - Map> dailyTemperatures = new HashMap<>(); // 각 날짜의 온도 목록을 저장할 맵 + Map dailyWeatherMap = new HashMap<>(); // 각 날짜의 날씨 정보를 저장할 맵 for (JsonNode forecast : forecastList) { String dateTime = forecast.path("dt_txt").asText(); // 예측 시간 정보 @@ -127,29 +128,23 @@ public List getWeeklyWeather(String city, LocalTime reques String dateString = localDateTime.toLocalDate().toString(); double temperature = forecast.path("main").path("temp").asDouble(); // 온도 정보 - // 해당 날짜의 온도 목록에 추가 - dailyTemperatures.computeIfAbsent(dateString, k -> new ArrayList<>()).add(temperature); - } - } - - // 각 날짜의 평균 온도를 계산하여 DailyWeatherResponse 객체로 변환한 후 리스트에 추가 - dailyTemperatures.forEach((dateString, temperatures) -> { - double avgTemperature = temperatures.stream().mapToDouble(Double::doubleValue).average().orElse(0.0); - String temperature = convertToCelsius(avgTemperature); - - // 아이콘 URL 가져오기 - String iconCode = forecastList.get(0).path("weather").get(0).path("icon").asText(); - String iconUrl = String.format(s3ImageService.get(S3BucketDirectory.WEATHER.getDirectory(), iconCode + ".png")); + // 해당 날짜의 온도 정보를 저장 (동일한 시간대에 여러 데이터가 있을 경우, 가장 첫 번째 데이터를 사용) + if (!dailyWeatherMap.containsKey(dateString)) { + // 아이콘 URL 가져오기 + String iconCode = forecast.path("weather").get(0).path("icon").asText(); + String iconUrl = String.format(s3ImageService.get(S3BucketDirectory.WEATHER.getDirectory(), iconCode + ".png")); - DailyWeatherResponse dailyWeather = new DailyWeatherResponse(); - dailyWeather.setDate(parseDayOfWeek(dateString)); - dailyWeather.setTemp(temperature); - dailyWeather.setIconUrl(iconUrl); + DailyWeatherResponse dailyWeather = new DailyWeatherResponse(); + dailyWeather.setDate(parseDayOfWeek(dateString)); + dailyWeather.setTemp(convertToCelsius(temperature)); + dailyWeather.setIconUrl(iconUrl); - weeklyWeather.add(dailyWeather); - }); + dailyWeatherMap.put(dateString, dailyWeather); + } + } + } - // 날짜 순서대로 정렬 + weeklyWeather.addAll(dailyWeatherMap.values()); weeklyWeather.sort(Comparator.comparing(DailyWeatherResponse::getDate)); } catch (IOException e) { @@ -161,6 +156,7 @@ public List getWeeklyWeather(String city, LocalTime reques } + /** 현지 시간으로 변환 **/ private String getLocalTime(int timezoneOffset) { Instant now = Instant.now(); @@ -171,6 +167,7 @@ private String getLocalTime(int timezoneOffset) { } + /** 온도를 섭씨로 변환 **/ private String convertToCelsius(double kelvin) { double celsius = kelvin - 273.15; @@ -179,6 +176,7 @@ private String convertToCelsius(double kelvin) { } + /** 날짜 문자열에서 요일을 파싱 **/ private String parseDayOfWeek(String dateString) { LocalDate localDate = LocalDate.parse(dateString); diff --git a/backend/src/main/resources/application.yml b/backend/src/main/resources/application.yml index 87d1c333..c430f506 100644 --- a/backend/src/main/resources/application.yml +++ b/backend/src/main/resources/application.yml @@ -38,4 +38,5 @@ api-key: amadeus: accessKey: ${AMADEUS_ACCESS_KEY} secretKey: ${AMADEUS_SECRET_KEY} - open-weather: ${OPEN_WEATHER_API_KEY} \ No newline at end of file + open-weather: ${OPEN_WEATHER_API_KEY} + exchange-rate: ${EXCHANGE_RATE_API_KEY} \ No newline at end of file