<template> <div class="answer-discuss"> <!-- 编辑评论 --> <div v-if="editCommentState" class="edit-comment flexcenter"> <div class="box"> <div class="text">编辑评论</div> <div class="input-box"> <div class="top flexflex"> <textarea ref="editInputRef" class="input-textarea flex1" maxlength="500" v-model="editInput" @focus="judgeLogin" @input="autoResize" @paste="handleInputPaste" placeholder="说说你的想法或疑问…"></textarea> </div> <div class="picture-box" v-if="editPicture.url"> <div class="picture"> <img class="close" @click="closeEditFileUpload()" src="@/img/close-icon.png" /> <img class="img" @click="handleAnswerText" :src="editPicture.base64 || editPicture.url" /> </div> </div> <div class="bottom flexacenter"> <div class="operate flexacenter"> <div class="item" :class="{ pitch: editEmojiState }"> <img class="icon" src="@/img/smiling-face.png" @click="openEditEmoji()" alt="" /> <div class="emoji-box"> <div class="emoji-icon" v-for="item in emojiData" :key="item" @click="selectEditEmoji(item)">{{ item }}</div> </div> </div> <div class="item flexacenter" @click="judgeLogin()"> <input class="file" type="file" @change="handleFileUpload($event)" accept=".png, .jpg, .jpeg" /> <img class="icon" style="border-radius: 0" src="@/img/picture-icon.png" alt="" /> <span class="file-hint">最多可上传1张图片,支持在输入框中直接粘贴图片。</span> </div> </div> </div> </div> <div class="btn-list flexacenter"> <div class="btn" @click="closeEdit()">取消</div> <div class="btn send" @click="postEditComment()">发送</div> </div> </div> </div> <div class="header flexacenter"> 回答&讨论 <span class="num">{{ commentTotalCount || "" }}</span> </div> <div class="input-box"> <div class="top flexflex"> <img class="avatar" v-if="user.avatar" :src="user.avatar" /> <textarea class="input-textarea flex1" maxlength="500" v-model="inputTextarea" @focus="judgeLogin" @input="autoResize" @paste="handleInputPaste" placeholder="说说你的看法…"></textarea> </div> <div class="picture-box" v-if="picture.url"> <div class="picture"> <img class="close" @click="closeFileUpload()" src="/img/close-icon.png" /> <img class="img" @click="handleAnswerText" :src="picture.base64 || picture.url" /> </div> </div> <div class="bottom flexacenter"> <div class="operate flexacenter"> <div class="item" :class="{ pitch: emojiState }"> <img class="icon" src="/img/smiling-face.png" @click="openEmoji()" alt="" /> <div class="emoji-box"> <div class="emoji-icon" v-for="item in emojiData" :key="item" @click="selectEmoji(item)">{{ item }}</div> </div> </div> <div class="item flexacenter" @click="judgeLogin()"> <input class="file" type="file" @change="handleFileUpload($event)" accept=".png, .jpg, .jpeg" /> <img class="icon" style="border-radius: 0" src="/img/picture-icon.png" alt="" /> <span class="file-hint">最多可上传1张图片,支持在输入框中直接粘贴图片。</span> </div> </div> <div class="btn" @click="submitAnswerComments()">发送</div> </div> </div> <div class="comments-box"> <div class="comments-item" v-for="(item, index) in commentList" :key="index"> <div class="comments-header flexacenter"> <div class="comments-header-left flexacenter"> <img class="comments-avatar" @click="openUserInfo(index)" :src="item['avatar']" /> <div class="comments-username" @click="openUserInfo(index)">{{ item["nickname"] || "匿名用户" }}</div> <div class="comments-time">{{ handleDate(item["timestamp"]) }}</div> <div class="comments-identity" v-if="item['isauthor'] == 1">提问者</div> <img class="comments-title" v-if="item['groupimage']" :src="item.groupimage" :alt="item.grouptitle" style="height: 17px" /> <div class="avatar-box flexflex" v-if="item['avatarState']"> <a class="avatar-item flexcenter" target="_blank" @click.prevent="sendMessage(item['uin'])"> <img class="avatar-icon" src="@/img/send-messages-icon.png" /> 发送信息 </a> <a class="avatar-item flexcenter" target="_blank" @click.prevent="TAHomePage(item['uin'])"> <img class="avatar-icon" src="@/img/homepage-icon.png" /> TA的主页 </a> <div class="avatar-mask" @click="closeUserInfo(index)"></div> </div> </div> <div class="comments-header-right flexacenter"> <div class="menu-box flexacenter"> <img class="menu-icon" src="/img/menu-icon-gray.svg" /> <div class="operate-boxx"> <div class="item flexcenter" @click="openMenuState(index)">举报</div> <div class="item flexcenter" v-if="permissions.includes('comment.edit')" @click="openEdit(item['token'], index)">编辑</div> <div class="item flexcenter" v-if="permissions.includes('comment.delete')" @click="commentDelete(item['token'], index)">删除</div> </div> </div> <img class="comment-icon" @click="openAnswerCommentsChild(index)" src="/img/comment-icon-gray.svg" /> <div class="flexacenter like-box" @click="operateAnswerCommentsLike(item.token, index)"> <img class="like-icon" v-if="item['islike'] == 0" src="/img/like-icon-gray.png" /> <img class="like-icon" v-else src="/img/like-icon-colours.png" /> <div class="like-quantity">{{ item["likenum"] || "" }}</div> </div> </div> </div> <div class="comments-content"> <div class="comments-text" v-html="item['content']"></div> <img class="comments-img" @click="handleAnswerText" :src="item.image?.base64 || item.image?.url" v-if="item.image?.url" /> <div class="input-box" v-if="item['childState']"> <img class="cross" @click="closeAnswerCommentsChild(index)" src="/img/cross-icon.png" /> <div class="top flexflex"> <textarea class="input-textarea flex1" maxlength="500" placeholder="说说你的看法…" v-model="item['commentInput']" @focus="judgeLogin" @input="autoResize" @paste="handleInputPaste($event, index)"></textarea> </div> <div class="picture-box" v-if="item.picture?.url"> <div class="picture"> <img class="close" @click="closeFileUpload(index)" src="/img/close-icon.png" /> <img class="img" @click="handleAnswerText" :src="item.picture.base64 || item.picture.url" /> </div> </div> <div class="bottom flexacenter"> <div class="operate flexacenter"> <div class="item" :class="{ pitch: item.emojiState }"> <img class="icon" src="/img/smiling-face.png" @click="openEmoji(index)" alt="" /> <div class="emoji-box"> <div class="emoji-icon" v-for="item in emojiData" :key="item" @click="selectEmoji(item, index)">{{ item }}</div> </div> </div> <div class="item flexacenter" @click="judgeLogin()"> <input class="file" type="file" @change="handleFileUpload($event, index)" accept=".png, .jpg, .jpeg" /> <img class="icon" style="border-radius: 0" src="/img/picture-icon.png" alt="" /> <span class="file-hint">最多可上传1张图片,支持在输入框中直接粘贴图片。</span> </div> </div> <div class="btn" @click="submitAnswerComments(index)">发送</div> </div> </div> </div> <div class="child-comments" v-if="item['child'].length != 0"> <div class="comments-item" v-for="(ite, i) in item['child']" :key="ite.id"> <div class="comments-header flexacenter"> <div class="comments-header-left flexacenter"> <img class="comments-avatar" @click="openUserInfo(index, i)" :src="ite['avatar']" /> <div class="comments-username" @click="openUserInfo(index, i)">{{ ite["nickname"] || "匿名用户" }}</div> <div class="comments-time">{{ handleDate(ite["timestamp"]) }}</div> <!-- <div class="comments-identity" v-if="ite['questioner'] == 1">提问者</div> --> <!-- <div class="comments-identity" v-else-if="ite['isauthor'] == 1">回答者</div> --> <div class="comments-identity" v-if="ite['isauthor'] == 1">提问者</div> <img class="comments-title" v-if="ite['groupimage']" :src="ite.groupimage" :alt="ite.grouptitle" style="height: 17px" /> <div class="avatar-box flexflex" v-if="ite['avatarState']"> <a class="avatar-item flexcenter" target="_blank" @click.prevent="sendMessage(ite['uin'])"> <img class="avatar-icon" src="@/img/send-messages-icon.png" /> 发送信息 </a> <a class="avatar-item flexcenter" target="_blank" @click.prevent="TAHomePage(ite['uin'])"> <img class="avatar-icon" src="@/img/homepage-icon.png" /> TA的主页 </a> <div class="avatar-mask" @click="closeUserInfo(index, i)"></div> </div> </div> <div class="comments-header-right flexacenter"> <div class="menu-box flexacenter"> <img class="menu-icon" src="/img/menu-icon-gray.svg" /> <div class="operate-boxx"> <div class="item flexcenter" @click="openMenuState(index, i)">举报</div> <div class="item flexcenter" v-if="permissions.includes('comment.edit')" @click="openEdit(ite['token'], index, i)">编辑</div> <div class="item flexcenter" v-if="permissions.includes('comment.delete')" @click="commentDelete(ite['token'], index, i)">删除</div> </div> </div> <img class="comment-icon" @click="openAnswerCommentsChild(index, i)" src="/img/comment-icon-gray.svg" /> <div class="flexacenter like-box" @click="operateAnswerCommentsLike(ite.token, index, i)"> <img class="like-icon" v-if="ite['islike'] == 0" src="/img/like-icon-gray.png" /> <img class="like-icon" v-else src="/img/like-icon-colours.png" /> <div class="like-quantity">{{ ite["likenum"] || "" }}</div> </div> </div> </div> <div class="comments-content"> <div class="comments-text"> <!-- <div class="comments-reply" v-if="JSON.stringify(ite['reply']) != '[]'">@{{ ite["reply"]["nickname"] }}</div> --> <div class="comments-reply" v-if="ite?.reply?.nickname">@{{ ite["reply"]["nickname"] || "匿名用户" }}</div> <span v-html="ite['content']"></span> </div> <img class="comments-img" @click="handleAnswerText" :src="ite.image?.base64 || ite.image?.url" v-if="ite.image?.url" /> <div class="input-box" v-if="ite['childState']"> <img class="cross" @click="closeAnswerCommentsChild(index)" src="/img/cross-icon.png" /> <div class="top flexflex"> <textarea class="input-textarea flex1" maxlength="500" v-model="ite['commentInput']" :placeholder="'回复“' + (ite['nickname'] || '匿名用户') + '”:'" @focus="judgeLogin" @input="autoResize" @paste="handleInputPaste($event, index, i)"></textarea> </div> <div class="picture-box" v-if="ite.picture?.url"> <div class="picture"> <img class="close" @click="closeFileUpload(index, i)" src="/img/close-icon.png" /> <img class="img" @click="handleAnswerText" :src="ite.picture.base64 || ite.picture.url" /> </div> </div> <div class="bottom flexacenter"> <div class="operate flexacenter"> <div class="item" :class="{ pitch: ite.emojiState }"> <img class="icon" src="/img/smiling-face.png" @click="openEmoji(index, i)" alt="" /> <div class="emoji-box"> <div class="emoji-icon" v-for="item in emojiData" :key="item" @click="selectEmoji(item, index, i)">{{ item }}</div> </div> </div> <div class="item flexacenter" @click="judgeLogin()"> <input class="file" type="file" @change="handleFileUpload($event, index, i)" accept=".png, .jpg, .jpeg" /> <img class="icon" style="border-radius: 0" src="/img/picture-icon.png" alt="" /> <span class="file-hint">最多可上传1张图片,支持在输入框中直接粘贴图片。</span> </div> </div> <div class="btn" @click="submitAnswerComments(index, i)">发送</div> </div> </div> </div> </div> <div class="comments-also flexacenter" v-if="item['childnum'] > item['child'].length" @click="alsoCommentsData(index, i)"> <div class>还有{{ item["childnum"] - item.child.length }}条回复</div> <img class="also-icon" src="/img/arrow-circular-gray.png" /> </div> </div> </div> </div> <el-dialog v-model="dialogVisible" title="提示" width="500"> <span>确定删除该讨论吗?</span> <template #footer> <div class="dialog-footer"> <el-button @click="dialogVisible = false">取 消</el-button> <el-button type="primary" @click="confirmCommentDelete">确 定</el-button> </div> </template> </el-dialog> </div> </template> <script setup> const props = defineProps({ token: String, }); onMounted(() => { // getComment() }); let permissions = ref([]); onMounted(() => { setTimeout(() => { // permissions.value = window["permissions"] || []; // if (process.env.NODE_ENV !== "production") permissions.value = ["comment.edit", "comment.delete"]; // else permissions.value = window["permissions"] || []; }, 1000); }); const emit = defineEmits(); const $ajax = inject("$ajax"); const $ajaxGET = inject("$ajaxGET"); const detailsToken = inject("detailsToken"); const handleDate = inject("handleDate"); const isNeedLogin = inject("isNeedLogin"); const handleMsg = inject("handleMsg"); const uploadImg = inject("uploadImg"); const handleAnswerText = inject("handleAnswerText"); const emojiMaskState = inject("emojiMaskState"); const user = inject("user"); const goLogin = inject("goLogin"); const detailLoading = inject("detailLoading"); // 点击ta的主页 const TAHomePage = (uin) => { redirectToExternalWebsite(`https://bbs.gter.net/home.php?mod=space&uid=${uin}`); }; // 点击发送信息 const sendMessage = (uin) => { if (uin && typeof messagePrivateItem == "function") { messagePrivateItem({ uin: uin }); return; } else redirectToExternalWebsite(`https://bbs.gter.net/home.php?mod=space&showmsg=1&uid=${uin}`); }; // 跳转 url const redirectToExternalWebsite = (url) => { const link = document.createElement("a"); link.href = url; link.target = "_blank"; link.click(); }; const commentList = ref([]); let commentCount = ref(0); let commentTotalCount = ref(0); let commentPage = ref(1); let isgetCommentSate = false; // 请求评论状态 let alreadyCommentIdList = []; const getComment = () => { if (commentPage.value == 0 || isgetCommentSate) return; isgetCommentSate = true; $ajax("/api/comment/lists", { token: detailsToken.value, page: commentPage.value, limit: 1500, }) .then((res) => { if (res.code != 200) return; let data = res.data; data.data.forEach((element, index) => { element["isReplyBoxShow"] = 0; // element.timestamp = util.timeformat(element.timestamp, 2) if (element.child.length > 0) { element.child.forEach((el) => { // el.timestamp = util.timeformat(el.timestamp, 2) el["isReplyBoxShow"] = 0; }); } }); if (commentPage.value > 1) { let alreadyCommentIdList = alreadyCommentIdList; for (let index = 0; index < data.data.length; index++) { if (alreadyCommentIdList.includes(data.data[index].id)) { data.data.splice(index, 1); index--; } } } commentList.value = commentList.value.concat(data.data); // console.log("commentList", commentList.value) commentCount.value = data.count; commentTotalCount.value = data.comments; commentPage.value = data.count > commentList.length ? commentPage.value + 1 : 0; // console.log("commentList", commentList) // this.setData({ // commentList, // commentCount: data.count, // commentTotalCount: data.comments, // commentPage: data.count > commentList.length ? this.data.commentPage + 1 : 0, // }) }) .finally(() => { isgetCommentSate = false; }); }; let picture = ref({}); // 监听 detailsToken 的变化 watch( detailsToken, (newValue, oldValue) => { if (newValue !== oldValue) { commentPage.value = 1; commentList.value = []; picture.value = {}; commentTotalCount.value = 0; commentCount.value = 0; alreadyCommentIdList = []; getComment(); } }, { immediate: true } ); const maxSize = 20 * 1024 * 1024; // 20MB const handleFileUpload = (event, index, i) => { if (isNeedLogin.value) { goLogin(); return; } closeEmoji(); const file = event.target.files[0]; // 获取选择的文件 if (!file) return; if (file.size > maxSize) { handleMsg("error", "文件大小不能超过 20MB"); return; } const reader = new FileReader(); reader.onload = (e) => { const base64 = e.target.result; uploadImg(base64).then((res) => { const obj = { base64, ...res, }; if (editCommentState.value) editPicture.value = obj; else { if (i != undefined) commentList.value[index].child[i]["picture"] = obj; else if (index != undefined) commentList.value[index]["picture"] = obj; else picture.value = obj; } handleMsg("success", "上传成功"); }); }; reader.readAsDataURL(file); }; // 删除上传的图片 const closeFileUpload = (index, i) => { if (i != undefined) commentList.value[index].child[i]["picture"] = {}; else if (index != undefined) commentList.value[index]["picture"] = {}; else picture.value = {}; }; // let emojiState = ref(false); const emojiData = ["😀", "😁", "😆", "😅", "😂", "😉", "😍", "🥰", "😋", "😜", "🤪", "😎", "🤩", "🥳", "😔", "🙁", "😭", "😡", "😳", "🤗", "🤔", "🤭", "🤫", "😯", "😵", "🙄", "🥴", "🤢", "🤑", "🤠", "👌", "✌️", "🤟", "🤘", "🤙", "👍", "👎", "✊", "👏", "🤝", "🙏", "💪", "❤️", "💔", "🌹", "🥀", "🎉", "🎁", "🧧", "🌙", "⭐", "🌍", "💌", "📬", "🚗", "🚕", "🚲", "🛵", "🚀", "🚁", "⛵", "🚢", "🍎", "🍐", "🍊", "🍉", "🍓", "🍑", "🍔", "🍟", "🍕", "🥪", "🍜", "🍡", "🍨", "🍦", "🎂", "🍰", "🍭", "🍿", "🍩", "🧃", "🍹"]; // 打开 Emoji const openEmoji = (index, i) => { if (isNeedLogin.value) { goLogin(); return; } if (i != undefined) commentList.value[index].child[i]["emojiState"] = true; else if (index != undefined) commentList.value[index]["emojiState"] = true; else { closeEmoji(); closeAnswerCommentsChild(); emojiState.value = true; } emojiMaskState.value = true; }; // 关闭 Emoji const closeEmoji = (index, i) => { commentList.value.forEach((ele) => { ele["emojiState"] = false; if (ele["child"] && ele["child"].length != 0) { ele["child"].forEach((el) => { el["emojiState"] = false; }); } }); emojiState.value = false; emojiMaskState.value = false; editEmojiState.value = false; }; defineExpose({ closeEmoji, }); // 选择 Emoji const selectEmoji = (key, index, i) => { closeEmoji(); if (i != undefined) { if (!commentList.value[index]["child"][i]["commentInput"]) commentList.value[index]["child"][i]["commentInput"] = ""; commentList.value[index]["child"][i]["commentInput"] += key; } else if (index != undefined) { if (!commentList.value[index]["commentInput"]) commentList.value[index]["commentInput"] = ""; commentList.value[index]["commentInput"] += key; } else { inputTextarea.value += key; } }; // 自动输入框增高 const autoResize = (e) => { e.target.style.height = "auto"; // 重置高度 e.target.style.height = `${e.target.scrollHeight}px`; // 设置为内容高度 }; const handleInputPaste = (event, index, ii) => { if (isNeedLogin.value) { goLogin(); return; } const items = event.clipboardData.items; // 获取粘贴的内容 for (let i = 0; i < items.length; i++) { const item = items[i]; if (item.type.startsWith("image/")) { event.preventDefault(); const file = item.getAsFile(); // 获取文件 if (file.size > maxSize) { handleMsg("error", "文件大小不能超过 20MB"); return; } const reader = new FileReader(); reader.onload = (e) => { const base64 = e.target.result; uploadImg(base64).then((res) => { const obj = { base64, ...res, }; if (editCommentState.value) editPicture.value = obj; else { if (ii != undefined) commentList.value[index].child[ii]["picture"] = obj; else if (index != undefined) commentList.value[index]["picture"] = obj; else picture.value = obj; } handleMsg("success", "上传成功"); }); }; reader.readAsDataURL(file); } } }; let inputTextarea = ref(""); // 提交回答-评论 const submitAnswerComments = (index, i) => { if (isNeedLogin.value) { goLogin(); return; } let content = ""; let parentid = null; let token = detailsToken.value; let image = {}; if (i != null) { content = commentList.value[index]["child"][i]["commentInput"]; parentid = commentList.value[index]["child"][i]["id"]; image = commentList.value[index]["child"][i]["picture"]; } else if (index != null) { content = commentList.value[index]["commentInput"]; parentid = commentList.value[index]["id"]; image = commentList.value[index]["picture"]; } else { content = inputTextarea.value; image = picture.value; } detailLoading.value = true; $ajax("/api/comment/submit", { content, token, parentid, image: image ? { aid: image.aid, url: image.url } : null, }) .then((res) => { if (res.code != 200) { handleMsg("error", res["message"]); return; } let data = res.data; if (i != null) { let targetData = { id: data["commentid"], content, isauthor: 1, islike: 0, likenum: 0, reply: { nickname: commentList.value[index]["child"][i]["nickname"], }, ...data, image, }; commentList.value[index]["child"].push(targetData); commentList.value[index]["childnum"]++; } else if (index != null) { let targetData = { id: data["commentid"], content, isauthor: 1, islike: 0, likenum: 0, reply: [], ...data, image, }; commentList.value[index]["child"].unshift(targetData); commentList.value[index]["childnum"]++; } else { let targetData = { id: data["commentid"], content, isauthor: 1, islike: 0, likenum: 0, ...data, child: [], image, }; commentList.value.unshift(targetData); // commentCount.value++ inputTextarea.value = ""; picture.value = {}; } commentTotalCount.value = data.count || 0; emit("updateAnswers", data.count); // targetAnswerList[index]["commentnum"] = data["count"] closeAnswerCommentsChild(); handleMsg("success", res["message"] || "操作成功"); }) .finally(() => { detailLoading.value = false; }); }; // 回答-评论 点赞 const operateAnswerCommentsLike = (token, index, i) => { if (isNeedLogin.value) { goLogin(); return; } $ajax("/api/comment/like", { token, }).then((res) => { if (res.code != 200) return; let data = res.data; if (i != undefined) { commentList.value[index].child[i]["islike"] = data["status"]; commentList.value[index].child[i]["likenum"] = data["likenum"]; } else { commentList.value[index]["islike"] = data["status"]; commentList.value[index]["likenum"] = data["likenum"]; } handleMsg("success", res["message"] || "操作成功"); }); }; // 打开 回答-评论 的子评论 const openAnswerCommentsChild = (index, i) => { // console.log("isNeedLogin", isNeedLogin) if (isNeedLogin.value) { goLogin(); return; } closeAnswerCommentsChild(); if (i == null) commentList.value[index]["childState"] = true; else commentList.value[index]["child"][i]["childState"] = true; }; // 关闭 回答-评论 的子评论 const closeAnswerCommentsChild = () => { commentList.value.forEach((ele) => { ele["childState"] = false; ele["commentInput"] = ""; // 删除原本输入值 if (ele["child"] && ele["child"].length != 0) { ele["child"].forEach((el) => { el["childState"] = false; el["commentInput"] = ""; }); } }); }; // 获取剩下的子评论 const alsoCommentsData = (index, i) => { // const targetAnswerList = [...answerList.value] const parentid = commentList.value[index]["id"]; const token = detailsToken.value; $ajax("/api/comment/childrenList", { token, parentid, limit: 2000, page: 1, childlimit: 3, }).then((res) => { if (res.code != 200) return; let data = res.data; let merged = [...commentList.value[index]["child"], ...data.data.filter((item2) => !commentList.value[index]["child"].find((item1) => item1.id == item2.id))]; commentList.value[index]["child"] = merged; // answerList.value = targetAnswerList }); }; const handleMenuState = inject("handleMenuState"); const openMenuState = (index, i) => { if (isNeedLogin.value) { goLogin(); return; } let reportToken = ""; if (i === undefined) reportToken = commentList.value[index]["token"]; else reportToken = commentList.value[index]["child"][i]["token"]; handleMenuState(reportToken); }; const openUserInfo = (index, i) => { if (i != undefined && commentList.value[index].child[i]["uin"] > 0) commentList.value[index].child[i]["avatarState"] = true; else if (i == undefined && index != undefined && commentList.value[index]["uin"] > 0) commentList.value[index]["avatarState"] = true; }; const closeUserInfo = (index, i) => { if (i != undefined) commentList.value[index].child[i]["avatarState"] = false; else if (index != undefined) commentList.value[index]["avatarState"] = false; }; // 点击删除 // const commentDelete = (token, index, i) => { // $ajax("/api/comment/commentDelete", { // token, // }).then((res) => { // if (res.code != 200) { // ElMessage.error(res.message); // return; // } // if (i >= 0) { // commentList.value[index].child.splice(i, 1); // commentList.value[index].childnum -= 1; // } else { // commentTotalCount.value -= commentList.value[index].childnum; // commentList.value.splice(index, 1); // } // commentTotalCount.value -= 1; // }); // }; let dialogVisible = ref(false); let commemtDelete = {}; // 点击删除 const commentDelete = (token, index, i) => { commemtDelete = { token, index, i, }; dialogVisible.value = true; }; const confirmCommentDelete = () => { $ajax("/api/comment/commentDelete", { token: commemtDelete.token, }).then((res) => { if (res.code != 200) { ElMessage.error(res.message); return; } if (commemtDelete.i >= 0) { commentList.value[commemtDelete.index].child.splice(commemtDelete.i, 1); commentList.value[commemtDelete.index].childnum -= 1; } else { commentTotalCount.value -= commentList.value[commemtDelete.index].childnum; commentList.value.splice(commemtDelete.index, 1); } commentTotalCount.value -= 1; dialogVisible.value = false; ElMessage.success(res.message || "操作成功"); }); }; const judgeLogin = () => { if (isNeedLogin.value) { goLogin(); return; } }; let editCommentState = ref(false); let editToken = ""; let editPicture = ref({}); let editInput = ref(""); let editEmojiState = ref(false); const editInputRef = ref(null); const openEdit = (token, index, i) => { const list = JSON.parse(JSON.stringify(commentList.value)); let target = {}; if (i != null) target = list[index]["child"][i]; else target = list[index]; console.log(token, index, i, target); editToken = target.token || ""; editInput.value = target.content || ""; editPicture.value = target.image || {}; editCommentState.value = true; nextTick(() => { console.log("editInput.value", editInputRef.value); editInputRef.value.style.height = `${editInputRef.value.scrollHeight}px`; }); }; const closeEdit = () => { editPicture.value = {}; editToken = ""; editInput.value = ""; editCommentState.value = false; }; // 打开 Emoji const openEditEmoji = (index, i) => { if (isNeedLogin.value) { goLogin(); return; } editEmojiState.value = true; }; const selectEditEmoji = (key) => { closeEmoji(); editInput.value += key; }; const postEditComment = () => { if (isNeedLogin.value) { goLogin(); return; } const image = editPicture.value; $ajax("/api/comment/commentsEditSubmit", { content: editInput.value, token: editToken, image: image ? { aid: image.aid, url: image.url } : null, }).then((res) => { if (res.code != 200) { ElMessage.error(res.message); return; } commentList.value.forEach((element) => { if (element.token == editToken) { element["content"] = editInput.value; element["image"] = image; } element.child && element.child.forEach((ele) => { if (ele.token == editToken) { ele["content"] = editInput.value; ele["image"] = image; } }); }); editPicture.value = {}; editToken = ""; editCommentState.value = false; editEmojiState.value = false; ElMessage.success(res.message); }); }; const closeEditFileUpload = () => (editPicture.value = {}); </script>