feat(Details): 新增投票详情页管理功能和评论优化
- 添加投票详情页的管理功能,包括隐藏、推荐、精华和删除操作 - 优化评论组件,支持多图上传和显示 - 新增投币功能组件 - 更新API接口调用方式,适配新后端接口 - 完善用户权限管理逻辑 - 修复样式问题和交互体验
This commit is contained in:
12
app.vue
12
app.vue
@@ -49,6 +49,8 @@ let isNeedLogin = ref(true); // 是否需要登录状态
|
||||
let isGetLoginState = ref(true); // 在获取登录状态 false 代表没有已经确定了
|
||||
let realname = ref(1); // 是否已经实名
|
||||
let userInfoWin = ref({});
|
||||
let permissions = ref([]);
|
||||
let ismanager = ref(false);
|
||||
|
||||
provide("userInfoWin", userInfoWin);
|
||||
|
||||
@@ -81,12 +83,15 @@ const goLogin = () => {
|
||||
|
||||
const getUserInfoWin = () => {
|
||||
const checkUser = () => {
|
||||
const user = window.userInfoWin;
|
||||
const user = window.userInfoWin;
|
||||
if (!user) return;
|
||||
document.removeEventListener("getUser", checkUser);
|
||||
realname.value = user.realname;
|
||||
userInfoWin.value = user;
|
||||
if (user?.uin > 0 || user?.uid > 0) isNeedLogin.value = false;
|
||||
|
||||
permissions.value = user?.authority || [];
|
||||
ismanager.value = permissions.value.indexOf("topic:manager") >= 0;
|
||||
};
|
||||
document.addEventListener("getUser", checkUser);
|
||||
};
|
||||
@@ -106,6 +111,9 @@ provide("goLogin", goLogin);
|
||||
provide("isGetLoginState", isGetLoginState);
|
||||
provide("realname", realname);
|
||||
provide("openAttest", openAttest);
|
||||
provide("permissions", permissions);
|
||||
provide("ismanager", ismanager);
|
||||
|
||||
</script>
|
||||
<style lang="less">
|
||||
* {
|
||||
@@ -261,6 +269,7 @@ input::-webkit-contacts-auto-fill-button {
|
||||
|
||||
.options-popup-btn {
|
||||
justify-content: space-between;
|
||||
|
||||
.options-popup-item {
|
||||
font-size: 13px;
|
||||
width: 160px;
|
||||
@@ -275,6 +284,7 @@ input::-webkit-contacts-auto-fill-button {
|
||||
color: #fff;
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
&.options-no {
|
||||
background-color: #fff;
|
||||
border-color: rgba(170, 170, 170, 1);
|
||||
|
||||
@@ -167,6 +167,7 @@
|
||||
background-color: transparent;
|
||||
min-height: 80px;
|
||||
padding-bottom: 11px;
|
||||
max-height: 400px;
|
||||
}
|
||||
.input-box .top .input-textarea * {
|
||||
background: transparent !important;
|
||||
@@ -187,10 +188,13 @@
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px dotted rgba(215, 215, 215, 0.501961);
|
||||
padding-left: 14px;
|
||||
padding-top: 10px;
|
||||
overflow: auto;
|
||||
}
|
||||
.input-box .picture-box .picture {
|
||||
position: relative;
|
||||
width: fit-content;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.input-box .picture-box .picture .img {
|
||||
height: 60px;
|
||||
|
||||
@@ -194,6 +194,7 @@
|
||||
background-color: transparent;
|
||||
min-height: 80px;
|
||||
padding-bottom: 11px;
|
||||
max-height: 400px;
|
||||
// &.placeholder::after {
|
||||
// content: "说说你的看法…";
|
||||
// color: #7f7f7f;
|
||||
@@ -223,10 +224,13 @@
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px dotted rgba(215, 215, 215, 0.501961);
|
||||
padding-left: 14px;
|
||||
padding-top: 10px;
|
||||
overflow: auto;
|
||||
|
||||
.picture {
|
||||
position: relative;
|
||||
width: fit-content;
|
||||
margin-right: 10px;
|
||||
|
||||
.img {
|
||||
height: 60px;
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
.content .header .label {
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 15px;
|
||||
font-weight: 400;
|
||||
}
|
||||
.content .header .label .item {
|
||||
font-size: 14px;
|
||||
@@ -48,6 +49,77 @@
|
||||
color: #ffffff;
|
||||
background-color: #04b0d5;
|
||||
}
|
||||
.content .header .view {
|
||||
font-size: 12px;
|
||||
color: #aaaaaa;
|
||||
margin-right: 15px;
|
||||
font-weight: 400;
|
||||
}
|
||||
.content .header .view .icon {
|
||||
width: 13px;
|
||||
height: 8px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
.content .header .btn {
|
||||
width: 24px;
|
||||
height: 16px;
|
||||
background-color: #f2f2f2;
|
||||
border-radius: 150px;
|
||||
cursor: pointer;
|
||||
font-weight: 400;
|
||||
}
|
||||
.content .header .btn .icon {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
.content .header .mask {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
z-index: 12;
|
||||
background-color: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
.content .header .operate {
|
||||
position: absolute;
|
||||
top: 23px;
|
||||
right: 0;
|
||||
width: 80px;
|
||||
background-color: #f2f2f2;
|
||||
border-radius: 8px;
|
||||
padding: 5px;
|
||||
z-index: 13;
|
||||
font-weight: 400;
|
||||
}
|
||||
.content .header .operate::after {
|
||||
content: "";
|
||||
width: calc(100% - 10px);
|
||||
height: calc(100% - 10px);
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
display: block;
|
||||
transform: translate(-50%, -50%);
|
||||
background-color: #fbfbfb;
|
||||
z-index: -1;
|
||||
}
|
||||
.content .header .operate .item {
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
color: #333333;
|
||||
padding: 14px 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
.content .header .operate .item:first-of-type {
|
||||
padding-top: 14px;
|
||||
}
|
||||
.content .header .operate .item:last-of-type {
|
||||
padding-top: 14px;
|
||||
}
|
||||
.content .header .operate .item:not(:last-of-type) {
|
||||
border-bottom: 1px dotted #d7d7d7;
|
||||
}
|
||||
.content .left {
|
||||
width: 658px;
|
||||
min-height: calc(100vh - 165px);
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
.label {
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 15px;
|
||||
font-weight: 400;
|
||||
|
||||
.item {
|
||||
font-size: 14px;
|
||||
@@ -53,6 +54,88 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.view {
|
||||
font-size: 12px;
|
||||
color: #aaaaaa;
|
||||
margin-right: 15px;
|
||||
font-weight: 400;
|
||||
|
||||
.icon {
|
||||
width: 13px;
|
||||
height: 8px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.btn {
|
||||
width: 24px;
|
||||
height: 16px;
|
||||
background-color: rgba(242, 242, 242, 1);
|
||||
border-radius: 150px;
|
||||
cursor: pointer;
|
||||
font-weight: 400;
|
||||
|
||||
.icon {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
.mask {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
z-index: 12;
|
||||
background-color: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.operate {
|
||||
position: absolute;
|
||||
top: 23px;
|
||||
right: 0;
|
||||
width: 80px;
|
||||
background-color: rgba(242, 242, 242, 1);
|
||||
border-radius: 8px;
|
||||
padding: 5px;
|
||||
z-index: 13;
|
||||
font-weight: 400;
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
width: calc(100% - 10px);
|
||||
height: calc(100% - 10px);
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
display: block;
|
||||
transform: translate(-50%, -50%);
|
||||
background-color: rgba(251, 251, 251, 1);
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.item {
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
color: #333333;
|
||||
padding: 14px 0;
|
||||
cursor: pointer;
|
||||
|
||||
&:first-of-type {
|
||||
padding-top: 14px;
|
||||
}
|
||||
|
||||
&:last-of-type {
|
||||
padding-top: 14px;
|
||||
}
|
||||
|
||||
&:not(:last-of-type) {
|
||||
border-bottom: 1px dotted #d7d7d7;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.left {
|
||||
|
||||
BIN
assets/img/bi-black-icon.png
Normal file
BIN
assets/img/bi-black-icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
BIN
assets/img/dot-dot-dot-gray.png
Normal file
BIN
assets/img/dot-dot-dot-gray.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 542 B |
@@ -14,33 +14,31 @@
|
||||
</el-popover>
|
||||
</div>
|
||||
<div class="floor-left flexacenter">
|
||||
<div class="item flexacenter" style="cursor: auto">
|
||||
<img class="icon" src="@/assets/img/eye-icon-black.svg" />
|
||||
<div>{{ info["views"] }}</div>
|
||||
</div>
|
||||
<div class="item flexacenter" @click="handleLike">
|
||||
<img class="icon pitch" v-if="islike == 1" src="@/assets/img/like-red-pitch.png" />
|
||||
<img class="icon" v-else src="@/assets/img/like-icon.png" />
|
||||
<div>{{ info["likes"] || "" }}</div>
|
||||
<div>{{ topicInfo["likes"] || "赞" }}</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="item flexacenter" @click="handleCollect()">
|
||||
<img class="icon" v-if="iscollection == 1" src="@/assets/img/collect-icon-colours.svg" />
|
||||
<img class="icon" v-else src="@/assets/img/collect-icon.png" />
|
||||
<div>{{ info["favs"] || "收藏" }}</div>
|
||||
<div>{{ topicInfo["collections"] || "收藏" }}</div>
|
||||
</div>
|
||||
<div class="item flexacenter" style="cursor: auto">
|
||||
<img class="icon" src="@/assets/img/discuss-icon.png" />
|
||||
<div>{{ commentComments }}</div>
|
||||
<div>{{ commentTotalCount || "讨论" }}</div>
|
||||
</div>
|
||||
<div class="item flexacenter" style="cursor: auto">
|
||||
<img class="icon" src="@/assets/img/discuss-icon.png" />
|
||||
<div>{{ commentComments }}</div>
|
||||
<div class="item flexacenter" style="cursor: auto" @click="openBi()">
|
||||
<img class="icon" src="@/assets/img/bi-black-icon.png" />
|
||||
<div>{{ 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">
|
||||
@@ -51,7 +49,9 @@
|
||||
<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>
|
||||
@@ -86,6 +86,8 @@
|
||||
</div>
|
||||
</div>
|
||||
<Like v-if="isLikeGif"></Like>
|
||||
|
||||
<bi-card :coins="topicInfo.coins" :token="topicToken"></bi-card>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
@@ -94,8 +96,11 @@ import { ElMessage } from "element-plus";
|
||||
let props = defineProps({
|
||||
ripostecount: Object,
|
||||
commentComments: Number,
|
||||
|
||||
});
|
||||
|
||||
let topicInfo = inject("topicInfo");
|
||||
|
||||
const respondShowState = ref(false);
|
||||
|
||||
let openAttest = inject("openAttest");
|
||||
@@ -110,6 +115,7 @@ let islike = inject("islike");
|
||||
let iscollection = inject("iscollection");
|
||||
let qrcode = inject("qrcode");
|
||||
let token = inject("token");
|
||||
let topicToken = inject("topicToken");
|
||||
const topHeadRef = inject("topHeadRef");
|
||||
const isLoaded = inject("isLoaded");
|
||||
|
||||
@@ -158,14 +164,14 @@ const handleCollect = () => {
|
||||
|
||||
topHeadRef.value.count = {};
|
||||
|
||||
operateCollectHttp({ token: token.value }).then((res) => {
|
||||
operateCollectHttp({ token: topicToken.value }).then((res) => {
|
||||
if (res.code != 200) {
|
||||
ElMessage.error(res["message"]);
|
||||
return;
|
||||
}
|
||||
let data = res.data;
|
||||
|
||||
info.value["favs"] = data["count"];
|
||||
topicInfo.value["collections"] = data["collections"];
|
||||
iscollection.value = data["status"];
|
||||
|
||||
ElMessage.success(res["message"]);
|
||||
@@ -195,7 +201,7 @@ const handleLike = () => {
|
||||
return;
|
||||
}
|
||||
|
||||
operateLikeHttp({ token: token.value }).then((res) => {
|
||||
operateLikeHttp({ token: topicToken.value }).then((res) => {
|
||||
if (res.code != 200) {
|
||||
ElMessage.error(res.message);
|
||||
return;
|
||||
@@ -204,7 +210,7 @@ const handleLike = () => {
|
||||
let data = res.data;
|
||||
const status = data["status"];
|
||||
|
||||
info.value["likes"] = data["count"];
|
||||
topicInfo.value["likes"] = data["likes"];
|
||||
islike.value = status;
|
||||
|
||||
ElMessage.success(res.message);
|
||||
@@ -227,7 +233,7 @@ const emit = defineEmits(["closeDiscussInputFields"]);
|
||||
// // 点击底部调用关闭讨论输入框
|
||||
const closeDiscussInputFields = () => emit("closeDiscussInputFields");
|
||||
|
||||
onMounted(() => {});
|
||||
onMounted(() => { });
|
||||
|
||||
watch(isLoaded, (newValue, oldValue) => {
|
||||
if (newValue === true) {
|
||||
@@ -262,6 +268,15 @@ onBeforeUnmount(() => {
|
||||
const randomBottomEmojis = inject("randomBottomEmojis");
|
||||
const selectEomji = inject("selectEomji");
|
||||
const jointriposte = inject("jointriposte");
|
||||
|
||||
const openBi = () => {
|
||||
if (isNeedLogin.value) {
|
||||
goLogin();
|
||||
return;
|
||||
}
|
||||
|
||||
BiComponent.initComponent();
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
@@ -281,12 +296,15 @@ const jointriposte = inject("jointriposte");
|
||||
-webkit-box-shadow: 0px -1px 2px rgba(0, 0, 0, 0.192156862745098);
|
||||
box-shadow: 0px -1px 2px rgba(0, 0, 0, 0.192156862745098);
|
||||
display: none;
|
||||
|
||||
&.show {
|
||||
display: flex;
|
||||
animation: animafloor 1s forwards;
|
||||
animation-timing-function: cubic-bezier(0.98, -0.2, 0.55, 0.97); /* 先快后慢的时间曲线 */
|
||||
animation-timing-function: cubic-bezier(0.98, -0.2, 0.55, 0.97);
|
||||
/* 先快后慢的时间曲线 */
|
||||
animation-fill-mode: both;
|
||||
}
|
||||
|
||||
.floor-content {
|
||||
width: 1200px;
|
||||
height: 100%;
|
||||
@@ -294,6 +312,7 @@ const jointriposte = inject("jointriposte");
|
||||
padding: 0 30px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.floor-left {
|
||||
margin-left: 30px;
|
||||
// flex: 1;
|
||||
@@ -301,8 +320,8 @@ const jointriposte = inject("jointriposte");
|
||||
|
||||
.item {
|
||||
cursor: pointer;
|
||||
color: #aaaaaa;
|
||||
font-size: 13px;
|
||||
color: #333333;
|
||||
font-size: 14px;
|
||||
margin-right: 50px;
|
||||
|
||||
.icon {
|
||||
@@ -316,9 +335,11 @@ const jointriposte = inject("jointriposte");
|
||||
0% {
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: scale(1.2);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: scale(1);
|
||||
}
|
||||
@@ -365,6 +386,7 @@ const jointriposte = inject("jointriposte");
|
||||
border-radius: 152px;
|
||||
background-color: #fff;
|
||||
border: 1px solid rgba(215, 215, 215, 1);
|
||||
|
||||
.avatar {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
@@ -378,6 +400,7 @@ const jointriposte = inject("jointriposte");
|
||||
outline: none;
|
||||
padding: 0 12px;
|
||||
font-size: 14px;
|
||||
|
||||
/deep/ .el-input__wrapper {
|
||||
box-shadow: none;
|
||||
padding: 0;
|
||||
@@ -390,6 +413,7 @@ const jointriposte = inject("jointriposte");
|
||||
background-color: var(--main-color);
|
||||
border-radius: 20px;
|
||||
cursor: pointer;
|
||||
|
||||
.comment-btn-icon {
|
||||
width: 14px;
|
||||
height: 15px;
|
||||
@@ -417,6 +441,7 @@ const jointriposte = inject("jointriposte");
|
||||
.respond-box {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
|
||||
.respond-item {
|
||||
font-family: "emojifont";
|
||||
font-size: 18px;
|
||||
|
||||
@@ -8,10 +8,11 @@
|
||||
<div class="top flexflex">
|
||||
<textarea ref="editInputRef" class="input-textarea flex1" maxlength="500" v-model="editInput" @focus="judgeLogin" @input="autoResize" @paste="handleInputPaste" placeholder="说说你的想法或疑问…"></textarea>
|
||||
</div>
|
||||
<div class="picture-box" v-if="editPicture.url">
|
||||
<div class="picture">
|
||||
<img class="close" @click="closeEditFileUpload()" src="@/assets/img/close-icon.png" />
|
||||
<img class="img" @click="handleAnswerText" :src="editPicture.base64 || editPicture.url" />
|
||||
|
||||
<div class="picture-box flexacenter" v-if="editPicture.length != 0">
|
||||
<div class="picture" v-for="(item, index) in editPicture" :key="item.url">
|
||||
<img class="close" @click="closeEditFileUpload(item.aid)" src="@/assets/img/close-icon.png" />
|
||||
<img class="img" @click="handleAnswerText" :src="item.url" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -61,10 +62,10 @@
|
||||
<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>
|
||||
</div>
|
||||
<div class="picture-box" v-if="picture.url">
|
||||
<div class="picture">
|
||||
<img class="close" @click="closeFileUpload()" src="@/assets/img/close-icon.png" />
|
||||
<img class="img" @click="handleAnswerText" :src="picture.base64 || picture.url" />
|
||||
<div class="picture-box flexacenter" v-if="picture.length != 0">
|
||||
<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="img" @click="handleAnswerText" :src="item.url" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottom flexacenter">
|
||||
@@ -98,15 +99,15 @@
|
||||
<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']">
|
||||
<template #reference>
|
||||
<img class="comment-avatar" :src="item['avatar']" />
|
||||
<img class="comment-avatar" :src="item.avatar || item.user['avatar']" />
|
||||
</template>
|
||||
|
||||
<div class="avatar-box flexflex" v-if="item['uin']">
|
||||
<a class="avatar-item flexcenter" target="_blank" @click.prevent="sendMessage(item['uin'])">
|
||||
<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'])">
|
||||
<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>
|
||||
@@ -115,11 +116,10 @@
|
||||
<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"] }}</div>
|
||||
<div class="comments-time">{{ item["timestampnow"] || handleDate(item["timestamp"]) }}</div>
|
||||
<div class="comments-identity" v-if="item['isauthor']">作者</div>
|
||||
<!-- <img class="comments-title" v-if="item['groupid'] === 14" src="@/assets/img/title.png" /> -->
|
||||
<img class="comments-title" v-if="item['groupimage']" :src="item.groupimage" :alt="item.grouptitle" />
|
||||
<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" />
|
||||
</div>
|
||||
<div class="comment-header-right flexacenter">
|
||||
<div class="menu-box flexacenter">
|
||||
@@ -130,7 +130,6 @@
|
||||
<div class="item flexcenter" v-if="permissions.includes('comment.delete')" @click="commentDelete(item['token'], index)">删除</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <img class="comment-icon" title="回复" @click="openAnswerCommentsChild(index)" src="@/assets/img/comment-icon-gray.svg" /> -->
|
||||
<img class="comment-icon" title="回复" @click="!item['childState'] ? openAnswerCommentsChild(index) : closeAnswerCommentsChild()" src="@/assets/img/comment-icon-gray.svg" />
|
||||
<div class="flexacenter like-box" @click="commentLike(index)">
|
||||
<img class="like-icon" v-if="item['islike'] == 1" src="@/assets/img/like-red-pitch.png" />
|
||||
@@ -139,19 +138,22 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- shutAnswerCommentsChild openAnswerCommentsChild -->
|
||||
<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" />
|
||||
<!-- <img class="comments-img" @click="handleAnswerText" :src="item.image?.base64 || item.image?.url" v-if="item.image?.url" /> -->
|
||||
<div class="comments-img-box">
|
||||
<img class="comments-img" v-for="(item, index) in item.attachments.images" @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>
|
||||
</div>
|
||||
<div class="picture-box" v-if="item.picture?.url">
|
||||
<div class="picture">
|
||||
<img class="close" @click="closeFileUpload(index)" src="@/assets/img/close-icon.png" />
|
||||
<img class="img" @click="handleAnswerText" :src="item.picture?.base64 || item.picture.url" />
|
||||
|
||||
<div 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="img" @click="handleAnswerText" :src="it.url" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottom flexacenter">
|
||||
@@ -176,30 +178,21 @@
|
||||
<div class="btn" @click="submitAnswerComments(item['commentInput'], index)">发送</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="comments-input-masking" @click="closeAnswerCommentsChild()" v-if="item['childState']"></div>
|
||||
<div class="comments-input-box" :class="{ 'comments-input-box-show': item['childState'] }">
|
||||
<div class="comments-input">
|
||||
<el-input v-model="commentInput" type="textarea" placeholder="回复" :maxlength="500" show-word-limit></el-input>
|
||||
<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)">发送</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<!-- 子评论 -->
|
||||
<div class="child-comments" v-if="item['child'].length > 0">
|
||||
<div class="comment-item flexflex" v-for="(ite, i) in item['child']" :key="ite.id">
|
||||
<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']" />
|
||||
<img class="comment-avatar" :src="ite.avatar || ite.user['avatar']" />
|
||||
</template>
|
||||
|
||||
<div class="avatar-box flexflex" v-if="ite['uin']">
|
||||
<a class="avatar-item flexcenter" target="_blank" @click.prevent="sendMessage(ite['uin'])">
|
||||
<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'])">
|
||||
<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>
|
||||
@@ -208,10 +201,10 @@
|
||||
<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"] }}</div>
|
||||
<div class="comments-time">{{ ite["timestampnow"] || handleDate(ite["timestamp"]) }}</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']" :src="ite.groupimage" :alt="ite.grouptitle" />
|
||||
<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">
|
||||
@@ -234,19 +227,24 @@
|
||||
<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" />
|
||||
<!-- <img class="comments-img" @click="handleAnswerText" :src="ite.image?.base64 || ite.image?.url" v-if="ite.image?.url" /> -->
|
||||
<div class="comments-img-box">
|
||||
<img class="comments-img" v-for="(item, index) in ite.attachments.images" @click="handleAnswerText" :src="ite.thumb || ite.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" />
|
||||
<div class="top flexflex">
|
||||
<textarea class="input-textarea flex1" maxlength="500" :placeholder="'回复“' + (ite['nickname'] || '匿名用户') + '”:'" v-model="ite['commentInput']" @input="autoResize" @paste="handleInputPaste($event, index)"></textarea>
|
||||
<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" v-if="ite.picture?.url">
|
||||
<div class="picture">
|
||||
<img class="close" @click="closeFileUpload(index, i)" src="@/assets/img/close-icon.png" />
|
||||
<img class="img" @click="handleAnswerText" :src="ite.picture.base64 || ite.picture.url" />
|
||||
|
||||
<div 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="img" @click="handleAnswerText" :src="it.url" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bottom flexacenter">
|
||||
<div class="operate flexacenter">
|
||||
<div class="item" :class="{ pitch: ite.emojiState }">
|
||||
@@ -348,14 +346,7 @@ watch(
|
||||
|
||||
onMounted(() => window.addEventListener("scroll", handleScroll));
|
||||
|
||||
let permissions = ref([]);
|
||||
|
||||
onMounted(() => {
|
||||
setTimeout(() => {
|
||||
permissions.value = window["permissions"] || [];
|
||||
// permissions.value = ["comment.edit", "comment.delete"]
|
||||
}, 1000);
|
||||
});
|
||||
let permissions = inject("permissions");
|
||||
|
||||
const sendMessage = inject("sendMessage");
|
||||
const TAHomePage = inject("TAHomePage");
|
||||
@@ -378,7 +369,7 @@ const getCommentList = () => {
|
||||
|
||||
commentListHttp({
|
||||
page: commentPage.value,
|
||||
childlimit: 1,
|
||||
childlimit: 3,
|
||||
limit: 10,
|
||||
token: props.token,
|
||||
})
|
||||
@@ -386,6 +377,21 @@ const getCommentList = () => {
|
||||
if (res.code != 200) return;
|
||||
|
||||
let data = res.data;
|
||||
|
||||
data.data.forEach((element, index) => {
|
||||
element.timestamp = strtimeago(element.created_at, 4);
|
||||
element["picture"] = [];
|
||||
element["isReplyBoxShow"] = 0;
|
||||
|
||||
if (element.child.length > 0) {
|
||||
element.child.forEach((el) => {
|
||||
el["picture"] = [];
|
||||
el.timestamp = strtimeago(element.created_at, 4);
|
||||
el["isReplyBoxShow"] = 0;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
commentCount.value = data["count"];
|
||||
if (data["count"] == 0) isEmptyState.value = true;
|
||||
else isEmptyState.value = false;
|
||||
@@ -431,10 +437,10 @@ const commentLike = (index, i) => {
|
||||
|
||||
if (i != null) {
|
||||
targetCommentList[index]["child"][i].islike = status;
|
||||
targetCommentList[index]["child"][i].likenum = data["likenum"];
|
||||
targetCommentList[index]["child"][i].likenum = data["count"];
|
||||
} else {
|
||||
targetCommentList[index].islike = status;
|
||||
targetCommentList[index].likenum = data["likenum"];
|
||||
targetCommentList[index].likenum = data["count"];
|
||||
}
|
||||
|
||||
ElMessage.success(res.message);
|
||||
@@ -487,7 +493,7 @@ let openAttest = inject("openAttest");
|
||||
const realname = inject("realname");
|
||||
|
||||
// 提交回答-评论
|
||||
const submitAnswerComments = (content, index, i) => {
|
||||
const submitAnswerComments = (content = "", index, i) => {
|
||||
console.log("submitAnswerComments", submitAnswerComments);
|
||||
|
||||
if (realname.value == 0 && userInfoWin.value.uin > 0) {
|
||||
@@ -521,12 +527,16 @@ const submitAnswerComments = (content, index, i) => {
|
||||
// ElMessage.error("请填写评论内容")
|
||||
// return
|
||||
// }
|
||||
const attachments = {
|
||||
images: image,
|
||||
};
|
||||
|
||||
|
||||
detailsSubmitommentListHttp({
|
||||
content,
|
||||
token: props.token,
|
||||
parentid,
|
||||
image: image ? { aid: image.aid, url: image.url } : null,
|
||||
replyid: parentid,
|
||||
attachments,
|
||||
}).then((res) => {
|
||||
if (res.code != 200) {
|
||||
ElMessage.error(res.message);
|
||||
@@ -534,6 +544,7 @@ const submitAnswerComments = (content, index, i) => {
|
||||
}
|
||||
|
||||
let data = res.data;
|
||||
const timestamp = strtimeago(new Date());
|
||||
|
||||
if (i != null) {
|
||||
// console.log("targetCommentList[index]", targetCommentList[index])
|
||||
@@ -551,10 +562,13 @@ const submitAnswerComments = (content, index, i) => {
|
||||
},
|
||||
voteoption: haveVotedValue.value || null,
|
||||
...data,
|
||||
// ...data.data
|
||||
timestampnow: "刚刚",
|
||||
uin: data.data?.uin,
|
||||
image,
|
||||
attachments,
|
||||
picture: [],
|
||||
timestamp,
|
||||
|
||||
uin: userInfoWin.value.uin,
|
||||
uid: userInfoWin.value.uid,
|
||||
|
||||
};
|
||||
|
||||
targetCommentList[index]["child"].unshift(targetData);
|
||||
@@ -567,12 +581,12 @@ const submitAnswerComments = (content, index, i) => {
|
||||
islike: 0,
|
||||
likenum: 0,
|
||||
...data,
|
||||
// ...data.data,
|
||||
timestampnow: "刚刚",
|
||||
uin: data.data?.uin,
|
||||
timestamp,
|
||||
child: [],
|
||||
voteoption: haveVotedValue.value || null,
|
||||
image,
|
||||
attachments,
|
||||
uin: userInfoWin.value.uin,
|
||||
uid: userInfoWin.value.uid,
|
||||
};
|
||||
if (index != null) {
|
||||
targetCommentList[index]["commentInput"] = "";
|
||||
@@ -597,7 +611,7 @@ const submitAnswerComments = (content, index, i) => {
|
||||
|
||||
closeAnswerCommentsChild();
|
||||
|
||||
picture.value = {};
|
||||
picture.value = [];
|
||||
|
||||
if (bottomNavigationState) {
|
||||
bottomNavigationState = false;
|
||||
@@ -620,7 +634,7 @@ const alsoCommentsData = (index, ind) => {
|
||||
let page = targetCommentItem["childPage"] ?? 1;
|
||||
|
||||
detailsChildCommentListHttp({
|
||||
childlimit: 1,
|
||||
childlimit: 3,
|
||||
limit: 10,
|
||||
page,
|
||||
parentid,
|
||||
@@ -628,22 +642,32 @@ const alsoCommentsData = (index, ind) => {
|
||||
}).then((res) => {
|
||||
if (res.code != 200) return;
|
||||
let data = res.data;
|
||||
let childData = targetCommentItem.child.concat(data.data);
|
||||
|
||||
const filteredData = childData.filter((obj, index, self) => {
|
||||
// 检查当前对象在数组中的第一个索引是否与当前索引相等
|
||||
return self.findIndex((item) => item.id == obj.id) == index;
|
||||
});
|
||||
data.data.forEach((element, index) => {
|
||||
element.timestamp = strtimeago(element.created_at, 4);
|
||||
element["isReplyBoxShow"] = 0;
|
||||
element["picture"] = [];
|
||||
})
|
||||
// let childData = targetCommentItem.child.concat(data.data);
|
||||
|
||||
targetCommentItem.child = filteredData;
|
||||
targetCommentItem["childnum"] = data.count;
|
||||
// const filteredData = childData.filter((obj, index, self) => {
|
||||
// // 检查当前对象在数组中的第一个索引是否与当前索引相等
|
||||
// return self.findIndex((item) => item.id == obj.id) == index;
|
||||
// });
|
||||
|
||||
if (targetCommentItem.child.length == data["count"]) page = 0;
|
||||
else page++;
|
||||
// targetCommentItem.child = filteredData;
|
||||
// targetCommentItem["childnum"] = data.count;
|
||||
|
||||
targetCommentItem["childPage"] = page;
|
||||
// if (targetCommentItem.child.length == data["count"]) page = 0;
|
||||
// else page++;
|
||||
|
||||
commentList.value[index] = targetCommentItem;
|
||||
// targetCommentItem["childPage"] = page;
|
||||
|
||||
let merged = [...commentList.value[index]["child"], ...data.data.filter((item2) => !commentList.value[index]["child"].find((item1) => item1.id == item2.id))];
|
||||
|
||||
commentList.value[index]["child"] = merged;
|
||||
|
||||
// commentList.value[index] = targetCommentItem;
|
||||
});
|
||||
};
|
||||
|
||||
@@ -740,12 +764,11 @@ const postCommentFocusBlur = () => {
|
||||
}, 200);
|
||||
};
|
||||
|
||||
let picture = ref({});
|
||||
let picture = ref([]);
|
||||
|
||||
let emojiState = ref(false);
|
||||
let emojiMaskState = ref(false);
|
||||
|
||||
// , "🤝", "🙏", "💪", "❤️", "💔", "🌹", "🥀", "🎉", "🎁", "🧧", "🌙", "⭐", "🌍", "💌", "📬", "🚗", "🚕", "🚲", "🛵", "🚀", "🚁", "⛵", "🚢", "🍎", "🍐", "🍊", "🍉", "🍓", "🍑", "🍔", "🍟", "🍕", "🥪", "🍜", "🍡", "🍨", "🍦", "🎂", "🍰", "🍭", "🍿", "🍩", "🧃", "🍹"];
|
||||
const emojiData = ["😀", "😁", "😆", "😅", "😂", "😉", "😍", "🥰", "😘", "🤥", "😪", "😵💫", "🤓", "🥺", "😋", "😜", "🤪", "😎", "🤩", "🥳", "😔", "🙁", "😭", "😡", "😳", "🤗", "🤔", "🤭", "🤫", "😯", "😵", "🙄", "🥴", "🤢", "🤑", "🤠", "👌", "✌️", "🤟", "🤘", "🤙", "👍", "👎", "✊", "👏", "🤝", "🙏", "💪", "❎️", "✳️", "✴️", "❇️", "#️⃣", "*️⃣", "1️⃣", "2️⃣", "3️⃣", "4️⃣", "5️⃣", "6️⃣", "7️⃣", "8️⃣", "9️⃣", "🔟", "🆗", "🈶", "🉐", "🉑", "🌹", "🥀", "🌸", "🌺", "🌷", "🌲", "☘️", "🍀", "🍁", "🌙", "⭐", "🌍", "☀️", "⭐️", "🌟", "☁️", "🌈", "☂️", "❄️", "☃️", "☄️", "🔥", "💧", "🍎", "🍐", "🍊", "🍉", "🍓", "🍑", "🍔", "🍟", "🍕", "🥪", "🍜", "🍡", "🍨", "🍦", "🎂", "🍰", "🍭", "🍿", "🍩", "🧃", "🍹", "🍒", "🥝", "🥒", "🥦", "🥨", "🌭", "🥘", "🍱", "🍢", "🥮", "🍩", "🍪", "🧁", "🍵", "🍶", "🍻", "🥂", "🧋", "🎉", "🎁", "🧧", "🎃", "🎄", "🧨", "✨️", "🎈", "🎊", "🎋", "🎍", "🎀", "🎖️", "🏆️", "🏅", "💌", "📬", "🚗", "🚕", "🚲", "🛵", "🚀", "🚁", "⛵", "🚢", "🔮", "🧸", "🀄️"];
|
||||
|
||||
// 打开 Emoji
|
||||
@@ -844,6 +867,8 @@ const handleInputPaste = (event, index, ii) => {
|
||||
}
|
||||
}
|
||||
};
|
||||
const maxPicture = ref(10);
|
||||
|
||||
|
||||
const handleFileUpload = (event, index, i) => {
|
||||
closeEmoji();
|
||||
@@ -859,19 +884,36 @@ const handleFileUpload = (event, index, i) => {
|
||||
return;
|
||||
}
|
||||
|
||||
let target = [];
|
||||
if (editCommentState.value) target = editPicture.value;
|
||||
else {
|
||||
if (i != undefined) target = commentList.value[index].child[i]["picture"];
|
||||
else if (index != undefined) target = commentList.value[index]["picture"];
|
||||
else target = picture.value;
|
||||
}
|
||||
|
||||
console.log("target", target);
|
||||
|
||||
if (target.length >= maxPicture.value) {
|
||||
creationAlertBox("error", `最多只能上传 ${maxPicture.value} 张图片`);
|
||||
return;
|
||||
}
|
||||
|
||||
const reader = new FileReader();
|
||||
reader.onload = (e) => {
|
||||
const base64 = e.target.result;
|
||||
uploadImg(file).then((res) => {
|
||||
const obj = {
|
||||
base64,
|
||||
...res,
|
||||
aid: res.aid || "",
|
||||
url: res.url || "",
|
||||
};
|
||||
if (editCommentState.value) editPicture.value = obj;
|
||||
target.push(obj);
|
||||
|
||||
if (editCommentState.value) editPicture.value = target;
|
||||
else {
|
||||
if (i != undefined) commentList.value[index].child[i]["picture"] = obj;
|
||||
else if (index != undefined) commentList.value[index]["picture"] = obj;
|
||||
else picture.value = obj;
|
||||
if (i != undefined) commentList.value[index].child[i]["picture"] = target;
|
||||
else if (index != undefined) commentList.value[index]["picture"] = target;
|
||||
else picture.value = target;
|
||||
}
|
||||
ElMessage.success("上传成功");
|
||||
});
|
||||
@@ -880,12 +922,22 @@ const handleFileUpload = (event, index, i) => {
|
||||
};
|
||||
|
||||
// 删除上传的图片
|
||||
const closeFileUpload = (index, i) => {
|
||||
if (i != undefined) commentList.value[index].child[i]["picture"] = {};
|
||||
else if (index != undefined) commentList.value[index]["picture"] = {};
|
||||
else picture.value = {};
|
||||
const closeFileUpload = (aid, index, i) => {
|
||||
let target = [];
|
||||
|
||||
if (i != undefined) target = [...commentList.value[index].child[i]["picture"]];
|
||||
else if (index != undefined) target = [...commentList.value[index]["picture"]];
|
||||
else target = [...picture.value];
|
||||
|
||||
let sub = target.findIndex((item) => item.aid == aid);
|
||||
if (sub != -1) target.splice(sub, 1);
|
||||
if (i != undefined) commentList.value[index].child[i]["picture"] = target;
|
||||
else if (index != undefined) commentList.value[index]["picture"] = target;
|
||||
else picture.value = target;
|
||||
};
|
||||
|
||||
const closePictureUpload = (index) => picture.value.splice(index, 1);
|
||||
|
||||
// 上传图片 获取图片url
|
||||
const uploadImg = (file) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
@@ -1100,15 +1152,18 @@ defineExpose({ changeCommentVoteoption, wipeCommentVoteoption, reviewsComment, b
|
||||
.automatic-reviews-popup {
|
||||
border-radius: 10px !important;
|
||||
padding: 0 !important;
|
||||
|
||||
.automatic-header {
|
||||
padding: 20px;
|
||||
border-bottom: 1px dotted #ebebeb;
|
||||
|
||||
.automatic-title {
|
||||
font-weight: 650;
|
||||
font-size: 18px;
|
||||
color: #000000;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.automatic-have {
|
||||
background-color: rgba(246, 246, 246, 1);
|
||||
font-size: 12px;
|
||||
@@ -1131,9 +1186,11 @@ defineExpose({ changeCommentVoteoption, wipeCommentVoteoption, reviewsComment, b
|
||||
width: fit-content;
|
||||
}
|
||||
}
|
||||
|
||||
.automatic-bottom {
|
||||
justify-content: flex-end;
|
||||
padding: 0 10px 10px;
|
||||
|
||||
.automatic-send {
|
||||
background-color: var(--main-color);
|
||||
color: #fff;
|
||||
@@ -1148,15 +1205,18 @@ defineExpose({ changeCommentVoteoption, wipeCommentVoteoption, reviewsComment, b
|
||||
|
||||
.emoji-popover {
|
||||
box-sizing: border-box;
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
padding: 0px !important;
|
||||
border-radius: 10px !important;
|
||||
border: 1px solid #ebebeb !important;
|
||||
|
||||
.el-popper__arrow {
|
||||
z-index: 1;
|
||||
|
||||
&:before {
|
||||
background-color: #fff;
|
||||
border-top-color: #fff !important;
|
||||
|
||||
@@ -37,5 +37,6 @@ onUnmounted(() => {
|
||||
transform: translate(-50%, -50%);
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
z-index: 10;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -11,22 +11,26 @@ export const detailsHttp = (query) => {
|
||||
|
||||
// 详情数据 - 获取评论数据
|
||||
export const commentListHttp = (params) => {
|
||||
return Http.post("/api/comment/lists", params);
|
||||
// return Http.post("/api/comment/lists", params);
|
||||
return Http.get("https://api.gter.net/v2/api/forum/getCommentList", params);
|
||||
};
|
||||
|
||||
// 评论相关 - 评论点赞
|
||||
export const detailsLikeCommentHttp = (query) => {
|
||||
return Http.post("/api/comment/like", query);
|
||||
// return Http.post("/api/comment/like", query);
|
||||
return Http.post("https://api.gter.net/v2/api/forum/likeComment", query);
|
||||
};
|
||||
|
||||
// 详情数据 - 获取子评论数据
|
||||
export const detailsChildCommentListHttp = (query) => {
|
||||
return Http.post("/api/comment/childrenList", query);
|
||||
// return Http.post("/api/comment/childrenList", query);
|
||||
return Http.post("https://api.gter.net/v2/api/forum/childrenList", query);
|
||||
};
|
||||
|
||||
// 详情数据 - 提交评论
|
||||
export const detailsSubmitommentListHttp = (query) => {
|
||||
return Http.post("/api/comment/submit", query);
|
||||
// return Http.post("/api/comment/submit", query);
|
||||
return Http.postV2("https://api.gter.net/v2/api/forum/postComment", query);
|
||||
};
|
||||
|
||||
// 详情数据 - 提交评论
|
||||
@@ -56,12 +60,14 @@ export const deleteHttp = (query) => {
|
||||
|
||||
// 操作-点赞
|
||||
export const operateLikeHttp = (query) => {
|
||||
return Http.post("/api/operate/like", query);
|
||||
// return Http.post("/api/operate/like", query);
|
||||
return Http.post("https://api.gter.net/v2/api/forum/postTopicLike", query);
|
||||
};
|
||||
|
||||
// 数据操作 - 收藏
|
||||
export const operateCollectHttp = (query) => {
|
||||
return Http.post("/api/operate/collect", query);
|
||||
// return Http.post("/api/operate/collect", query);
|
||||
return Http.post("https://api.gter.net/v2/api/forum/postTopicCollect", query);
|
||||
};
|
||||
|
||||
// 数据操作 - 投票操作
|
||||
@@ -101,7 +107,8 @@ export const MyUserCollectHttp = (query) => {
|
||||
|
||||
// 评论相关 - 举报 Comment related
|
||||
export const commentReportHttp = (query) => {
|
||||
return Http.post("/api/comment/report", query);
|
||||
// return Http.post("/api/comment/report", query);
|
||||
return Http.postV2("https://api.gter.net/v2/api/forum/postTopicReport", query);
|
||||
};
|
||||
|
||||
// 回应相关 - 回应列表
|
||||
@@ -130,3 +137,28 @@ export const commonUploadConfigHttp = (query) => {
|
||||
export const commentDeleteHttp = (query) => {
|
||||
return Http.post("/api/comment/commentDelete", query);
|
||||
};
|
||||
|
||||
// 详情数据 - 投票详情
|
||||
export const topicDetailHttp = (query) => {
|
||||
return Http.get("https://api.gter.net/v2/api/forum/getTopicDetails", query);
|
||||
};
|
||||
|
||||
export const topicRecommendHttp = (query) => {
|
||||
return Http.post("https://api.gter.net/v2/api/forum/setTopicRecommend", query);
|
||||
};
|
||||
|
||||
export const topicEssenceHttp = (query) => {
|
||||
return Http.post("https://api.gter.net/v2/api/forum/setTopicBest", query);
|
||||
};
|
||||
|
||||
export const topicDeleteHttp = (query) => {
|
||||
return Http.del("https://api.gter.net/v2/api/forum/deleteTopic", query);
|
||||
};
|
||||
|
||||
export const topicHideHttp = (query) => {
|
||||
return Http.post("https://api.gter.net/v2/api/forum/setTopicHide", query);
|
||||
};
|
||||
|
||||
export const topicgetOperationHttp = (query) => {
|
||||
return Http.post("https://api.gter.net/v2/api/forum/getTopicOperation", query);
|
||||
};
|
||||
|
||||
@@ -1,115 +1,256 @@
|
||||
// 处理时间
|
||||
export const handleDate = (dateTimeStamp = new Date()) => {
|
||||
dateTimeStamp = dateTimeStamp ? dateTimeStamp : null
|
||||
if (!dateTimeStamp) return '刚刚'
|
||||
var timestamp = new Date(dateTimeStamp)
|
||||
timestamp = timestamp.getTime()
|
||||
var minute = 1000 * 60
|
||||
var hour = minute * 60
|
||||
var day = hour * 24
|
||||
var now = new Date().getTime()
|
||||
var diffValue = now - timestamp
|
||||
var result
|
||||
if (diffValue < 0) return
|
||||
dateTimeStamp = dateTimeStamp ? dateTimeStamp : null;
|
||||
if (!dateTimeStamp) return "刚刚";
|
||||
var timestamp = new Date(dateTimeStamp);
|
||||
timestamp = timestamp.getTime();
|
||||
var minute = 1000 * 60;
|
||||
var hour = minute * 60;
|
||||
var day = hour * 24;
|
||||
var now = new Date().getTime();
|
||||
var diffValue = now - timestamp;
|
||||
var result;
|
||||
if (diffValue < 0) return;
|
||||
|
||||
var dayC = diffValue / day
|
||||
var hourC = diffValue / (hour + 1)
|
||||
var minC = diffValue / minute
|
||||
var dayC = diffValue / day;
|
||||
var hourC = diffValue / (hour + 1);
|
||||
var minC = diffValue / minute;
|
||||
if (dayC >= 7) {
|
||||
let date = new Date(timestamp)
|
||||
let Y = date.getFullYear() + "-"
|
||||
let M = (date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1) + "-"
|
||||
let D = (date.getDate() < 10 ? "0" + date.getDate() : date.getDate()) + " "
|
||||
let date = new Date(timestamp);
|
||||
let Y = date.getFullYear() + "-";
|
||||
let M = (date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1) + "-";
|
||||
let D = (date.getDate() < 10 ? "0" + date.getDate() : date.getDate()) + " ";
|
||||
// let h = (date.getHours() < 10 ? "0" + date.getHours() : date.getHours()) + ":"
|
||||
// let m = date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes()
|
||||
result = "" + Y + M + D
|
||||
} else if (dayC >= 1) result = "" + Math.round(dayC) + "天前"
|
||||
else if (hourC >= 1) result = "" + Math.round(hourC) + "小时前"
|
||||
else if (minC >= 1) result = "" + Math.round(minC) + "分钟前"
|
||||
else result = "刚刚"
|
||||
result = "" + Y + M + D;
|
||||
} else if (dayC >= 1) result = "" + Math.round(dayC) + "天前";
|
||||
else if (hourC >= 1) result = "" + Math.round(hourC) + "小时前";
|
||||
else if (minC >= 1) result = "" + Math.round(minC) + "分钟前";
|
||||
else result = "刚刚";
|
||||
|
||||
return result
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
// 处理 截止时间
|
||||
export const handleDeadline = (dateTimeStamp = new Date()) => {
|
||||
if (typeof dateTimeStamp == "number") dateTimeStamp = dateTimeStamp ? dateTimeStamp * 1000 : null
|
||||
if (typeof dateTimeStamp == "number") dateTimeStamp = dateTimeStamp ? dateTimeStamp * 1000 : null;
|
||||
if (typeof dateTimeStamp == "string" && dateTimeStamp.match(/^\d{4}-\d{2}-\d{2}$/)) dateTimeStamp += " 23:59:59";
|
||||
|
||||
var timestamp = new Date(dateTimeStamp);
|
||||
timestamp = timestamp.getTime();
|
||||
var minute = 1000 * 60;
|
||||
var hour = minute * 60;
|
||||
var day = hour * 24;
|
||||
var now = new Date().getTime();
|
||||
var diffValue = timestamp - now;
|
||||
var result;
|
||||
if (diffValue < 0) return "投票已";
|
||||
|
||||
var timestamp = new Date(dateTimeStamp)
|
||||
timestamp = timestamp.getTime()
|
||||
var minute = 1000 * 60
|
||||
var hour = minute * 60
|
||||
var day = hour * 24
|
||||
var now = new Date().getTime()
|
||||
var diffValue = timestamp - now
|
||||
var result
|
||||
if (diffValue < 0) return "投票已"
|
||||
var dayC = diffValue / day;
|
||||
var hourC = diffValue / (hour + 1);
|
||||
var minC = diffValue / minute;
|
||||
if (dayC >= 1) result = "" + Math.round(dayC) + "天后";
|
||||
else if (hourC >= 1) result = "" + Math.round(hourC) + "小时后";
|
||||
else if (minC >= 1) result = "" + Math.round(minC) + "分钟后";
|
||||
|
||||
var dayC = diffValue / day
|
||||
var hourC = diffValue / (hour + 1)
|
||||
var minC = diffValue / minute
|
||||
if (dayC >= 1) result = "" + Math.round(dayC) + "天后"
|
||||
else if (hourC >= 1) result = "" + Math.round(hourC) + "小时后"
|
||||
else if (minC >= 1) result = "" + Math.round(minC) + "分钟后"
|
||||
|
||||
return result
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
export const timestampToDate = (timestamp) => {
|
||||
var date = new Date(timestamp);
|
||||
var year = date.getFullYear();
|
||||
var month = ("0" + (date.getMonth() + 1)).slice(-2); // Months are zero based. Add leading 0.
|
||||
var day = ("0" + date.getDate()).slice(-2); // Add leading 0.
|
||||
var day = ("0" + date.getDate()).slice(-2); // Add leading 0.
|
||||
return `${year}-${month}-${day}`;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// isblank 是否需要 新标签页 默认是新标签页
|
||||
export const goToURL = (url, isblank = true) => {
|
||||
if (typeof document !== "object") return
|
||||
if (typeof document !== "object") return;
|
||||
|
||||
let aTab = document.createElement('a')
|
||||
document.body.appendChild(aTab)
|
||||
aTab.setAttribute('href', url)
|
||||
if (isblank) aTab.setAttribute('target', "_blank")
|
||||
aTab.click()
|
||||
}
|
||||
let aTab = document.createElement("a");
|
||||
document.body.appendChild(aTab);
|
||||
aTab.setAttribute("href", url);
|
||||
if (isblank) aTab.setAttribute("target", "_blank");
|
||||
aTab.click();
|
||||
};
|
||||
|
||||
export const colourValue = [{
|
||||
main: "rgba(44, 186, 230, 1)",
|
||||
bg: "rgba(234, 245, 248, 1)",
|
||||
bc: "rgba(213, 235, 242, 1)",
|
||||
}, {
|
||||
main: "rgba(49, 215, 46, 1)",
|
||||
bg: "rgba(244, 247, 244, 1)",
|
||||
bc: "rgba(225, 244, 225, 1)",
|
||||
}, {
|
||||
main: "rgba(106, 117, 217, 1)",
|
||||
bg: "rgba(237, 238, 247, 1)",
|
||||
bc: "rgba(227, 228, 246, 1)",
|
||||
}, {
|
||||
main: "rgba(172, 183, 46, 1)",
|
||||
bg: "rgba(245, 246, 228, 1)",
|
||||
bc: "rgba(238, 238, 215, 1)",
|
||||
}, {
|
||||
main: "rgba(38, 223, 190, 1)",
|
||||
bg: "rgba(237, 247, 245, 1)",
|
||||
bc: "rgba(220, 244, 239, 1)",
|
||||
}, {
|
||||
main: "rgba(242, 122, 71, 1)",
|
||||
bg: "rgba(255, 244, 239, 1)",
|
||||
bc: "rgba(249, 231, 224, 1)",
|
||||
}]
|
||||
export const colourValue = [
|
||||
{
|
||||
main: "rgba(44, 186, 230, 1)",
|
||||
bg: "rgba(234, 245, 248, 1)",
|
||||
bc: "rgba(213, 235, 242, 1)",
|
||||
},
|
||||
{
|
||||
main: "rgba(49, 215, 46, 1)",
|
||||
bg: "rgba(244, 247, 244, 1)",
|
||||
bc: "rgba(225, 244, 225, 1)",
|
||||
},
|
||||
{
|
||||
main: "rgba(106, 117, 217, 1)",
|
||||
bg: "rgba(237, 238, 247, 1)",
|
||||
bc: "rgba(227, 228, 246, 1)",
|
||||
},
|
||||
{
|
||||
main: "rgba(172, 183, 46, 1)",
|
||||
bg: "rgba(245, 246, 228, 1)",
|
||||
bc: "rgba(238, 238, 215, 1)",
|
||||
},
|
||||
{
|
||||
main: "rgba(38, 223, 190, 1)",
|
||||
bg: "rgba(237, 247, 245, 1)",
|
||||
bc: "rgba(220, 244, 239, 1)",
|
||||
},
|
||||
{
|
||||
main: "rgba(242, 122, 71, 1)",
|
||||
bg: "rgba(255, 244, 239, 1)",
|
||||
bc: "rgba(249, 231, 224, 1)",
|
||||
},
|
||||
];
|
||||
|
||||
export const base62ToDecimal = base62 => {
|
||||
const base = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
let decimal = 0
|
||||
export const base62ToDecimal = (base62) => {
|
||||
const base = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
let decimal = 0;
|
||||
|
||||
for (let i = 0; i < base62.length; i++) {
|
||||
decimal += base.indexOf(base62[i]) * Math.pow(62, base62.length - i - 1)
|
||||
decimal += base.indexOf(base62[i]) * Math.pow(62, base62.length - i - 1);
|
||||
}
|
||||
|
||||
return decimal
|
||||
}
|
||||
return decimal;
|
||||
};
|
||||
|
||||
export const managerHide = (token, state, type = "offer") => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const obj = {
|
||||
offer: "Offer",
|
||||
offer_summary: "总结",
|
||||
interviewexperience: "面经",
|
||||
thread: "帖子",
|
||||
question: "帖子",
|
||||
vote: "投票",
|
||||
};
|
||||
|
||||
const isConfirmed = confirm(`确定要${state == 0 ? "隐藏" : "显示"}该${obj[type]}吗?`);
|
||||
if (isConfirmed) {
|
||||
topicHideHttp({
|
||||
token,
|
||||
hidden: Number(state !== 1),
|
||||
}).then((res) => {
|
||||
const data = res.data;
|
||||
creationAlertBox("success", res.message || "");
|
||||
resolve(data.hidden);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 推荐
|
||||
export const managerRecommend = (token, state) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const post = () => {
|
||||
topicRecommendHttp({
|
||||
token,
|
||||
recommend: state == 1 ? 0 : 1,
|
||||
}).then((res) => {
|
||||
const data = res.data;
|
||||
creationAlertBox("success", res.message || "");
|
||||
resolve(data.recommend);
|
||||
});
|
||||
};
|
||||
|
||||
if (state == 1) {
|
||||
const isConfirmed = confirm(`确定要取消推荐吗?`);
|
||||
if (isConfirmed) post();
|
||||
else resolve(state);
|
||||
} else post();
|
||||
});
|
||||
};
|
||||
|
||||
// 精华
|
||||
export const managerEssence = (token, state) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const post = () => {
|
||||
topicEssenceHttp({
|
||||
token,
|
||||
best: state == 1 ? 0 : 1,
|
||||
}).then((res) => {
|
||||
const data = res.data;
|
||||
creationAlertBox("success", res.message || "");
|
||||
resolve(data.best);
|
||||
});
|
||||
};
|
||||
|
||||
if (state == 1) {
|
||||
const isConfirmed = confirm(`确定要取消精华吗?`);
|
||||
if (isConfirmed) post();
|
||||
else resolve(state);
|
||||
} else post();
|
||||
});
|
||||
};
|
||||
|
||||
// 删除
|
||||
export const managerDelete = (token) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const post = () => {
|
||||
topicDeleteHttp({
|
||||
token,
|
||||
}).then((res) => {
|
||||
creationAlertBox("success", res.message || "");
|
||||
resolve();
|
||||
});
|
||||
};
|
||||
|
||||
const isConfirmed = confirm(`确定要删除吗?`);
|
||||
if (!isConfirmed) reject();
|
||||
else post();
|
||||
});
|
||||
};
|
||||
|
||||
export const strtimeago = (dateStr, type = 1) => {
|
||||
dateStr = dateStr + ""; // 反之传入的不是字符串
|
||||
dateStr = dateStr.replaceAll("-", "/"); // 修改格式
|
||||
var minute = 1000 * 60; // 把分,时,天,周,半个月,一个月用毫秒表示
|
||||
var hour = minute * 60;
|
||||
var day = hour * 24;
|
||||
var now = new Date().getTime(); // 获取当前时间毫秒
|
||||
let objectTime = new Date(dateStr).getTime();
|
||||
var diffValue = now - objectTime; // 时间差
|
||||
if (diffValue < 0) return "刚刚";
|
||||
|
||||
var minC = diffValue / minute; // 计算时间差的分,时,天,周,月
|
||||
var hourC = diffValue / hour;
|
||||
var dayC = diffValue / day;
|
||||
|
||||
const diffInMilliseconds = now - objectTime;
|
||||
const diffInYears = diffInMilliseconds / (1000 * 60 * 60 * 24 * 365);
|
||||
const diffInMonths = diffInYears * 12;
|
||||
|
||||
let result = "";
|
||||
if (dayC >= 7) {
|
||||
var datetime = new Date(dateStr);
|
||||
var Nyear = datetime.getFullYear();
|
||||
var Nmonth = datetime.getMonth() + 1 < 10 ? "0" + (datetime.getMonth() + 1) : datetime.getMonth() + 1;
|
||||
var Ndate = datetime.getDate() < 10 ? "0" + datetime.getDate() : datetime.getDate();
|
||||
var Nhour = datetime.getHours() < 10 ? "0" + datetime.getHours() : datetime.getHours();
|
||||
var Nmin = datetime.getMinutes() < 10 ? "0" + datetime.getMinutes() : datetime.getMinutes();
|
||||
if (type == 4) {
|
||||
if (new Date().getFullYear() !== Nyear) result = `${Nyear}年${Nmonth}月${Ndate}日`;
|
||||
else result = `${Nmonth}月${Ndate}日 ${Nhour}:${Nmin}`;
|
||||
}
|
||||
if (type == 1) result = Nyear + "-" + Nmonth + "-" + Ndate;
|
||||
if (type == 2) {
|
||||
result = `${Nmonth}月${Ndate}日 ${Nhour}:${Nmin}`;
|
||||
if (new Date().getFullYear() !== Nyear) result = `${Nyear}年${result}`;
|
||||
}
|
||||
if (type == 3) {
|
||||
if (diffInYears >= 1) result = Math.floor(diffInYears) + "年前";
|
||||
else if (diffInMonths >= 1) result = Math.floor(diffInMonths) + "个月前";
|
||||
else result = parseInt(dayC) + "天前";
|
||||
}
|
||||
} else if (dayC >= 1) result = parseInt(dayC) + "天前";
|
||||
else if (hourC >= 1 && hourC <= 24) result = parseInt(hourC) + "小时前";
|
||||
else if (minC >= 1 && minC <= 60) result = parseInt(minC) + "分钟前";
|
||||
else result = "刚刚";
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<template>
|
||||
|
||||
<Head>
|
||||
<Title>{{ `${seo["title"] || "投票"} - 寄托天下出国留学网` }}</Title>
|
||||
<Meta name="keyword" :content="seo['keyword']" />
|
||||
@@ -7,13 +8,39 @@
|
||||
<TopHead ref="topHeadRef"></TopHead>
|
||||
<div class="content flexflex" :style="{ '--main-color': colourValue[uniqidIndex]['main'], '--bg-color': colourValue[uniqidIndex]['bg'], '--bc-color': colourValue[uniqidIndex]['bc'] }">
|
||||
<div class="header flexflex">
|
||||
<div class="label flexflex" v-if="sectionn?.length || tags?.length || info.recommend == 1 || info.best == 1">
|
||||
<img class="item icon" v-if="info.recommend == 1" src="@/assets/img/recommend-icon.png" />
|
||||
<img class="item icon" v-if="info.best == 1" src="@/assets/img/essence-icon.png" />
|
||||
<a class="item blue" v-for="(item, index) in sectionn" :key="item" :href="'/section/' + item.uniqid" target="_blank">{{ item.name }}</a>
|
||||
<a class="item" v-for="(item, index) in tags" :key="item" :href="'/tag/' + item" target="_blank">{{ item }}</a>
|
||||
<div class="label flexflex" v-if="sectionn?.length || tags?.length || topicInfo.recommend == 1 || topicInfo.best == 1">
|
||||
<img class="item icon" v-if="topicInfo.recommend == 1" src="@/assets/img/recommend-icon.png" />
|
||||
<img class="item icon" v-if="topicInfo.best == 1" src="@/assets/img/essence-icon.png" />
|
||||
<a class="item blue" v-for="(item, index) in sectionn" :key="item" :href="`https://f.gter.net/section/${item.uniqid}`" target="_blank">{{ item.name }}</a>
|
||||
<a class="item" v-for="(item, index) 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="flex1">{{ info.title }}</div>
|
||||
<div class="view flexacenter">
|
||||
<img class="icon" src="@/assets/img/eye-icon.svg" />
|
||||
<div class="text">{{ topicInfo.views }}</div>
|
||||
</div>
|
||||
|
||||
<div class="btn flexcenter" @click.stop="cutShow">
|
||||
<img class="icon" src="@/assets/img/dot-dot-dot-gray.png" />
|
||||
</div>
|
||||
|
||||
<div v-if="show">
|
||||
<div class="mask" @click.stop="cutShow"></div>
|
||||
<div class="operate">
|
||||
<div class="item" @click.stop="report">举报</div>
|
||||
<template v-if="ismanager">
|
||||
<div class="item" @click.stop="hide">{{ topicInfo.hidden == 0 ? "隐藏" : "显示" }}</div>
|
||||
<div class="item" @click.stop="recommend">{{ topicInfo.recommend == 1 ? "取消" : "" }}推荐</div>
|
||||
<div class="item" @click.stop="essence">{{ topicInfo.best == 1 ? "取消" : "" }}精华</div>
|
||||
</template>
|
||||
|
||||
<template v-if="ismyself">
|
||||
<div class="item" @click.stop="deleteItem">删除</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span>{{ info.title }}</span>
|
||||
</div>
|
||||
<div class="left">
|
||||
<div class="info flexacenter">
|
||||
@@ -96,8 +123,7 @@
|
||||
回应
|
||||
<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>
|
||||
@@ -125,7 +151,7 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<DetailsComments ref="commentsRef" :token="token" @update:commentComments="commentComments = $event"></DetailsComments>
|
||||
<DetailsComments ref="commentsRef" :token="topicToken" @update:commentComments="commentComments = $event"></DetailsComments>
|
||||
</div>
|
||||
<DetailsArea @closeDiscussInputFields="closeDiscussInputFields" :ripostecount="ripostecount" :commentComments="commentComments"></DetailsArea>
|
||||
</div>
|
||||
@@ -147,8 +173,7 @@
|
||||
</div>
|
||||
<template v-else>
|
||||
<div class="respond-pop-title">
|
||||
共<span class="respond-pop-amount">{{ ripostecount.user }}</span
|
||||
>人回应
|
||||
共<span class="respond-pop-amount">{{ ripostecount.user }}</span>人回应
|
||||
<img class="respond-title-icon" @click="closePopList()" src="@/assets/img/cross-grey.png" />
|
||||
</div>
|
||||
<div class="respond-list">
|
||||
@@ -166,6 +191,9 @@
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<Report v-if="reportAlertShow" :reportToken="reportToken"></Report>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
@@ -414,9 +442,9 @@ const getDetails = async () => {
|
||||
info.value = data["info"];
|
||||
|
||||
isvote.value = data["isvote"];
|
||||
iscollection.value = data["iscollection"];
|
||||
islike.value = data["islike"];
|
||||
ismyself.value = data["ismyself"];
|
||||
// iscollection.value = data["iscollection"];
|
||||
// islike.value = data["islike"];
|
||||
// ismyself.value = data["ismyself"];
|
||||
option.value = data["option"];
|
||||
qrcode.value = data.share?.qrcode;
|
||||
token.value = data["token"];
|
||||
@@ -429,9 +457,77 @@ const getDetails = async () => {
|
||||
});
|
||||
|
||||
getRiposte();
|
||||
|
||||
const topic = data.topic
|
||||
console.log("topic", topic);
|
||||
getTopicDetail(topic.uniqid);
|
||||
});
|
||||
};
|
||||
|
||||
let topicToken = ref("");
|
||||
let topicInfo = ref({});
|
||||
let sectionn = ref([]);
|
||||
let tags = ref([]);
|
||||
|
||||
provide("topicInfo", topicInfo);
|
||||
|
||||
provide("topicToken", topicToken);
|
||||
|
||||
const getTopicDetail = (uniqid) => {
|
||||
topicDetailHttp({ uniqid }).then((res) => {
|
||||
if (res.code != 200) {
|
||||
ElMessage.error(res.message);
|
||||
return;
|
||||
}
|
||||
let data = res.data;
|
||||
topicToken.value = data.token;
|
||||
console.log("topicDetail", data);
|
||||
|
||||
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));
|
||||
tags.value = newTag;
|
||||
}
|
||||
|
||||
sectionn.value = targetInfo.sectionn;
|
||||
|
||||
|
||||
topicInfo.value = targetInfo;
|
||||
|
||||
// ismyself.value = data.ismyself;
|
||||
|
||||
|
||||
if (data.islogin) getTopicOperation();
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
const getTopicOperation = () => {
|
||||
topicgetOperationHttp({
|
||||
token: topicToken.value,
|
||||
actions: ["like", "collection"],
|
||||
})
|
||||
.then((res) => {
|
||||
console.log("res", res);
|
||||
|
||||
const data = res.data;
|
||||
const like = data.like;
|
||||
const collection = data.collection;
|
||||
|
||||
islike.value = like.status;
|
||||
iscollection.value = collection.status;
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log("err", err);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
provide("getDetails", getDetails);
|
||||
|
||||
// 点击发送信息
|
||||
@@ -447,10 +543,10 @@ const TAHomePage = (uin) => {
|
||||
};
|
||||
|
||||
// 跳转 url
|
||||
const redirectToExternalWebsite = (url) => {
|
||||
const redirectToExternalWebsite = (url, target = "_blank") => {
|
||||
const link = document.createElement("a");
|
||||
link.href = url;
|
||||
link.target = "_blank";
|
||||
link.target = target;
|
||||
link.click();
|
||||
};
|
||||
|
||||
@@ -688,6 +784,68 @@ const selectEomjiListPop = (key) => {
|
||||
});
|
||||
};
|
||||
|
||||
let show = ref(false);
|
||||
let ismanager = inject("ismanager");
|
||||
const cutShow = () => {
|
||||
show.value = !show.value; // 修改为切换显示状态
|
||||
};
|
||||
|
||||
let reportAlertShow = ref(false);
|
||||
let reportToken = ref("");
|
||||
provide("reportAlertShow", reportAlertShow);
|
||||
|
||||
// 点击打开举报
|
||||
const report = (token) => {
|
||||
if (isNeedLogin.value) {
|
||||
goLogin();
|
||||
return;
|
||||
}
|
||||
|
||||
cutShow()
|
||||
reportToken.value = topicToken.value;
|
||||
reportAlertShow.value = true;
|
||||
};
|
||||
|
||||
|
||||
// 隐藏
|
||||
const hide = () => {
|
||||
const target = topicInfo.value;
|
||||
managerHide(topicToken.value, target.hidden, "vote").then((value) => {
|
||||
target.hidden = value;
|
||||
topicInfo.value = target;
|
||||
cutShow();
|
||||
});
|
||||
};
|
||||
|
||||
// 推荐
|
||||
const recommend = () => {
|
||||
const target = topicInfo.value;
|
||||
managerRecommend(topicToken.value, target.recommend).then((value) => {
|
||||
target.recommend = value;
|
||||
topicInfo.value = target;
|
||||
cutShow();
|
||||
});
|
||||
};
|
||||
|
||||
// 精华
|
||||
const essence = () => {
|
||||
const target = topicInfo.value;
|
||||
managerEssence(topicToken.value, target.best).then((value) => {
|
||||
target.best = value;
|
||||
topicInfo.value = target;
|
||||
cutShow();
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
const deleteItem = () => {
|
||||
managerDelete(token)
|
||||
.then(() => redirectToExternalWebsite("/", "_self"))
|
||||
.finally(() => cutShow());
|
||||
};
|
||||
|
||||
|
||||
|
||||
const { $cache } = useNuxtApp();
|
||||
|
||||
try {
|
||||
@@ -716,7 +874,7 @@ try {
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (error) {}
|
||||
} catch (error) { }
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
@@ -727,11 +885,13 @@ try {
|
||||
.default-popup {
|
||||
.el-dialog__header {
|
||||
padding: 0;
|
||||
|
||||
.el-dialog__headerbtn {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
}
|
||||
}
|
||||
|
||||
.el-dialog__body {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ axios.interceptors.request.use(
|
||||
async (config) => {
|
||||
// 开发时登录用的,可以直接替换小程序的 authorization
|
||||
if (process.env.NODE_ENV !== "production") {
|
||||
const miucms_session = "20c7981bcd7b24e373e462ee60a8d326";
|
||||
const miucms_session = "01346a38444d71aaadb3adad52b52c39";
|
||||
document.cookie = "miucms_session=" + miucms_session;
|
||||
config["headers"]["authorization"] = miucms_session;
|
||||
}
|
||||
@@ -98,6 +98,26 @@ const postV2 = (url, params) => {
|
||||
});
|
||||
};
|
||||
|
||||
const del = (url, params) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
//是将对象 序列化成URL的形式,以&进行拼接
|
||||
axios
|
||||
.delete(url, params)
|
||||
.then((res) => {
|
||||
let data = res.data;
|
||||
if (data.code == 401 && !process.server) goLogin();
|
||||
resolve(data);
|
||||
})
|
||||
.catch((err) => {
|
||||
if (err.data.code == 401) {
|
||||
goLogin();
|
||||
resolve(err.data);
|
||||
} else reject(err.data);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// 打开登录
|
||||
const goLogin = () => {
|
||||
if (typeof ajax_login === "function") ajax_login();
|
||||
@@ -107,4 +127,5 @@ export default {
|
||||
get,
|
||||
post,
|
||||
postV2,
|
||||
del,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user