This commit is contained in:
dyhj625 2025-02-18 13:19:21 +09:00
parent 27f5db0c6c
commit 922b7e0904
5 changed files with 95 additions and 101 deletions

View File

@ -68,7 +68,7 @@
<script setup> <script setup>
import { defineProps, defineEmits, ref } from 'vue'; import { defineProps, defineEmits, ref } from 'vue';
import BoardProfile from './BoardProfile.vue'; import BoardProfile from './BoardProfile.vue';
import BoardCommentArea from './BoardComentArea.vue'; import BoardCommentArea from './BoardCommentArea.vue';
import PlusButton from '../button/PlusBtn.vue'; import PlusButton from '../button/PlusBtn.vue';
const props = defineProps({ const props = defineProps({

View File

@ -8,13 +8,13 @@
<p>해당 직원에게 부여할 연차 개수를 선택하세요. (남은 개수: {{ availableQuota }})</p> <p>해당 직원에게 부여할 연차 개수를 선택하세요. (남은 개수: {{ availableQuota }})</p>
<div class="vacation-control"> <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> <span class="grant-count">{{ grantCount }}</span>
<button @click="increaseCount" :disabled="grantCount >= availableQuota" class="count-btn">+</button> <button @click="increaseCount" :disabled="grantCount >= availableQuota" class="count-btn">+</button>
</div> </div>
<button class="gift-btn" @click="saveVacationGrant" :disabled="grantCount === 0"> <button class="gift-btn" @click="saveVacationGrant" :disabled="grantCount === 0">
<i class="bx bx-gift"></i> <!-- 선물상자 아이콘 --> <i class="bx bx-gift"></i>
</button> </button>
</div> </div>
</div> </div>
@ -26,65 +26,60 @@
import axios from "@api"; import axios from "@api";
const props = defineProps({ const props = defineProps({
isOpen: Boolean, // isOpen: Boolean,
targetUser: Object, // targetUser: Object,
}); });
const emit = defineEmits(["close", "updateVacation"]); const emit = defineEmits(["close", "updateVacation"]);
const grantCount = ref(0); const grantCount = ref(0);
const maxQuota = 2; // 1 const maxQuota = 2;
const sentCount = ref(0); // const sentCount = ref(0);
const availableQuota = ref(2); // const availableQuota = ref(2);
//
const fetchSentVacationCount = async () => { const fetchSentVacationCount = async () => {
try { try {
const payload = { receiverId: props.targetUser.MEMBERSEQ }; const payload = { receiverId: props.targetUser.MEMBERSEQ };
const response = await axios.get("vacation/sent", { params: payload });
const response = await axios.get(`vacation/sent`,{ params: payload }); sentCount.value = response.data.data[0].count || 0;
console.log(response.data.data[0].count) availableQuota.value = Math.max(maxQuota - sentCount.value, 0);
sentCount.value = response.data.data[0].count || 0; // grantCount.value = availableQuota.value; //
availableQuota.value = Math.max(maxQuota - sentCount.value, 0); // (0 )
console.log(`✅ 보낸 개수: ${sentCount.value}, 남은 개수: ${availableQuota.value}`);
} catch (error) { } catch (error) {
console.error("🚨 연차 전송 기록 조회 실패:", error); console.error("🚨 연차 전송 기록 조회 실패:", error);
availableQuota.value = maxQuota; availableQuota.value = maxQuota;
grantCount.value = maxQuota; //
} }
}; };
//
const increaseCount = () => { const increaseCount = () => {
if (grantCount.value < availableQuota.value) { if (grantCount.value < availableQuota.value) {
grantCount.value++; grantCount.value++;
} }
}; };
//
const decreaseCount = () => { const decreaseCount = () => {
if (grantCount.value > 0) { if (grantCount.value > 0) {
grantCount.value--; grantCount.value--;
} }
}; };
// (saveVacations API )
const saveVacationGrant = async () => { const saveVacationGrant = async () => {
try { try {
const payload = [ const payload = [
{ {
date: new Date().toISOString().split("T")[0], // date: new Date().toISOString().split("T")[0],
type: "700103", // type: "700103",
senderId: props.targetUser.senderId, // ID senderId: props.targetUser.senderId,
receiverId: props.targetUser.MEMBERSEQ, // ID receiverId: props.targetUser.MEMBERSEQ,
count: grantCount.value, // 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") { if (response.data && response.data.status === "OK") {
alert("✅ 연차가 부여되었습니다."); alert("✅ 연차가 부여되었습니다.");
await fetchSentVacationCount(); // await fetchSentVacationCount();
emit("updateVacation"); // emit("updateVacation");
closeModal(); closeModal();
} else { } else {
alert("🚨 연차 추가 중 오류가 발생했습니다."); alert("🚨 연차 추가 중 오류가 발생했습니다.");
@ -95,36 +90,30 @@
} }
}; };
//
const closeModal = () => { const closeModal = () => {
emit("close"); emit("close");
}; };
//
watch( watch(
() => props.isOpen, () => props.isOpen,
async (newVal) => { async (newVal) => {
if (newVal && props.targetUser && props.targetUser.MEMBERSEQ) { if (newVal && props.targetUser && props.targetUser.MEMBERSEQ) {
console.log("🟢 모달이 열렸습니다. 데이터를 로드합니다."); console.log("🟢 모달이 열렸습니다. 데이터를 로드합니다.");
grantCount.value = 0; // await fetchSentVacationCount();
await fetchSentVacationCount(); //
} }
} }
); );
// targetUser fetchSentVacationCount
watch( watch(
() => props.targetUser, () => props.targetUser,
async (newUser) => { async (newUser) => {
if (newUser && newUser.MEMBERSEQ) { if (newUser && newUser.MEMBERSEQ) {
console.log(`🔄 새로운 대상(${newUser.name})이 선택되었습니다.`);
await fetchSentVacationCount(); await fetchSentVacationCount();
} }
}, },
{ deep: true } { deep: true }
); );
//
onMounted(async () => { onMounted(async () => {
if (props.isOpen && props.targetUser && props.targetUser.MEMBERSEQ) { if (props.isOpen && props.targetUser && props.targetUser.MEMBERSEQ) {
await fetchSentVacationCount(); await fetchSentVacationCount();
@ -132,6 +121,7 @@
}); });
</script> </script>
<style scoped> <style scoped>
/* 모달 본문 */ /* 모달 본문 */

View File

@ -1,5 +1,5 @@
<template> <template>
<div v-if="isOpen" class="modal-dialog" @click.self="closeModal"> <div v-if="isOpen" class="modal-dialog" @click.self="closeModal">
<div class="modal-content modal-scroll"> <div class="modal-content modal-scroll">
<h5 class="modal-title">📅 연차 사용 내역</h5> <h5 class="modal-title">📅 연차 사용 내역</h5>
<button class="close-btn" @click="closeModal"></button> <button class="close-btn" @click="closeModal"></button>
@ -13,7 +13,7 @@
class="vacation-item" class="vacation-item"
> >
<span v-if="vacation.type === 'used'" class="vacation-index"> <span v-if="vacation.type === 'used'" class="vacation-index">
{{ totalUsedVacationCount - usedVacations.findIndex(v => v.date === vacation.date) }}) {{ totalUsedVacationCount - usedVacations.findIndex(v => v.date === vacation.date) }} )
</span> </span>
<span :class="vacation.type === 'used' ? 'minus-symbol' : 'plus-symbol'"> <span :class="vacation.type === 'used' ? 'minus-symbol' : 'plus-symbol'">
{{ vacation.type === 'used' ? '-' : '+' }} {{ vacation.type === 'used' ? '-' : '+' }}
@ -29,53 +29,57 @@
🚫 사용한 연차가 없습니다. 🚫 사용한 연차가 없습니다.
</p> </p>
</div> </div>
</div> </div>
</template> </template>
<script setup> <script setup>
import { defineProps, defineEmits, computed } from "vue"; import { defineProps, defineEmits, computed } from "vue";
const props = defineProps({ const props = defineProps({
isOpen: Boolean, isOpen: Boolean,
myVacations: { myVacations: {
type: Array, type: Array,
default: () => [], default: () => [],
}, },
receivedVacations: { receivedVacations: {
type: Array, type: Array,
default: () => [], default: () => [],
}, },
userColors: { userColors: {
type: Object, type: Object,
default: () => ({}), 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 usedVacations = computed(() => props.myVacations.map(v => ({ ...v, type: "used" })));
const receivedVacations = computed(() => props.receivedVacations.map(v => ({ ...v, type: "received" }))); const receivedVacations = computed(() => props.receivedVacations
.filter(v => !v.senderId) //
.map(v => ({ ...v, type: "received" }))
);
const mergedVacations = computed(() => { const mergedVacations = computed(() => {
return [...usedVacations.value, ...receivedVacations.value].sort( return [...usedVacations.value, ...receivedVacations.value].sort(
(a, b) => new Date(b.date) - new Date(a.date) (a, b) => new Date(b.date) - new Date(a.date)
); );
}); });
// (YYYY-MM-DD) // (YYYY-MM-DD)
const formatDate = (dateString) => { const formatDate = (dateString) => {
const date = new Date(dateString); const date = new Date(dateString);
return date.toISOString().split("T")[0]; // YYYY-MM-DD return date.toISOString().split("T")[0]; // YYYY-MM-DD
}; };
const closeModal = () => {
emit("close");
};
</script>
const closeModal = () => {
emit("close");
};
</script>
<style scoped> <style scoped>
/* 모달 스타일 */ /* 모달 스타일 */

View File

@ -103,7 +103,7 @@
</template> </template>
<script setup> <script setup>
import BoardCommentArea from '@c/board/BoardComentArea.vue'; import BoardCommentArea from '@c/board/BoardCommentArea.vue';
import BoardProfile from '@c/board/BoardProfile.vue'; import BoardProfile from '@c/board/BoardProfile.vue';
import BoardCommentList from '@c/board/BoardCommentList.vue'; import BoardCommentList from '@c/board/BoardCommentList.vue';
import BoardRecommendBtn from '@c/button/BoardRecommendBtn.vue'; import BoardRecommendBtn from '@c/button/BoardRecommendBtn.vue';