新讨论测试

This commit is contained in:
A1300399510 2025-02-17 19:00:34 +08:00
parent d45e8484a5
commit 08fd75e930
4 changed files with 314 additions and 27 deletions

View File

@ -509,7 +509,7 @@ import axios from "axios"
export default { export default {
name: "#answer-app", name: "#answer-app",
async setup() { async setup() {
const author = "cb8ef16ff29a8a00d62c999146c539ad" const author = "c1fb97e6994539d87922b1b60c09d43c"
const $ajax = (url, data) => { const $ajax = (url, data) => {
url = url.indexOf("//") > -1 ? url : baseURL + url url = url.indexOf("//") > -1 ? url : baseURL + url
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {

View File

@ -1,5 +1,42 @@
<template> <template>
<div class="answer-discuss"> <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"> <div class="header flexacenter">
回答&讨论 回答&讨论
<span class="num">{{ commentTotalCount || "" }}</span> <span class="num">{{ commentTotalCount || "" }}</span>
@ -55,9 +92,13 @@
</div> </div>
</div> </div>
<div class="comments-header-right flexacenter"> <div class="comments-header-right flexacenter">
<div class="menu-box flexacenter" @click="openMenuState(index)"> <div class="menu-box flexacenter">
<img class="menu-icon" src="/img/menu-icon-gray.svg" /> <img class="menu-icon" src="/img/menu-icon-gray.svg" />
<div class="report-box flexcenter">举报</div> <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> </div>
<img class="comment-icon" @click="openAnswerCommentsChild(index)" src="/img/comment-icon-gray.svg" /> <img class="comment-icon" @click="openAnswerCommentsChild(index)" src="/img/comment-icon-gray.svg" />
<div class="flexacenter like-box" @click="operateAnswerCommentsLike(item.token, index)"> <div class="flexacenter like-box" @click="operateAnswerCommentsLike(item.token, index)">
@ -124,7 +165,11 @@
<div class="comments-header-right flexacenter"> <div class="comments-header-right flexacenter">
<div class="menu-box flexacenter"> <div class="menu-box flexacenter">
<img class="menu-icon" src="/img/menu-icon-gray.svg" /> <img class="menu-icon" src="/img/menu-icon-gray.svg" />
<div class="report-box flexcenter">举报</div> <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> </div>
<img class="comment-icon" @click="openAnswerCommentsChild(index, i)" src="/img/comment-icon-gray.svg" /> <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)"> <div class="flexacenter like-box" @click="operateAnswerCommentsLike(ite.token, index, i)">
@ -189,6 +234,15 @@ const props = defineProps({
onMounted(() => { onMounted(() => {
// getComment() // getComment()
}) })
let permissions = ref([])
onMounted(() => {
setTimeout(() => {
permissions.value = window["permissions"] || []
// permissions.value = ["comment.edit", "comment.delete"]
}, 1000)
})
const emit = defineEmits() const emit = defineEmits()
const $ajax = inject("$ajax") const $ajax = inject("$ajax")
@ -331,10 +385,12 @@ const handleFileUpload = (event, index, i) => {
...res, ...res,
} }
if (editCommentState.value) editPicture.value = obj
else {
if (i != undefined) commentList.value[index].child[i]["picture"] = obj if (i != undefined) commentList.value[index].child[i]["picture"] = obj
else if (index != undefined) commentList.value[index]["picture"] = obj else if (index != undefined) commentList.value[index]["picture"] = obj
else picture.value = obj else picture.value = obj
}
handleMsg("success", "上传成功") handleMsg("success", "上传成功")
}) })
} }
@ -383,6 +439,7 @@ const closeEmoji = (index, i) => {
emojiState.value = false emojiState.value = false
emojiMaskState.value = false emojiMaskState.value = false
editEmojiState.value = false
} }
defineExpose({ defineExpose({
@ -437,9 +494,12 @@ const handleInputPaste = (event, index, ii) => {
base64, base64,
...res, ...res,
} }
if (editCommentState.value) editPicture.value = obj
else {
if (ii != undefined) commentList.value[index].child[ii]["picture"] = obj if (ii != undefined) commentList.value[index].child[ii]["picture"] = obj
else if (index != undefined) commentList.value[index]["picture"] = obj else if (index != undefined) commentList.value[index]["picture"] = obj
else picture.value = obj else picture.value = obj
}
handleMsg("success", "上传成功") handleMsg("success", "上传成功")
}) })
} }
@ -648,11 +708,120 @@ const closeUserInfo = (index, i) => {
else if (index != undefined) commentList.value[index]["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
})
}
const judgeLogin = () => { const judgeLogin = () => {
if (isNeedLogin.value) { if (isNeedLogin.value) {
goLogin() goLogin()
return 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> </script>
<style scoped></style> <style scoped></style>

View File

@ -685,6 +685,54 @@ a {
box-shadow: 0 0 3px rgba(0, 0, 0, 0.11764706); box-shadow: 0 0 3px rgba(0, 0, 0, 0.11764706);
padding: 18px 22px; padding: 18px 22px;
} }
#answer-app .main .details-area-box .details-box .answer-discuss .edit-comment {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-color: rgba(0, 0, 0, 0.5);
z-index: 12;
}
#answer-app .main .details-area-box .details-box .answer-discuss .edit-comment .box {
width: 650px;
border-radius: 10px;
background: #fff;
padding: 20px 15px;
}
#answer-app .main .details-area-box .details-box .answer-discuss .edit-comment .box .text {
font-size: 18px;
font-weight: 650;
margin-bottom: 15px;
color: #000;
}
#answer-app .main .details-area-box .details-box .answer-discuss .edit-comment .box .input-box {
margin-right: 0;
}
#answer-app .main .details-area-box .details-box .answer-discuss .edit-comment .box .input-box .bottom {
border-top: 1px solid #ebebeb;
}
#answer-app .main .details-area-box .details-box .answer-discuss .edit-comment .box .btn-list {
padding: 15px 0;
justify-content: flex-end;
}
#answer-app .main .details-area-box .details-box .answer-discuss .edit-comment .box .btn-list .btn {
font-size: 14px;
color: #333;
width: 80px;
height: 28px;
line-height: 28px;
text-align: center;
border-radius: 43px;
cursor: pointer;
background-color: #fff;
border: 1px solid #ebebeb;
margin-left: 20px;
}
#answer-app .main .details-area-box .details-box .answer-discuss .edit-comment .box .btn-list .btn.send {
background-color: #fddf6d;
border: 1px solid #fddf6d;
}
#answer-app .main .details-area-box .details-box .answer-discuss .header { #answer-app .main .details-area-box .details-box .answer-discuss .header {
font-family: "PingFangSC-Semibold", "PingFang SC Semibold", "PingFang SC", sans-serif; font-family: "PingFangSC-Semibold", "PingFang SC Semibold", "PingFang SC", sans-serif;
font-weight: 650; font-weight: 650;
@ -1294,7 +1342,7 @@ a {
#answer-app .main .details-area-box .details-box .comments-box .comments-item .comments-header .comments-header-right .menu-box { #answer-app .main .details-area-box .details-box .comments-box .comments-item .comments-header .comments-header-right .menu-box {
position: relative; position: relative;
} }
#answer-app .main .details-area-box .details-box .comments-box .comments-item .comments-header .comments-header-right .menu-box:hover .report-box { #answer-app .main .details-area-box .details-box .comments-box .comments-item .comments-header .comments-header-right .menu-box:hover .operate-boxx {
display: flex; display: flex;
} }
#answer-app .main .details-area-box .details-box .comments-box .comments-item .comments-header .comments-header-right .menu-box .menu-icon { #answer-app .main .details-area-box .details-box .comments-box .comments-item .comments-header .comments-header-right .menu-box .menu-icon {
@ -1302,27 +1350,35 @@ a {
height: 14px; height: 14px;
cursor: pointer; cursor: pointer;
} }
#answer-app .main .details-area-box .details-box .comments-box .comments-item .comments-header .comments-header-right .menu-box .report-box { #answer-app .main .details-area-box .details-box .comments-box .comments-item .comments-header .comments-header-right .menu-box .operate-boxx {
display: none; display: none;
flex-direction: column;
position: absolute; position: absolute;
top: 24px; top: 24px;
right: 0; right: 0;
width: 60px;
height: 24px;
background-color: #f6f6f6;
border: 1px solid #d7d7d7;
border-radius: 5px;
font-size: 12px; font-size: 12px;
color: #7f7f7f; color: #7f7f7f;
cursor: pointer; cursor: pointer;
width: 60px;
z-index: 2;
border-radius: 5px;
background-color: #f6f6f6;
border: 1px solid #d7d7d7;
} }
#answer-app .main .details-area-box .details-box .comments-box .comments-item .comments-header .comments-header-right .menu-box .report-box::after { #answer-app .main .details-area-box .details-box .comments-box .comments-item .comments-header .comments-header-right .menu-box .operate-boxx .item {
height: 24px;
}
#answer-app .main .details-area-box .details-box .comments-box .comments-item .comments-header .comments-header-right .menu-box .operate-boxx .item:not(:last-of-type) {
border-bottom: 1px solid #d7d7d7;
}
#answer-app .main .details-area-box .details-box .comments-box .comments-item .comments-header .comments-header-right .menu-box .operate-boxx::after {
content: ""; content: "";
width: 58px; width: 58px;
height: 36px; height: 36px;
position: absolute; position: absolute;
top: -14px; top: -14px;
right: 0; right: 0;
z-index: -1;
} }
#answer-app .main .details-area-box .details-box .comments-box .comments-item .comments-header .comments-header-right .comment-icon { #answer-app .main .details-area-box .details-box .comments-box .comments-item .comments-header .comments-header-right .comment-icon {
width: 14px; width: 14px;

