localhost-back/src/main/java/io/company/localhost/service/localvacaService.java

159 lines
6.0 KiB
Java

package io.company.localhost.service;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import io.company.localhost.common.dto.MapDto;
import io.company.localhost.mapper.localvacaMapper;
import lombok.RequiredArgsConstructor;
@Service
@RequiredArgsConstructor
public class localvacaService {
private final localvacaMapper localvacaMapper;
private final RestTemplate restTemplate = new RestTemplate();
@Value("${api.public-holiday.key}")
private String serviceKey;
public void insertVacation(MapDto map) {
localvacaMapper.insertVacation(map);
}
public List<MapDto> getVacationList(int year, int month) {
return localvacaMapper.findVacations(year, month);
}
/**
* 🔹 특정 연월에 대한 공휴일 데이터 조회
*/
public List<MapDto> getHolidays(int year, int month) {
// ✅ ServiceKey를 디코딩해서 사용
String decodedServiceKey = URLDecoder.decode(serviceKey, StandardCharsets.UTF_8);
System.out.println("📌 디코딩된 ServiceKey: " + decodedServiceKey);
// ✅ URI를 직접 문자열로 구성하여 ServiceKey가 다시 인코딩되지 않도록 함
String url = "http://apis.data.go.kr/B090041/openapi/service/SpcdeInfoService/getRestDeInfo"
+ "?solYear=" + year
+ "&solMonth=" + String.format("%02d", month)
+ "&ServiceKey=" + decodedServiceKey // ✅ 디코딩된 상태로 직접 추가
+ "&_type=json";
System.out.println("📌 API 요청 URL: " + url);
// ✅ API 요청 헤더 추가 (User-Agent 포함)
HttpHeaders headers = new HttpHeaders();
headers.set(HttpHeaders.USER_AGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64)");
HttpEntity<String> entity = new HttpEntity<>(headers);
// ✅ `exchange` 메서드를 사용하여 요청
ResponseEntity<Map> response = restTemplate.exchange(url, HttpMethod.GET, entity, Map.class);
System.out.println("📌 API 응답 데이터: " + response.getBody());
return parseResponse(response.getBody());
}
/**
* 🔹 공휴일 데이터를 MapDto로 변환
*/
private List<MapDto> parseResponse(Map<String, Object> response) {
List<MapDto> holidays = new ArrayList<>();
if (response == null || !response.containsKey("response")) {
System.out.println("📌 응답이 비어 있음.");
return holidays;
}
Map<String, Object> responseBody = (Map<String, Object>) response.get("response");
System.out.println("📌 responseBody: " + responseBody);
if (responseBody == null || !responseBody.containsKey("body")) {
System.out.println("📌 API 응답 데이터에서 'body' 필드 없음.");
return holidays;
}
Map<String, Object> body = (Map<String, Object>) responseBody.get("body");
System.out.println("📌 body: " + body);
if (body == null || !body.containsKey("items")) {
System.out.println("📌 API 응답 데이터에서 'items' 필드 없음.");
return holidays;
}
Object items = body.get("items");
System.out.println("📌 items: " + items);
// ✅ 'items'가 Map 타입인지 확인 후 처리
if (items instanceof Map) {
Map<String, Object> itemMap = (Map<String, Object>) items;
if (itemMap.containsKey("item")) {
Object itemData = itemMap.get("item");
System.out.println("📌 itemData: " + itemData);
// ✅ 'item'이 리스트인지 단일 객체인지 확인 후 변환
if (itemData instanceof List) {
for (Map<String, Object> item : (List<Map<String, Object>>) itemData) {
holidays.add(convertToMapDto(item));
}
} else if (itemData instanceof Map) {
holidays.add(convertToMapDto((Map<String, Object>) itemData));
}
}
}
System.out.println("📌 최종 holidays: " + holidays);
return holidays;
}
/**
* 🔹 공휴일 데이터를 MapDto로 변환
*/
private MapDto convertToMapDto(Map<String, Object> item) {
MapDto dto = new MapDto();
// ✅ locdate를 안전하게 변환 (int, long, double 등 다양한 형태 대응)
String locdateStr = String.valueOf(item.get("locdate"));
if (locdateStr.contains(".")) {
locdateStr = locdateStr.split("\\.")[0]; // 소수점 제거
}
// ✅ YYYY-MM-DD 형식으로 변환
if (locdateStr.length() == 8) {
String formattedDate = locdateStr.substring(0, 4) + "-" + locdateStr.substring(4, 6) + "-" + locdateStr.substring(6, 8);
dto.put("date", formattedDate);
} else {
dto.put("date", locdateStr); // 변환 불가능한 경우 원본 저장
}
dto.put("name", item.get("dateName"));
return dto;
}
/**
* 내 연차 사용 내역 조회 (사용한 연차 & 받은 연차)
*/
public Map<String, List<MapDto>> getUserVacationHistory(Long userId) {
List<MapDto> usedVacations = localvacaMapper.getUsedVacations(userId);
List<MapDto> receivedVacations = localvacaMapper.getReceivedVacations(userId);
Map<String, List<MapDto>> history = new HashMap<>();
history.put("usedVacations", usedVacations);
history.put("receivedVacations", receivedVacations);
return history;
}
}