날씨 스토리지에저장

This commit is contained in:
dyhj625 2025-04-07 16:15:49 +09:00
parent 25c691338d
commit ffc8b44b46

View File

@ -1,9 +1,8 @@
/*
작성자 : 서지희
작성일 : 2025-04-04
수정자 :
수정일 :
설명 : 위치 기반으로 날씨를 조회하고, 오늘의 최저/최고 기온과 현재 날씨 아이콘/설명을 저장합니다.
수정일 : 2025-04-07
설명 : 위치 기반으로 날씨를 조회하고, 10 단위 캐시로 저장합니다.
*/
import { ref } from 'vue';
import { defineStore } from 'pinia';
@ -20,67 +19,96 @@ export const useWeatherStore = defineStore('weather', () => {
const dailyWeatherList = ref([]);
const getWeatherInfo = async () => {
navigator.geolocation.getCurrentPosition(async position => {
const lat = position.coords.latitude;
const lon = position.coords.longitude;
return new Promise((resolve, reject) => {
navigator.geolocation.getCurrentPosition(async position => {
const lat = position.coords.latitude;
const lon = position.coords.longitude;
try {
const res = await $api.get(`/weather`, {
params: { lat, lon },
withCredentials: true,
});
try {
const res = await $api.get(`/weather`, {
params: { lat, lon },
withCredentials: true,
});
if (!res?.data?.data) return;
if (!res?.data?.data) return;
const resData = res.data.data;
const raw = resData.weatherInfo;
const data = JSON.parse(raw);
console.log(data.list)
if (!data || !Array.isArray(data.list) || data.list.length === 0) {
console.error('날씨 데이터 형식 오류 또는 없음:', data);
return;
const resData = res.data.data;
const raw = resData.weatherInfo;
const data = JSON.parse(raw);
if (!data || !Array.isArray(data.list)) {
console.error('날씨 데이터 형식 오류');
return;
}
dailyWeatherList.value = resData.dailyWeatherList;
const now = new Date();
const todayStr = now.toISOString().split('T')[0];
const nowTime = now.getTime();
const todayList = data.list.filter(item => item.dt_txt.startsWith(todayStr));
if (todayList.length > 0) {
const minTemp = Math.min(...todayList.map(i => i.main.temp_min));
const maxTemp = Math.max(...todayList.map(i => i.main.temp_max));
weather.value.tempMin = Math.round(minTemp);
weather.value.tempMax = Math.round(maxTemp);
}
const closest = data.list.reduce((prev, curr) => {
const prevDiff = Math.abs(new Date(prev.dt_txt).getTime() - nowTime);
const currDiff = Math.abs(new Date(curr.dt_txt).getTime() - nowTime);
return currDiff < prevDiff ? curr : prev;
});
weather.value.icon = closest.weather[0].icon.replace(/n$/, 'd');
weather.value.description = closest.weather[0].description;
resolve({ weather: weather.value, dailyWeatherList: dailyWeatherList.value });
} catch (e) {
console.error('날씨 정보 가져오기 실패:', e);
reject(e);
}
// 주간 예보 리스트 저장
dailyWeatherList.value = resData.dailyWeatherList;
const now = new Date();
const nowTime = now.getTime();
const todayStr = now.toISOString().split('T')[0];
// 오늘의 데이터만 필터링
const todayList = data.list.filter(item => item.dt_txt.startsWith(todayStr));
if (todayList.length > 0) {
// 오늘의 최저 / 최고 기온 계산
const minTemp = Math.min(...todayList.map(i => i.main.temp_min));
const maxTemp = Math.max(...todayList.map(i => i.main.temp_max));
weather.value.tempMin = Math.round(minTemp);
weather.value.tempMax = Math.round(maxTemp);
} else {
weather.value.tempMin = null;
weather.value.tempMax = null;
}
// 현재 시간과 가장 가까운 시간대 데이터 추출 (아이콘 및 설명용)
const closest = data.list.reduce((prev, curr) => {
const prevDiff = Math.abs(new Date(prev.dt_txt).getTime() - nowTime);
const currDiff = Math.abs(new Date(curr.dt_txt).getTime() - nowTime);
return currDiff < prevDiff ? curr : prev;
});
weather.value.icon = closest.weather[0].icon.replace(/n$/, 'd');
weather.value.description = closest.weather[0].description;
} catch (e) {
console.error('날씨 정보 가져오기 실패:', e);
}
}, reject);
});
};
// 로컬스토리지 캐시 포함한 로직
const getWeatherInfoWithCache = async () => {
const now = new Date();
const pad = n => String(n).padStart(2, '0');
const key = `weather_${pad(now.getMonth() + 1)}${pad(now.getDate())}${pad(now.getHours())}${Math.floor(now.getMinutes() / 10) * 10}`;
const cached = localStorage.getItem(key);
if (cached) {
const parsed = JSON.parse(cached);
weather.value = parsed.weather;
dailyWeatherList.value = parsed.dailyWeatherList;
return;
}
// 캐시 삭제
Object.keys(localStorage).forEach(k => {
if (k.startsWith('weather_')) localStorage.removeItem(k);
});
try {
const { weather: w, dailyWeatherList: d } = await getWeatherInfo();
localStorage.setItem(key, JSON.stringify({ weather: w, dailyWeatherList: d }));
} catch (e) {
// 오류 시 기존 로컬스토리지 값 중 가장 최신 값 사용
const oldKey = Object.keys(localStorage).filter(k => k.startsWith('weather_')).sort().pop();
if (oldKey) {
const fallback = JSON.parse(localStorage.getItem(oldKey));
weather.value = fallback.weather;
dailyWeatherList.value = fallback.dailyWeatherList;
}
}
};
return {
weather,
dailyWeatherList,
getWeatherInfo,
getWeatherInfoWithCache,
};
});