diff --git a/src/components/button/HalfDayButtons.vue b/src/components/button/HalfDayButtons.vue
index 2dc31e0..83f4c35 100644
--- a/src/components/button/HalfDayButtons.vue
+++ b/src/components/button/HalfDayButtons.vue
@@ -22,21 +22,21 @@
-
+const addVacationRequests = () => {
+ emit("addVacationRequests");
+};
+
+ }
+
diff --git a/src/components/vacation/ProfileList.vue b/src/components/vacation/ProfileList.vue
index 526537c..ae2d257 100644
--- a/src/components/vacation/ProfileList.vue
+++ b/src/components/vacation/ProfileList.vue
@@ -1,6 +1,6 @@
-
+
-
{
const totalUsers = userList.value.length;
- if (totalUsers <= 7) return "120px"; // 7๋ช
์ดํ
- if (totalUsers <= 10) return "100px"; // ~10๋ช
- if (totalUsers <= 20) return "80px"; // ~20๋ช
- return "60px"; // 20๋ช
์ด์
+ if (totalUsers <= 7) return "100px"; // 7๋ช
์ดํ
+ if (totalUsers <= 10) return "80px"; // ~10๋ช
+ if (totalUsers <= 20) return "60px"; // ~20๋ช
+ return "40px"; // 20๋ช
์ด์
});
// ๊ฐ๋ณ ์ ์ ์คํ์ผ ์ ์ฉ
diff --git a/src/views/vacation/VacationManagement.vue b/src/views/vacation/VacationManagement.vue
index bfb72c6..2412d73 100644
--- a/src/views/vacation/VacationManagement.vue
+++ b/src/views/vacation/VacationManagement.vue
@@ -9,16 +9,16 @@
@profileClick="handleProfileClick"
:remainingVacationData="remainingVacationData"
/>
-
@@ -99,7 +99,6 @@ const handleProfileClick = async (user) => {
if (user.MEMBERSEQ === userStore.user.id) {
// ๋ด ํ๋กํ์ ํด๋ฆญํ ๊ฒฝ์ฐ
const response = await axios.get(`vacation/history`);
- console.log(response)
if (response.status === 200 && response.data) {
myVacations.value = response.data.data.usedVacations || [];
@@ -188,23 +187,28 @@ const getVacationType = (typeCode) => {
return vacationCodeMap.value[typeCode] || "๊ธฐํ";
};
-/**
- * API ์ด๋ฒคํธ(fetchedEvents)์ ์ฌ์ฉ์๊ฐ ์ ํํ ๋ ์ง(selectedDates)๋ฅผ ๋ณํฉํ์ฌ
- * calendarEvents๋ฅผ ์
๋ฐ์ดํธํ๋ ํจ์
- * - ์ ํ ์ด๋ฒคํธ๋ display: "background" ์ต์
์ ์ฌ์ฉํ์ฌ ๋ฐฐ๊ฒฝ์ผ๋ก ํ์
- * - ์ ํ๋ ํ์
์ ๋ฐ๋ผ ํด๋์ค(selected-am, selected-pm, selected-full)๋ฅผ ๋ถ์ฌํจ
- */
+
function updateCalendarEvents() {
-const selectedEvents = Array.from(selectedDates.value).map(([date, type]) => {
- return {
- title: getVacationType(type),
- start: date,
- backgroundColor: "rgba(0, 128, 0, 0.3)",
- display: "background",
- classNames: [getVacationTypeClass(type)],
- };
-});
-calendarEvents.value = [...fetchedEvents.value, ...selectedEvents];
+ // ์ ๊ท ์ ํํ ์ฐ์ฐจ(์ถ๊ฐ ๋์): type์ด "delete"๊ฐ ์๋ ํญ๋ชฉ
+ const selectedEvents = Array.from(selectedDates.value)
+ .filter(([date, type]) => type !== "delete")
+ .map(([date, type]) => ({
+ title: getVacationType(type),
+ start: date,
+ backgroundColor: "rgba(0, 128, 0, 0.3)",
+ display: "background",
+ classNames: [getVacationTypeClass(type)]
+ }));
+
+ // ๊ธฐ์กด ๋ฐฑ์๋์์ ๋ถ๋ฌ์จ ์ ์ฅ๋ ์ฐ์ฐจ ์ด๋ฒคํธ ์ค,
+ // ํด๋น ๋ ์ง๊ฐ ์ญ์ ๋์์ผ๋ก ํ์๋์ด ์์ผ๋ฉด ์ ๊ฑฐ
+ const filteredFetchedEvents = fetchedEvents.value.filter(event => {
+ if (event.saved) { // saved ํ๋๊ทธ๊ฐ ์๋ ์ด๋ฒคํธ๋ ์ ์ฅ๋ ์ฐ์ฐจ
+ return selectedDates.value.get(event.start) !== "delete";
+ }
+ return true;
+ });
+ calendarEvents.value = [...filteredFetchedEvents, ...selectedEvents];
}
/**
@@ -221,30 +225,46 @@ calendarEvents.value = [...fetchedEvents.value, ...selectedEvents];
* - ์ฃผ๋ง(ํ , ์ผ)๊ณผ ๊ณตํด์ผ์ ํด๋ฆญ๋์ง ์์
* - ํด๋ฆญ ์ ํด๋น ๋ ์ง๋ฅผ selectedDates์ ์ถ๊ฐ ๋๋ ์ ๊ฑฐํ ํ updateCalendarEvents() ํธ์ถ
*/
-function handleDateClick(info) {
-const clickedDateStr = info.dateStr;
-const clickedDate = info.date;
+ function handleDateClick(info) {
+ const clickedDateStr = info.dateStr; // "YYYY-MM-DD" ํ์
+ const clickedDate = info.date;
+ const todayStr = new Date().toISOString().split("T")[0];
-// ์ฃผ๋ง (ํ :6, ์ผ:0)์ ํด๋ฆญ ๋ฌด์
-if (clickedDate.getDay() === 0 || clickedDate.getDay() === 6) {
+ // ์ฃผ๋ง, ๊ณตํด์ผ, ์ค๋ ์ด์ ๋ ์ง๋ ํด๋ฆญ ๋ถ๊ฐ
+ if (
+ clickedDate.getDay() === 0 ||
+ clickedDate.getDay() === 6 ||
+ holidayDates.value.has(clickedDateStr) ||
+ clickedDateStr < todayStr
+ ) {
return;
-}
-// ๊ณตํด์ผ์ด๋ฉด ํด๋ฆญ ๋ฌด์
-if (holidayDates.value.has(clickedDateStr)) {
- return;
-}
-if (!selectedDates.value.has(clickedDateStr)) {
- const type = halfDayType.value
- ? halfDayType.value === "AM"
- ? "700101"
- : "700102"
- : "700103";
- selectedDates.value.set(clickedDateStr, type);
-} else {
+ }
+
+ // ํ ๊ธ: ์ด๋ฏธ ์ ํ๋ ๋ ์ง๋ผ๋ฉด ํด์
+ if (selectedDates.value.has(clickedDateStr)) {
selectedDates.value.delete(clickedDateStr);
-}
-halfDayType.value = null;
-updateCalendarEvents();
+ updateCalendarEvents();
+ return;
+ }
+
+ // ์ ์ฅ๋(๋ณด๋ธ์ฌ๋ ์๋) ์ฐ์ฐจ๊ฐ ์๋์ง ํ์ธ
+ const unsentVacation = myVacations.value.find(
+ (vac) => vac.LOCVACUDT && vac.LOCVACUDT.startsWith(clickedDateStr) && !vac.LOCVACRMM
+ );
+
+ if (unsentVacation) {
+ // ๊ธฐ์กด ์ ์ฅ๋ ์ฐ์ฐจ๊ฐ ์๋ค๋ฉด, ํด๋ฆญ ์ "delete" ํ๋๊ทธ ์ง์ (์ฆ, ์จ๊น ์ฒ๋ฆฌ)
+ selectedDates.value.set(clickedDateStr, "delete");
+ } else {
+ // ๊ทธ๋ ์ง ์์ผ๋ฉด ์ ๊ท ์ฐ์ฐจ ์ถ๊ฐ: halfDayType ๊ฐ์ ๋ฐ๋ผ ๊ฒฐ์
+ const type = halfDayType.value
+ ? (halfDayType.value === "AM" ? "700101" : "700102")
+ : "700103";
+ selectedDates.value.set(clickedDateStr, type);
+ }
+
+ halfDayType.value = null;
+ updateCalendarEvents();
}
/**
@@ -257,66 +277,93 @@ halfDayType.value = halfDayType.value === type ? null : type;
/**
* ๋ฐฑ์๋์์ ํด๊ฐ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ ์ด๋ฒคํธ๋ก ๋ณํ
*/
-async function fetchVacationData(year, month) {
-try {
+ async function fetchVacationData(year, month) {
+ try {
const response = await axios.get(`vacation/list/${year}/${month}`);
- if (response.status == 200) {
- const vacationList = response.data;
- const events = vacationList
+ if (response.status === 200) {
+ const vacationList = response.data;
+ // ๋ด ์ฐ์ฐจ ๋ฐ์ดํฐ ์
๋ฐ์ดํธ (์ฌ์ฉ์ ๋ณธ์ธ์ ์ฐ์ฐจ๋ง)
+ myVacations.value = vacationList.filter(
+ (vac) => vac.MEMBERSEQ === userStore.user.id
+ );
+ // ๊ธฐ์กด ์ ์ฅ๋ ์ฐ์ฐจ ์ด๋ฒคํธ์ saved ํ๋๊ทธ ์ถ๊ฐ
+ const events = vacationList
+ .filter((vac) => !vac.LOCVACRMM) // ๋ณด๋ธ์ฌ๋์ด ์๋(์ ์ฅ๋) ์ฐ์ฐจ
.map((vac) => {
- let dateStr = vac.LOCVACUDT.split("T")[0];
- let className = "fc-daygrid-event";
- let backgroundColor = userColors.value[vac.MEMBERSEQ] || "#FFFFFF";
- return {
+ let dateStr = vac.LOCVACUDT.split("T")[0];
+ let backgroundColor = userColors.value[vac.MEMBERSEQ] || "#FFFFFF";
+ return {
title: getVacationType(vac.LOCVACTYP),
start: dateStr,
backgroundColor,
classNames: [getVacationTypeClass(vac.LOCVACTYP)],
- };
+ saved: true, // saved ํ๋๊ทธ ์ถ๊ฐ
+ };
})
.filter((event) => event !== null);
- return events;
+ return events;
} else {
- console.warn("๐ ํด๊ฐ ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์ค์ง ๋ชปํจ");
- return [];
+ console.warn("๐ ํด๊ฐ ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์ค์ง ๋ชปํจ");
+ return [];
}
-} catch (error) {
+ } catch (error) {
console.error("Error fetching vacation data:", error);
return [];
-}
+ }
}
/**
* ํด๊ฐ ์์ฒญ ์ถ๊ฐ (์ ํ๋ ๋ ์ง๋ฅผ ๋ฐฑ์๋๋ก ์ ์ก)
*/
-async function addVacationRequests() {
-if (selectedDates.value.size === 0) {
- alert("ํด๊ฐ๋ฅผ ์ ํํด์ฃผ์ธ์.");
- return;
-}
-const vacationRequests = Array.from(selectedDates.value).map(([date, type]) => ({
- date,
- type,
-}));
-try {
- const response = await axios.post("vacation", vacationRequests);
+ async function saveVacationChanges() {
+ // ์ถ๊ฐํ ์ฐ์ฐจ: selectedDates ํญ๋ชฉ ์ค type์ด "delete"๊ฐ ์๋ ๊ฒฝ์ฐ
+ const selectedDatesArray = Array.from(selectedDates.value);
+ const vacationsToAdd = selectedDatesArray
+ .filter(([date, type]) => type !== "delete")
+ .filter(([date, type]) =>
+ // ๊ธฐ์กด ๋ฐ์ดํฐ์ ์๊ฑฐ๋, ๊ธฐ์กด ๋ฐ์ดํฐ์ ์๋๋ผ๋ ๋ณด๋ธ์ฌ๋(LOCVACRMM)์ด ์๋ ๊ฒฝ์ฐ ์ถ๊ฐ
+ !myVacations.value.some(vac => vac.LOCVACUDT.startsWith(date)) ||
+ myVacations.value.some(vac => vac.LOCVACUDT.startsWith(date) && vac.LOCVACRMM)
+ )
+ .map(([date, type]) => ({ date, type }));
+
+ // ์ญ์ ํ ์ฐ์ฐจ: ๊ธฐ์กด ๋ฐ์ดํฐ ์ค ๋ณด๋ธ์ฌ๋์ด ์๋ ํญ๋ชฉ์์,
+ // ํด๋น ๋ ์ง๊ฐ "delete"๋ก ์ง์ ๋์๊ฑฐ๋ ์ ํ๋์ง ์์ ๊ฒฝ์ฐ
+ const vacationsToDelete = myVacations.value
+ .filter(vac => {
+ const date = vac.LOCVACUDT.split("T")[0];
+ // ์ค์ง ํด๋น ๋ ์ง๊ฐ "delete"๋ก ์ ํ๋ ๊ฒฝ์ฐ๋ง ์ญ์ ๋์์ผ๋ก ์ฒ๋ฆฌ
+ return selectedDates.value.get(date) === "delete" && !vac.LOCVACRMM;
+ })
+ .map(vac => {
+ const id = vac.LOCVACSEQ ;
+ return typeof id === "number" ? Number(id) : id;
+ });
+
+
+ console.log("vacationsToAdd:", vacationsToAdd);
+ console.log("vacationsToDelete:", vacationsToDelete);
+
+ try {
+ const response = await axios.post("vacation/batchUpdate", {
+ add: vacationsToAdd,
+ delete: vacationsToDelete
+ });
if (response.data && response.data.status === "OK") {
- alert("ํด๊ฐ๊ฐ ์ ์ฅ๋์์ต๋๋ค.");
- await fetchRemainingVacation();
- // ์ ์ฅ ํ ํ์ฌ ๋ฌ ๋ฐ์ดํฐ ๋ค์ ๋ถ๋ฌ์ค๊ธฐ
- const currentDate = fullCalendarRef.value.getApi().getDate();
- const year = currentDate.getFullYear();
- const month = String(currentDate.getMonth() + 1).padStart(2, "0");
- loadCalendarData(year, month);
- selectedDates.value.clear();
- updateCalendarEvents();
+ alert("โ
ํด๊ฐ ๋ณ๊ฒฝ ์ฌํญ์ด ์ ์ฅ๋์์ต๋๋ค.");
+ await fetchRemainingVacation();
+ const currentDate = fullCalendarRef.value.getApi().getDate();
+ await loadCalendarData(currentDate.getFullYear(), currentDate.getMonth() + 1);
+ // ์ด๊ธฐํ: ์ ํํ ๋ ์ง ํด์
+ selectedDates.value.clear();
+ updateCalendarEvents();
} else {
- alert("ํด๊ฐ ์ ์ฅ ์ค ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค.");
+ alert("โ ํด๊ฐ ์ ์ฅ ์ค ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค.");
}
-} catch (error) {
- console.error(error);
- alert("ํด๊ฐ ์ ์ฅ์ ์คํจํ์ต๋๋ค.");
-}
+ } catch (error) {
+ console.error("๐จ ํด๊ฐ ๋ณ๊ฒฝ ์ ์ฅ ์คํจ:", error);
+ alert("โ ํด๊ฐ ์ ์ฅ ์์ฒญ์ ์คํจํ์ต๋๋ค.");
+ }
}
/**