휴가 선택 활성화 수정정

This commit is contained in:
dyhj625 2025-02-24 13:58:48 +09:00
parent 02f0cda3b4
commit 09e79cb690

View File

@ -4,6 +4,12 @@
<div class="row g-0"> <div class="row g-0">
<!-- Sidebar: 사이드바 영역 --> <!-- Sidebar: 사이드바 영역 -->
<div class="col-3 app-calendar-sidebar border-end" id="app-calendar-sidebar"> <div class="col-3 app-calendar-sidebar border-end" id="app-calendar-sidebar">
<div class="sidebar-content">
<!-- 사원 프로필 리스트 -->
<ProfileList
@profileClick="handleProfileClick"
:remainingVacationData="remainingVacationData"
/>
<!-- 모달들은 화면 오버레이로 동작하므로 사이드바 내부에 두어도 무방 --> <!-- 모달들은 화면 오버레이로 동작하므로 사이드바 내부에 두어도 무방 -->
<VacationModal <VacationModal
v-if="isModalOpen" v-if="isModalOpen"
@ -21,12 +27,6 @@
@close="isGrantModalOpen = false" @close="isGrantModalOpen = false"
@updateVacation="fetchRemainingVacation" @updateVacation="fetchRemainingVacation"
/> />
<div class="sidebar-content">
<!-- 사원 프로필 리스트 -->
<ProfileList
@profileClick="handleProfileClick"
:remainingVacationData="remainingVacationData"
/>
</div> </div>
<div class="sidebar-actions text-center my-3"> <div class="sidebar-actions text-center my-3">
<!-- 액션 버튼 --> <!-- 액션 버튼 -->
@ -54,7 +54,6 @@
</div> </div>
</template> </template>
<script setup> <script setup>
import { reactive, ref, onMounted, nextTick, computed, watch } from "vue"; import { reactive, ref, onMounted, nextTick, computed, watch } from "vue";
import axios from "@api"; import axios from "@api";
@ -76,11 +75,11 @@
const userListStore = useUserStore(); const userListStore = useUserStore();
const userList = ref([]); const userList = ref([]);
const userColors = ref({}); const userColors = ref({});
const myVacations = ref([]); // " " const myVacations = ref([]); // " " ( )
const receivedVacations = ref([]); // " " const receivedVacations = ref([]); // " "
const isModalOpen = ref(false); const isModalOpen = ref(false);
const remainingVacationData = ref({}); const remainingVacationData = ref({});
const modalYear = ref(new Date().getFullYear());
const lastRemainingYear = ref(new Date().getFullYear()); const lastRemainingYear = ref(new Date().getFullYear());
const lastRemainingMonth = ref(String(new Date().getMonth() + 1).padStart(2, "0")); const lastRemainingMonth = ref(String(new Date().getMonth() + 1).padStart(2, "0"));
const isGrantModalOpen = ref(false); const isGrantModalOpen = ref(false);
@ -95,6 +94,9 @@
const holidayDates = ref(new Set()); const holidayDates = ref(new Set());
const fetchedEvents = ref([]); const fetchedEvents = ref([]);
// : ( )
const toggledDates = ref(new Set());
const calendarOptions = reactive({ const calendarOptions = reactive({
plugins: [dayGridPlugin, interactionPlugin], plugins: [dayGridPlugin, interactionPlugin],
initialView: "dayGridMonth", initialView: "dayGridMonth",
@ -113,12 +115,15 @@
onMounted(async () => { onMounted(async () => {
await userStore.userInfo(); await userStore.userInfo();
await fetchRemainingVacation(); await fetchRemainingVacation();
// vacation history
const currentYear = new Date().getFullYear();
await fetchVacationHistory(currentYear);
}); });
// lastRemainingYear // API ( )
watch(lastRemainingYear, async (newYear, oldYear) => { async function fetchVacationHistory(year) {
try { try {
const response = await axios.get(`vacation/history?year=${newYear}`); const response = await axios.get(`vacation/history?year=${year}`);
if (response.status === 200 && response.data) { if (response.status === 200 && response.data) {
myVacations.value = response.data.data.usedVacations || []; myVacations.value = response.data.data.usedVacations || [];
receivedVacations.value = response.data.data.receivedVacations || []; receivedVacations.value = response.data.data.receivedVacations || [];
@ -130,6 +135,11 @@
} catch (error) { } catch (error) {
console.error("🚨 연차 데이터 불러오기 실패:", error); console.error("🚨 연차 데이터 불러오기 실패:", error);
} }
}
// lastRemainingYear
watch(lastRemainingYear, async (newYear, oldYear) => {
await fetchVacationHistory(newYear);
}); });
const fetchRemainingVacation = async () => { const fetchRemainingVacation = async () => {
@ -147,34 +157,23 @@
}; };
// //
//
const handleProfileClick = async (user) => { const handleProfileClick = async (user) => {
try { try {
//
if (isModalOpen.value) { if (isModalOpen.value) {
isModalOpen.value = false; isModalOpen.value = false;
return; return;
} }
if (user.MEMBERSEQ === userStore.user.id) {
const year = new Date().getFullYear(); //
//
const response = await axios.get(`vacation/history?year=${year}`);
if (response.status === 200 && response.data) {
myVacations.value = response.data.data.usedVacations || [];
receivedVacations.value = response.data.data.receivedVacations || [];
isModalOpen.value = true;
//
lastRemainingYear.value = year;
isGrantModalOpen.value = false;
} else {
console.warn("❌ 연차 내역을 불러오지 못했습니다.");
}
} else {
//
if (isGrantModalOpen.value) { if (isGrantModalOpen.value) {
isGrantModalOpen.value = false; isGrantModalOpen.value = false;
return; return;
} }
if (user.MEMBERSEQ === userStore.user.id) {
const year = new Date().getFullYear();
await fetchVacationHistory(year);
isModalOpen.value = true;
lastRemainingYear.value = year;
isGrantModalOpen.value = false;
} else {
selectedUser.value = user; selectedUser.value = user;
isGrantModalOpen.value = true; isGrantModalOpen.value = true;
isModalOpen.value = false; isModalOpen.value = false;
@ -221,10 +220,9 @@ const handleProfileClick = async (user) => {
return vacationCodeMap.value[typeCode] || "기타"; return vacationCodeMap.value[typeCode] || "기타";
}; };
// computed: lastRemainingYear // computed: lastRemainingYear
const filteredMyVacations = computed(() => { const filteredMyVacations = computed(() => {
const filtered = myVacations.value.filter(vac => { const filtered = myVacations.value.filter(vac => {
// vac.date vac.LOCVACUDT
const dateStr = vac.date || vac.LOCVACUDT; const dateStr = vac.date || vac.LOCVACUDT;
const year = dateStr ? dateStr.split("T")[0].substring(0, 4) : null; const year = dateStr ? dateStr.split("T")[0].substring(0, 4) : null;
console.log("vacation year:", year, "lastRemainingYear:", lastRemainingYear.value); console.log("vacation year:", year, "lastRemainingYear:", lastRemainingYear.value);
@ -243,8 +241,8 @@ const filteredReceivedVacations = computed(() => {
}); });
}); });
function updateCalendarEvents() { function updateCalendarEvents() {
// selectedDates "delete"
const selectedEvents = Array.from(selectedDates.value) const selectedEvents = Array.from(selectedDates.value)
.filter(([date, type]) => type !== "delete") .filter(([date, type]) => type !== "delete")
.map(([date, type]) => ({ .map(([date, type]) => ({
@ -255,12 +253,18 @@ const filteredReceivedVacations = computed(() => {
display: "background", display: "background",
classNames: [getVacationTypeClass(type), "selected-event"] classNames: [getVacationTypeClass(type), "selected-event"]
})); }));
// fetchedEvents, "delete"
// () , .
const filteredFetchedEvents = fetchedEvents.value.filter(event => { const filteredFetchedEvents = fetchedEvents.value.filter(event => {
if (event.saved) { if (event.saved && selectedDates.value.get(event.start) === "delete") {
return selectedDates.value.get(event.start) !== "delete"; if (event.memberSeq === userStore.user.id) {
return false;
}
} }
return true; return true;
}); });
calendarEvents.value = [...filteredFetchedEvents, ...selectedEvents]; calendarEvents.value = [...filteredFetchedEvents, ...selectedEvents];
} }
@ -274,6 +278,7 @@ const filteredReceivedVacations = computed(() => {
const clickedDateStr = info.dateStr; const clickedDateStr = info.dateStr;
const clickedDate = info.date; const clickedDate = info.date;
const todayStr = new Date().toISOString().split("T")[0]; const todayStr = new Date().toISOString().split("T")[0];
if ( if (
clickedDate.getDay() === 0 || clickedDate.getDay() === 0 ||
clickedDate.getDay() === 6 || clickedDate.getDay() === 6 ||
@ -282,22 +287,36 @@ const filteredReceivedVacations = computed(() => {
) { ) {
return; return;
} }
// : LOCVACUDT 10 clickedDateStr , LOCVACRMM
const isMyVacation = myVacations.value.some(vac => {
const vacDate = vac.date ? String(vac.date).substring(0, 10) : "";
return vacDate === clickedDateStr &&
(!vac.LOCVACRMM || String(vac.LOCVACRMM).trim() === "");
});
if (isMyVacation) {
// : selectedDates "delete" ( )
if (selectedDates.value.get(clickedDateStr) === "delete") {
selectedDates.value.delete(clickedDateStr);
} else {
selectedDates.value.set(clickedDateStr, "delete");
}
updateCalendarEvents();
return;
}
// : /
if (selectedDates.value.has(clickedDateStr)) { if (selectedDates.value.has(clickedDateStr)) {
console.log("일반 날짜 토글 off: 기존 선택 해제");
selectedDates.value.delete(clickedDateStr); selectedDates.value.delete(clickedDateStr);
updateCalendarEvents(); updateCalendarEvents();
return; return;
} }
const unsentVacation = myVacations.value.find(
(vac) => vac.LOCVACUDT && vac.LOCVACUDT.startsWith(clickedDateStr) && !vac.LOCVACRMM
);
if (unsentVacation) {
selectedDates.value.set(clickedDateStr, "delete");
} else {
const type = halfDayType.value const type = halfDayType.value
? (halfDayType.value === "AM" ? "700101" : "700102") ? (halfDayType.value === "AM" ? "700101" : "700102")
: "700103"; : "700103";
console.log("일반 날짜 토글 on: 선택 및 타입", type);
selectedDates.value.set(clickedDateStr, type); selectedDates.value.set(clickedDateStr, type);
}
halfDayType.value = null; halfDayType.value = null;
updateCalendarEvents(); updateCalendarEvents();
} }
@ -311,15 +330,13 @@ const filteredReceivedVacations = computed(() => {
const response = await axios.get(`vacation/list/${year}/${month}`); const response = await axios.get(`vacation/list/${year}/${month}`);
if (response.status === 200) { if (response.status === 200) {
const vacationList = response.data; const vacationList = response.data;
// lastRemainingYear
if (lastRemainingYear.value !== year) { if (lastRemainingYear.value !== year) {
//
myVacations.value = vacationList.filter( myVacations.value = vacationList.filter(
(vac) => vac.MEMBERSEQ === userStore.user.id (vac) => vac.MEMBERSEQ === userStore.user.id
); );
lastRemainingYear.value = year; lastRemainingYear.value = year;
// modalMonth ( )
} }
//
const events = vacationList const events = vacationList
.filter((vac) => !vac.LOCVACRMM) .filter((vac) => !vac.LOCVACRMM)
.map((vac) => { .map((vac) => {
@ -331,6 +348,7 @@ const filteredReceivedVacations = computed(() => {
backgroundColor, backgroundColor,
classNames: [getVacationTypeClass(vac.LOCVACTYP)], classNames: [getVacationTypeClass(vac.LOCVACTYP)],
saved: true, saved: true,
memberSeq: vac.MEMBERSEQ, //
}; };
}) })
.filter((event) => event.start); .filter((event) => event.start);
@ -416,6 +434,7 @@ const filteredReceivedVacations = computed(() => {
const today = new Date(); const today = new Date();
const year = today.getFullYear(); const year = today.getFullYear();
const month = String(today.getMonth() + 1).padStart(2, "0"); const month = String(today.getMonth() + 1).padStart(2, "0");
await fetchVacationData(year, month);
await loadCalendarData(year, month); await loadCalendarData(year, month);
}); });
</script> </script>