This commit is contained in:
parent
4907a12e65
commit
daa3bb9921
@ -9,12 +9,7 @@
|
||||
<!-- 날씨 정보 영역 -->
|
||||
<div class="navbar-nav align-items-center">
|
||||
<div class="d-flex align-items-center weather-box">
|
||||
<img
|
||||
v-if="weather.icon"
|
||||
:src="customIconUrl"
|
||||
:alt="weather.description"
|
||||
:class="customIconClass"
|
||||
/>
|
||||
<img v-if="weather.icon" :src="customIconUrl" :alt="weather.description" :class="customIconClass" />
|
||||
<div class="d-flex flex-column">
|
||||
<span class="weather-desc">{{ weather.description }}</span>
|
||||
<span class="weather-temp" v-if="weather.tempMin !== null && weather.tempMax !== null">
|
||||
@ -268,6 +263,7 @@
|
||||
import { useProjectStore } from '@/stores/useProjectStore';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { useThemeStore } from '@s/darkmode';
|
||||
import { useWeatherStore } from '@/stores/useWeatherStore';
|
||||
import { computed, onMounted, ref, watch } from 'vue';
|
||||
import axios from '@api';
|
||||
|
||||
@ -277,9 +273,12 @@
|
||||
const userStore = useUserInfoStore();
|
||||
const projectStore = useProjectStore();
|
||||
const router = useRouter();
|
||||
const weatherStore = useWeatherStore();
|
||||
|
||||
const user = ref(null);
|
||||
const selectedProject = ref(null);
|
||||
const weather = ref({});
|
||||
const dailyWeatherList = ref([]);
|
||||
|
||||
// 내가 참여하고 있는 진행 중인 프로젝트 목록
|
||||
const myActiveProjects = computed(() => {
|
||||
@ -302,9 +301,7 @@
|
||||
if (!selectedProject.value) return;
|
||||
|
||||
// 모든 진행 중인 프로젝트 리스트에서 선택된 프로젝트 찾기
|
||||
let selected = projectStore.activeProjectList.find(
|
||||
project => project.PROJCTSEQ === selectedProject.value
|
||||
);
|
||||
let selected = projectStore.activeProjectList.find(project => project.PROJCTSEQ === selectedProject.value);
|
||||
|
||||
if (selected) {
|
||||
projectStore.setSelectedProject(selected);
|
||||
@ -312,15 +309,42 @@
|
||||
};
|
||||
|
||||
// 선택된 프로젝트 변경 감지
|
||||
watch(() => projectStore.selectedProject, (newProject) => {
|
||||
watch(
|
||||
() => projectStore.selectedProject,
|
||||
newProject => {
|
||||
if (newProject) {
|
||||
selectedProject.value = newProject.PROJCTSEQ;
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
const customIconUrl = computed(() => {
|
||||
if (weather.value.icon === '01d' || weather.value.icon === '01n') {
|
||||
return '/img/icons/sunny-custom.png';
|
||||
}
|
||||
return `https://openweathermap.org/img/wn/${weather.value.icon}@2x.png`;
|
||||
});
|
||||
|
||||
const customIconClass = computed(() => {
|
||||
if (weather.value.icon === '01d' || weather.value.icon === '01n') {
|
||||
return 'custom-sunny-icon';
|
||||
}
|
||||
return 'weather-icon';
|
||||
});
|
||||
|
||||
const weatherKorean = computed(() => weather.value.description || '날씨 정보 없음');
|
||||
|
||||
// const { isDarkMode, switchToDarkMode, switchToLightMode } = useThemeStore();
|
||||
|
||||
const handleLogout = async () => {
|
||||
await authStore.logout();
|
||||
router.push('/login');
|
||||
};
|
||||
|
||||
const goToMyPage = () => {
|
||||
router.push('/mypage');
|
||||
};
|
||||
|
||||
onMounted(async () => {
|
||||
// if (isDarkMode) {
|
||||
// switchToDarkMode();
|
||||
@ -342,119 +366,47 @@
|
||||
projectStore.setSelectedProject(firstProject);
|
||||
}
|
||||
|
||||
// 날씨 정보 갱신
|
||||
await weatherStore.getWeatherInfo();
|
||||
weather.value = weatherStore.weather; // 오늘 날씨
|
||||
dailyWeatherList.value = weatherStore.dailyWeatherList; // 주간 날씨
|
||||
});
|
||||
|
||||
const weather = ref({
|
||||
icon: '',
|
||||
description: '',
|
||||
tempMin: null,
|
||||
tempMax: null,
|
||||
});
|
||||
|
||||
const customIconUrl = computed(() => {
|
||||
if (weather.value.icon === "01d" || weather.value.icon === "01n") {
|
||||
return "/img/icons/sunny-custom.png";
|
||||
}
|
||||
return `https://openweathermap.org/img/wn/${weather.value.icon}@2x.png`;
|
||||
});
|
||||
|
||||
const customIconClass = computed(() => {
|
||||
if (weather.value.icon === "01d" || weather.value.icon === "01n") {
|
||||
return "custom-sunny-icon";
|
||||
}
|
||||
return "weather-icon";
|
||||
});
|
||||
|
||||
const weatherKorean = computed(() => weather.value.description || '날씨 정보 없음');
|
||||
|
||||
onMounted(() => {
|
||||
|
||||
if (!userStore.user) return;
|
||||
|
||||
navigator.geolocation.getCurrentPosition(async (position) => {
|
||||
const lat = position.coords.latitude;
|
||||
const lon = position.coords.longitude;
|
||||
|
||||
try {
|
||||
await userStore.userInfo();
|
||||
const res = await axios.get(`/weather`, {
|
||||
params: { lat, lon },
|
||||
withCredentials: true,
|
||||
});
|
||||
|
||||
const raw = res.data;
|
||||
const data = JSON.parse(raw.data);
|
||||
|
||||
if (!data || !Array.isArray(data.list) || data.list.length === 0) {
|
||||
console.error('날씨 데이터 형식 오류 또는 없음:', data);
|
||||
return;
|
||||
}
|
||||
|
||||
const now = new Date();
|
||||
const closest = data.list.reduce((prev, curr) => {
|
||||
const prevTime = new Date(prev.dt_txt).getTime();
|
||||
const currTime = new Date(curr.dt_txt).getTime();
|
||||
const nowTime = now.getTime();
|
||||
const prevDiff = Math.abs(prevTime - nowTime);
|
||||
const currDiff = Math.abs(currTime - nowTime);
|
||||
return prevDiff < currDiff ? prev : curr;
|
||||
});
|
||||
|
||||
weather.value.icon = closest.weather[0].icon.replace(/n$/, 'd');
|
||||
weather.value.description = closest.weather[0].description;
|
||||
weather.value.tempMin = Math.round(closest.main.temp_min);
|
||||
weather.value.tempMax = Math.round(closest.main.temp_max);
|
||||
} catch (e) {
|
||||
console.error('날씨 정보 가져오기 실패:', e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const handleLogout = async () => {
|
||||
await authStore.logout();
|
||||
router.push('/login');
|
||||
};
|
||||
|
||||
const goToMyPage = () => {
|
||||
router.push('/mypage');
|
||||
};
|
||||
|
||||
</script>
|
||||
<style scoped>
|
||||
.weather-icon {
|
||||
.weather-icon {
|
||||
width: 40%;
|
||||
height: 40%;
|
||||
}
|
||||
.weather-desc {
|
||||
}
|
||||
.weather-desc {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
line-height: 1.6;
|
||||
}
|
||||
.weather-temp {
|
||||
}
|
||||
.weather-temp {
|
||||
font-size: 13px;
|
||||
color: #888;
|
||||
line-height: 1.2;
|
||||
}
|
||||
.weather-box {
|
||||
}
|
||||
.weather-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
max-width: 3000px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
.custom-sunny-icon {
|
||||
}
|
||||
.custom-sunny-icon {
|
||||
width: 5%;
|
||||
height: auto;
|
||||
}
|
||||
@media (max-width: 1200px) {
|
||||
}
|
||||
@media (max-width: 1200px) {
|
||||
.custom-sunny-icon {
|
||||
width: 6%;
|
||||
}
|
||||
}
|
||||
@media (max-width: 1100px) {
|
||||
}
|
||||
@media (max-width: 1100px) {
|
||||
.custom-sunny-icon {
|
||||
width: 14%;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
71
src/stores/useWeatherStore.js
Normal file
71
src/stores/useWeatherStore.js
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
작성자 : 서지희
|
||||
작성일 : 2025-04-04
|
||||
수정자 :
|
||||
수정일 :
|
||||
설명 :
|
||||
*/
|
||||
import { ref } from 'vue';
|
||||
import { defineStore } from 'pinia';
|
||||
import $api from '@api';
|
||||
|
||||
export const useWeatherStore = defineStore('weather', () => {
|
||||
const weather = ref({
|
||||
icon: '',
|
||||
description: '',
|
||||
tempMin: null,
|
||||
tempMax: null,
|
||||
});
|
||||
|
||||
const dailyWeatherList = ref([]);
|
||||
|
||||
const getWeatherInfo = async () => {
|
||||
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,
|
||||
});
|
||||
|
||||
if (!res?.data?.data) return;
|
||||
|
||||
const resData = res.data.data;
|
||||
const raw = resData.weatherInfo;
|
||||
const data = JSON.parse(raw);
|
||||
|
||||
if (!data || !Array.isArray(data.list) || data.list.length === 0) {
|
||||
console.error('날씨 데이터 형식 오류 또는 없음:', data);
|
||||
return;
|
||||
}
|
||||
|
||||
dailyWeatherList.value = resData.dailyWeatherList;
|
||||
|
||||
const now = new Date();
|
||||
const closest = data.list.reduce((prev, curr) => {
|
||||
const prevTime = new Date(prev.dt_txt).getTime();
|
||||
const currTime = new Date(curr.dt_txt).getTime();
|
||||
const nowTime = now.getTime();
|
||||
const prevDiff = Math.abs(prevTime - nowTime);
|
||||
const currDiff = Math.abs(currTime - nowTime);
|
||||
return prevDiff < currDiff ? prev : curr;
|
||||
});
|
||||
|
||||
weather.value.icon = closest.weather[0].icon.replace(/n$/, 'd');
|
||||
weather.value.description = closest.weather[0].description;
|
||||
weather.value.tempMin = Math.round(closest.main.temp_min);
|
||||
weather.value.tempMax = Math.round(closest.main.temp_max);
|
||||
} catch (e) {
|
||||
console.error('날씨 정보 가져오기 실패:', e);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
weather,
|
||||
dailyWeatherList,
|
||||
getWeatherInfo,
|
||||
};
|
||||
});
|
||||
Loading…
Reference in New Issue
Block a user