-
+
+
{
+ await userStore.userInfo();
+ await fetchRemainingVacation();
+});
+
+const fetchRemainingVacation = async () => {
+ try {
+ const response = await axios.get("vacation/remaining");
+ if (response.status === 200) {
+ console.log("✅ 남은 연차 데이터:", response.data);
+ remainingVacationData.value = response.data.data.reduce((acc, vacation) => {
+ acc[vacation.employeeId] = vacation.remainingQuota;
+ return acc;
+ }, {});
+ }
+ } catch (error) {
+ console.error("🚨 남은 연차 데이터를 불러오지 못했습니다:", error);
+ }
+};
// 프로필 클릭 시 연차 내역 가져오기
const handleProfileClick = async (user) => {
try {
- console.log(`🔍 ${user.MEMBERSEQ}님의 연차 내역 요청 중...`);
- const response = await axios.get(`vacation/history`);
+ if (user.MEMBERSEQ === userStore.user.id) {
+ // 내 프로필을 클릭한 경우
+ const response = await axios.get(`vacation/history`);
- if (response.status === 200 && response.data) {
- console.log("✅ 연차 내역 응답:", response.data);
- myVacations.value = response.data.data.usedVacations || [];
- receivedVacations.value = response.data.data.receivedVacations || [];
-
- console.log("📌 myVacations:", myVacations.value);
- console.log("📌 receivedVacations:", receivedVacations.value);
-
- isModalOpen.value = true;
+ if (response.status === 200 && response.data) {
+ myVacations.value = response.data.data.usedVacations || [];
+ receivedVacations.value = response.data.data.receivedVacations || [];
+ isModalOpen.value = true; // 내 연차 모달 열기
+ isGrantModalOpen.value = false;
+ } else {
+ console.warn("❌ 연차 내역을 불러오지 못했습니다.");
+ }
} else {
- console.warn("❌ 연차 내역을 불러오지 못했습니다.");
+ // 다른 사람의 프로필을 클릭한 경우
+ selectedUser.value = user;
+ isGrantModalOpen.value = true; // 연차 부여 모달 열기
+ isModalOpen.value = false;
}
} catch (error) {
console.error("🚨 연차 데이터 불러오기 실패:", error);
@@ -81,8 +122,8 @@ const handleProfileClick = async (user) => {
const fetchUserList = async () => {
try {
- await userStore.fetchUserList();
- userList.value = userStore.userList;
+ await userListStore.fetchUserList();
+ userList.value = userListStore.userList;
if (!userList.value.length) {
console.warn("📌 사용자 목록이 비어 있음!");
@@ -104,6 +145,7 @@ const calendarEvents = ref([]); // 최종적으로 FullCalendar에 표시할 이
const fetchedEvents = ref([]); // API에서 불러온 이벤트 (휴가, 공휴일)
const selectedDates = ref(new Map()); // 사용자가 클릭한 날짜 및 타입
const halfDayType = ref(null);
+const vacationCodeMap = ref({}); // 휴가 코드명 저장용
// 공휴일 날짜(YYYY-MM-DD 형식)를 저장 (클릭 불가 처리용)
const holidayDates = ref(new Set());
@@ -124,6 +166,28 @@ datesSet: handleMonthChange,
events: calendarEvents,
});
+const fetchVacationCodes = async () => {
+ try {
+ const response = await axios.get("vacation/codes");
+ if (response.status === 200 && response.data) {
+ // 배열을 객체 형태로 변환
+ vacationCodeMap.value = response.data.data.reduce((acc, item) => {
+ acc[item.code] = item.name; // code를 key로, name을 value로 설정
+ return acc;
+ }, {});
+ } else {
+ console.warn("❌ 공통 코드 데이터를 불러오지 못했습니다.");
+ }
+ } catch (error) {
+ console.error("🚨 공통 코드 API 호출 실패:", error);
+ }
+};
+
+// 🔹 typeCode를 통해 code명 반환
+const getVacationType = (typeCode) => {
+ return vacationCodeMap.value[typeCode] || "기타";
+};
+
/**
* API 이벤트(fetchedEvents)와 사용자가 선택한 날짜(selectedDates)를 병합하여
* calendarEvents를 업데이트하는 함수
@@ -132,29 +196,26 @@ events: calendarEvents,
*/
function updateCalendarEvents() {
const selectedEvents = Array.from(selectedDates.value).map(([date, type]) => {
- let className = "";
- let title = "";
- if (type === "D") {
- className = "selected-am"; // 오전: 왼쪽 절반
- title = "오전반차 (선택)";
- } else if (type === "N") {
- className = "selected-pm"; // 오후: 오른쪽 절반
- title = "오후반차 (선택)";
- } else {
- className = "selected-full"; // 전체 영역
- title = "연차 (선택)";
- }
return {
- title,
+ title: getVacationType(type),
start: date,
backgroundColor: "rgba(0, 128, 0, 0.3)",
display: "background",
- classNames: [className],
+ classNames: [getVacationTypeClass(type)],
};
});
calendarEvents.value = [...fetchedEvents.value, ...selectedEvents];
}
+/**
+ * ✅ 반차 유형에 따라 클래스명 지정 (색상 변경 없이 영역만 조정)
+ */
+ const getVacationTypeClass = (type) => {
+ if (type === "700101") return "half-day-am"; // 오전반차 → 왼쪽 절반
+ if (type === "700102") return "half-day-pm"; // 오후반차 → 오른쪽 절반
+ return "full-day"; // 연차 → 전체 배경
+};
+
/**
* 날짜 클릭 이벤트
* - 주말(토, 일)과 공휴일은 클릭되지 않음
@@ -175,9 +236,9 @@ if (holidayDates.value.has(clickedDateStr)) {
if (!selectedDates.value.has(clickedDateStr)) {
const type = halfDayType.value
? halfDayType.value === "AM"
- ? "D"
- : "N"
- : "F";
+ ? "700101"
+ : "700102"
+ : "700103";
selectedDates.value.set(clickedDateStr, type);
} else {
selectedDates.value.delete(clickedDateStr);
@@ -206,22 +267,11 @@ try {
let dateStr = vac.LOCVACUDT.split("T")[0];
let className = "fc-daygrid-event";
let backgroundColor = userColors.value[vac.MEMBERSEQ] || "#FFFFFF";
- let title = "연차";
- if (vac.LOCVACTYP === "D") {
- title = "오전반차";
- className += " half-day-am";
- } else if (vac.LOCVACTYP === "N") {
- title = "오후반차";
- className += " half-day-pm";
- } else if (vac.LOCVACTYP === "F") {
- title = "연차";
- className += " full-day";
- }
return {
- title,
+ title: getVacationType(vac.LOCVACTYP),
start: dateStr,
backgroundColor,
- classNames: [className],
+ classNames: [getVacationTypeClass(vac.LOCVACTYP)],
};
})
.filter((event) => event !== null);
@@ -252,6 +302,7 @@ try {
const response = await axios.post("vacation", vacationRequests);
if (response.data && response.data.status === "OK") {
alert("휴가가 저장되었습니다.");
+ await fetchRemainingVacation();
// 저장 후 현재 달 데이터 다시 불러오기
const currentDate = fullCalendarRef.value.getApi().getDate();
const year = currentDate.getFullYear();
@@ -317,6 +368,7 @@ fullCalendarRef.value.getApi().refetchEvents();
// 컴포넌트 마운트 시 현재 달의 데이터 로드
onMounted(async () => {
await fetchUserList(); // 사용자 목록 먼저 불러오기
+await fetchVacationCodes();
const today = new Date();
const year = today.getFullYear();
const month = String(today.getMonth() + 1).padStart(2, "0");