날씨 스토리지에저장
This commit is contained in:
parent
25c691338d
commit
ffc8b44b46
@ -1,9 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
작성자 : 서지희
|
작성자 : 서지희
|
||||||
작성일 : 2025-04-04
|
작성일 : 2025-04-04
|
||||||
수정자 :
|
수정일 : 2025-04-07
|
||||||
수정일 :
|
설명 : 위치 기반으로 날씨를 조회하고, 10분 단위 캐시로 저장합니다.
|
||||||
설명 : 위치 기반으로 날씨를 조회하고, 오늘의 최저/최고 기온과 현재 날씨 아이콘/설명을 저장합니다.
|
|
||||||
*/
|
*/
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import { defineStore } from 'pinia';
|
import { defineStore } from 'pinia';
|
||||||
@ -20,6 +19,7 @@ export const useWeatherStore = defineStore('weather', () => {
|
|||||||
const dailyWeatherList = ref([]);
|
const dailyWeatherList = ref([]);
|
||||||
|
|
||||||
const getWeatherInfo = async () => {
|
const getWeatherInfo = async () => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
navigator.geolocation.getCurrentPosition(async position => {
|
navigator.geolocation.getCurrentPosition(async position => {
|
||||||
const lat = position.coords.latitude;
|
const lat = position.coords.latitude;
|
||||||
const lon = position.coords.longitude;
|
const lon = position.coords.longitude;
|
||||||
@ -35,34 +35,25 @@ export const useWeatherStore = defineStore('weather', () => {
|
|||||||
const resData = res.data.data;
|
const resData = res.data.data;
|
||||||
const raw = resData.weatherInfo;
|
const raw = resData.weatherInfo;
|
||||||
const data = JSON.parse(raw);
|
const data = JSON.parse(raw);
|
||||||
console.log(data.list)
|
if (!data || !Array.isArray(data.list)) {
|
||||||
if (!data || !Array.isArray(data.list) || data.list.length === 0) {
|
console.error('날씨 데이터 형식 오류');
|
||||||
console.error('날씨 데이터 형식 오류 또는 없음:', data);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 주간 예보 리스트 저장
|
|
||||||
dailyWeatherList.value = resData.dailyWeatherList;
|
dailyWeatherList.value = resData.dailyWeatherList;
|
||||||
|
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
const nowTime = now.getTime();
|
|
||||||
const todayStr = now.toISOString().split('T')[0];
|
const todayStr = now.toISOString().split('T')[0];
|
||||||
|
const nowTime = now.getTime();
|
||||||
|
|
||||||
// 오늘의 데이터만 필터링
|
|
||||||
const todayList = data.list.filter(item => item.dt_txt.startsWith(todayStr));
|
const todayList = data.list.filter(item => item.dt_txt.startsWith(todayStr));
|
||||||
|
|
||||||
if (todayList.length > 0) {
|
if (todayList.length > 0) {
|
||||||
// 오늘의 최저 / 최고 기온 계산
|
|
||||||
const minTemp = Math.min(...todayList.map(i => i.main.temp_min));
|
const minTemp = Math.min(...todayList.map(i => i.main.temp_min));
|
||||||
const maxTemp = Math.max(...todayList.map(i => i.main.temp_max));
|
const maxTemp = Math.max(...todayList.map(i => i.main.temp_max));
|
||||||
weather.value.tempMin = Math.round(minTemp);
|
weather.value.tempMin = Math.round(minTemp);
|
||||||
weather.value.tempMax = Math.round(maxTemp);
|
weather.value.tempMax = Math.round(maxTemp);
|
||||||
} else {
|
|
||||||
weather.value.tempMin = null;
|
|
||||||
weather.value.tempMax = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 현재 시간과 가장 가까운 시간대 데이터 추출 (아이콘 및 설명용)
|
|
||||||
const closest = data.list.reduce((prev, curr) => {
|
const closest = data.list.reduce((prev, curr) => {
|
||||||
const prevDiff = Math.abs(new Date(prev.dt_txt).getTime() - nowTime);
|
const prevDiff = Math.abs(new Date(prev.dt_txt).getTime() - nowTime);
|
||||||
const currDiff = Math.abs(new Date(curr.dt_txt).getTime() - nowTime);
|
const currDiff = Math.abs(new Date(curr.dt_txt).getTime() - nowTime);
|
||||||
@ -72,15 +63,52 @@ export const useWeatherStore = defineStore('weather', () => {
|
|||||||
weather.value.icon = closest.weather[0].icon.replace(/n$/, 'd');
|
weather.value.icon = closest.weather[0].icon.replace(/n$/, 'd');
|
||||||
weather.value.description = closest.weather[0].description;
|
weather.value.description = closest.weather[0].description;
|
||||||
|
|
||||||
|
resolve({ weather: weather.value, dailyWeatherList: dailyWeatherList.value });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('날씨 정보 가져오기 실패:', e);
|
console.error('날씨 정보 가져오기 실패:', e);
|
||||||
|
reject(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 {
|
return {
|
||||||
weather,
|
weather,
|
||||||
dailyWeatherList,
|
dailyWeatherList,
|
||||||
getWeatherInfo,
|
getWeatherInfo,
|
||||||
|
getWeatherInfoWithCache,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user