Merge remote-tracking branch 'origin/main' into board-comment
This commit is contained in:
commit
eab2971c87
@ -8,13 +8,13 @@
|
||||
<p>해당 직원에게 부여할 연차 개수를 선택하세요. (남은 개수: {{ availableQuota }}개)</p>
|
||||
|
||||
<div class="vacation-control">
|
||||
<button @click="decreaseCount" :disabled="grantCount <= 0" class="count-btn">-</button>
|
||||
<button @click="decreaseCount" :disabled="grantCount < 2" class="count-btn">-</button>
|
||||
<span class="grant-count">{{ grantCount }}</span>
|
||||
<button @click="increaseCount" :disabled="grantCount >= availableQuota" class="count-btn">+</button>
|
||||
</div>
|
||||
|
||||
<button class="gift-btn" @click="saveVacationGrant" :disabled="grantCount === 0">
|
||||
<i class="bx bx-gift"></i> <!-- 선물상자 아이콘 -->
|
||||
<i class="bx bx-gift"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@ -26,65 +26,60 @@
|
||||
import axios from "@api";
|
||||
|
||||
const props = defineProps({
|
||||
isOpen: Boolean, // 모달 상태
|
||||
targetUser: Object, // 선택한 사용자 정보
|
||||
isOpen: Boolean,
|
||||
targetUser: Object,
|
||||
});
|
||||
|
||||
const emit = defineEmits(["close", "updateVacation"]);
|
||||
const grantCount = ref(0);
|
||||
const maxQuota = 2; // 1년에 보낼 수 있는 최대 개수
|
||||
const sentCount = ref(0); // 현재까지 보낸 개수
|
||||
const availableQuota = ref(2); // 남은 개수
|
||||
const maxQuota = 2;
|
||||
const sentCount = ref(0);
|
||||
const availableQuota = ref(2);
|
||||
|
||||
// ✅ 해당 사용자에게 이미 보낸 연차 개수 조회
|
||||
const fetchSentVacationCount = async () => {
|
||||
try {
|
||||
const payload = { receiverId: props.targetUser.MEMBERSEQ };
|
||||
|
||||
const response = await axios.get(`vacation/sent`,{ params: payload });
|
||||
console.log(response.data.data[0].count)
|
||||
sentCount.value = response.data.data[0].count || 0; // 이미 보낸 개수
|
||||
availableQuota.value = Math.max(maxQuota - sentCount.value, 0); // 남은 개수 (0 이하 방지)
|
||||
console.log(`✅ 보낸 개수: ${sentCount.value}, 남은 개수: ${availableQuota.value}`);
|
||||
const response = await axios.get("vacation/sent", { params: payload });
|
||||
sentCount.value = response.data.data[0].count || 0;
|
||||
availableQuota.value = Math.max(maxQuota - sentCount.value, 0);
|
||||
grantCount.value = availableQuota.value; // ✅ 남은 개수로 기본값 설정
|
||||
} catch (error) {
|
||||
console.error("🚨 연차 전송 기록 조회 실패:", error);
|
||||
availableQuota.value = maxQuota;
|
||||
grantCount.value = maxQuota; // 기본값 설정
|
||||
}
|
||||
};
|
||||
|
||||
// ✅ 연차 개수 증가
|
||||
const increaseCount = () => {
|
||||
if (grantCount.value < availableQuota.value) {
|
||||
grantCount.value++;
|
||||
}
|
||||
};
|
||||
|
||||
// ✅ 연차 개수 감소
|
||||
const decreaseCount = () => {
|
||||
if (grantCount.value > 0) {
|
||||
grantCount.value--;
|
||||
}
|
||||
};
|
||||
|
||||
// ✅ 연차 부여 저장 요청 (saveVacations API 호출)
|
||||
const saveVacationGrant = async () => {
|
||||
try {
|
||||
const payload = [
|
||||
{
|
||||
date: new Date().toISOString().split("T")[0], // 오늘 날짜
|
||||
type: "700103", // 연차 코드
|
||||
senderId: props.targetUser.senderId, // 보내는 사람 ID
|
||||
receiverId: props.targetUser.MEMBERSEQ, // 받는 사람 ID
|
||||
count: grantCount.value, // 부여 개수
|
||||
date: new Date().toISOString().split("T")[0],
|
||||
type: "700103",
|
||||
senderId: props.targetUser.senderId,
|
||||
receiverId: props.targetUser.MEMBERSEQ,
|
||||
count: grantCount.value,
|
||||
},
|
||||
];
|
||||
|
||||
const response = await axios.post("vacation/save", payload);
|
||||
|
||||
const response = await axios.post("vacation", payload);
|
||||
console.log(response)
|
||||
if (response.data && response.data.status === "OK") {
|
||||
alert("✅ 연차가 부여되었습니다.");
|
||||
await fetchSentVacationCount(); // ✅ 보낸 개수 업데이트
|
||||
emit("updateVacation"); // ✅ 연차 정보 갱신 요청
|
||||
await fetchSentVacationCount();
|
||||
emit("updateVacation");
|
||||
closeModal();
|
||||
} else {
|
||||
alert("🚨 연차 추가 중 오류가 발생했습니다.");
|
||||
@ -95,36 +90,30 @@
|
||||
}
|
||||
};
|
||||
|
||||
// ✅ 모달 닫기
|
||||
const closeModal = () => {
|
||||
emit("close");
|
||||
};
|
||||
|
||||
// ✅ 모달이 열릴 때 초기 값 설정 및 보낸 개수 조회
|
||||
watch(
|
||||
() => props.isOpen,
|
||||
async (newVal) => {
|
||||
if (newVal && props.targetUser && props.targetUser.MEMBERSEQ) {
|
||||
console.log("🟢 모달이 열렸습니다. 데이터를 로드합니다.");
|
||||
grantCount.value = 0; // 초기화
|
||||
await fetchSentVacationCount(); // 보낸 개수 불러오기
|
||||
await fetchSentVacationCount();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// ✅ targetUser가 변경될 때도 fetchSentVacationCount 호출
|
||||
watch(
|
||||
() => props.targetUser,
|
||||
async (newUser) => {
|
||||
if (newUser && newUser.MEMBERSEQ) {
|
||||
console.log(`🔄 새로운 대상(${newUser.name})이 선택되었습니다.`);
|
||||
await fetchSentVacationCount();
|
||||
}
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
// ✅ 컴포넌트가 마운트될 때도 보낸 개수 불러오기
|
||||
onMounted(async () => {
|
||||
if (props.isOpen && props.targetUser && props.targetUser.MEMBERSEQ) {
|
||||
await fetchSentVacationCount();
|
||||
@ -132,6 +121,7 @@
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<style scoped>
|
||||
|
||||
/* 모달 본문 */
|
||||
|
||||
@ -1,81 +1,85 @@
|
||||
<template>
|
||||
<div v-if="isOpen" class="modal-dialog" @click.self="closeModal">
|
||||
<div class="modal-content modal-scroll">
|
||||
<h5 class="modal-title">📅 내 연차 사용 내역</h5>
|
||||
<button class="close-btn" @click="closeModal">✖</button>
|
||||
<div v-if="isOpen" class="modal-dialog" @click.self="closeModal">
|
||||
<div class="modal-content modal-scroll">
|
||||
<h5 class="modal-title">📅 내 연차 사용 내역</h5>
|
||||
<button class="close-btn" @click="closeModal">✖</button>
|
||||
|
||||
<!-- 연차 사용 및 받은 연차 리스트 -->
|
||||
<div class="modal-body" v-if="mergedVacations.length > 0">
|
||||
<ol class="vacation-list">
|
||||
<li
|
||||
v-for="(vacation, index) in mergedVacations"
|
||||
:key="index"
|
||||
class="vacation-item"
|
||||
>
|
||||
<span v-if="vacation.type === 'used'" class="vacation-index">
|
||||
{{ totalUsedVacationCount - usedVacations.findIndex(v => v.date === vacation.date) }})
|
||||
</span>
|
||||
<span :class="vacation.type === 'used' ? 'minus-symbol' : 'plus-symbol'">
|
||||
{{ vacation.type === 'used' ? '-' : '+' }}
|
||||
</span>
|
||||
<span :style="{ color: userColors[vacation.senderId || vacation.receiverId] || '#000' }"
|
||||
class="vacation-date">{{ formatDate(vacation.date) }}</span>
|
||||
</li>
|
||||
</ol>
|
||||
<!-- 연차 사용 및 받은 연차 리스트 -->
|
||||
<div class="modal-body" v-if="mergedVacations.length > 0">
|
||||
<ol class="vacation-list">
|
||||
<li
|
||||
v-for="(vacation, index) in mergedVacations"
|
||||
:key="index"
|
||||
class="vacation-item"
|
||||
>
|
||||
<span v-if="vacation.type === 'used'" class="vacation-index">
|
||||
{{ totalUsedVacationCount - usedVacations.findIndex(v => v.date === vacation.date) }} )
|
||||
</span>
|
||||
<span :class="vacation.type === 'used' ? 'minus-symbol' : 'plus-symbol'">
|
||||
{{ vacation.type === 'used' ? '-' : '+' }}
|
||||
</span>
|
||||
<span :style="{ color: userColors[vacation.senderId || vacation.receiverId] || '#000' }"
|
||||
class="vacation-date">{{ formatDate(vacation.date) }}</span>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
<!-- 연차 데이터 없음 -->
|
||||
<p v-if="mergedVacations.length === 0" class="no-data">
|
||||
🚫 사용한 연차가 없습니다.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 연차 데이터 없음 -->
|
||||
<p v-if="mergedVacations.length === 0" class="no-data">
|
||||
🚫 사용한 연차가 없습니다.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { defineProps, defineEmits, computed } from "vue";
|
||||
|
||||
<script setup>
|
||||
import { defineProps, defineEmits, computed } from "vue";
|
||||
const props = defineProps({
|
||||
isOpen: Boolean,
|
||||
myVacations: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
receivedVacations: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
userColors: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
});
|
||||
|
||||
const props = defineProps({
|
||||
isOpen: Boolean,
|
||||
myVacations: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
receivedVacations: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
userColors: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
});
|
||||
const emit = defineEmits(["close"]);
|
||||
|
||||
const emit = defineEmits(["close"]);
|
||||
// ✅ 사용한 연차 개수
|
||||
const totalUsedVacationCount = computed(() => props.myVacations.length);
|
||||
|
||||
// ✅ 사용한 연차 개수
|
||||
const totalUsedVacationCount = computed(() => props.myVacations.length);
|
||||
// ✅ 사용한 연차 + 받은 연차 통합 후 내림차순 정렬
|
||||
const usedVacations = computed(() => props.myVacations.map(v => ({ ...v, type: "used" })));
|
||||
const receivedVacations = computed(() => props.receivedVacations
|
||||
.filter(v => !v.senderId) // ✅ 보낸 사람이 있는 경우 리스트에서 제외
|
||||
.map(v => ({ ...v, type: "received" }))
|
||||
);
|
||||
|
||||
// ✅ 사용한 연차 + 받은 연차 통합 후 내림차순 정렬
|
||||
const usedVacations = computed(() => props.myVacations.map(v => ({ ...v, type: "used" })));
|
||||
const receivedVacations = computed(() => props.receivedVacations.map(v => ({ ...v, type: "received" })));
|
||||
const mergedVacations = computed(() => {
|
||||
return [...usedVacations.value, ...receivedVacations.value].sort(
|
||||
(a, b) => new Date(b.date) - new Date(a.date)
|
||||
);
|
||||
});
|
||||
|
||||
const mergedVacations = computed(() => {
|
||||
return [...usedVacations.value, ...receivedVacations.value].sort(
|
||||
(a, b) => new Date(b.date) - new Date(a.date)
|
||||
);
|
||||
});
|
||||
// ✅ 날짜 형식 변환 (YYYY-MM-DD)
|
||||
const formatDate = (dateString) => {
|
||||
const date = new Date(dateString);
|
||||
return date.toISOString().split("T")[0]; // YYYY-MM-DD 형식
|
||||
};
|
||||
|
||||
// ✅ 날짜 형식 변환 (YYYY-MM-DD)
|
||||
const formatDate = (dateString) => {
|
||||
const date = new Date(dateString);
|
||||
return date.toISOString().split("T")[0]; // YYYY-MM-DD 형식
|
||||
};
|
||||
const closeModal = () => {
|
||||
emit("close");
|
||||
};
|
||||
</script>
|
||||
|
||||
const closeModal = () => {
|
||||
emit("close");
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 모달 스타일 */
|
||||
|
||||
Loading…
Reference in New Issue
Block a user