fix(DetailsArea): 修复举报功能并更新相关样式

修复举报功能,区分评论和主题举报类型。更新讨论图标和投币文本样式。移除不必要的背景色和注释代码。

refactor(api): 重构举报相关API接口
将评论举报和主题举报分离为独立接口,提高代码可维护性。

style: 清理多余空格和注释
统一代码格式,删除无用注释和空白行。
This commit is contained in:
DESKTOP-RQ919RC\Pc
2025-11-12 19:10:49 +08:00
parent ac9a2debf2
commit a584a2771b
11 changed files with 148 additions and 265 deletions

View File

@@ -447,6 +447,7 @@
margin-right: 10px; margin-right: 10px;
margin-bottom: 13px; margin-bottom: 13px;
border-radius: 5px; border-radius: 5px;
cursor: pointer;
} }
.comment-list .comment-item .comment-content .alreadyVoted { .comment-list .comment-item .comment-content .alreadyVoted {
font-size: 12px; font-size: 12px;

View File

@@ -560,6 +560,7 @@
margin-right: 10px; margin-right: 10px;
margin-bottom: 13px; margin-bottom: 13px;
border-radius: 5px; border-radius: 5px;
cursor: pointer;
} }
.alreadyVoted { .alreadyVoted {

View File

@@ -79,7 +79,6 @@
width: 100vw; width: 100vw;
height: 100vh; height: 100vh;
z-index: 12; z-index: 12;
background-color: rgba(0, 0, 0, 0.1);
} }
.content .header .operate { .content .header .operate {
position: absolute; position: absolute;

View File

@@ -89,7 +89,7 @@
width: 100vw; width: 100vw;
height: 100vh; height: 100vh;
z-index: 12; z-index: 12;
background-color: rgba(0, 0, 0, 0.1); // background-color: rgba(0, 0, 0, 0.1);
} }
.operate { .operate {

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -25,20 +25,20 @@
<img class="icon" v-else src="@/assets/img/collect-icon.png" /> <img class="icon" v-else src="@/assets/img/collect-icon.png" />
<div>{{ topicInfo["collections"] || "收藏" }}</div> <div>{{ topicInfo["collections"] || "收藏" }}</div>
</div> </div>
<div class="item flexacenter" style="cursor: auto"> <div class="item flexacenter" style="cursor: auto">
<img class="icon" src="@/assets/img/discuss-icon.png" /> <img class="icon" src="@/assets/img/discuss-black-icon.png" />
<div>{{ commentComments || "讨论" }}</div> <div>{{ commentComments || "讨论" }}</div>
</div> </div>
<div class="item flexacenter" @click="openBi()"> <div class="item flexacenter" @click="openBi()">
<img class="icon" src="@/assets/img/bi-black-icon.png" /> <img class="icon" src="@/assets/img/bi-black-icon.png" />
<div>{{ topicInfo.coins || "投币" }}</div> <div class="coinText" id="coinText">{{ topicInfo.coins || "投币" }}</div>
</div> </div>
<ClientOnly> <ClientOnly>
<el-popover placement="bottom" width="628px" trigger="click" popper-style="padding: 0;border-radius: 10px;" v-model:visible="transmitBoxState"> <el-popover placement="bottom" width="628px" trigger="click" popper-style="padding: 0;border-radius: 10px;" v-model:visible="transmitBoxState">
<template #reference> <template #reference>
<div class="item flexacenter" @click="handleShare"> <div class="item flexacenter" @click="handleShare"><img class="icon" src="@/assets/img/transmit-icon.png" />转发</div>
<img class="icon" src="@/assets/img/transmit-icon.png" />转发
</div>
</template> </template>
<div class="transmit-box flexflex"> <div class="transmit-box flexflex">
@@ -49,9 +49,7 @@
<div class="transmit-headline">{{ info["title"] }}</div> <div class="transmit-headline">{{ info["title"] }}</div>
<div class="transmit-url">{{ getFullUrl() }}</div> <div class="transmit-url">{{ getFullUrl() }}</div>
</div> </div>
<div class="transmit-web-btn flexcenter" @click="copyText(`${info['title']} + ${getFullUrl()}`)"> <div class="transmit-web-btn flexcenter" @click="copyText(`${info['title']} + ${getFullUrl()}`)">复制链接</div>
复制链接
</div>
</div> </div>
<div class="transmit-right transmit-mini"> <div class="transmit-right transmit-mini">
<div class="transmit-title">转发小程序版</div> <div class="transmit-title">转发小程序版</div>
@@ -96,7 +94,6 @@ import { ElMessage } from "element-plus";
let props = defineProps({ let props = defineProps({
ripostecount: Object, ripostecount: Object,
commentComments: Number, commentComments: Number,
}); });
let topicInfo = inject("topicInfo"); let topicInfo = inject("topicInfo");
@@ -233,7 +230,7 @@ const emit = defineEmits(["closeDiscussInputFields"]);
// // 点击底部调用关闭讨论输入框 // // 点击底部调用关闭讨论输入框
const closeDiscussInputFields = () => emit("closeDiscussInputFields"); const closeDiscussInputFields = () => emit("closeDiscussInputFields");
onMounted(() => { }); onMounted(() => {});
watch(isLoaded, (newValue, oldValue) => { watch(isLoaded, (newValue, oldValue) => {
if (newValue === true) { if (newValue === true) {
@@ -276,7 +273,7 @@ const openBi = () => {
} }
BiComponent.initComponent(); BiComponent.initComponent();
} };
</script> </script>
<style scoped lang="less"> <style scoped lang="less">

View File

@@ -6,15 +6,12 @@
<div class="text">编辑评论</div> <div class="text">编辑评论</div>
<div class="input-box"> <div class="input-box">
<div class="top flexflex"> <div class="top flexflex">
<textarea ref="editInputRef" class="input-textarea flex1" maxlength="500" v-model="editInput" <textarea ref="editInputRef" class="input-textarea flex1" maxlength="500" v-model="editInput" @focus="judgeLogin" @input="autoResize" @paste="handleInputPaste" placeholder="说说你的想法或疑问…"></textarea>
@focus="judgeLogin" @input="autoResize" @paste="handleInputPaste"
placeholder="说说你的想法或疑问…"></textarea>
</div> </div>
<div class="picture-box flexacenter" v-if="editPicture.length != 0"> <div class="picture-box flexacenter" v-if="editPicture.length != 0">
<div class="picture" v-for="item in editPicture" :key="item.url"> <div class="picture" v-for="item in editPicture" :key="item.url">
<img class="close" @click="closeEditFileUpload(item.aid)" <img class="close" @click="closeEditFileUpload(item.aid)" src="@/assets/img/close-icon.png" />
src="@/assets/img/close-icon.png" />
<img class="img" @click="handleAnswerText" :src="item.url" /> <img class="img" @click="handleAnswerText" :src="item.url" />
</div> </div>
</div> </div>
@@ -22,21 +19,18 @@
<div class="bottom flexacenter"> <div class="bottom flexacenter">
<div class="operate flexacenter"> <div class="operate flexacenter">
<div class="item" :class="{ pitch: editEmojiState }" style="z-index: 2"> <div class="item" :class="{ pitch: editEmojiState }" style="z-index: 2">
<el-popover placement="left-start" popper-class="emoji-popover" :width="584" <el-popover placement="left-start" popper-class="emoji-popover" :width="584" trigger="click" v-model:visible="editEmojiState" :teleported="false">
trigger="click" v-model:visible="editEmojiState" :teleported="false">
<template #reference> <template #reference>
<img class="icon" src="@/assets/img/smiling-face.png" alt="" /> <img class="icon" src="@/assets/img/smiling-face.png" alt="" />
</template> </template>
<div class="emoji-box"> <div class="emoji-box">
<div class="emoji-icon" v-for="item in emojiData" :key="item" <div class="emoji-icon" v-for="item in emojiData" :key="item" @click="selectEditEmoji(item)">{{ item }}</div>
@click="selectEditEmoji(item)">{{ item }}</div>
</div> </div>
</el-popover> </el-popover>
</div> </div>
<div class="item flexacenter" @click="judgeLogin()"> <div class="item flexacenter" @click="judgeLogin()">
<input class="file" type="file" @change="handleFileUpload($event)" <input class="file" type="file" @change="handleFileUpload($event)" accept=".png, .jpg, .jpeg" />
accept=".png, .jpg, .jpeg" />
<img class="icon" style="border-radius: 0" src="@/assets/img/picture-icon.png" alt="" /> <img class="icon" style="border-radius: 0" src="@/assets/img/picture-icon.png" alt="" />
<span class="file-hint">最多可上传{{ maxPicture }}张图片支持在输入框中直接粘贴图片</span> <span class="file-hint">最多可上传{{ maxPicture }}张图片支持在输入框中直接粘贴图片</span>
</div> </div>
@@ -55,39 +49,27 @@
<span class="comment-amount">{{ commentComments || 0 }}</span> <span class="comment-amount">{{ commentComments || 0 }}</span>
</div> </div>
<!-- <div class="post-comment" ref="postInputRef" :class="{ 'post-comment-focus': postCommentFocusState }" @click="loginJudgment()">
<div class="post-comment-input">
<el-input class="post-input flex1" type="textarea" :autosize="postCommentFocusState" :maxlength="500" show-word-limit placeholder="说说你的想法或疑问…" v-model="commentInputTop" @blur="postCommentFocusBlur" @focus="postCommentFocusState = true"></el-input>
</div>
<div class="post-ok flexcenter" @click="submitAnswerComments(commentInputTop)">发送</div>
</div> -->
<div class="input-box"> <div class="input-box">
<div class="top flexflex"> <div class="top flexflex">
<img class="avatar" v-if="userInfoWin.avatar" :src="userInfoWin.avatar" /> <img class="avatar" v-if="userInfoWin.avatar" :src="userInfoWin.avatar" />
<textarea class="input-textarea flex1" maxlength="500" v-model="commentInputTop" @focus="judgeLogin" <textarea class="input-textarea flex1" maxlength="500" v-model="commentInputTop" @focus="judgeLogin" @input="autoResize" @paste="handleInputPaste" placeholder="说说你的想法或疑问…"></textarea>
@input="autoResize" @paste="handleInputPaste" placeholder="说说你的想法或疑问…"></textarea>
</div> </div>
<div class="picture-box flexacenter" v-if="picture.length != 0" style="width: 470px;"> <div class="picture-box flexacenter" v-if="picture.length != 0" style="width: 470px">
<div class="picture" v-for="(item, index) in picture" :key="index"> <div class="picture" v-for="(item, index) in picture" :key="index">
<img class="close" @click="closePictureUpload(index)" src="@/assets/img/close-icon.png" /> <img class="close" @click="closeFileUpload(item.aid)" src="@/assets/img/close-icon.png" />
<img class="img" @click="handleAnswerText" :src="item.url" /> <img class="img" @click="handleAnswerText" :src="item.url" />
</div> </div>
</div> </div>
<div class="bottom flexacenter"> <div class="bottom flexacenter">
<div class="operate flexacenter"> <div class="operate flexacenter">
<div class="item" :class="{ pitch: emojiState }"> <div class="item" :class="{ pitch: emojiState }">
<el-popover placement="left" popper-class="emoji-popover" :width="625" trigger="click" <el-popover placement="left" popper-class="emoji-popover" :width="625" trigger="click" v-model:visible="emojiState" :teleported="false">
v-model:visible="emojiState" :teleported="false">
<template #reference> <template #reference>
<img class="icon" src="@/assets/img/smiling-face.png" alt="" /> <img class="icon" src="@/assets/img/smiling-face.png" alt="" />
</template> </template>
<div class="emoji-box"> <div class="emoji-box">
<div class="emoji-icon" v-for="item in emojiData" :key="item" <div class="emoji-icon" v-for="item in emojiData" :key="item" @click="selectEmoji(item)">{{ item }}</div>
@click="selectEmoji(item)">{{ item
}}</div>
</div> </div>
</el-popover> </el-popover>
</div> </div>
@@ -107,21 +89,17 @@
<template v-else> <template v-else>
<div class="comment-list"> <div class="comment-list">
<div class="comment-item flexflex" v-for="(item, index) in commentList" :key="item.id"> <div class="comment-item flexflex" v-for="(item, index) in commentList" :key="item.id">
<el-popover placement="bottom-start" :width="140" trigger="click" popper-class="avatar-box-popper" <el-popover placement="bottom-start" :width="140" trigger="click" popper-class="avatar-box-popper" :show-arrow="false" v-model:visible="item['popoverState']">
:show-arrow="false" v-model:visible="item['popoverState']">
<template #reference> <template #reference>
<img class="comment-avatar" :src="item.avatar || item.user['avatar']" /> <img class="comment-avatar" :src="item.avatar || item.user['avatar']" />
</template> </template>
<div class="avatar-box flexflex" <div class="avatar-box flexflex" v-if="item.uin || item.user['uin'] || item.uid || item.user['uid']">
v-if="item.uin || item.user['uin'] || item.uid || item.user['uid']"> <a class="avatar-item flexcenter" target="_blank" @click.prevent="sendMessage(item.uin || item.user['uin'], item.uid || item.user['uid'])">
<a class="avatar-item flexcenter" target="_blank"
@click.prevent="sendMessage(item.uin || item.user['uin'], item.uid || item.user['uid'])">
<img class="avatar-icon" src="@/assets/img/send-messages-icon.png" /> <img class="avatar-icon" src="@/assets/img/send-messages-icon.png" />
发送信息 发送信息
</a> </a>
<a class="avatar-item flexcenter" target="_blank" <a class="avatar-item flexcenter" target="_blank" @click.prevent="TAHomePage(item.uin || item.user['uin'], item.uid || item.user['uid'])">
@click.prevent="TAHomePage(item.uin || item.user['uin'], item.uid || item.user['uid'])">
<img class="avatar-icon" src="@/assets/img/homepage-icon.png" /> <img class="avatar-icon" src="@/assets/img/homepage-icon.png" />
TA的主页 TA的主页
</a> </a>
@@ -130,82 +108,59 @@
<div class="comment-content flex1"> <div class="comment-content flex1">
<div class="comment-header flexacenter"> <div class="comment-header flexacenter">
<div class="comment-header-left flexacenter"> <div class="comment-header-left flexacenter">
<div class="comments-username" @click="openAvatarPopover(index)">{{ item.nickname || <div class="comments-username" @click="openAvatarPopover(index)">{{ item.nickname || item.user["nickname"] || "匿名用户" }}</div>
item.user["nickname"]
|| "匿名用户" }}</div>
<div class="comments-time">{{ item["timestamp"] }}</div> <div class="comments-time">{{ item["timestamp"] }}</div>
<div class="comments-identity" v-if="item['isauthor'] == 1">作者</div> <div class="comments-identity" v-if="item['isauthor'] == 1">作者</div>
<img class="comments-title" v-if="item.groupimage || item?.user?.groupimage" <img class="comments-title" v-if="item.groupimage || item?.user?.groupimage" :src="item.groupimage || item?.user?.groupimage" :alt="item?.user?.grouptitle" style="height: 18px" />
:src="item.groupimage || item?.user?.groupimage" :alt="item?.user?.grouptitle"
style="height: 18px" />
</div> </div>
<div class="comment-header-right flexacenter"> <div class="comment-header-right flexacenter">
<div class="menu-box flexacenter"> <div class="menu-box flexacenter">
<img class="menu-icon" src="@/assets/img/menu-icon-gray.svg" /> <img class="menu-icon" src="@/assets/img/menu-icon-gray.svg" />
<div class="operate-box"> <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" v-if="permissions.includes('comment.edit')" <div class="item flexcenter" v-if="permissions.includes('comment.edit')" @click="openEdit(item['token'], index)">编辑</div>
@click="openEdit(item['token'], index)">编辑</div> <div class="item flexcenter" v-if="permissions.includes('comment.delete')" @click="commentDelete(item['token'], index)">删除</div>
<div class="item flexcenter" v-if="permissions.includes('comment.delete')"
@click="commentDelete(item['token'], index)">删除</div>
</div> </div>
</div> </div>
<img class="comment-icon" title="回复" <img class="comment-icon" title="回复" @click="!item['childState'] ? openAnswerCommentsChild(index) : closeAnswerCommentsChild()" src="@/assets/img/comment-icon-gray.svg" />
@click="!item['childState'] ? openAnswerCommentsChild(index) : closeAnswerCommentsChild()"
src="@/assets/img/comment-icon-gray.svg" />
<div class="flexacenter like-box" @click="commentLike(index)"> <div class="flexacenter like-box" @click="commentLike(index)">
<img class="like-icon" v-if="item['islike'] == 1" <img class="like-icon" v-if="item['islike'] == 1" src="@/assets/img/like-red-pitch.png" />
src="@/assets/img/like-red-pitch.png" />
<img class="like-icon" v-else src="@/assets/img/like-icon-gray.png" /> <img class="like-icon" v-else src="@/assets/img/like-icon-gray.png" />
<div class="like-quantity">{{ item["likenum"] || 0 }}</div> <div class="like-quantity">{{ item["likenum"] || 0 }}</div>
</div> </div>
</div> </div>
</div> </div>
<div class="comment-text" v-if="item['content']" <div class="comment-text" v-if="item['content']" @click="!item['childState'] ? openAnswerCommentsChild(index) : closeAnswerCommentsChild()">{{ item["content"] }}</div>
@click="!item['childState'] ? openAnswerCommentsChild(index) : closeAnswerCommentsChild()"> <div class="comments-img-box flexacenter" v-if="item.attachments.images?.length != 0" style="overflow: auto; width: 440px">
{{ item["content"] }} <img class="comments-img" v-for="(item, index) in item.attachments.images" :key="index" @click="handleAnswerText" :src="item.thumb || item.url" />
</div>
<!-- <img class="comments-img" @click="handleAnswerText" :src="item.image?.base64 || item.image?.url" v-if="item.image?.url" /> -->
<div class="comments-img-box flexacenter" v-if="item.attachments.images?.length != 0"
style="overflow: auto;width: 440px;">
<img class="comments-img" v-for="(item, index) in item.attachments.images" :key="index"
@click="handleAnswerText" :src="item.thumb || item.url" />
</div> </div>
<div class="alreadyVoted" v-if="item.voteoption">已投{{ item.voteoption }}</div> <div class="alreadyVoted" v-if="item.voteoption">已投{{ item.voteoption }}</div>
<div class="input-box" v-if="item['childState']"> <div class="input-box" v-if="item['childState']">
<img class="cross" @click="closeAnswerCommentsChild()" src="@/assets/img/cross-icon.png" /> <img class="cross" @click="closeAnswerCommentsChild()" src="@/assets/img/cross-icon.png" />
<div class="top flexflex"> <div class="top flexflex">
<textarea class="input-textarea flex1" maxlength="500" placeholder="说说你的想法或疑问…" <textarea class="input-textarea flex1" maxlength="500" placeholder="说说你的想法或疑问…" v-model="item['commentInput']" @input="autoResize" @paste="handleInputPaste($event, index)"></textarea>
v-model="item['commentInput']" @input="autoResize"
@paste="handleInputPaste($event, index)"></textarea>
</div> </div>
<div class="picture-box flexacenter" v-if="item?.picture?.length != 0" style="width: 440px">
<div class="picture-box flexacenter" v-if="item?.picture?.length != 0"
style="width: 440px;">
<div class="picture" v-for="it in item.picture" :key="it.url"> <div class="picture" v-for="it in item.picture" :key="it.url">
<img class="close" @click="closeFileUpload(it.aid, index)" <img class="close" @click="closeFileUpload(it.aid, index)" src="@/assets/img/close-icon.png" />
src="@/assets/img/close-icon.png" />
<img class="img" @click="handleAnswerText" :src="it.url" /> <img class="img" @click="handleAnswerText" :src="it.url" />
</div> </div>
</div> </div>
<div class="bottom flexacenter"> <div class="bottom flexacenter">
<div class="operate flexacenter"> <div class="operate flexacenter">
<div class="item" :class="{ pitch: item.emojiState }"> <div class="item" :class="{ pitch: item.emojiState }">
<el-popover placement="left" popper-class="emoji-popover" :width="625" <el-popover placement="left" popper-class="emoji-popover" :width="625" trigger="click" v-model:visible="item.emojiState" :teleported="false">
trigger="click" v-model:visible="item.emojiState" :teleported="false">
<template #reference> <template #reference>
<img class="icon" src="@/assets/img/smiling-face.png" alt="" /> <img class="icon" src="@/assets/img/smiling-face.png" alt="" />
</template> </template>
<div class="emoji-box"> <div class="emoji-box">
<div class="emoji-icon" v-for="item in emojiData" :key="item" <div class="emoji-icon" v-for="item in emojiData" :key="item" @click="selectEmoji(item, index)">{{ item }}</div>
@click="selectEmoji(item, index)">{{ item }}</div>
</div> </div>
</el-popover> </el-popover>
</div> </div>
<div class="item flexacenter"> <div class="item flexacenter">
<input class="file" type="file" @change="handleFileUpload($event, index)" <input class="file" type="file" @change="handleFileUpload($event, index)" accept=".png, .jpg, .jpeg" />
accept=".png, .jpg, .jpeg" />
<img class="icon" src="@/assets/img/picture-icon.png" alt="" /> <img class="icon" src="@/assets/img/picture-icon.png" alt="" />
<span class="file-hint">最多可上传{{ maxPicture }}张图片支持在输入框中直接粘贴图片</span> <span class="file-hint">最多可上传{{ maxPicture }}张图片支持在输入框中直接粘贴图片</span>
</div> </div>
@@ -217,22 +172,17 @@
<!-- 子评论 --> <!-- 子评论 -->
<div class="child-comments" v-if="item['child'].length > 0"> <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"> <div class="comment-item flexflex" v-for="(ite, i) in item['child']" :key="ite.id">
<el-popover placement="bottom-start" :width="140" trigger="click" <el-popover placement="bottom-start" :width="140" trigger="click" popper-class="avatar-box-popper" :show-arrow="false" v-model:visible="ite['popoverState']">
popper-class="avatar-box-popper" :show-arrow="false"
v-model:visible="ite['popoverState']">
<template #reference> <template #reference>
<img class="comment-avatar" :src="ite.avatar || ite.user['avatar']" /> <img class="comment-avatar" :src="ite.avatar || ite.user['avatar']" />
</template> </template>
<div class="avatar-box flexflex" <div class="avatar-box flexflex" v-if="ite.uin || ite.user['uin'] || ite.uid || ite.user['uid']">
v-if="ite.uin || ite.user['uin'] || ite.uid || ite.user['uid']"> <a class="avatar-item flexcenter" target="_blank" @click.prevent="sendMessage(ite.uin || ite.user['uin'], ite.uid || ite.user['uid'])">
<a class="avatar-item flexcenter" target="_blank"
@click.prevent="sendMessage(ite.uin || ite.user['uin'], ite.uid || ite.user['uid'])">
<img class="avatar-icon" src="@/assets/img/send-messages-icon.png" /> <img class="avatar-icon" src="@/assets/img/send-messages-icon.png" />
发送信息 发送信息
</a> </a>
<a class="avatar-item flexcenter" target="_blank" <a class="avatar-item flexcenter" target="_blank" @click.prevent="TAHomePage(ite.uin || ite.user['uin'], ite.uid || ite.user['uid'])">
@click.prevent="TAHomePage(ite.uin || ite.user['uin'], ite.uid || ite.user['uid'])">
<img class="avatar-icon" src="@/assets/img/homepage-icon.png" /> <img class="avatar-icon" src="@/assets/img/homepage-icon.png" />
TA的主页 TA的主页
</a> </a>
@@ -241,67 +191,45 @@
<div class="comment-content flex1"> <div class="comment-content flex1">
<div class="comment-header flexacenter"> <div class="comment-header flexacenter">
<div class="comment-header-left flexacenter"> <div class="comment-header-left flexacenter">
<div class="comments-username" @click="openAvatarPopover(index, i)">{{ <div class="comments-username" @click="openAvatarPopover(index, i)">{{ ite.nickname || ite.user["nickname"] || "匿名用户" }}</div>
ite.nickname ||
ite.user["nickname"] || "匿名用户" }}</div>
<div class="comments-time">{{ ite["timestamp"] }}</div> <div class="comments-time">{{ ite["timestamp"] }}</div>
<div class="comments-identity" v-if="ite['isauthor']">作者</div> <div class="comments-identity" v-if="ite['isauthor']">作者</div>
<img class="comments-title" v-if="ite.groupimage || ite.user?.groupimage" <img class="comments-title" v-if="ite.groupimage || ite.user?.groupimage" :src="ite.groupimage || ite.user?.groupimage" :alt="ite?.user?.grouptitle" style="height: 18px" />
:src="ite.groupimage || ite.user?.groupimage"
:alt="ite?.user?.grouptitle" style="height: 18px" />
</div> </div>
<div class="comment-header-right flexacenter"> <div class="comment-header-right flexacenter">
<div class="menu-box flexacenter"> <div class="menu-box flexacenter">
<img class="menu-icon" src="@/assets/img/menu-icon-gray.svg" /> <img class="menu-icon" src="@/assets/img/menu-icon-gray.svg" />
<div class="operate-box"> <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" <div class="item flexcenter" v-if="permissions.includes('comment.edit')" @click="openEdit(ite['token'], index, i)">编辑</div>
v-if="permissions.includes('comment.edit')" <div class="item flexcenter" v-if="permissions.includes('comment.delete')" @click="commentDelete(ite['token'], index, i)">删除</div>
@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> </div>
<img class="comment-icon" title="回复" <img class="comment-icon" title="回复" @click="!ite['childState'] ? openAnswerCommentsChild(index, i) : closeAnswerCommentsChild()" src="@/assets/img/comment-icon-gray.svg" />
@click="!ite['childState'] ? openAnswerCommentsChild(index, i) : closeAnswerCommentsChild()"
src="@/assets/img/comment-icon-gray.svg" />
<div class="flexacenter like-box" @click="commentLike(index, i)"> <div class="flexacenter like-box" @click="commentLike(index, i)">
<img class="like-icon" v-if="ite['islike'] == 1" <img class="like-icon" v-if="ite['islike'] == 1" src="@/assets/img/like-red-pitch.png" />
src="@/assets/img/like-red-pitch.png" />
<img class="like-icon" v-else src="@/assets/img/like-icon-gray.png" /> <img class="like-icon" v-else src="@/assets/img/like-icon-gray.png" />
<div class="like-quantity">{{ ite["likenum"] || 0 }}</div> <div class="like-quantity">{{ ite["likenum"] || 0 }}</div>
</div> </div>
</div> </div>
</div> </div>
<div class="comment-text" v-if="ite['content']" <div class="comment-text" v-if="ite['content']" @click="!ite['childState'] ? openAnswerCommentsChild(index, i) : closeAnswerCommentsChild()">
@click="!ite['childState'] ? openAnswerCommentsChild(index, i) : closeAnswerCommentsChild()"> <div class="comments-reply" v-if="ite?.reply?.nickname">@{{ ite?.reply?.nickname }}</div>
<div class="comments-reply" v-if="ite?.reply?.nickname">@{{ ite?.reply?.nickname
}}</div>
{{ ite["content"] }} {{ ite["content"] }}
</div> </div>
<!-- <img class="comments-img" @click="handleAnswerText" :src="ite.image?.base64 || ite.image?.url" v-if="ite.image?.url" /> --> <div class="comments-img-box flexacenter" v-if="ite.attachments.images?.length != 0" style="overflow: auto; width: 410px">
<div class="comments-img-box flexacenter" v-if="ite.attachments.images?.length != 0" <img class="comments-img" v-for="(item, index) in ite.attachments.images" :key="index" @click="handleAnswerText" :src="item.thumb || item.url" />
style="overflow: auto;width: 410px;">
<img class="comments-img" v-for="(item, index) in ite.attachments.images"
:key="index" @click="handleAnswerText" :src="item.thumb || item.url" />
</div> </div>
<div class="alreadyVoted" v-if="ite.voteoption">已投{{ ite.voteoption }}</div> <div class="alreadyVoted" v-if="ite.voteoption">已投{{ ite.voteoption }}</div>
<div class="input-box" v-if="ite['childState']"> <div class="input-box" v-if="ite['childState']">
<img class="cross" @click="closeAnswerCommentsChild()" <img class="cross" @click="closeAnswerCommentsChild()" src="@/assets/img/cross-icon.png" />
src="@/assets/img/cross-icon.png" />
<div class="top flexflex"> <div class="top flexflex">
<textarea class="input-textarea flex1" maxlength="500" <textarea class="input-textarea flex1" maxlength="500" :placeholder="'回复“' + (ite['nickname'] || ite.user['nickname'] || '匿名用户') + '”:'" v-model="ite['commentInput']" @input="autoResize" @paste="handleInputPaste($event, index)"></textarea>
:placeholder="'回复“' + (ite['nickname'] || ite.user['nickname'] || '匿名用户') + '”:'"
v-model="ite['commentInput']" @input="autoResize"
@paste="handleInputPaste($event, index)"></textarea>
</div> </div>
<div class="picture-box flexacenter" v-if="ite.picture?.length != 0" <div class="picture-box flexacenter" v-if="ite.picture?.length != 0" style="width: 408px">
style="width: 408px;">
<div class="picture" v-for="it in ite.picture" :key="it.url"> <div class="picture" v-for="it in ite.picture" :key="it.url">
<img class="close" @click="closeFileUpload(it.aid, index, i)" <img class="close" @click="closeFileUpload(it.aid, index, i)" src="@/assets/img/close-icon.png" />
src="@/assets/img/close-icon.png" />
<img class="img" @click="handleAnswerText" :src="it.url" /> <img class="img" @click="handleAnswerText" :src="it.url" />
</div> </div>
</div> </div>
@@ -309,50 +237,30 @@
<div class="bottom flexacenter"> <div class="bottom flexacenter">
<div class="operate flexacenter"> <div class="operate flexacenter">
<div class="item" :class="{ pitch: ite.emojiState }"> <div class="item" :class="{ pitch: ite.emojiState }">
<el-popover placement="left" popper-class="emoji-popover" <el-popover placement="left" popper-class="emoji-popover" :width="625" trigger="click" v-model:visible="ite.emojiState" :teleported="false">
:width="625" trigger="click" v-model:visible="ite.emojiState"
:teleported="false">
<template #reference> <template #reference>
<img class="icon" src="@/assets/img/smiling-face.png" <img class="icon" src="@/assets/img/smiling-face.png" alt="" />
alt="" />
</template> </template>
<div class="emoji-box"> <div class="emoji-box">
<div class="emoji-icon" v-for="item in emojiData" <div class="emoji-icon" v-for="item in emojiData" :key="item" @click="selectEmoji(item, index, i)">{{ item }}</div>
:key="item" @click="selectEmoji(item, index, i)">{{ item
}}</div>
</div> </div>
</el-popover> </el-popover>
</div> </div>
<div class="item flexacenter"> <div class="item flexacenter">
<input class="file" type="file" <input class="file" type="file" @change="handleFileUpload($event, index, i)" accept=".png, .jpg, .jpeg" />
@change="handleFileUpload($event, index, i)"
accept=".png, .jpg, .jpeg" />
<img class="icon" src="@/assets/img/picture-icon.png" alt="" /> <img class="icon" src="@/assets/img/picture-icon.png" alt="" />
<span class="file-hint">最多可上传{{ maxPicture <span class="file-hint">最多可上传{{ maxPicture }}张图片支持在输入框中直接粘贴图片</span>
}}张图片支持在输入框中直接粘贴图片</span>
</div> </div>
</div> </div>
<div class="btn" <div class="btn" @click="submitAnswerComments(ite['commentInput'], index, i)">发送</div>
@click="submitAnswerComments(ite['commentInput'], index, i)">发送</div>
</div> </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>
<div class="operate-bottom flexacenter">
<div class="comments-btn comments-btn-cancel flexcenter" @click="closeAnswerCommentsChild()">取消</div>
<div class="comments-btn flexcenter" @click="submitAnswerComments(commentInput, index, i)">发送</div>
</div>
</div>
</div> -->
</div> </div>
</div> </div>
</div> </div>
<!-- 还有几个 --> <!-- 还有几个 -->
<div class="comments-also flexacenter" v-if="item['childnum'] > item['child'].length" <div class="comments-also flexacenter" v-if="item['childnum'] > item['child'].length" @click="alsoCommentsData(index)">
@click="alsoCommentsData(index)">
<div class="">还有{{ item["childnum"] - item["child"].length }}条回复</div> <div class="">还有{{ item["childnum"] - item["child"].length }}条回复</div>
<img class="also-icon" src="@/assets/img/arrow-circular-gray.png" /> <img class="also-icon" src="@/assets/img/arrow-circular-gray.png" />
</div> </div>
@@ -363,17 +271,15 @@
</template> </template>
</div> </div>
<Report v-if="reportAlertShow" :reportToken="reportToken"></Report> <Report v-if="reportAlertShow" :reportToken="reportToken" :reportType="reportType"></Report>
<!-- 投票后自动评论 --> <!-- 投票后自动评论 -->
<el-dialog class="default-popup automatic-reviews-popup" v-model="reviewsPopoverState" width="720px" align-center <el-dialog class="default-popup automatic-reviews-popup" v-model="reviewsPopoverState" width="720px" align-center autosize :close-on-click-modal="false">
autosize :close-on-click-modal="false">
<div class="automatic-header"> <div class="automatic-header">
<div class="automatic-title">说说您的投票理由</div> <div class="automatic-title">说说您的投票理由</div>
<div class="automatic-have">已投{{ haveVotedValue }}</div> <div class="automatic-have">已投{{ haveVotedValue }}</div>
</div> </div>
<el-input class="automatic-input" placeholder="请输入…" v-model="reviewsPopoverInput" type="textarea" <el-input class="automatic-input" placeholder="请输入…" v-model="reviewsPopoverInput" type="textarea" maxlength="500" show-word-limit></el-input>
maxlength="500" show-word-limit></el-input>
<div class="automatic-bottom flexflex"> <div class="automatic-bottom flexflex">
<div class="automatic-send flexcenter" @click="submitAnswerComments(reviewsPopoverInput)">发送</div> <div class="automatic-send flexcenter" @click="submitAnswerComments(reviewsPopoverInput)">发送</div>
</div> </div>
@@ -418,7 +324,7 @@ watch(
); );
onMounted(() => { onMounted(() => {
window.addEventListener("scroll", handleScroll) window.addEventListener("scroll", handleScroll);
checkWConfig(); checkWConfig();
}); });
@@ -432,21 +338,18 @@ const checkWConfig = () => {
const config = wConfig.config || {}; const config = wConfig.config || {};
maxPicture.value = config.topic_image_count; maxPicture.value = config.topic_image_count;
} }
} else { } else getWConfig();
getWConfig();
}
}; };
const getWConfig = () => { const getWConfig = () => {
getWConfigHttp().then((res) => { getWConfigHttp().then((res) => {
if (res.code != 200) return if (res.code != 200) return;
let data = res["data"] || {}; let data = res["data"] || {};
const config = data.config || {}; const config = data.config || {};
maxPicture.value = config.topic_image_count; maxPicture.value = config.topic_image_count;
data.time = new Date().toISOString(); data.time = new Date().toISOString();
localStorage.setItem("wConfig", JSON.stringify(data)); localStorage.setItem("wConfig", JSON.stringify(data));
}); });
}; };
@@ -482,7 +385,6 @@ const getCommentList = () => {
let data = res.data; let data = res.data;
data.data.forEach((element, index) => { data.data.forEach((element, index) => {
element.timestamp = strtimeago(element.created_at, 4); element.timestamp = strtimeago(element.created_at, 4);
element["picture"] = []; element["picture"] = [];
@@ -491,7 +393,7 @@ const getCommentList = () => {
if (element.child.length > 0) { if (element.child.length > 0) {
element.child.forEach((el) => { element.child.forEach((el) => {
el["picture"] = []; el["picture"] = [];
el.timestamp = strtimeago(element.created_at, 4); el.timestamp = strtimeago(el.created_at, 4);
el["isReplyBoxShow"] = 0; el["isReplyBoxShow"] = 0;
}); });
} }
@@ -505,7 +407,6 @@ const getCommentList = () => {
commentComments.value = data["commentcount"]; commentComments.value = data["commentcount"];
emit("update:commentComments", data["commentcount"]); emit("update:commentComments", data["commentcount"]);
if (commentList.value.length == data["count"]) commentPage.value = 0; if (commentList.value.length == data["count"]) commentPage.value = 0;
@@ -600,7 +501,6 @@ const realname = inject("realname");
// 提交回答-评论 // 提交回答-评论
const submitAnswerComments = (content = "", index, i) => { const submitAnswerComments = (content = "", index, i) => {
if (realname.value == 0 && userInfoWin.value.uin > 0) { if (realname.value == 0 && userInfoWin.value.uin > 0) {
openAttest(); openAttest();
return; return;
@@ -612,31 +512,22 @@ const submitAnswerComments = (content = "", index, i) => {
} }
const targetCommentList = [...commentList.value]; const targetCommentList = [...commentList.value];
// let content = ""
let parentid = null; let parentid = null;
// if (index == null) content = commentInputTop.value let image = [];
// else content = commentInput.value
let image = {};
if (i != null) { if (i != null) {
parentid = targetCommentList[index]["child"][i]["id"]; parentid = targetCommentList[index]["child"][i]["id"];
image = commentList.value[index]["child"][i]["picture"] || {}; image = commentList.value[index]["child"][i]["picture"] || [];
} else if (index != null) { } else if (index != null) {
parentid = targetCommentList[index]["id"]; parentid = targetCommentList[index]["id"];
image = commentList.value[index]["picture"] || {}; image = commentList.value[index]["picture"] || [];
} else image = picture.value; } else image = picture.value;
// if (!content) {
// ElMessage.error("请填写评论内容")
// return
// }
const attachments = { const attachments = {
images: image, images: image,
}; };
detailsSubmitommentListHttp({ detailsSubmitommentListHttp({
content, content,
token: props.token, token: props.token,
@@ -650,9 +541,10 @@ const submitAnswerComments = (content = "", index, i) => {
let data = res.data; let data = res.data;
const timestamp = strtimeago(new Date()); const timestamp = strtimeago(new Date());
if (i != null) { if (i != null) {
targetCommentList[index]["child"][i]["commentInput"] = ""; targetCommentList[index]["child"][i]["commentInput"] = "";
targetCommentList[index]["child"][i]["picture"] = {}; targetCommentList[index]["child"][i]["picture"] = [];
let targetData = { let targetData = {
id: data["commentid"], id: data["commentid"],
@@ -668,10 +560,8 @@ const submitAnswerComments = (content = "", index, i) => {
attachments, attachments,
picture: [], picture: [],
timestamp, timestamp,
uin: userInfoWin.value.uin, uin: userInfoWin.value.uin,
uid: userInfoWin.value.uid, uid: userInfoWin.value.uid,
}; };
targetCommentList[index]["child"].unshift(targetData); targetCommentList[index]["child"].unshift(targetData);
@@ -704,8 +594,6 @@ const submitAnswerComments = (content = "", index, i) => {
} }
} }
commentComments.value = data.count || 0; commentComments.value = data.count || 0;
emit("update:commentComments", data.count || 0); emit("update:commentComments", data.count || 0);
@@ -755,7 +643,7 @@ const alsoCommentsData = (index, ind) => {
element.timestamp = strtimeago(element.created_at, 4); element.timestamp = strtimeago(element.created_at, 4);
element["isReplyBoxShow"] = 0; element["isReplyBoxShow"] = 0;
element["picture"] = []; element["picture"] = [];
}) });
let merged = [...commentList.value[index]["child"], ...data.data.filter((item2) => !commentList.value[index]["child"].find((item1) => item1.id == item2.id))]; let merged = [...commentList.value[index]["child"], ...data.data.filter((item2) => !commentList.value[index]["child"].find((item1) => item1.id == item2.id))];
@@ -765,6 +653,7 @@ const alsoCommentsData = (index, ind) => {
let reportAlertShow = ref(false); let reportAlertShow = ref(false);
let reportToken = ref(""); let reportToken = ref("");
let reportType = ref("");
// 点击打开举报 // 点击打开举报
const report = (token) => { const report = (token) => {
@@ -774,6 +663,7 @@ const report = (token) => {
} }
reportToken.value = token; reportToken.value = token;
reportType.value = "comment";
reportAlertShow.value = true; reportAlertShow.value = true;
}; };
@@ -976,7 +866,6 @@ const handleInputPaste = (event, index, ii) => {
}; };
const maxPicture = ref(10); const maxPicture = ref(10);
const handleFileUpload = (event, index, i) => { const handleFileUpload = (event, index, i) => {
closeEmoji(); closeEmoji();
const file = event.target.files[0]; // 获取选择的文件 const file = event.target.files[0]; // 获取选择的文件
@@ -991,8 +880,6 @@ const handleFileUpload = (event, index, i) => {
return; return;
} }
let target = []; let target = [];
if (editCommentState.value) target = editPicture.value; if (editCommentState.value) target = editPicture.value;
else { else {
@@ -1001,8 +888,6 @@ const handleFileUpload = (event, index, i) => {
else target = picture.value; else target = picture.value;
} }
console.log(target.length, maxPicture.value);
if (target.length >= maxPicture.value) { if (target.length >= maxPicture.value) {
creationAlertBox("error", `最多只能上传 ${maxPicture.value} 张图片`); creationAlertBox("error", `最多只能上传 ${maxPicture.value} 张图片`);
return; return;
@@ -1045,8 +930,6 @@ const closeFileUpload = (aid, index, i) => {
else picture.value = target; else picture.value = target;
}; };
const closePictureUpload = (index) => picture.value.splice(index, 1);
// 上传图片 获取图片url // 上传图片 获取图片url
const uploadImg = (file) => { const uploadImg = (file) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
@@ -1122,7 +1005,6 @@ const confirmCommentDelete = () => {
return; return;
} }
if (commemtDelete.i >= 0) { if (commemtDelete.i >= 0) {
commentList.value[commemtDelete.index].child.splice(commemtDelete.i, 1); commentList.value[commemtDelete.index].child.splice(commemtDelete.i, 1);
commentList.value[commemtDelete.index].childnum -= 1; commentList.value[commemtDelete.index].childnum -= 1;
@@ -1168,7 +1050,7 @@ const openEdit = (token, index, i) => {
}; };
const closeEdit = () => { const closeEdit = () => {
editPicture.value = [] editPicture.value = [];
editToken = ""; editToken = "";
editInput.value = ""; editInput.value = "";
editCommentState.value = false; editCommentState.value = false;
@@ -1222,7 +1104,7 @@ const postEditComment = () => {
}); });
}); });
editPicture.value = [] editPicture.value = [];
editToken = ""; editToken = "";
editCommentState.value = false; editCommentState.value = false;
editEmojiState.value = false; editEmojiState.value = false;
@@ -1230,7 +1112,12 @@ const postEditComment = () => {
}); });
}; };
const closeEditFileUpload = () => (editPicture.value = []); const closeEditFileUpload = (aid) => {
let target = editPicture.value;
let sub = target.findIndex((item) => item.aid == aid);
if (sub != -1) target.splice(sub, 1);
editPicture.value = target;
};
defineExpose({ changeCommentVoteoption, wipeCommentVoteoption, reviewsComment, bottomNavigationBar, closeAnswerCommentsChild }); defineExpose({ changeCommentVoteoption, wipeCommentVoteoption, reviewsComment, bottomNavigationBar, closeAnswerCommentsChild });
</script> </script>

View File

@@ -3,7 +3,7 @@
<div class="alert-form"> <div class="alert-form">
<div class="comments reports"> <div class="comments reports">
<div class="head"> <div class="head">
<span style="display: flex; align-items: center;"> <img style="width: 25px; margin-right: 7px;" src="//app.gter.net/image/gter/offer/img/exclamationpoint.png" />举报投诉 </span> <span style="display: flex; align-items: center"> <img style="width: 25px; margin-right: 7px" src="//app.gter.net/image/gter/offer/img/exclamationpoint.png" />举报投诉 </span>
<div class="close icon-close iconfont" @click="alertShow = false"></div> <div class="close icon-close iconfont" @click="alertShow = false"></div>
</div> </div>
<div class="form"> <div class="form">
@@ -26,42 +26,42 @@
</div> </div>
</template> </template>
<script setup> <script setup>
import { ElMessage } from "element-plus" import { ElMessage } from "element-plus";
const props = defineProps(["reportToken", "reportType"]);
const reasonList = ["广告", "辱骂", "重复发送", "不良信息", "其他"];
let reportAlertShow = inject("reportAlertShow");
const props = defineProps(["reportToken"]) let checkList = ref([]);
const reasonList = ["广告", "辱骂", "重复发送", "不良信息", "其他"] let alertShow = ref(false);
let reportAlertShow = inject("reportAlertShow") let alertText = ref("");
let checkList = ref([]) const selectRadio = (value) => {
let alertShow = ref(false) const index = checkList.value.indexOf(value);
let alertText = ref("") if (index === -1) checkList.value.push(value);
else checkList.value.splice(index, 1);
const selectRadio = value => { };
const index = checkList.value.indexOf(value)
if (index === -1) checkList.value.push(value)
else checkList.value.splice(index, 1)
}
// 举报提交 // 举报提交
const alertSubmit = () => { const alertSubmit = () => {
if (checkList.value.length == 0) { if (checkList.value.length == 0) {
ElMessage.error("请选择举报类型") ElMessage.error("请选择举报类型");
return return;
} }
checkList.value.push(alertText.value) checkList.value.push(alertText.value);
reportAlertShow.value = false reportAlertShow.value = false;
commentReportHttp({
(props.reportType === "comment" ? commentReportHttp : reportHttp)({
message: checkList.value, message: checkList.value,
token: props.reportToken, token: props.reportToken,
}).then(res => { }).then((res) => {
checkList.value = [] checkList.value = [];
reportAlertShow.value = false reportAlertShow.value = false;
ElMessage.success(res.message || "举报成功") ElMessage.success(res.message || "举报成功");
}) });
} };
// 取消 // 取消
const cancel = () => (reportAlertShow.value = false) const cancel = () => (reportAlertShow.value = false);
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>

View File

@@ -35,7 +35,6 @@ export const detailsSubmitommentListHttp = (query) => {
// 详情数据 - 提交评论 // 详情数据 - 提交评论
export const commentsEditSubmit = (query) => { export const commentsEditSubmit = (query) => {
// return Http.post("/api/comment/commentsEditSubmit", query);
return Http.postV2("https://api.gter.net/v2/api/forum/postCommentEdit", query); return Http.postV2("https://api.gter.net/v2/api/forum/postCommentEdit", query);
}; };
@@ -106,12 +105,14 @@ export const MyUserCollectHttp = (query) => {
return Http.post("/api/user/collect", query); return Http.post("/api/user/collect", query);
}; };
// 评论相关 - 举报 Comment related export const reportHttp = (query) => {
export const commentReportHttp = (query) => {
// return Http.post("/api/comment/report", query);
return Http.postV2("https://api.gter.net/v2/api/forum/postTopicReport", query); return Http.postV2("https://api.gter.net/v2/api/forum/postTopicReport", query);
}; };
export const commentReportHttp = (query) => {
return Http.postV2("https://api.gter.net/v2/api/forum/postCommentReport", query);
};
// 回应相关 - 回应列表 // 回应相关 - 回应列表
export const getRiposteHttp = (query) => { export const getRiposteHttp = (query) => {
return Http.post("/api/riposte/riposteGet", query); return Http.post("/api/riposte/riposteGet", query);

View File

@@ -1,5 +1,4 @@
<template> <template>
<Head> <Head>
<Title>{{ `${seo["title"] || "投票"} - 寄托天下出国留学网` }}</Title> <Title>{{ `${seo["title"] || "投票"} - 寄托天下出国留学网` }}</Title>
<Meta name="keyword" :content="seo['keyword']" /> <Meta name="keyword" :content="seo['keyword']" />
@@ -14,7 +13,7 @@
<a class="item blue" v-for="item in sectionn" :key="item" :href="`https://f.gter.net/section/${item.uniqid}`" target="_blank">{{ item.name }}</a> <a class="item blue" v-for="item in sectionn" :key="item" :href="`https://f.gter.net/section/${item.uniqid}`" target="_blank">{{ item.name }}</a>
<a class="item" v-for="item in tags" :key="item" :href="`https://f.gter.net/tag/${item}?type=vote`" target="_blank">{{ item }}</a> <a class="item" v-for="item in tags" :key="item" :href="`https://f.gter.net/tag/${item}?type=vote`" target="_blank">{{ item }}</a>
</div> </div>
<div class="flexacenter" style="position: relative;"> <div class="flexacenter" style="position: relative">
<div class="flex1">{{ info.title }}</div> <div class="flex1">{{ info.title }}</div>
<div class="view flexacenter"> <div class="view flexacenter">
<img class="icon" src="@/assets/img/eye-icon.svg" /> <img class="icon" src="@/assets/img/eye-icon.svg" />
@@ -123,7 +122,8 @@
回应 回应
<div class="respond-amount">{{ ripostecount.total || 0 }}</div> <div class="respond-amount">{{ ripostecount.total || 0 }}</div>
<div v-if="ripostecount.user > 0" class="respond-list-btn" @click="openPopList"> <div v-if="ripostecount.user > 0" class="respond-list-btn" @click="openPopList">
<span class="respond-list-btn-amount">{{ ripostecount.user }}</span>人回应 <span class="respond-list-btn-amount">{{ ripostecount.user }}</span
>人回应
<img class="respond-list-btn-icon" src="@/assets/img/arrowsRight.svg" /> <img class="respond-list-btn-icon" src="@/assets/img/arrowsRight.svg" />
</div> </div>
</div> </div>
@@ -192,8 +192,7 @@
</div> </div>
</div> </div>
<Report v-if="reportAlertShow" :reportToken="reportToken" :reportType="reportType"></Report>
<Report v-if="reportAlertShow" :reportToken="reportToken"></Report>
</template> </template>
<script setup> <script setup>
@@ -458,12 +457,13 @@ const getDetails = async () => {
getRiposte(); getRiposte();
const topic = data.topic const topic = data.topic;
console.log("topic", topic);
getTopicDetail(topic.uniqid); getTopicDetail(topic.uniqid);
}); });
}; };
provide("getDetails", getDetails);
let topicToken = ref(""); let topicToken = ref("");
let topicInfo = ref({}); let topicInfo = ref({});
let sectionn = ref([]); let sectionn = ref([]);
@@ -486,7 +486,6 @@ const getTopicDetail = (uniqid) => {
const targetInfo = data.info; const targetInfo = data.info;
if (!targetInfo.hidden) targetInfo.hidden = 0; if (!targetInfo.hidden) targetInfo.hidden = 0;
const sectionNameSet = new Set(targetInfo.sectionn.map((item) => item.name)); const sectionNameSet = new Set(targetInfo.sectionn.map((item) => item.name));
if (targetInfo.tags) { if (targetInfo.tags) {
const newTag = targetInfo?.tags.filter((tagName) => !sectionNameSet.has(tagName)); const newTag = targetInfo?.tags.filter((tagName) => !sectionNameSet.has(tagName));
@@ -495,17 +494,13 @@ const getTopicDetail = (uniqid) => {
sectionn.value = targetInfo.sectionn; sectionn.value = targetInfo.sectionn;
topicInfo.value = targetInfo; topicInfo.value = targetInfo;
ismyself.value = data.ismyself; ismyself.value = data.ismyself;
if (data.islogin) getTopicOperation(); if (data.islogin) getTopicOperation();
}); });
} };
const getTopicOperation = () => { const getTopicOperation = () => {
topicgetOperationHttp({ topicgetOperationHttp({
@@ -527,19 +522,15 @@ const getTopicOperation = () => {
}); });
}; };
provide("getDetails", getDetails);
// 点击发送信息 // 点击发送信息
const sendMessage = (uin) => { const sendMessage = (uin, uid) => {
if (uin && typeof messagePrivateItem == "function") { if (typeof messagePrivateItem == "function") messagePrivateItem({ uin, uid });
messagePrivateItem({ uin: uin }); else redirectToExternalWebsite(`https://bbs.gter.net/home.php?mod=space&showmsg=1&uid=${uin}&uid=${uid}`);
} else redirectToExternalWebsite(`https://bbs.gter.net/home.php?mod=space&showmsg=1&uid=${uin}`);
}; };
// 点击ta的主页 // 点击ta的主页
const TAHomePage = (uin) => { const TAHomePage = (uin, uid) => {
redirectToExternalWebsite(`https://bbs.gter.net/home.php?mod=space&uid=${uin}`); redirectToExternalWebsite(`https://bbs.gter.net/home.php?mod=space&uid=${uin}&uid=${uid}`);
}; };
// 跳转 url // 跳转 url
@@ -792,6 +783,8 @@ const cutShow = () => {
let reportAlertShow = ref(false); let reportAlertShow = ref(false);
let reportToken = ref(""); let reportToken = ref("");
let reportType = ref("");
provide("reportAlertShow", reportAlertShow); provide("reportAlertShow", reportAlertShow);
// 点击打开举报 // 点击打开举报
@@ -801,12 +794,12 @@ const report = (token) => {
return; return;
} }
cutShow() cutShow();
reportToken.value = topicToken.value; reportToken.value = topicToken.value;
reportType.value = "topic";
reportAlertShow.value = true; reportAlertShow.value = true;
}; };
// 隐藏 // 隐藏
const hide = () => { const hide = () => {
const target = topicInfo.value; const target = topicInfo.value;
@@ -837,15 +830,13 @@ const essence = () => {
}); });
}; };
// 删除
const deleteItem = () => { const deleteItem = () => {
managerDelete(token) managerDelete(token)
.then(() => redirectToExternalWebsite("/", "_self")) .then(() => redirectToExternalWebsite("/", "_self"))
.finally(() => cutShow()); .finally(() => cutShow());
}; };
const { $cache } = useNuxtApp(); const { $cache } = useNuxtApp();
try { try {
@@ -874,7 +865,7 @@ try {
}); });
} }
} }
} catch (error) { } } catch (error) {}
</script> </script>
<style scoped lang="less"> <style scoped lang="less">

