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-bottom: 13px;
border-radius: 5px;
cursor: pointer;
}
.comment-list .comment-item .comment-content .alreadyVoted {
font-size: 12px;

View File

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

View File

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

View File

@@ -89,7 +89,7 @@
width: 100vw;
height: 100vh;
z-index: 12;
background-color: rgba(0, 0, 0, 0.1);
// background-color: rgba(0, 0, 0, 0.1);
}
.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" />
<div>{{ topicInfo["collections"] || "收藏" }}</div>
</div>
<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>
<div class="item flexacenter" @click="openBi()">
<img class="icon" src="@/assets/img/bi-black-icon.png" />
<div>{{ topicInfo.coins || "投币" }}</div>
<div class="coinText" id="coinText">{{ topicInfo.coins || "投币" }}</div>
</div>
<ClientOnly>
<el-popover placement="bottom" width="628px" trigger="click" popper-style="padding: 0;border-radius: 10px;" v-model:visible="transmitBoxState">
<template #reference>
<div class="item flexacenter" @click="handleShare">
<img class="icon" src="@/assets/img/transmit-icon.png" />转发
</div>
<div class="item flexacenter" @click="handleShare"><img class="icon" src="@/assets/img/transmit-icon.png" />转发</div>
</template>
<div class="transmit-box flexflex">
@@ -49,9 +49,7 @@
<div class="transmit-headline">{{ info["title"] }}</div>
<div class="transmit-url">{{ getFullUrl() }}</div>
</div>
<div class="transmit-web-btn flexcenter" @click="copyText(`${info['title']} + ${getFullUrl()}`)">
复制链接
</div>
<div class="transmit-web-btn flexcenter" @click="copyText(`${info['title']} + ${getFullUrl()}`)">复制链接</div>
</div>
<div class="transmit-right transmit-mini">
<div class="transmit-title">转发小程序版</div>
@@ -96,7 +94,6 @@ import { ElMessage } from "element-plus";
let props = defineProps({
ripostecount: Object,
commentComments: Number,
});
let topicInfo = inject("topicInfo");
@@ -276,7 +273,7 @@ const openBi = () => {
}
BiComponent.initComponent();
}
};
</script>
<style scoped lang="less">

View File

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

View File

@@ -3,7 +3,7 @@
<div class="alert-form">
<div class="comments reports">
<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>
<div class="form">
@@ -26,42 +26,42 @@
</div>
</template>
<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"])
const reasonList = ["广告", "辱骂", "重复发送", "不良信息", "其他"]
let reportAlertShow = inject("reportAlertShow")
let checkList = ref([]);
let alertShow = ref(false);
let alertText = ref("");
let checkList = ref([])
let alertShow = ref(false)
let alertText = ref("")
const selectRadio = value => {
const index = checkList.value.indexOf(value)
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 = () => {
if (checkList.value.length == 0) {
ElMessage.error("请选择举报类型")
return
ElMessage.error("请选择举报类型");
return;
}
checkList.value.push(alertText.value)
reportAlertShow.value = false
commentReportHttp({
checkList.value.push(alertText.value);
reportAlertShow.value = false;
(props.reportType === "comment" ? commentReportHttp : reportHttp)({
message: checkList.value,
token: props.reportToken,
}).then(res => {
checkList.value = []
reportAlertShow.value = false
ElMessage.success(res.message || "举报成功")
})
}
}).then((res) => {
checkList.value = [];
reportAlertShow.value = false;
ElMessage.success(res.message || "举报成功");
});
};
// 取消
const cancel = () => (reportAlertShow.value = false)
const cancel = () => (reportAlertShow.value = false);
</script>
<style lang="less" scoped>

View File

@@ -35,7 +35,6 @@ export const detailsSubmitommentListHttp = (query) => {
// 详情数据 - 提交评论
export const commentsEditSubmit = (query) => {
// return Http.post("/api/comment/commentsEditSubmit", 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);
};
// 评论相关 - 举报 Comment related
export const commentReportHttp = (query) => {
// return Http.post("/api/comment/report", query);
export const reportHttp = (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) => {
return Http.post("/api/riposte/riposteGet", query);

View File

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

View File

@@ -1,4 +1,5 @@
<template>
<Head>
<Title>投票 - 寄托天下出国留学网</Title>
</Head>
@@ -38,16 +39,18 @@
</div>
<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" @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-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 class="vote-data-item flexacenter"><img class="vote-data-icon" src="@/assets/img/comment-icon.svg" />&nbsp; {{ item["comments"] }}</div>
</div>
</div>
</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>
<Like v-if="isLikeGif"></Like>
@@ -242,6 +245,7 @@ try {
display: flex;
flex-wrap: wrap;
min-height: 100vh;
&.firstdata {
.vote-item {
margin-right: 22.5px;
@@ -251,6 +255,7 @@ try {
}
}
}
.vote-item {
width: 385px;
background-color: rgba(255, 255, 255, 1);
@@ -333,6 +338,7 @@ try {
.vote-option-number {
display: none;
}
.tick-icon {
display: block;
}