View File

@ -856,6 +856,61 @@ a {
box-shadow: 0 0 3px rgba(0, 0, 0, 0.117647058823529); box-shadow: 0 0 3px rgba(0, 0, 0, 0.117647058823529);
padding: 18px 22px; padding: 18px 22px;
.edit-comment {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-color: rgba(0, 0, 0, 0.5);
z-index: 12;
.box {
width: 650px;
// height: 500px;
border-radius: 10px;
background: #fff;
padding: 20px 15px;
.text {
font-size: 18px;
font-weight: 650;
margin-bottom: 15px;
color: #000;
}
.input-box {
margin-right: 0;
.bottom {
border-top: 1px solid #ebebeb;
}
}
.btn-list {
padding: 15px 0;
justify-content: flex-end;
.btn {
font-size: 14px;
color: #333;
width: 80px;
height: 28px;
line-height: 28px;
text-align: center;
border-radius: 43px;
cursor: pointer;
background-color: #fff;
border: 1px solid #ebebeb;
margin-left: 20px;
&.send {
background-color: #fddf6d;
border: 1px solid #fddf6d;
}
}
}
}
}
.header { .header {
font-family: "PingFangSC-Semibold", "PingFang SC Semibold", "PingFang SC", sans-serif; font-family: "PingFangSC-Semibold", "PingFang SC Semibold", "PingFang SC", sans-serif;
font-weight: 650; font-weight: 650;
@ -1572,7 +1627,7 @@ a {
.menu-box { .menu-box {
position: relative; position: relative;
&:hover .report-box { &:hover .operate-boxx {
display: flex; display: flex;
} }
@ -1582,20 +1637,26 @@ a {
cursor: pointer; cursor: pointer;
} }
.report-box { .operate-boxx {
display: none; display: none;
flex-direction: column;
position: absolute; position: absolute;
top: 24px; top: 24px;
right: 0; right: 0;
width: 60px;
height: 24px;
background-color: rgba(246, 246, 246, 1);
border: 1px solid rgba(215, 215, 215, 1);
border-radius: 5px;
font-size: 12px; font-size: 12px;
color: #7f7f7f; color: #7f7f7f;
cursor: pointer; cursor: pointer;
width: 60px;
z-index: 2;
border-radius: 5px;
background-color: rgba(246, 246, 246, 1);
border: 1px solid rgba(215, 215, 215, 1);
.item {
height: 24px;
&:not(:last-of-type) {
border-bottom: 1px solid rgba(215, 215, 215, 1);
}
}
&::after { &::after {
content: ""; content: "";
width: 58px; width: 58px;
@ -1603,6 +1664,7 @@ a {
position: absolute; position: absolute;
top: -14px; top: -14px;
right: 0; right: 0;
z-index: -1;
} }
} }
} }