View File

@@ -1,4 +1,5 @@
<template> <template>
<Head> <Head>
<Title>投票 - 寄托天下出国留学网</Title> <Title>投票 - 寄托天下出国留学网</Title>
</Head> </Head>
@@ -38,16 +39,18 @@
</div> </div>
<div class="vote-data-right flexacenter"> <div class="vote-data-right flexacenter">
<div class="vote-data-item flexacenter"><img class="vote-data-icon" src="@/assets/img/eye-icon.svg" />&nbsp; {{ item.views }}</div> <div class="vote-data-item flexacenter"><img class="vote-data-icon" src="@/assets/img/eye-icon.svg" />&nbsp; {{ item.views }}</div>
<div class="vote-data-item flexacenter" @click.stop.prevent="handleLike(item['token'], index)"> <!-- <div class="vote-data-item flexacenter" @click.stop.prevent="handleLike(item['token'], index)"> -->
<div class="vote-data-item flexacenter">
<img v-if="item['islike'] == 0" class="vote-data-icon" src="@/assets/img/like-icon-gray.png" /> <img v-if="item['islike'] == 0" class="vote-data-icon" src="@/assets/img/like-icon-gray.png" />
<img v-else class="vote-data-icon" src="@/assets/img/like-red-pitch.png" />&nbsp; {{ item["likes"] }} <img v-else class="vote-data-icon" src="@/assets/img/like-red-pitch.png" />&nbsp; {{ item["likes"] }}
<!-- <img class="vote-data-icon" src="@/assets/img/expression-icon.png" />&nbsp; {{ item["ripostes"] }} -->
</div> </div>
<div class="vote-data-item flexacenter"><img class="vote-data-icon" src="@/assets/img/comment-icon.svg" />&nbsp; {{ item["comments"] }}</div> <div class="vote-data-item flexacenter"><img class="vote-data-icon" src="@/assets/img/comment-icon.svg" />&nbsp; {{ item["comments"] }}</div>
</div> </div>
</div> </div>
</a> </a>
<div class="empty-box flexcenter" v-if="keyword && list.length == 0 && !loading"><Empty :isNeedIssue="true"></Empty></div> <div class="empty-box flexcenter" v-if="keyword && list.length == 0 && !loading">
<Empty :isNeedIssue="true"></Empty>
</div>
</div> </div>
<Like v-if="isLikeGif"></Like> <Like v-if="isLikeGif"></Like>
@@ -201,7 +204,7 @@ try {
count.value = data.count; count.value = data.count;
}); });
} }
} catch (error) {} } catch (error) { }
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.vote-item { .vote-item {
@@ -242,6 +245,7 @@ try {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
min-height: 100vh; min-height: 100vh;
&.firstdata { &.firstdata {
.vote-item { .vote-item {
margin-right: 22.5px; margin-right: 22.5px;
@@ -251,6 +255,7 @@ try {
} }
} }
} }
.vote-item { .vote-item {
width: 385px; width: 385px;
background-color: rgba(255, 255, 255, 1); background-color: rgba(255, 255, 255, 1);
@@ -333,6 +338,7 @@ try {
.vote-option-number { .vote-option-number {
display: none; display: none;
} }
.tick-icon { .tick-icon {
display: block; display: block;
} }