댓글 삭제 진행중

This commit is contained in:
kimdaae328 2025-02-20 18:58:53 +09:00
parent 917b701663
commit 87acf373d9
4 changed files with 205 additions and 74 deletions

View File

@ -14,21 +14,33 @@
@deleteClick="deleteClick"
@submitPassword="submitPassword"
@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">
<template v-if="isEditTextarea">
<textarea v-model="editedContent" class="form-control"></textarea>
<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>
</div>
</template>
<template v-else>
<p class="m-0">{{ comment.content }}</p>
<span>{{ comment.commentId }}</span>
</template>
</div>
@ -89,7 +101,7 @@ const props = defineProps({
});
// emits
const emit = defineEmits(['submitComment', 'updateReaction', 'toggleEdit', 'editClick']);
const emit = defineEmits(['submitComment', 'updateReaction', 'toggleEdit',]);
//
const isComment = ref(false);
@ -97,6 +109,22 @@ const toggleComment = () => {
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) => {
emit('submitComment', { parentId: props.comment.commentId, ...newComment });
@ -114,16 +142,103 @@ const handleUpdateReaction = (reactionData) => {
};
//
const editClick = (data) => {
emit('editClick', data);
//
const editClick = () => {
if (props.unknown) {
console.log('수정')
togglePassword("edit");
}
};
//
const editedContent = ref(props.comment.content);
const submitEdit = () => {
emit('submitComment', { commentId: props.comment.commentId, content: editedContent.value });
emit('toggleEdit', props.comment.commentId, false); //
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: props.comment.commentId,
});
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 cancelEdit = () => {
isEditTextarea.value = false;
};
//
const submitEdit = () => {
emit('submitComment', { commentId: props.comment.commentId, content: editedContent.value });
isEditTextarea.value = false; //
};
</script>

View File

@ -43,6 +43,7 @@
class="form-control flex-grow-1"
v-model="password"
/>
<!-- <span v-if="passwordAlert" class="invalid-feedback d-block text-start">{{ passwordAlert }}</span> -->
</div>
</div>
@ -85,7 +86,7 @@ watch(() => props.unknown, (newVal) => {
function handleCommentSubmit() {
emit('submitComment', {
comment: comment.value,
password: password.value,
password: isCheck.value ? password.value : '',
});
comment.value = '';

View File

@ -14,6 +14,7 @@
@deleteClick="deleteClick"
@submitPassword="submitPassword"
@submitComment="submitComment"
@commentDeleted="handleCommentDeleted"
@updateReaction="(reactionData) => handleUpdateReaction(reactionData, comment.commentId, comment.boardId)"
/>
</li>

View File

@ -98,11 +98,9 @@
<BoardCommentList
:unknown="unknown"
:comments="comments"
:isEditTextarea="isEditTextarea"
@editClick="editClick"
@deleteClick="deleteClick"
@updateReaction="handleCommentReaction"
@submitComment="handleCommentReply"
@commentDeleted="handleCommentDeleted"
/>
<Pagination
v-if="pagination.pages"
@ -149,7 +147,6 @@ const authorId = ref(null); // 작성자 id
const isAuthor = computed(() => currentUserId.value === authorId.value);
const isEditTextarea = ref(false);
const password = ref('');
const passwordAlert = ref("");
@ -265,15 +262,6 @@ const fetchComments = async (page = 1) => {
}
});
//
// const replyResponse = await axios.get(`board/${currentBoardId.value}/reply`, {
// params: {
// LOCCMTPNT: 120
// }
// });
// console.log(replyResponse.data)
const commentsList = response.data.data.list.map(comment => ({
commentId: comment.LOCCMTSEQ, // ID
boardId: comment.LOCBRDSEQ,
@ -290,18 +278,29 @@ const fetchComments = async (page = 1) => {
}));
for (const comment of commentsList) {
//
if (!comment.commentId) continue;
const replyResponse = await axios.get(`board/${currentBoardId.value}/reply`, {
params: {
LOCCMTPNT: comment.parentId // ID
}
params: { LOCCMTPNT: comment.commentId }
});
console.log(`대댓글:`, replyResponse.data);
// children
// console.log(`📌 (${comment.commentId} ):`, replyResponse.data);
if (replyResponse.data.data) {
comment.children = 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 {
comment.children = []; //
}
}
@ -324,47 +323,34 @@ const fetchComments = async (page = 1) => {
navigateLastPage: response.data.data.navigateLastPage //
};
console.log("📌 댓글 목록:", comments.value);
} catch (error) {
console.log('댓글 목록 불러오기 오류:', error);
}
};
//
// const fetchReplies = async () => {
// try {
// const response = await axios.get(`board/${currentBoardId.value}/reply`);
// const replyData = response.data.data || [];
// return replyData.map(reply => ({
// commentId: reply.LOCCMTSEQ, // ID
// 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
// }));
// } catch (error) {
// console.error(" :", error);
// return [];
// }
// };
//
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);
@ -380,23 +366,47 @@ const handleCommentSubmit = async ({ comment, password }) => {
//
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
});
try {
console.log('대댓글 작성 요청 데이터:', {
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.log('대댓글 작성 실패:', response.data.message);
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 {
@ -497,6 +507,10 @@ const handlePageChange = (page) => {
}
};
const handleCommentDeleted = (deletedCommentId) => {
comments.value = comments.value.filter(comment => comment.commentId !== deletedCommentId);
};
//
const formattedDate = (dateString) => {
if (!dateString) return "날짜 없음";