diff --git a/src/components/board/BoardComment.vue b/src/components/board/BoardComment.vue
index 07e2327..dd6cfc0 100644
--- a/src/components/board/BoardComment.vue
+++ b/src/components/board/BoardComment.vue
@@ -14,16 +14,29 @@
@deleteClick="deleteClick"
@submitPassword="submitPassword"
@updateReaction="handleUpdateReaction"
- @toggleEdit="emit('toggleEdit', comment.commentId, true)"
+ @toggleEdit="toggleEdit(true)"
/>
+
+
+
+
+
+
+
{{ passwordAlert }}
+
-
-
+
+
@@ -51,55 +64,45 @@
/>
-
-
diff --git a/src/components/board/BoardCommentArea.vue b/src/components/board/BoardCommentArea.vue
index db85f1d..27ada9c 100644
--- a/src/components/board/BoardCommentArea.vue
+++ b/src/components/board/BoardCommentArea.vue
@@ -43,6 +43,7 @@
class="form-control flex-grow-1"
v-model="password"
/>
+
@@ -74,20 +75,18 @@ const props = defineProps({
const comment = ref('');
const password = ref('');
-const isCheck = ref(false);
+const isCheck = ref(props.unknown);
const emit = defineEmits(['submitComment']);
watch(() => props.unknown, (newVal) => {
- if (!newVal) {
- isCheck.value = false;
- }
+ isCheck.value = newVal;
});
function handleCommentSubmit() {
emit('submitComment', {
comment: comment.value,
- password: password.value,
+ password: isCheck.value ? password.value : '',
});
comment.value = '';
diff --git a/src/components/board/BoardCommentList.vue b/src/components/board/BoardCommentList.vue
index f287e93..1141f6e 100644
--- a/src/components/board/BoardCommentList.vue
+++ b/src/components/board/BoardCommentList.vue
@@ -9,13 +9,14 @@
:unknown="unknown"
:comment="comment"
:isPassword="isPassword"
+ :isEditTextarea="isEditTextarea"
@editClick="editClick"
@deleteClick="deleteClick"
@submitPassword="submitPassword"
@submitComment="submitComment"
- @updateReaction="(reactionData) => handleUpdateReaction(reactionData, comment.commentId)"
+ @commentDeleted="handleCommentDeleted"
+ @updateReaction="(reactionData) => handleUpdateReaction(reactionData, comment.commentId, comment.boardId)"
/>
-
@@ -38,6 +39,10 @@ const props = defineProps({
type: Boolean,
default: false,
},
+ isEditTextarea: {
+ type: Boolean,
+ default: false,
+ }
});
const emit = defineEmits(['submitComment', 'updateReaction', 'editClick']);
@@ -46,17 +51,13 @@ const submitComment = (replyData) => {
emit('submitComment', replyData);
};
-const handleUpdateReaction = (reactionData, commentId) => {
- // console.log('📢 BoardCommentList에서 이벤트 수신:', reactionData);
- // console.log('📌 전달할 댓글 ID>>>>:', commentId);
-
+const handleUpdateReaction = (reactionData, commentId, boardId) => {
const updatedReactionData = {
...reactionData,
- commentId: commentId
+ commentId: commentId || reactionData.commentId,
+ boardId: boardId || reactionData.boardId,
};
- // console.log('🚀 최종 전달할 데이터:', updatedReactionData);
-
emit('updateReaction', updatedReactionData);
}
diff --git a/src/views/board/BoardList.vue b/src/views/board/BoardList.vue
index 34740d2..523356f 100644
--- a/src/views/board/BoardList.vue
+++ b/src/views/board/BoardList.vue
@@ -1,102 +1,104 @@
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- | 번호 |
- 제목 |
- 작성자 |
- 작성일 |
- 조회수 |
-
-
-
-
-
-
- | 공지 |
-
- 📌 {{ notice.title }}
-
-
- N
- |
- {{ notice.author }} |
- {{ notice.date }} |
- {{ notice.views }} |
-
-
-
-
- | {{ post.id }} |
-
- {{ post.title }}
-
-
- N
- |
- {{ post.author }} |
- {{ post.date }} |
- {{ post.views }} |
-
-
-
-
+
+
-
-
+
+
+
+
+
+ | 번호 |
+ 제목 |
+ 작성자 |
+ 작성일 |
+ 조회수 |
+
+
+
+
+
+
+ | 공지 |
+
+ 📌 {{ notice.title }}
+
+
+ N
+ |
+ {{ notice.author }} |
+ {{ notice.date }} |
+ {{ notice.views }} |
+
+
+
+
+ | {{ post.id }} |
+
+ {{ post.title }}
+
+
+ N
+ |
+ {{ post.author }} |
+ {{ post.date }} |
+ {{ post.views }} |
+
+
+
+
+
+
@@ -262,4 +264,9 @@ onMounted(() => {
diff --git a/src/views/board/BoardView.vue b/src/views/board/BoardView.vue
index 2559318..dcb5d40 100644
--- a/src/views/board/BoardView.vue
+++ b/src/views/board/BoardView.vue
@@ -5,22 +5,34 @@
@@ -86,13 +98,9 @@
currentUserId.value === authorId.value);
-const isEditTextarea = ref({});
+const password = ref('');
const passwordAlert = ref("");
const isPassword = ref(false);
const lastClickedButton = ref("");
@@ -195,15 +203,13 @@ const fetchBoardDetails = async () => {
// 좋아요, 싫어요
const handleUpdateReaction = async ({ boardId, commentId, isLike, isDislike }) => {
try {
- const aa = await axios.post(`/board/${boardId}/${commentId}/reaction`, {
+ await axios.post(`/board/${boardId}/${commentId}/reaction`, {
LOCBRDSEQ: boardId, // 게시글 id
LOCCMTSEQ: commentId, //댓글 id
// MEMBERSEQ: 1, // 멤버아이디 지금은 1 나중에 수정해야함
LOCGOBGOD: isLike ? 'T' : 'F',
LOCGOBBAD: isDislike ? 'T' : 'F'
});
- console.log("좋아요 API 응답 데이터:", aa.data);
-
const response = await axios.get(`board/${boardId}`);
const updatedData = response.data.data;
@@ -215,52 +221,91 @@ const handleUpdateReaction = async ({ boardId, commentId, isLike, isDislike }) =
dislikeClicked.value = isDislike;
// console.log(updatedData)
+ // console.log("갱신된 데이터:", updatedData);
+
} catch (error) {
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) => {
try {
+ // 댓글
const response = await axios.get(`board/${currentBoardId.value}/comments`, {
params: {
LOCBRDSEQ: currentBoardId.value,
page
}
});
- console.log("목록 API 응답 데이터:", response.data);
- let allComments = response.data.data.list.map(comment => ({
- commentId: comment.LOCCMTSEQ, // 댓글 id
+ const commentsList = response.data.data.list.map(comment => ({
+ commentId: comment.LOCCMTSEQ, // 댓글 ID
boardId: comment.LOCBRDSEQ,
- parentId: comment.LOCCMTPNT, // 부모 id
- author: comment.author || "익명 사용자", // 작성자
- content: comment.LOCCMTRPY, // 댓글 내용
- createdAt: formattedDate(comment.LOCCMTRDT), // 생성 날짜
- children: []
+ parentId: comment.LOCCMTPNT, // 부모 ID
+ author: comment.author || "익명 사용자",
+ content: comment.LOCCMTRPY,
+ likeCount: comment.likeCount || 0,
+ 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 = {};
- let rootComments = [];
+ const replyResponse = await axios.get(`board/${currentBoardId.value}/reply`, {
+ params: { LOCCMTPNT: comment.commentId }
+ });
- allComments.forEach(comment => {
- commentMap[comment.commentId] = comment;
- });
+ // console.log(`📌 대댓글 데이터 (${comment.commentId}의 대댓글):`, replyResponse.data);
- allComments.forEach(comment => {
- if (comment.parentId && commentMap[comment.parentId]) {
- commentMap[comment.parentId].children.push(comment);
+ if (replyResponse.data.data) {
+ comment.children = replyResponse.data.data.map(reply => ({
+ 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 {
- rootComments.push(comment);
+ comment.children = []; // 대댓글이 없으면 빈 배열로 초기화
}
- });
+ }
- comments.value = rootComments;
-
- // console.log("변환된 comments 데이터:", comments.value);
+ // 최종적으로 댓글 목록 업데이트
+ comments.value = commentsList;
pagination.value = {
...pagination.value,
@@ -278,51 +323,90 @@ const fetchComments = async (page = 1) => {
navigateLastPage: response.data.data.navigateLastPage // 페이지네이션에서 마지막 페이지 번호
};
+ console.log("📌 댓글 목록:", comments.value);
+
+
} catch (error) {
- console.error('댓글 목록 불러오기 오류:', error);
+ console.log('댓글 목록 불러오기 오류:', error);
}
};
// 댓글 작성
const handleCommentSubmit = async ({ comment, password }) => {
+ // if (unknown.value && !password) {
+ // passwordAlert.value = "익명 사용자는 비밀번호를 입력해야 합니다."; // UI에 메시지 표시
+ // return;
+ // }
+ // if (!password) {
+ // passwordAlert.value = "비밀번호를 입력해야 합니다."; // UI에서 경고 표시
+ // return;
+ // }
+
+
try {
const response = await axios.post(`board/${currentBoardId.value}/comment`, {
LOCBRDSEQ: currentBoardId.value,
LOCCMTRPY: comment,
- LOCCMTPWD: password || null,
+ LOCCMTPWD: password,
LOCCMTPNT: 1
});
- // console.log('📥 서버 응답 전체:', response.data);
+ // console.log('서버 응답 전체1212121212:', response.data);
if (response.status === 200) {
console.log('댓글 작성 성공:', response.data.message);
await fetchComments();
} else {
- console.error('댓글 작성 실패:', response.data.message);
+ console.log('댓글 작성 실패:', response.data.message);
}
} 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);
- await fetchComments();
- } else {
- console.error('대댓글 작성 실패:', response.data.message);
+// 대댓글 작성
+const handleCommentReply = async (reply) => {
+ try {
+ console.log('대댓글 작성 요청 데이터:', {
+ 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) => {
-
if (unknown) {
togglePassword("edit");
} else {
@@ -348,24 +432,23 @@ const togglePassword = (button) => {
};
-const submitPassword = async (inputPassword) => {
- console.log(inputPassword)
- if (!inputPassword) {
+const submitPassword = async () => {
+ if (!password.value) {
passwordAlert.value = "비밀번호를 입력해주세요.";
return;
}
+ // console.log("📌 요청 시작: submitPassword 실행됨");
+
try {
- const requestData = {
- LOCBRDPWD: inputPassword,
- LOCBRDSEQ: 288
- };
+ const response = await axios.post(`board/${currentBoardId.value}/password`, {
+ LOCBRDPWD: password.value,
+ LOCBRDSEQ: 288, // 나중에 현재 게시글 ID 사용해야함
+ });
- const postResponse = await axios.post(`board/${currentBoardId.value}/password`, requestData);
-
- if (postResponse.data.code === 200 && postResponse.data.data === true) {
+ if (response.data.code === 200 && response.data.data === true) {
+ password.value = '';
isPassword.value = false;
- passwordAlert.value = "";
if (lastClickedButton.value === "edit") {
router.push({ name: "BoardEdit", params: { id: currentBoardId.value } });
@@ -374,15 +457,21 @@ const submitPassword = async (inputPassword) => {
}
lastClickedButton.value = null;
} else {
- passwordAlert.value = "비밀번호가 일치하지 않습니다.";
+ passwordAlert.value = "비밀번호가 일치하지 않습니다.????";
}
} catch (error) {
- if (error.response && error.response.status === 401) {
- passwordAlert.value = "비밀번호가 일치하지 않습니다.";
- } else if (error.response) {
- alert(`오류 발생: ${error.response.data.message || "서버 오류"}`);
+ // console.log("📌 전체 오류:", error);
+
+ if (error.response) {
+ if (error.response.status === 401) {
+ passwordAlert.value = "비밀번호가 일치하지 않습니다.";
+ } else {
+ passwordAlert.value = error.response.data?.message || "서버 오류가 발생했습니다.";
+ }
+ } else if (error.request) {
+ passwordAlert.value = "네트워크 오류가 발생했습니다. 다시 시도해주세요.";
} 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) => {
if (!dateString) return "날짜 없음";
diff --git a/src/views/vacation/VacationManagement.vue b/src/views/vacation/VacationManagement.vue
index 2412d73..1d6eda5 100644
--- a/src/views/vacation/VacationManagement.vue
+++ b/src/views/vacation/VacationManagement.vue
@@ -195,9 +195,10 @@ function updateCalendarEvents() {
.map(([date, type]) => ({
title: getVacationType(type),
start: date,
- backgroundColor: "rgba(0, 128, 0, 0.3)",
+ backgroundColor: "rgb(113 212 243 / 76%)",
+ textColor: "#fff", // 흰색 텍스트
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;
});
-
- console.log("vacationsToAdd:", vacationsToAdd);
- console.log("vacationsToDelete:", vacationsToDelete);
-
try {
const response = await axios.post("vacation/batchUpdate", {
add: vacationsToAdd,
@@ -424,5 +421,7 @@ await loadCalendarData(year, month);