新讨论

This commit is contained in:
A1300399510
2025-02-13 19:05:38 +08:00
parent 9e72739b53
commit 9b0c3f9416
7 changed files with 466 additions and 57 deletions

View File

@@ -13,9 +13,9 @@
<div class="post-ok flexcenter" @click="submitAnswerComments(commentInputTop)">发送</div>
</div> -->
<div class="input-box" v-if="false">
<div class="input-box" v-if="true">
<div class="top flexflex">
<img class="avatar" v-if="user.avatar" :src="user.avatar" />
<img class="avatar" v-if="userInfoWin.avatar" :src="userInfoWin.avatar" />
<textarea class="input-textarea flex1" maxlength="500" v-model="commentInputTop" @input="autoResize" @paste="handleInputPaste" placeholder="说说你的想法或疑问…"></textarea>
</div>
<div class="picture-box" v-if="picture.url">
@@ -35,7 +35,7 @@
</div>
<div class="item flexacenter">
<input class="file" type="file" @change="handleFileUpload($event)" accept=".png, .jpg, .jpeg" />
<img class="icon" style="border-radius: 0;" src="@/assets/img/picture-icon.png" alt="" />
<img class="icon" src="@/assets/img/picture-icon.png" alt="" />
<span class="file-hint">最多可上传1张图片支持在输入框中直接粘贴图片</span>
</div>
</div>
@@ -76,7 +76,11 @@
<div class="comment-header-right flexacenter">
<div class="menu-box flexacenter">
<img class="menu-icon" src="@/assets/img/menu-icon-gray.svg" />
<div class="report-box flexcenter" @click="report(item['token'])">举报</div>
<div class="operate-box">
<div class="item flexcenter" @click="report(item['token'])">举报</div>
<div class="item flexcenter" @click="report(item['token'])">编辑</div>
<div class="item flexcenter" @click="commentDelete(item['token'], index)">删除</div>
</div>
</div>
<!-- <img class="comment-icon" title="回复" @click="openAnswerCommentsChild(index)" src="@/assets/img/comment-icon-gray.svg" /> -->
<img class="comment-icon" title="回复" @click="!item['childState'] ? openAnswerCommentsChild(index) : closeAnswerCommentsChild()" src="@/assets/img/comment-icon-gray.svg" />
@@ -89,8 +93,37 @@
</div>
<!-- shutAnswerCommentsChild openAnswerCommentsChild -->
<div class="comment-text" @click="!item['childState'] ? openAnswerCommentsChild(index) : closeAnswerCommentsChild()">{{ item["content"] }}</div>
<img class="comments-img" @click="handleAnswerText" :src="item.image?.base64 || item.image?.url" v-if="item.image?.url" />
<div class="alreadyVoted" v-if="item.voteoption">已投{{ item.voteoption }}</div>
<div class="comments-input-masking" @click="closeAnswerCommentsChild()" v-if="item['childState']"></div>
<div class="input-box" v-if="item['childState']">
<img class="cross" @click="closeAnswerCommentsChild()" src="@/assets/img/cross-icon.png" />
<div class="top flexflex">
<textarea class="input-textarea flex1" maxlength="500" placeholder="说说你的想法或疑问…" v-model="item['commentInput']" @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="@/assets/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="@/assets/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">
<input class="file" type="file" @change="handleFileUpload($event, index)" accept=".png, .jpg, .jpeg" />
<img class="icon" src="@/assets/img/picture-icon.png" alt="" />
<span class="file-hint">最多可上传1张图片支持在输入框中直接粘贴图片</span>
</div>
</div>
<div class="btn" @click="submitAnswerComments(item['commentInput'], index)">发送</div>
</div>
</div>
<!-- <div class="comments-input-masking" @click="closeAnswerCommentsChild()" v-if="item['childState']"></div>
<div class="comments-input-box" :class="{ 'comments-input-box-show': item['childState'] }">
<div class="comments-input">
<el-input v-model="commentInput" type="textarea" placeholder="回复" :maxlength="500" show-word-limit></el-input>
@@ -99,7 +132,7 @@
<div class="comments-btn flexcenter" @click="submitAnswerComments(commentInput, index)">发送</div>
</div>
</div>
</div>
</div> -->
<!-- 子评论 -->
<div class="child-comments" v-if="item['child'].length > 0">
<div class="comment-item flexflex" v-for="(ite, i) in item['child']" :key="ite.id">
@@ -130,7 +163,12 @@
<div class="comment-header-right flexacenter">
<div class="menu-box flexacenter">
<img class="menu-icon" src="@/assets/img/menu-icon-gray.svg" />
<div class="report-box flexcenter" @click="report(ite['token'])">举报</div>
<div class="operate-box">
<div class="item flexcenter" @click="report(ite['token'])">举报</div>
<div class="item flexcenter" @click="report(ite['token'])">编辑</div>
<div class="item flexcenter" @click="commentDelete(ite['token'], index, i)">删除</div>
</div>
<!-- <div class="report-box flexcenter" @click="report(ite['token'])">举报</div> -->
</div>
<img class="comment-icon" title="回复" @click="!ite['childState'] ? openAnswerCommentsChild(index, i) : closeAnswerCommentsChild()" src="@/assets/img/comment-icon-gray.svg" />
<div class="flexacenter like-box" @click="commentLike(index, i)">
@@ -144,8 +182,37 @@
<div class="comments-reply" v-if="ite?.reply?.nickname">@{{ ite?.reply?.nickname }}</div>
{{ ite["content"] }}
</div>
<img class="comments-img" @click="handleAnswerText" :src="ite.image?.base64 || ite.image?.url" v-if="ite.image?.url" />
<div class="alreadyVoted" v-if="ite.voteoption">已投{{ ite.voteoption }}</div>
<div class="comments-input-masking" @click="closeAnswerCommentsChild()" v-if="ite['childState']"></div>
<div class="input-box" v-if="ite['childState']">
<img class="cross" @click="closeAnswerCommentsChild()" src="@/assets/img/cross-icon.png" />
<div class="top flexflex">
<textarea class="input-textarea flex1" maxlength="500" :placeholder="'回复“' + (ite['nickname'] || '匿名用户') + '”:'" v-model="ite['commentInput']" @input="autoResize" @paste="handleInputPaste($event, index)"></textarea>
</div>
<div class="picture-box" v-if="ite.picture?.url">
<div class="picture">
<img class="close" @click="closeFileUpload(index, i)" src="@/assets/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="@/assets/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">
<input class="file" type="file" @change="handleFileUpload($event, index, i)" accept=".png, .jpg, .jpeg" />
<img class="icon" src="@/assets/img/picture-icon.png" alt="" />
<span class="file-hint">最多可上传1张图片支持在输入框中直接粘贴图片</span>
</div>
</div>
<div class="btn" @click="submitAnswerComments(ite['commentInput'], index, i)">发送</div>
</div>
</div>
<!-- <div class="comments-input-masking" @click="closeAnswerCommentsChild()" v-if="ite['childState']"></div>
<div class="comments-input-box" :class="{ 'comments-input-box-show': ite['childState'] }">
<div class="comments-input">
<el-input v-model="commentInput" type="textarea" placeholder="回复" :maxlength="500" show-word-limit></el-input>
@@ -154,7 +221,7 @@
<div class="comments-btn flexcenter" @click="submitAnswerComments(commentInput, index, i)">发送</div>
</div>
</div>
</div>
</div> -->
</div>
</div>
</div>
@@ -183,6 +250,13 @@
<div class="automatic-send flexcenter" @click="submitAnswerComments(reviewsPopoverInput)">发送</div>
</div>
</el-dialog>
<!-- 大图 -->
<div class="detail-image-mask flexcenter" v-if="dialogSrc" @click="dialogSrc = ''">
<div class="detail-image flexcenter">
<img class="detail-img" :src="dialogSrc" />
</div>
</div>
</template>
<script setup>
@@ -205,11 +279,7 @@ watch(
onMounted(() => window.addEventListener("scroll", handleScroll))
onMounted(() => {
setInterval(() => {
console.log("userInfoWin", userInfoWin.value)
}, 2000)
})
onMounted(() => {})
const sendMessage = inject("sendMessage")
const TAHomePage = inject("TAHomePage")
@@ -323,18 +393,26 @@ const submitAnswerComments = (content, index, i) => {
// if (index == null) content = commentInputTop.value
// else content = commentInput.value
if (i != null) parentid = targetCommentList[index]["child"][i]["id"]
else if (index != null) parentid = targetCommentList[index]["id"]
let image = {}
if (!content) {
ElMessage.error("请填写评论内容")
return
}
if (i != null) {
parentid = targetCommentList[index]["child"][i]["id"]
image = commentList.value[index]["child"][i]["picture"] || {}
} else if (index != null) {
parentid = targetCommentList[index]["id"]
image = commentList.value[index]["picture"] || {}
} else image = picture.value
// if (!content) {
// ElMessage.error("请填写评论内容")
// return
// }
detailsSubmitommentListHttp({
content,
token: props.token,
parentid,
image: image ? { aid: image.aid, url: image.url } : null,
}).then(res => {
if (res.code != 200) {
ElMessage.error(res.message)
@@ -344,7 +422,10 @@ const submitAnswerComments = (content, index, i) => {
let data = res.data
if (i != null) {
console.log("data", data)
console.log("targetCommentList[index]", targetCommentList[index])
targetCommentList[index]["child"][i]["commentInput"] = ""
targetCommentList[index]["child"][i]["picture"] = {}
let targetData = {
id: data["commentid"],
content,
@@ -359,6 +440,7 @@ const submitAnswerComments = (content, index, i) => {
// ...data.data
timestampnow: "刚刚",
uin: data.data?.uin,
image,
}
targetCommentList[index]["child"].unshift(targetData)
@@ -376,8 +458,11 @@ const submitAnswerComments = (content, index, i) => {
uin: data.data?.uin,
child: [],
voteoption: haveVotedValue.value || null,
image,
}
if (index != null) {
targetCommentList[index]["commentInput"] = ""
targetCommentList[index]["picture"] = {}
targetCommentList[index]["child"].unshift(targetData)
targetCommentList[index]["childnum"]++
} else {
@@ -398,6 +483,8 @@ const submitAnswerComments = (content, index, i) => {
closeAnswerCommentsChild()
picture.value = {}
if (bottomNavigationState) {
bottomNavigationState = false
floorCommentBtn("back")
@@ -539,6 +626,209 @@ const postCommentFocusBlur = () => {
}, 200)
}
let picture = ref({})
let emojiState = ref(false)
let emojiMaskState = ref(false)
const emojiData = ["😀", "😁", "😆", "😅", "😂", "😉", "😍", "🥰", "😋", "😜", "🤪", "😎", "🤩", "🥳", "😔", "🙁", "😭", "😡", "😳", "🤗", "🤔", "🤭", "🤫", "😯", "😵", "🙄", "🥴", "🤢", "🤑", "🤠", "👌", "✌️", "🤟", "🤘", "🤙", "👍", "👎", "✊", "👏", "🤝", "🙏", "💪", "❤️", "💔", "🌹", "🥀", "🎉", "🎁", "🧧", "🌙", "⭐", "🌍", "💌", "📬", "🚗", "🚕", "🚲", "🛵", "🚀", "🚁", "⛵", "🚢", "🍎", "🍐", "🍊", "🍉", "🍓", "🍑", "🍔", "🍟", "🍕", "🥪", "🍜", "🍡", "🍨", "🍦", "🎂", "🍰", "🍭", "🍿", "🍩", "🧃", "🍹"]
// 打开 Emoji
const openEmoji = (index, i) => {
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
}
// 选择 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 {
commentInputTop.value += key
}
}
// 自动输入框增高
const autoResize = e => {
e.target.style.height = "auto" // 重置高度
e.target.style.height = `${e.target.scrollHeight}px` // 设置为内容高度
}
const maxSize = 20 * 1024 * 1024 // 20MB
const handleInputPaste = (event, index, ii) => {
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) {
ElMessage({
message: "文件大小不能超过 20MB",
type: "error",
})
return
}
const reader = new FileReader()
reader.onload = e => {
const base64 = e.target.result
uploadImg(base64).then(res => {
const obj = {
base64,
...res,
}
if (ii != undefined) commentList.value[index].child[ii]["picture"] = obj
else if (index != undefined) commentList.value[index]["picture"] = obj
else picture.value = obj
ElMessage({
message: "上传成功",
type: "success",
})
})
}
reader.readAsDataURL(file)
}
}
}
const handleFileUpload = (event, index, i) => {
closeEmoji()
const file = event.target.files[0] // 获取选择的文件
if (!file) return
if (file.size > maxSize) {
ElMessage({
message: "文件大小不能超过 20MB",
type: "error",
})
return
}
const reader = new FileReader()
reader.onload = e => {
const base64 = e.target.result
uploadImg(base64).then(res => {
const obj = {
base64,
...res,
}
if (i != undefined) {
commentList.value[index].child[i]["picture"] = obj
} else if (index != undefined) {
commentList.value[index]["picture"] = obj
} else picture.value = obj
ElMessage({
message: "上传成功",
type: "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 = {}
}
// 上传图片 获取图片url
const uploadImg = base64 => {
return new Promise((resolve, reject) => {
// detailLoading.value = true
commonUploadHttp({
data: base64,
}).then(res => {
if (res.code != 200) {
ElMessage({
message: res.message || "上传失败",
type: "error",
})
return
}
let data = res.data
resolve(data)
})
})
}
let dialogSrc = ref("") // 大图的src
// 处理点击答案图片 展开大图
const handleAnswerText = e => {
if (e.target.tagName === "IMG") {
var src = e.target.getAttribute("src")
dialogSrc.value = src
window.addEventListener("keydown", handleKeydown)
}
}
// 大图的监听 esc 键盘按钮
const handleKeydown = event => {
if (event.key !== "Escape") return
dialogSrc.value = ""
window.removeEventListener("keydown", handleKeydown) // 取消监听
}
// 点击删除
const commentDelete = (token, index, i) => {
commentDeleteHttp({
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
console.log("childnum", commentList.value[index])
} else {
commentComments.value -= commentList.value[index].childnum
commentList.value.splice(index, 1)
}
commentComments.value -= 1
})
}
defineExpose({ changeCommentVoteoption, wipeCommentVoteoption, reviewsComment, bottomNavigationBar, closeAnswerCommentsChild })
</script>