board-list-d머지
This commit is contained in:
parent
52809ba743
commit
04b7db1560
@ -14,16 +14,29 @@
|
|||||||
@deleteClick="deleteClick"
|
@deleteClick="deleteClick"
|
||||||
@submitPassword="submitPassword"
|
@submitPassword="submitPassword"
|
||||||
@updateReaction="handleUpdateReaction"
|
@updateReaction="handleUpdateReaction"
|
||||||
@toggleEdit="emit('toggleEdit', comment.commentId, true)"
|
@toggleEdit="toggleEdit(true)"
|
||||||
/>
|
/>
|
||||||
|
<!-- 댓글 비밀번호 입력창 (익명일 경우) -->
|
||||||
|
<div v-if="isPassword && unknown" class="mt-3 w-25 ms-auto">
|
||||||
|
<div class="input-group">
|
||||||
|
<input
|
||||||
|
type="password"
|
||||||
|
class="form-control"
|
||||||
|
v-model="password"
|
||||||
|
placeholder="비밀번호 입력"
|
||||||
|
/>
|
||||||
|
<button class="btn btn-primary" @click="submitPassword">확인</button>
|
||||||
|
</div>
|
||||||
|
<span v-if="passwordAlert" class="invalid-feedback d-block text-start">{{ passwordAlert }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="mt-6">
|
<div class="mt-6">
|
||||||
<template v-if="isEditTextarea">
|
<template v-if="isEditTextarea">
|
||||||
<textarea v-model="editedContent" class="form-control"></textarea>
|
<textarea v-model="editedContent" class="form-control"></textarea>
|
||||||
<div class="mt-2 d-flex justify-content-end">
|
<div class="mt-2 d-flex justify-content-end">
|
||||||
<button class="btn btn-secondary me-2" @click="emit('toggleEdit', comment.commentId, false)">취소</button>
|
<button class="btn btn-secondary me-2" @click="cancelEdit">취소</button>
|
||||||
<button class="btn btn-primary" @click="submitEdit">수정 완료</button>
|
<button class="btn btn-primary" @click="submitEdit">수정</button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
@ -51,55 +64,45 @@
|
|||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<!-- <ul class="list-unstyled twoDepth">
|
|
||||||
<li>
|
|
||||||
<BoardProfile profileName=곤데리2 :showDetail="false" />
|
|
||||||
<div class="mt-2">저도 궁금합니다.</div>
|
|
||||||
<BoardCommentArea v-if="comment" />
|
|
||||||
</li>
|
|
||||||
</ul> -->
|
|
||||||
<!-- <BoardProfile profileName=곤데리 :showDetail="false" />
|
|
||||||
<div class="mt-2">저도 궁금합니다.</div>
|
|
||||||
<PlusButton @click="toggleComment"/>
|
|
||||||
<BoardCommentArea v-if="comment" /> -->
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import axios from '@api';
|
||||||
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 './BoardCommentArea.vue';
|
import BoardCommentArea from './BoardCommentArea.vue';
|
||||||
import PlusButton from '../button/PlusBtn.vue';
|
import PlusButton from '../button/PlusBtn.vue';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
comment: {
|
comment: {
|
||||||
type: Object,
|
type: Object,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
unknown: {
|
unknown: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
isPlusButton: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
isPlusButton: {
|
isLike: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true,
|
default: false,
|
||||||
},
|
},
|
||||||
isLike: {
|
isEditTextarea: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false
|
||||||
},
|
},
|
||||||
isEditTextarea: {
|
isPassword: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false,
|
||||||
},
|
},
|
||||||
isPassword: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// emits 정의
|
// emits 정의
|
||||||
const emit = defineEmits(['submitComment', 'updateReaction', 'toggleEdit', 'editClick']);
|
const emit = defineEmits(['submitComment', 'updateReaction', 'toggleEdit',]);
|
||||||
|
|
||||||
// 댓글 입력 창 토글
|
// 댓글 입력 창 토글
|
||||||
const isComment = ref(false);
|
const isComment = ref(false);
|
||||||
@ -107,6 +110,22 @@ const toggleComment = () => {
|
|||||||
isComment.value = !isComment.value;
|
isComment.value = !isComment.value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 비밀번호 & 수정 모드 관련 상태
|
||||||
|
const password = ref('');
|
||||||
|
const passwordAlert = ref('');
|
||||||
|
const isPassword = ref(false);
|
||||||
|
const isEditTextarea = ref(false);
|
||||||
|
const lastClickedButton = ref("");
|
||||||
|
|
||||||
|
const toggleEdit = (status) => {
|
||||||
|
if (props.unknown) {
|
||||||
|
isPassword.value = status; // 익명 사용자면 비밀번호 입력창 표시
|
||||||
|
lastClickedButton.value = "edit";
|
||||||
|
} else {
|
||||||
|
isEditTextarea.value = status; // 비밀번호가 필요 없으면 바로 수정 모드
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// 부모 컴포넌트에 대댓글 추가 요청
|
// 부모 컴포넌트에 대댓글 추가 요청
|
||||||
const submitComment = (newComment) => {
|
const submitComment = (newComment) => {
|
||||||
emit('submitComment', { parentId: props.comment.commentId, ...newComment });
|
emit('submitComment', { parentId: props.comment.commentId, ...newComment });
|
||||||
@ -118,21 +137,109 @@ const submitComment = (newComment) => {
|
|||||||
const handleUpdateReaction = (reactionData) => {
|
const handleUpdateReaction = (reactionData) => {
|
||||||
emit('updateReaction', {
|
emit('updateReaction', {
|
||||||
boardId: props.comment.boardId,
|
boardId: props.comment.boardId,
|
||||||
commentId: props.comment.commentId,
|
commentId: props.comment.commentId || reactionData.commentId,
|
||||||
...reactionData
|
...reactionData,
|
||||||
});
|
});
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 수정
|
// 댓글 수정 버튼 클릭
|
||||||
const editClick = (data) => {
|
const editClick = () => {
|
||||||
emit('editClick', data);
|
if (props.unknown) {
|
||||||
|
console.log('수정')
|
||||||
|
togglePassword("edit");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const deleteClick = () => {
|
||||||
|
if (props.unknown) {
|
||||||
|
console.log('삭제')
|
||||||
|
togglePassword("delete");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const togglePassword = (button) => {
|
||||||
|
if (lastClickedButton.value === button) {
|
||||||
|
isPassword.value = !isPassword.value;
|
||||||
|
} else {
|
||||||
|
isPassword.value = true;
|
||||||
|
}
|
||||||
|
lastClickedButton.value = button;
|
||||||
|
};
|
||||||
|
|
||||||
|
// const deleteComment = async () => {
|
||||||
|
// if (!confirm("정말 이 댓글을 삭제하시겠습니까?")) return;
|
||||||
|
|
||||||
|
// try {
|
||||||
|
// console.log("댓글 삭제 요청 시작:");
|
||||||
|
// console.log("댓글 ID:", props.comment.commentId);
|
||||||
|
// console.log("게시글 ID:", props.comment.boardId);
|
||||||
|
// console.log("비밀번호 포함 여부:", props.unknown ? "예 (익명 사용자)" : "아니오 (로그인 사용자)");
|
||||||
|
|
||||||
|
// const response = await axios.delete(`board/${props.comment.commentId}`, {
|
||||||
|
// data: { LOCCMTSEQ: props.comment.commentId }
|
||||||
|
// });
|
||||||
|
|
||||||
|
// console.log("📌 서버 응답:", response.data);
|
||||||
|
|
||||||
|
// if (response.data.code === 200) {
|
||||||
|
// console.log("댓글 삭제 성공!");
|
||||||
|
// // emit("commentDeleted", props.comment.commentId);
|
||||||
|
// } else {
|
||||||
|
// console.log("❌ 댓글 삭제 실패:", response.data.message);
|
||||||
|
// // alert("댓글 삭제에 실패했습니다.");
|
||||||
|
// }
|
||||||
|
// } catch (error) {
|
||||||
|
// console.log("🚨 댓글 삭제 중 오류 발생:", error);
|
||||||
|
// alert("댓글 삭제 중 오류가 발생했습니다.");
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
|
||||||
|
|
||||||
|
// 비밀번호 제출
|
||||||
|
const submitPassword = async () => {
|
||||||
|
if (!password.value) {
|
||||||
|
passwordAlert.value = "비밀번호를 입력해주세요.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(props.comment.commentId)
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await axios.post(`board/${props.comment.commentId}/password`, {
|
||||||
|
LOCCMTPWD: password.value,
|
||||||
|
LOCCMTSEQ: 288,
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("응답!!!!!!!!", response); // 서버 응답 전체 확인
|
||||||
|
console.log("응답 데이터:", response.data);
|
||||||
|
|
||||||
|
if (response.data.code === 200 && response.data.data === true) {
|
||||||
|
console.log('되는거니')
|
||||||
|
// deleteComment()
|
||||||
|
// // password.value = '';
|
||||||
|
// // isPassword.value = false;
|
||||||
|
// // isEditTextarea.value = true;
|
||||||
|
} else {
|
||||||
|
passwordAlert.value = "비밀번호가 일치하지 않습니다.";
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
passwordAlert.value = "비밀번호 검증 중 오류가 발생했습니다.";
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 수정
|
|
||||||
const editedContent = ref(props.comment.content);
|
const editedContent = ref(props.comment.content);
|
||||||
const submitEdit = () => {
|
|
||||||
emit('submitComment', { commentId: props.comment.commentId, content: editedContent.value });
|
// 댓글 수정 취소
|
||||||
emit('toggleEdit', props.comment.commentId, false); // 수정 모드 종료
|
const cancelEdit = () => {
|
||||||
|
isEditTextarea.value = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 댓글 수정 내용 저장
|
||||||
|
const submitEdit = () => {
|
||||||
|
emit('submitComment', { commentId: props.comment.commentId, content: editedContent.value });
|
||||||
|
isEditTextarea.value = false; // 수정 모드 종료
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -43,6 +43,7 @@
|
|||||||
class="form-control flex-grow-1"
|
class="form-control flex-grow-1"
|
||||||
v-model="password"
|
v-model="password"
|
||||||
/>
|
/>
|
||||||
|
<!-- <span v-if="passwordAlert" class="invalid-feedback d-block text-start">{{ passwordAlert }}</span> -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -74,20 +75,18 @@ const props = defineProps({
|
|||||||
|
|
||||||
const comment = ref('');
|
const comment = ref('');
|
||||||
const password = ref('');
|
const password = ref('');
|
||||||
const isCheck = ref(false);
|
const isCheck = ref(props.unknown);
|
||||||
|
|
||||||
const emit = defineEmits(['submitComment']);
|
const emit = defineEmits(['submitComment']);
|
||||||
|
|
||||||
watch(() => props.unknown, (newVal) => {
|
watch(() => props.unknown, (newVal) => {
|
||||||
if (!newVal) {
|
isCheck.value = newVal;
|
||||||
isCheck.value = false;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function handleCommentSubmit() {
|
function handleCommentSubmit() {
|
||||||
emit('submitComment', {
|
emit('submitComment', {
|
||||||
comment: comment.value,
|
comment: comment.value,
|
||||||
password: password.value,
|
password: isCheck.value ? password.value : '',
|
||||||
});
|
});
|
||||||
|
|
||||||
comment.value = '';
|
comment.value = '';
|
||||||
|
|||||||
@ -9,13 +9,14 @@
|
|||||||
:unknown="unknown"
|
:unknown="unknown"
|
||||||
:comment="comment"
|
:comment="comment"
|
||||||
:isPassword="isPassword"
|
:isPassword="isPassword"
|
||||||
|
:isEditTextarea="isEditTextarea"
|
||||||
@editClick="editClick"
|
@editClick="editClick"
|
||||||
@deleteClick="deleteClick"
|
@deleteClick="deleteClick"
|
||||||
@submitPassword="submitPassword"
|
@submitPassword="submitPassword"
|
||||||
@submitComment="submitComment"
|
@submitComment="submitComment"
|
||||||
@updateReaction="(reactionData) => handleUpdateReaction(reactionData, comment.commentId)"
|
@commentDeleted="handleCommentDeleted"
|
||||||
|
@updateReaction="(reactionData) => handleUpdateReaction(reactionData, comment.commentId, comment.boardId)"
|
||||||
/>
|
/>
|
||||||
<!-- @updateReaction="handleUpdateReaction" -->
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</template>
|
</template>
|
||||||
@ -38,6 +39,10 @@ const props = defineProps({
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
isEditTextarea: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits(['submitComment', 'updateReaction', 'editClick']);
|
const emit = defineEmits(['submitComment', 'updateReaction', 'editClick']);
|
||||||
@ -46,17 +51,13 @@ const submitComment = (replyData) => {
|
|||||||
emit('submitComment', replyData);
|
emit('submitComment', replyData);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleUpdateReaction = (reactionData, commentId) => {
|
const handleUpdateReaction = (reactionData, commentId, boardId) => {
|
||||||
// console.log('📢 BoardCommentList에서 이벤트 수신:', reactionData);
|
|
||||||
// console.log('📌 전달할 댓글 ID>>>>:', commentId);
|
|
||||||
|
|
||||||
const updatedReactionData = {
|
const updatedReactionData = {
|
||||||
...reactionData,
|
...reactionData,
|
||||||
commentId: commentId
|
commentId: commentId || reactionData.commentId,
|
||||||
|
boardId: boardId || reactionData.boardId,
|
||||||
};
|
};
|
||||||
|
|
||||||
// console.log('🚀 최종 전달할 데이터:', updatedReactionData);
|
|
||||||
|
|
||||||
emit('updateReaction', updatedReactionData);
|
emit('updateReaction', updatedReactionData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,102 +1,104 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="container flex-grow-1 container-p-y">
|
<div class="container flex-grow-1 container-p-y">
|
||||||
<div class="row mb-4">
|
<div class="card">
|
||||||
<!-- 검색창 -->
|
<div class="card-header">
|
||||||
<div class="container col-8 px-3">
|
<!-- 검색창 -->
|
||||||
<search-bar @update:data="search" />
|
<div class="container col-6 mt-12 mb-8">
|
||||||
</div>
|
<search-bar @update:data="search" />
|
||||||
<!-- 새 글쓰기 -->
|
</div>
|
||||||
<div class="container col-2 px-12 py-2">
|
|
||||||
<router-link to="/board/write">
|
|
||||||
<WriteButton />
|
|
||||||
</router-link>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="card-datatable">
|
||||||
|
<div class="row mx-6 my-6 justify-content-between g-3 align-items-center">
|
||||||
|
<div class="col-md-6 d-flex flex-column flex-md-row align-items-md-center gap-2 mt-0">
|
||||||
|
<!-- 리스트 갯수 선택 -->
|
||||||
|
<select class="form-select w-25 w-md-100" v-model="selectedSize" @change="handleSizeChange">
|
||||||
|
<option value="10">10개씩</option>
|
||||||
|
<option value="20">20개씩</option>
|
||||||
|
<option value="30">30개씩</option>
|
||||||
|
<option value="50">50개씩</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
<div class="row g-3">
|
<!-- 셀렉트 박스 -->
|
||||||
<!-- 셀렉트 박스 -->
|
<select class="form-select w-25 w-md-100" v-model="selectedOrder" @change="handleSortChange">
|
||||||
<div class="col-12 col-md-auto">
|
<option value="date">최신날짜</option>
|
||||||
<select class="form-select" v-model="selectedOrder" @change="handleSortChange">
|
<option value="views">조회수</option>
|
||||||
<option value="date">최신날짜</option>
|
</select>
|
||||||
<option value="views">조회수</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<!-- 공지 접기 기능 -->
|
|
||||||
<div class="container col-1 px-0 py-2">
|
|
||||||
<label>
|
|
||||||
<input type="checkbox" v-model="showNotices" /> 공지 숨기기
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<!-- 리스트 갯수 선택 -->
|
|
||||||
<div class="container col-1 px-0 py-2">
|
|
||||||
<select class="form-select" v-model="selectedSize" @change="handleSizeChange">
|
|
||||||
<option value="10">10개씩</option>
|
|
||||||
<option value="20">20개씩</option>
|
|
||||||
<option value="30">30개씩</option>
|
|
||||||
<option value="50">50개씩</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<br>
|
|
||||||
<!-- 게시판 -->
|
|
||||||
<div class="table-responsive">
|
|
||||||
<table class="table table-bordered">
|
|
||||||
<thead class="table-light">
|
|
||||||
<tr>
|
|
||||||
<th style="width: 8%;">번호</th>
|
|
||||||
<th style="width: 50%;">제목</th>
|
|
||||||
<th style="width: 15%;">작성자</th>
|
|
||||||
<th style="width: 12%;">작성일</th>
|
|
||||||
<th style="width: 10%;">조회수</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<!-- 공지사항 -->
|
|
||||||
<template v-if="pagination.currentPage === 1 && !showNotices">
|
|
||||||
<tr v-for="(notice, index) in noticeList"
|
|
||||||
:key="'notice-' + index"
|
|
||||||
class="bg-label-gray"
|
|
||||||
@click="goDetail(notice.id)">
|
|
||||||
<td>공지</td>
|
|
||||||
<td>
|
|
||||||
📌 {{ notice.title }}
|
|
||||||
<i v-if="notice.img" class="bi bi-image me-1"></i>
|
|
||||||
<i v-if="notice.hasAttachment" class="bi bi-paperclip"></i>
|
|
||||||
<span v-if="isNewPost(notice.date)" class="badge bg-danger text-white ms-2 fs-tiny">N</span>
|
|
||||||
</td>
|
|
||||||
<td>{{ notice.author }}</td>
|
|
||||||
<td>{{ notice.date }}</td>
|
|
||||||
<td>{{ notice.views }}</td>
|
|
||||||
</tr>
|
|
||||||
</template>
|
|
||||||
<!-- 일반 게시물 -->
|
|
||||||
<tr v-for="(post, index) in generalList"
|
|
||||||
:key="'post-' + index"
|
|
||||||
class="invert-bg-white"
|
|
||||||
@click="goDetail(post.realId)">
|
|
||||||
<td>{{ post.id }}</td>
|
|
||||||
<td>
|
|
||||||
{{ post.title }}
|
|
||||||
<i v-if="post.img" class="bi bi-image me-1"></i>
|
|
||||||
<i v-if="post.hasAttachment" class="bi bi-paperclip"></i>
|
|
||||||
<span v-if="isNewPost(post.date)" class="badge bg-danger text-white ms-2 fs-tiny">N</span>
|
|
||||||
</td>
|
|
||||||
<td>{{ post.author }}</td>
|
|
||||||
<td>{{ post.date }}</td>
|
|
||||||
<td>{{ post.views }}</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 페이지네이션 -->
|
<!-- 공지 접기 기능 -->
|
||||||
<div class="row g-3">
|
<div class="form-check mb-0 ms-2">
|
||||||
<div class="mt-8">
|
<input class="form-check-input" type="checkbox" v-model="showNotices" id="hideNotices" />
|
||||||
<Pagination
|
<label class="form-check-label" for="hideNotices">공지 숨기기</label>
|
||||||
v-if="pagination.pages"
|
</div>
|
||||||
v-bind="pagination"
|
</div>
|
||||||
@update:currentPage="handlePageChange"
|
<div class="col-md-6 d-flex flex-column flex-md-row align-items-md-center justify-content-md-end gap-2">
|
||||||
/>
|
<!-- 새 글쓰기 -->
|
||||||
|
<router-link to="/board/write" class="ms-2">
|
||||||
|
<WriteButton class="btn add-new btn-primary"/>
|
||||||
|
</router-link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 게시판 -->
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="datatables-users table border-top dataTable dtr-column">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th style="width: 11%;" class="text-center">번호</th>
|
||||||
|
<th style="width: 45%;" class="text-center">제목</th>
|
||||||
|
<th style="width: 10%;" class="text-center">작성자</th>
|
||||||
|
<th style="width: 15%;" class="text-center">작성일</th>
|
||||||
|
<th style="width: 9%;" class="text-center">조회수</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<!-- 공지사항 -->
|
||||||
|
<template v-if="pagination.currentPage === 1 && !showNotices">
|
||||||
|
<tr v-for="(notice, index) in noticeList"
|
||||||
|
:key="'notice-' + index"
|
||||||
|
class="bg-label-gray"
|
||||||
|
@click="goDetail(notice.id)">
|
||||||
|
<td class="text-center">공지</td>
|
||||||
|
<td>
|
||||||
|
📌 {{ notice.title }}
|
||||||
|
<i v-if="notice.img" class="bi bi-image me-1"></i>
|
||||||
|
<i v-if="notice.hasAttachment" class="bi bi-paperclip"></i>
|
||||||
|
<span v-if="isNewPost(notice.date)" class="badge bg-danger text-white ms-2 fs-tiny">N</span>
|
||||||
|
</td>
|
||||||
|
<td class="text-center">{{ notice.author }}</td>
|
||||||
|
<td class="text-center">{{ notice.date }}</td>
|
||||||
|
<td class="text-center">{{ notice.views }}</td>
|
||||||
|
</tr>
|
||||||
|
</template>
|
||||||
|
<!-- 일반 게시물 -->
|
||||||
|
<tr v-for="(post, index) in generalList"
|
||||||
|
:key="'post-' + index"
|
||||||
|
class="invert-bg-white"
|
||||||
|
@click="goDetail(post.realId)">
|
||||||
|
<td class="text-center">{{ post.id }}</td>
|
||||||
|
<td>
|
||||||
|
{{ post.title }}
|
||||||
|
<i v-if="post.img" class="bi bi-image me-1"></i>
|
||||||
|
<i v-if="post.hasAttachment" class="bi bi-paperclip"></i>
|
||||||
|
<span v-if="isNewPost(post.date)" class="badge bg-danger text-white ms-2 fs-tiny">N</span>
|
||||||
|
</td>
|
||||||
|
<td class="text-center">{{ post.author }}</td>
|
||||||
|
<td class="text-center">{{ post.date }}</td>
|
||||||
|
<td class="text-center">{{ post.views }}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-footer">
|
||||||
|
<!-- 페이지네이션 -->
|
||||||
|
<div class="row g-3">
|
||||||
|
<div class="mt-8">
|
||||||
|
<Pagination
|
||||||
|
v-if="pagination.pages"
|
||||||
|
v-bind="pagination"
|
||||||
|
@update:currentPage="handlePageChange"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -262,4 +264,9 @@ onMounted(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.w-md-100 {
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -5,22 +5,34 @@
|
|||||||
<div class="card">
|
<div class="card">
|
||||||
<!-- 프로필 헤더 -->
|
<!-- 프로필 헤더 -->
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<BoardProfile
|
<div class="pb-5 border-bottom">
|
||||||
:boardId="currentBoardId"
|
<BoardProfile
|
||||||
:profileName="profileName"
|
:boardId="currentBoardId"
|
||||||
:unknown="unknown"
|
:profileName="profileName"
|
||||||
:author="isAuthor"
|
:unknown="unknown"
|
||||||
:views="views"
|
:author="isAuthor"
|
||||||
:commentNum="commentNum"
|
:views="views"
|
||||||
:date="formattedBoardDate"
|
:commentNum="commentNum"
|
||||||
:isLike="false"
|
:date="formattedBoardDate"
|
||||||
:isPassword="isPassword"
|
:isLike="false"
|
||||||
:passwordAlert="passwordAlert"
|
@editClick="editClick"
|
||||||
@editClick="editClick"
|
@deleteClick="deleteClick"
|
||||||
@deleteClick="deleteClick"
|
/>
|
||||||
@submitPassword="submitPassword"
|
|
||||||
class="pb-6 border-bottom"
|
<!-- 비밀번호 입력창 (익명일 경우) -->
|
||||||
/>
|
<div v-if="isPassword && unknown" class="mt-3 w-25 ms-auto">
|
||||||
|
<div class="input-group">
|
||||||
|
<input
|
||||||
|
type="password"
|
||||||
|
class="form-control"
|
||||||
|
v-model="password"
|
||||||
|
placeholder="비밀번호 입력"
|
||||||
|
/>
|
||||||
|
<button class="btn btn-primary" @click="submitPassword">확인</button>
|
||||||
|
</div>
|
||||||
|
<span v-if="passwordAlert" class="invalid-feedback d-block text-start">{{ passwordAlert }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 게시글 내용 -->
|
<!-- 게시글 내용 -->
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
@ -86,13 +98,9 @@
|
|||||||
<BoardCommentList
|
<BoardCommentList
|
||||||
:unknown="unknown"
|
:unknown="unknown"
|
||||||
:comments="comments"
|
:comments="comments"
|
||||||
:isEditTextarea="isEditTextarea"
|
@updateReaction="handleCommentReaction"
|
||||||
:isPassword="isPassword"
|
|
||||||
@editClick="editClick"
|
|
||||||
@deleteClick="deleteClick"
|
|
||||||
@submitPassword="submitPassword"
|
|
||||||
@updateReaction="handleUpdateReaction"
|
|
||||||
@submitComment="handleCommentReply"
|
@submitComment="handleCommentReply"
|
||||||
|
@commentDeleted="handleCommentDeleted"
|
||||||
/>
|
/>
|
||||||
<Pagination
|
<Pagination
|
||||||
v-if="pagination.pages"
|
v-if="pagination.pages"
|
||||||
@ -139,8 +147,8 @@ const authorId = ref(null); // 작성자 id
|
|||||||
|
|
||||||
const isAuthor = computed(() => currentUserId.value === authorId.value);
|
const isAuthor = computed(() => currentUserId.value === authorId.value);
|
||||||
|
|
||||||
const isEditTextarea = ref({});
|
|
||||||
|
|
||||||
|
const password = ref('');
|
||||||
const passwordAlert = ref("");
|
const passwordAlert = ref("");
|
||||||
const isPassword = ref(false);
|
const isPassword = ref(false);
|
||||||
const lastClickedButton = ref("");
|
const lastClickedButton = ref("");
|
||||||
@ -195,15 +203,13 @@ const fetchBoardDetails = async () => {
|
|||||||
// 좋아요, 싫어요
|
// 좋아요, 싫어요
|
||||||
const handleUpdateReaction = async ({ boardId, commentId, isLike, isDislike }) => {
|
const handleUpdateReaction = async ({ boardId, commentId, isLike, isDislike }) => {
|
||||||
try {
|
try {
|
||||||
const aa = await axios.post(`/board/${boardId}/${commentId}/reaction`, {
|
await axios.post(`/board/${boardId}/${commentId}/reaction`, {
|
||||||
LOCBRDSEQ: boardId, // 게시글 id
|
LOCBRDSEQ: boardId, // 게시글 id
|
||||||
LOCCMTSEQ: commentId, //댓글 id
|
LOCCMTSEQ: commentId, //댓글 id
|
||||||
// MEMBERSEQ: 1, // 멤버아이디 지금은 1 나중에 수정해야함
|
// MEMBERSEQ: 1, // 멤버아이디 지금은 1 나중에 수정해야함
|
||||||
LOCGOBGOD: isLike ? 'T' : 'F',
|
LOCGOBGOD: isLike ? 'T' : 'F',
|
||||||
LOCGOBBAD: isDislike ? 'T' : 'F'
|
LOCGOBBAD: isDislike ? 'T' : 'F'
|
||||||
});
|
});
|
||||||
console.log("좋아요 API 응답 데이터:", aa.data);
|
|
||||||
|
|
||||||
|
|
||||||
const response = await axios.get(`board/${boardId}`);
|
const response = await axios.get(`board/${boardId}`);
|
||||||
const updatedData = response.data.data;
|
const updatedData = response.data.data;
|
||||||
@ -215,52 +221,91 @@ const handleUpdateReaction = async ({ boardId, commentId, isLike, isDislike }) =
|
|||||||
dislikeClicked.value = isDislike;
|
dislikeClicked.value = isDislike;
|
||||||
// console.log(updatedData)
|
// console.log(updatedData)
|
||||||
|
|
||||||
|
// console.log("갱신된 데이터:", updatedData);
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
alert('반응을 업데이트하는 중 오류 발생');
|
alert('반응을 업데이트하는 중 오류 발생');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// 대댓글 좋아요
|
||||||
|
const handleCommentReaction = async ({ boardId, commentId, isLike, isDislike }) => {
|
||||||
|
if (!commentId) return; // 댓글 ID가 없으면 실행 안 함
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await axios.post(`/board/${boardId}/${commentId}/reaction`, {
|
||||||
|
LOCBRDSEQ: boardId, // 게시글 ID
|
||||||
|
LOCCMTSEQ: commentId, // 댓글 ID
|
||||||
|
LOCGOBGOD: isLike ? 'T' : 'F',
|
||||||
|
LOCGOBBAD: isDislike ? 'T' : 'F'
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("댓글 좋아요 API 응답 데이터:", response.data);
|
||||||
|
|
||||||
|
// 좋아요/싫어요 상태 업데이트를 위해 새로 불러오기
|
||||||
|
await fetchComments();
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
alert('댓글 반응을 업데이트하는 중 오류 발생');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// 댓글 목록 조회
|
// 댓글 목록 조회
|
||||||
const fetchComments = async (page = 1) => {
|
const fetchComments = async (page = 1) => {
|
||||||
try {
|
try {
|
||||||
|
// 댓글
|
||||||
const response = await axios.get(`board/${currentBoardId.value}/comments`, {
|
const response = await axios.get(`board/${currentBoardId.value}/comments`, {
|
||||||
params: {
|
params: {
|
||||||
LOCBRDSEQ: currentBoardId.value,
|
LOCBRDSEQ: currentBoardId.value,
|
||||||
page
|
page
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
console.log("목록 API 응답 데이터:", response.data);
|
|
||||||
|
|
||||||
let allComments = response.data.data.list.map(comment => ({
|
const commentsList = response.data.data.list.map(comment => ({
|
||||||
commentId: comment.LOCCMTSEQ, // 댓글 id
|
commentId: comment.LOCCMTSEQ, // 댓글 ID
|
||||||
boardId: comment.LOCBRDSEQ,
|
boardId: comment.LOCBRDSEQ,
|
||||||
parentId: comment.LOCCMTPNT, // 부모 id
|
parentId: comment.LOCCMTPNT, // 부모 ID
|
||||||
author: comment.author || "익명 사용자", // 작성자
|
author: comment.author || "익명 사용자",
|
||||||
content: comment.LOCCMTRPY, // 댓글 내용
|
content: comment.LOCCMTRPY,
|
||||||
createdAt: formattedDate(comment.LOCCMTRDT), // 생성 날짜
|
likeCount: comment.likeCount || 0,
|
||||||
children: []
|
dislikeCount: comment.dislikeCount || 0,
|
||||||
|
likeClicked: comment.likeClicked || false,
|
||||||
|
dislikeClicked: comment.dislikeClicked || false,
|
||||||
|
createdAtRaw: new Date(comment.LOCCMTRDT), // 정렬용
|
||||||
|
createdAt: formattedDate(comment.LOCCMTRDT), // 표시용
|
||||||
|
children: [] // 대댓글을 담을 배열
|
||||||
}));
|
}));
|
||||||
|
|
||||||
allComments.sort((a, b) => b.commentId - a.commentId);
|
for (const comment of commentsList) {
|
||||||
|
if (!comment.commentId) continue;
|
||||||
|
|
||||||
let commentMap = {};
|
const replyResponse = await axios.get(`board/${currentBoardId.value}/reply`, {
|
||||||
let rootComments = [];
|
params: { LOCCMTPNT: comment.commentId }
|
||||||
|
});
|
||||||
|
|
||||||
allComments.forEach(comment => {
|
// console.log(`📌 대댓글 데이터 (${comment.commentId}의 대댓글):`, replyResponse.data);
|
||||||
commentMap[comment.commentId] = comment;
|
|
||||||
});
|
|
||||||
|
|
||||||
allComments.forEach(comment => {
|
if (replyResponse.data.data) {
|
||||||
if (comment.parentId && commentMap[comment.parentId]) {
|
comment.children = replyResponse.data.data.map(reply => ({
|
||||||
commentMap[comment.parentId].children.push(comment);
|
commentId: reply.LOCCMTSEQ,
|
||||||
|
boardId: reply.LOCBRDSEQ,
|
||||||
|
parentId: reply.LOCCMTPNT, // 부모 댓글 ID
|
||||||
|
content: reply.LOCCMTRPY || "내용 없음",
|
||||||
|
createdAtRaw: new Date(reply.LOCCMTRDT),
|
||||||
|
createdAt: formattedDate(reply.LOCCMTRDT),
|
||||||
|
likeCount: reply.likeCount || 0,
|
||||||
|
dislikeCount: reply.dislikeCount || 0,
|
||||||
|
likeClicked: false,
|
||||||
|
dislikeClicked: false
|
||||||
|
}));
|
||||||
} else {
|
} else {
|
||||||
rootComments.push(comment);
|
comment.children = []; // 대댓글이 없으면 빈 배열로 초기화
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
comments.value = rootComments;
|
// 최종적으로 댓글 목록 업데이트
|
||||||
|
comments.value = commentsList;
|
||||||
// console.log("변환된 comments 데이터:", comments.value);
|
|
||||||
|
|
||||||
pagination.value = {
|
pagination.value = {
|
||||||
...pagination.value,
|
...pagination.value,
|
||||||
@ -278,51 +323,90 @@ const fetchComments = async (page = 1) => {
|
|||||||
navigateLastPage: response.data.data.navigateLastPage // 페이지네이션에서 마지막 페이지 번호
|
navigateLastPage: response.data.data.navigateLastPage // 페이지네이션에서 마지막 페이지 번호
|
||||||
};
|
};
|
||||||
|
|
||||||
|
console.log("📌 댓글 목록:", comments.value);
|
||||||
|
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('댓글 목록 불러오기 오류:', error);
|
console.log('댓글 목록 불러오기 오류:', error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 댓글 작성
|
// 댓글 작성
|
||||||
const handleCommentSubmit = async ({ comment, password }) => {
|
const handleCommentSubmit = async ({ comment, password }) => {
|
||||||
|
// if (unknown.value && !password) {
|
||||||
|
// passwordAlert.value = "익명 사용자는 비밀번호를 입력해야 합니다."; // UI에 메시지 표시
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// if (!password) {
|
||||||
|
// passwordAlert.value = "비밀번호를 입력해야 합니다."; // UI에서 경고 표시
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await axios.post(`board/${currentBoardId.value}/comment`, {
|
const response = await axios.post(`board/${currentBoardId.value}/comment`, {
|
||||||
LOCBRDSEQ: currentBoardId.value,
|
LOCBRDSEQ: currentBoardId.value,
|
||||||
LOCCMTRPY: comment,
|
LOCCMTRPY: comment,
|
||||||
LOCCMTPWD: password || null,
|
LOCCMTPWD: password,
|
||||||
LOCCMTPNT: 1
|
LOCCMTPNT: 1
|
||||||
});
|
});
|
||||||
// console.log('📥 서버 응답 전체:', response.data);
|
// console.log('서버 응답 전체1212121212:', response.data);
|
||||||
|
|
||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
console.log('댓글 작성 성공:', response.data.message);
|
console.log('댓글 작성 성공:', response.data.message);
|
||||||
await fetchComments();
|
await fetchComments();
|
||||||
} else {
|
} else {
|
||||||
console.error('댓글 작성 실패:', response.data.message);
|
console.log('댓글 작성 실패:', response.data.message);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('댓글 작성 중 오류 발생:', error);
|
console.log('댓글 작성 중 오류 발생:', error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCommentReply = async (reply) => {
|
|
||||||
const response = await axios.post(`board/${currentBoardId.value}/comment`, {
|
|
||||||
LOCBRDSEQ: currentBoardId.value,
|
|
||||||
LOCCMTRPY: reply.comment,
|
|
||||||
LOCCMTPWD: reply.password || null,
|
|
||||||
LOCCMTPNT: reply.parentId
|
|
||||||
});
|
|
||||||
|
|
||||||
if (response.status === 200) {
|
// 대댓글 작성
|
||||||
console.log('대댓글 작성 성공:', response.data.message);
|
const handleCommentReply = async (reply) => {
|
||||||
await fetchComments();
|
try {
|
||||||
} else {
|
console.log('대댓글 작성 요청 데이터:', {
|
||||||
console.error('대댓글 작성 실패:', response.data.message);
|
LOCBRDSEQ: currentBoardId.value,
|
||||||
|
LOCCMTRPY: reply.comment,
|
||||||
|
LOCCMTPWD: reply.password || null,
|
||||||
|
LOCCMTPNT: reply.parentId
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await axios.post(`board/${currentBoardId.value}/comment`, {
|
||||||
|
LOCBRDSEQ: currentBoardId.value,
|
||||||
|
LOCCMTRPY: reply.comment,
|
||||||
|
LOCCMTPWD: reply.password || null,
|
||||||
|
LOCCMTPNT: reply.parentId
|
||||||
|
});
|
||||||
|
|
||||||
|
// 응답 데이터를 자세히 로그로 확인
|
||||||
|
console.log('대댓글 작성 응답:', {
|
||||||
|
status: response.status,
|
||||||
|
data: response.data,
|
||||||
|
headers: response.headers
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.status === 200) {
|
||||||
|
if (response.data.code === 200) { // 서버 응답 코드도 확인
|
||||||
|
console.log('대댓글 작성 성공:', response.data);
|
||||||
|
await fetchComments(); // 댓글 목록 새로고침
|
||||||
|
} else {
|
||||||
|
console.log('대댓글 작성 실패 - 서버 응답:', response.data);
|
||||||
|
alert('대댓글 작성에 실패했습니다.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('대댓글 작성 중 오류 발생:', error);
|
||||||
|
if (error.response) {
|
||||||
|
console.error('서버 응답 에러:', error.response.data);
|
||||||
|
}
|
||||||
|
alert('대댓글 작성 중 오류가 발생했습니다.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const editClick = (unknown) => {
|
const editClick = (unknown) => {
|
||||||
|
|
||||||
if (unknown) {
|
if (unknown) {
|
||||||
togglePassword("edit");
|
togglePassword("edit");
|
||||||
} else {
|
} else {
|
||||||
@ -348,24 +432,23 @@ const togglePassword = (button) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const submitPassword = async (inputPassword) => {
|
const submitPassword = async () => {
|
||||||
console.log(inputPassword)
|
if (!password.value) {
|
||||||
if (!inputPassword) {
|
|
||||||
passwordAlert.value = "비밀번호를 입력해주세요.";
|
passwordAlert.value = "비밀번호를 입력해주세요.";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// console.log("📌 요청 시작: submitPassword 실행됨");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const requestData = {
|
const response = await axios.post(`board/${currentBoardId.value}/password`, {
|
||||||
LOCBRDPWD: inputPassword,
|
LOCBRDPWD: password.value,
|
||||||
LOCBRDSEQ: 288
|
LOCBRDSEQ: 288, // 나중에 현재 게시글 ID 사용해야함
|
||||||
};
|
});
|
||||||
|
|
||||||
const postResponse = await axios.post(`board/${currentBoardId.value}/password`, requestData);
|
if (response.data.code === 200 && response.data.data === true) {
|
||||||
|
password.value = '';
|
||||||
if (postResponse.data.code === 200 && postResponse.data.data === true) {
|
|
||||||
isPassword.value = false;
|
isPassword.value = false;
|
||||||
passwordAlert.value = "";
|
|
||||||
|
|
||||||
if (lastClickedButton.value === "edit") {
|
if (lastClickedButton.value === "edit") {
|
||||||
router.push({ name: "BoardEdit", params: { id: currentBoardId.value } });
|
router.push({ name: "BoardEdit", params: { id: currentBoardId.value } });
|
||||||
@ -374,15 +457,21 @@ const submitPassword = async (inputPassword) => {
|
|||||||
}
|
}
|
||||||
lastClickedButton.value = null;
|
lastClickedButton.value = null;
|
||||||
} else {
|
} else {
|
||||||
passwordAlert.value = "비밀번호가 일치하지 않습니다.";
|
passwordAlert.value = "비밀번호가 일치하지 않습니다.????";
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error.response && error.response.status === 401) {
|
// console.log("📌 전체 오류:", error);
|
||||||
passwordAlert.value = "비밀번호가 일치하지 않습니다.";
|
|
||||||
} else if (error.response) {
|
if (error.response) {
|
||||||
alert(`오류 발생: ${error.response.data.message || "서버 오류"}`);
|
if (error.response.status === 401) {
|
||||||
|
passwordAlert.value = "비밀번호가 일치하지 않습니다.";
|
||||||
|
} else {
|
||||||
|
passwordAlert.value = error.response.data?.message || "서버 오류가 발생했습니다.";
|
||||||
|
}
|
||||||
|
} else if (error.request) {
|
||||||
|
passwordAlert.value = "네트워크 오류가 발생했습니다. 다시 시도해주세요.";
|
||||||
} else {
|
} else {
|
||||||
alert("네트워크 오류가 발생했습니다. 다시 시도해주세요.");
|
passwordAlert.value = "요청 중 알 수 없는 오류가 발생했습니다.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -418,6 +507,10 @@ const handlePageChange = (page) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleCommentDeleted = (deletedCommentId) => {
|
||||||
|
comments.value = comments.value.filter(comment => comment.commentId !== deletedCommentId);
|
||||||
|
};
|
||||||
|
|
||||||
// 날짜
|
// 날짜
|
||||||
const formattedDate = (dateString) => {
|
const formattedDate = (dateString) => {
|
||||||
if (!dateString) return "날짜 없음";
|
if (!dateString) return "날짜 없음";
|
||||||
|
|||||||
@ -195,9 +195,10 @@ function updateCalendarEvents() {
|
|||||||
.map(([date, type]) => ({
|
.map(([date, type]) => ({
|
||||||
title: getVacationType(type),
|
title: getVacationType(type),
|
||||||
start: date,
|
start: date,
|
||||||
backgroundColor: "rgba(0, 128, 0, 0.3)",
|
backgroundColor: "rgb(113 212 243 / 76%)",
|
||||||
|
textColor: "#fff", // 흰색 텍스트
|
||||||
display: "background",
|
display: "background",
|
||||||
classNames: [getVacationTypeClass(type)]
|
classNames: [getVacationTypeClass(type), "selected-event"]
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// 기존 백엔드에서 불러온 저장된 연차 이벤트 중,
|
// 기존 백엔드에서 불러온 저장된 연차 이벤트 중,
|
||||||
@ -340,10 +341,6 @@ halfDayType.value = halfDayType.value === type ? null : type;
|
|||||||
return typeof id === "number" ? Number(id) : id;
|
return typeof id === "number" ? Number(id) : id;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
console.log("vacationsToAdd:", vacationsToAdd);
|
|
||||||
console.log("vacationsToDelete:", vacationsToDelete);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await axios.post("vacation/batchUpdate", {
|
const response = await axios.post("vacation/batchUpdate", {
|
||||||
add: vacationsToAdd,
|
add: vacationsToAdd,
|
||||||
@ -424,5 +421,7 @@ await loadCalendarData(year, month);
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
.fc-bg-event{
|
||||||
|
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user