talk_appAmin/pages/post/postInfo/postInfo.vue

786 lines
20 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<view>
<PostView :postValue="postValue" :postViewIndex="4" :postViewType="1"></PostView>
<view class="center-content-focus-line"></view>
<view class="comment" v-if="postValue.status == 0">
<view class="flex justifyBetween alignCenter commentTop">
<text class="commentLabel">{{"全部评论" + (postValue.commentCount != 0 ? "" + postValue.commentCount + "" : "")}}</text>
<text class="report">举报</text>
</view>
<view v-if="!postCommentList.length" class="no-comment">
<image class="no-comment-img" src="../../../static/images/icon/no_comment.png" mode=""></image>
<text class="no-comment-text">暂无评论,快去做评论第一人吧!</text>
<view class="no-comment-bt">
<text class="no-comment-bt-text" @click="toInput()">快去抢沙发</text>
</view>
</view>
<view v-else class="have-comment" v-for="(item, index) in postCommentList" :key="index">
<view class="flex alignCenter">
<!-- 头像 -->
<view class="have-comment-avatar-container">
<u-avatar class="have-comment-avatar-1" size="60rpx" :src="getAvatar(item.avatar)"></u-avatar>
<image v-if="item.isOfficial" class="have-comment-official-1"
src="../../../static/images/icon/tu3-6.png"></image>
</view>
<view class="flex flexColumn">
<text class="have-comment-uname">{{item.nickName}}</text>
<text class="have-comment-address">{{item.address}}</text>
</view>
</view>
<view class="have-comment-content">
<text class="have-comment-content-text-1">{{item.content}}</text>
<view class="have-comment-content-text-2">
<text>{{timeAgo(item.createTime)}}</text>
<text class="have-comment-content-text-2-hf" @click="toAnswerRoot(item, index)">回复</text>
</view>
</view>
<view class="" v-if="item.answerCommentAllCount != 0">
<view v-if="item.deployment" class="have-comment-answer"
v-for="(answer, answerIndex) in item.answerCommentList.slice(0, item.answerCommentDisplayCount)" :key="answerIndex">
<view class="flex alignCenter">
<!-- 头像 -->
<view class="have-comment-answer-avatar-container">
<u-avatar class="have-comment-answer-avatar-1" size="48rpx"
:src="getAvatar(answer.avatar)"></u-avatar>
<image v-if="answer.isOfficial" class="have-comment-answer-official-1"
src="../../../static/images/icon/tu3-6.png"></image>
</view>
<view class="flex alignCenter justifyBetween">
<text class="have-comment-answer-uname">{{answer.nickName}}</text>
<!-- <text v-if="answer.toUserName" class="have-comment-answer-uname">-></text> -->
<image v-if="answer.toUserName" class="have-comment-answer-uname-img"
src="../../../static/images/icon/ring-1.png"></image>
<text v-if="answer.toUserName"
class="have-comment-answer-uname">{{answer.toUserName}}</text>
</view>
</view>
<view class="have-comment-answer-content">
<text class="have-comment-answer-content-text-1">{{answer.content}}</text>
<view class="have-comment-answer-content-text-2">
<text>{{timeAgo(answer.createTime)}}</text>
<text class="have-comment-answer-content-text-2-hf"
@click="toAnswerSon(answer, index)">回复</text>
</view>
</view>
</view>
<view class="have-comment-answer-deploy flex alignCenter">
<up-line class="have-comment-answer-line" length="40rpx"></up-line>
<view class="have-comment-answer-deploy-1 flex alignCenter" @click="deploymentAnswer(index)"
v-if="!item.deployment">
<text class="deploymentAnswer-text">展开{{item.answerCommentAllCount}}条回复</text>
<image class="have-comment-answer-img-1" src="../../../static/images/icon/deployment-1.png"
mode=""></image>
</view>
<view class="have-comment-answer-deploy-1 flex alignCenter" @click="loadMoreAnswers(index)"
v-if="item.deployment && item.answerCommentDisplayCount < item.answerCommentAllCount">
<text class="deploymentAnswer-text">展开回复</text>
<image class="have-comment-answer-img-1" src="../../../static/images/icon/deployment-1.png"
mode=""></image>
</view>
<view class="have-comment-answer-deploy-1 flex alignCenter" v-if="item.deployment"
@click="putAnswer(index)">
<text class="deploymentAnswer-text">收起</text>
<image class="have-comment-answer-img-2" src="../../../static/images/icon/deployment-1.png"
mode=""></image>
</view>
</view>
</view>
<view class="have-comment-line">
</view>
</view>
</view>
</view>
<!-- 评论区输入框 -->
<up-popup :show="showInput" duration="0" @close="close" @open="open" class="comment-po">
<view class="flex justifyBetween comment-input" :style="{ marginBottom: bottomVal + 26 + 'px' }">
<view class="input-in flex alignCenter justifyCenter">
<input class="input-in-text" v-if="showInputText" focus="true" maxlength="55"
:placeholder="placeholderInput" @input="onKeyInput" :adjust-position="false" />
</view>
<view class="input-bt flex alignCenter justifyCenter">
<text class="input-bt-text" @click="send()">发送</text>
</view>
</view>
</up-popup>
<!-- 底部操作栏 -->
<up-tabbar :fixed="true" :placeholder="true" :safeAreaInsetBottom="true">
<!-- <view class="flex justifyCenter"> -->
<view class="flex alignCenter justifyCenter">
<view class="flex justifyCenter alignCenter commentInput" @click="toInput()">
<image class="commentInput-img-1" src="../../../static/images/icon/write-1.png" mode=""></image>
<text class="commentInput-text">友好评论~</text>
</view>
</view>
<view v-if="postValue.like" @click.stop="cancelCollection(postValue.id)"
class="flex alignCenter justifyCenter flexColumn">
<image class="commentInput-img" src="../../../static/images/icon/tu3-8.png" mode=""></image>
<text class="commentInput-txt-like">{{postValue.likeCount}}</text>
</view>
<view v-if="!postValue.like" @click.stop="addCollection(postValue.id)"
class="flex alignCenter justifyCenter flexColumn">
<image class="commentInput-img" src="../../../static/images/icon/tu3-7.png" mode=""></image>
<text class="commentInput-txt">{{postValue.likeCount}}</text>
</view>
<view v-if="postValue.favorite" @click.stop="cancelFavorite(postValue.id)"
class="flex flexColumn alignCenter justifyCenter ">
<image class="commentInput-img" src="../../../static/images/icon/tu3-2.png" mode=""></image>
<text class="commentInput-txt-favorite">{{postValue.favoriteCount}}</text>
</view>
<view v-if="!postValue.favorite" @click.stop="addFavorite(postValue.id)"
class="flex flexColumn alignCenter justifyCenter ">
<image class="commentInput-img" src="../../../static/images/icon/tu3-1.png" mode=""></image>
<text class="commentInput-txt">{{postValue.favoriteCount}}</text>
</view>
<view class="flex alignCenter justifyCenter flexColumn">
<image class="commentInput-img" src="../../../static/images/icon/tu2-9.png" mode=""></image>
<text class="commentInput-txt">转发</text>
</view>
<!-- </view> -->
</up-tabbar>
</template>
<script setup>
import {
ref,
reactive,
computed,
onMounted,
onBeforeUnmount,
getCurrentInstance
} from 'vue';
import {
useStore
} from 'vuex';
import {
onReachBottom,
onLoad,
onPageScroll
} from "@dcloudio/uni-app";
import PostView from "@/pages/common/postview/index.vue";
import {
listFollowUser,
getFollowUser,
delFollowUserByFollowUser,
addFollowUser,
updateFollowUser
} from "@/api/followUser/followUser";
import {
delLikeByPostLike,
addLike
} from "@/api/like/like";
import {
delPostFavoriteByPostFavorite,
addPostFavorite
} from "@/api/postFavorite/postFavorite";
import { listComment, getComment, delComment, addComment, updateComment } from "@/api/postComment/comment";
const bottomVal = ref(0);
const commentType = ref(0);
const toAnswerObj = ref([]);
const toAnswerIndex = ref(0);
const inputValue = ref("");
const loginUser = reactive(uni.getStorageSync('loginUserPost'));
const postValue = reactive(uni.getStorageSync('postInfo'));
const postCommentList = ref([]);
const total = ref(0);
const queryParams = reactive({
pageNum: 1,
pageSize: 10,
postId: null,
uid: null,
toUserId: null,
rootId: 0,
content: null,
hot: null,
type: null,
address: null,
});
const queryParamsSon = reactive({
pageNum: 1,
pageSize: 5,
postId: null,
uid: null,
toUserId: null,
rootId: 0,
content: null,
hot: null,
type: null,
address: null,
});
const getPostInfo = () => {
queryParams.postId = postValue.id;
listComment(queryParams).then(res => {
postCommentList.value = res.rows;
console.log(postCommentList.value[1].answerCommentList);
total.value = res.total
});
};
const store = useStore();
const QNDomain = store.state.user.QNDomain;
function getAvatar(avatar) {
return QNDomain + avatar;
}
function formatDate(input) {
const date = new Date(input);
if (isNaN(date)) {
throw new Error('Invalid date');
}
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return `${year}.${month}.${day}`;
}
function timeAgo(input) {
const date = new Date(input);
if (isNaN(date)) {
throw new Error('Invalid date');
}
const now = new Date();
const diff = now - date;
const minutes = Math.floor(diff / 60000); // 1 minute = 60000 ms
const hours = Math.floor(diff / 3600000); // 1 hour = 3600000 ms
const days = Math.floor(diff / 86400000); // 1 day = 86400000 ms
if (minutes < 60) {
return `${minutes}分钟前`;
} else if (hours < 24) {
return `${hours}小时前`;
} else if (days < 3) {
return `${days}天前`;
} else {
return formatDate(date);
}
}
// 监听键盘高度变化
onLoad(() => {
uni.pageScrollTo({
scrollTop: 0,
duration: 0
});
// if (!data.value) {
uni.onKeyboardHeightChange(res => {
if (res.height == 0) {
bottomVal.value = 0;
return;
}
bottomVal.value = res.height - 20;
console.log(bottomVal.value)
});
// }
})
onBeforeUnmount(async () => {
uni.offKeyboardHeightChange();
});
const placeholderInput = ref('')
// 创建响应式数据
const showInput = ref(false);
const showInputText = ref(false)
// 定义方法
function open() {
// 打开逻辑,比如设置 show 为 true
showInput.value = true;
setTimeout(() => {
showInputText.value = true;
}, 50);
// console.log('open');
}
function close() {
// 关闭逻辑,设置 show 为 false
showInput.value = false;
showInputText.value = false;
// console.log('close');
}
const toInput = () => {
placeholderInput.value = '发布评论'
commentType.value = 0;
open();
}
const toAnswerRoot = (answer, index) => {
toAnswerObj.value = answer;
toAnswerIndex.value = index;
placeholderInput.value = '回复:' + toAnswerObj.value.nickName;
commentType.value = 1;
open();
}
const toAnswerSon = (answer, index) => {
toAnswerObj.value = answer;
toAnswerIndex.value = index;
placeholderInput.value = '回复:' + toAnswerObj.value.nickName;
commentType.value = 2;
open();
}
const onKeyInput = (event) => {
console.log('输入的内容',event.detail.value);
inputValue.value = event.detail.value;
}
const send = () => {
const postComment = {
postId: postValue.id,
content: inputValue.value,
uid: loginUser.userId,
nickName: loginUser.nickName,
avatar: loginUser.avatar,
address: '天津',
rootId: null,
toUserId: null,
toUserName: null,
answerCommentAllCount: 0
};
if (commentType.value == 1) {
postComment.rootId = toAnswerObj.value.id;
}
if (commentType.value == 2) {
postComment.rootId = toAnswerObj.value.rootId;
postComment.toUserId = toAnswerObj.value.uid;
postComment.toUserName = toAnswerObj.value.nickName;
}
addComment(postComment).then(res => {
postComment.createTime = new Date();
if (commentType.value == 0) {
postCommentList.value.push(postComment);
} else if(commentType.value == 1 || commentType.value == 2) {
postCommentList.value[toAnswerIndex.value].answerCommentList.push(postComment);
postCommentList.value[toAnswerIndex.value].deployment = true;
postCommentList.value[toAnswerIndex.value].answerCommentDisplayCount += 1;
postCommentList.value[toAnswerIndex.value].answerCommentAllCount += 1;
}
postValue.commentCount += 1;
close();
})
}
const postListStorage = ref(uni.getStorageSync('postList'));
const upPostListStorage = () => {
postListStorage.value.forEach(item => {
if (item.id === postValue.id) {
Object.assign(item, postValue);
}
});
uni.setStorageSync('postList', postListStorage.value);
}
// 点赞操作
const cancelCollection = (postId) => {
const postLike = reactive({
likeId: postId,
})
delLikeByPostLike(postLike).then(res => {
postValue.likeCount -= 1;
postValue.like = !postValue.like;
upPostListStorage();
})
};
const addCollection = (postId) => {
const postLike = reactive({
likeId: postId,
})
addLike(postLike).then(res => {
postValue.likeCount += 1;
postValue.like = !postValue.like;
upPostListStorage();
})
};
// 收藏操作
const cancelFavorite = (postId) => {
const postFavorite = reactive({
favoriteId: postId,
})
delPostFavoriteByPostFavorite(postFavorite).then(res => {
postValue.favoriteCount -= 1;
postValue.favorite = !postValue.favorite;
upPostListStorage();
})
};
const addFavorite = (postId) => {
const postFavorite = reactive({
favoriteId: postId,
})
addPostFavorite(postFavorite).then(res => {
postValue.favoriteCount += 1;
postValue.favorite = !postValue.favorite;
upPostListStorage();
})
};
const deploymentAnswer = (index) => {
if (!postCommentList.value[index].deployment) {
postCommentList.value[index].deployment = true;
loadMoreAnswers(index);
}
};
const putAnswer = (index) => {
postCommentList.value[index].deployment = false;
postCommentList.value[index].answerCommentDisplayCount = 0;
postCommentList.value[index].answerCommentPage = 0;
postCommentList.value[index].answerCommentList = [];
};
const loadMoreAnswers = (index) => {
const increment = 5; // 每次加载的评论数量
const comment = postCommentList.value[index];
comment.answerCommentPage += 1;
queryParamsSon.postId = postValue.id;
queryParamsSon.rootId = comment.id;
queryParamsSon.pageNum = comment.answerCommentPage;
listComment(queryParamsSon).then(res => {
comment.answerCommentList.push(...res.rows);
});
if (comment.answerCommentDisplayCount + increment <= comment.answerCommentAllCount) {
comment.answerCommentDisplayCount += increment;
} else {
comment.answerCommentDisplayCount = comment.answerCommentAllCount; // 显示所有剩余的评论
}
if (comment.answerCommentDisplayCount == comment.answerCommentAllCount) {
comment.answerCommentList = comment.answerCommentList.filter(item => item.id != null);
}
};
getPostInfo();
</script>
<style lang="scss">
page {
background-color: #ffffff;
}
.data-v-6fcabaad {
border-radius: 20rpx 20rpx 20rpx 20rpx !important;
/* width: 200rpx !important;
height: 200rpx !important; */
}
.center-content-focus-line {
height: 8rpx;
background: #f4f5f6;
}
.comment {
padding: 32rpx;
}
.commentLabel {
font-weight: 400;
/* width: 265rpx; */
/* height: 38rpx; */
font-size: 36rpx;
/* text-align: left; */
color: #000000;
}
.report {
font-weight: 400;
/* width: 52rpx; */
/* height: 26rpx; */
font-size: 26rpx;
/* text-align: left; */
color: #999999;
}
.no-comment {
display: flex;
flex-direction: column;
align-items: center;
/* */
justify-content: center;
/* */
}
.no-comment-img {
margin-top: 44rpx;
width: 200rpx;
height: 145rpx;
}
.no-comment-text {
margin-top: 8rpx;
font-weight: 400;
font-size: 26rpx;
color: #999999;
}
.no-comment-bt {
margin-top: 36rpx;
width: 308rpx;
height: 82rpx;
border-radius: 40rpx 40rpx 40rpx 40rpx;
border-width: 2rpx;
border-color: #C9F6F5;
background: #ffffff;
display: flex;
align-items: center;
/* */
justify-content: center;
/* */
}
.no-comment-bt-text {
font-weight: 400;
font-size: 32rpx;
color: #CBF6F5;
}
.commentInput {
width: 364rpx;
height: 80rpx;
border-radius: 40rpx 40rpx 40rpx 40rpx;
background: #f7f8fa;
}
.commentInput-img {
width: 36rpx;
height: 36rpx;
// margin-right: 12rpx;
}
.commentInput-img-1 {
width: 36rpx;
height: 36rpx;
margin-right: 12rpx;
}
.commentInput-text {
font-weight: 400;
font-size: 30rpx;
color: #999999;
}
.commentInput-txt {
font-weight: 400;
font-size: 28rpx;
color: #787878;
}
.commentInput-txt-like {
font-weight: 400;
font-size: 28rpx;
color: #FA3939;
}
.commentInput-txt-favorite {
font-weight: 400;
font-size: 28rpx;
color: #FFC729;
}
.have-comment {
margin-top: 30rpx;
}
.have-comment-avatar-container {
position: relative;
width: 60rpx;
margin-right: 20rpx;
}
.have-comment-avatar-1 {
position: relative;
}
.have-comment-official-1 {
position: absolute;
width: 24rpx;
height: 24rpx;
bottom: 0;
right: 0;
}
.have-comment-uname {
font-weight: 400;
font-size: 26rpx;
color: #999999;
}
.have-comment-address {
font-weight: 400;
font-size: 24rpx;
color: #999999;
}
.have-comment-content {
margin-left: 80rpx;
margin-top: 10rpx;
}
.have-comment-content-text-1 {
font-weight: 400;
font-size: 30rpx;
color: #333333;
}
.have-comment-content-text-2 {
font-weight: 400;
font-size: 24rpx;
color: #999999;
margin-top: 12rpx;
}
.have-comment-content-text-2-hf {
margin-left: 32rpx;
}
.have-comment-answer {
margin-top: 24rpx;
margin-left: 80rpx;
}
.have-comment-answer-avatar-container {
position: relative;
width: 48rpx;
margin-right: 20rpx;
}
.have-comment-answer-avatar-1 {
position: relative;
}
.have-comment-answer-official-1 {
position: absolute;
width: 16rpx;
height: 16rpx;
bottom: 0;
right: 0;
}
.have-comment-answer-uname {
font-weight: 400;
font-size: 26rpx;
color: #999999;
}
.have-comment-answer-content {
margin-left: 80rpx;
margin-top: 10rpx;
}
.have-comment-answer-content-text-1 {
font-weight: 400;
font-size: 30rpx;
color: #333333;
}
.have-comment-answer-content-text-2 {
font-weight: 400;
font-size: 24rpx;
color: #999999;
margin-top: 12rpx;
}
.have-comment-answer-content-text-2-hf {
margin-left: 32rpx;
}
.deploymentAnswer-text {
font-weight: 400;
font-size: 24rpx;
color: #999999;
}
.input-in {
width: 560rpx;
height: 70rpx;
border-radius: 37rpx 37rpx 37rpx 37rpx;
background: #f7f8fa;
}
.input-in-text {
width: 520rpx;
}
.input-bt {
width: 120rpx;
height: 74rpx;
border-radius: 37rpx 37rpx 37rpx 37rpx;
background: #3477fc;
}
.input-text {
font-weight: 400;
font-size: 30rpx;
color: #FFFFFF;
}
.comment-input {
padding: 24rpx;
// margin-bottom: 800rpx;
}
.comment-po {
// height: 500rpx;
}
.input-bt-text {
font-weight: 400;
font-size: 28rpx;
color: #FFFFFF;
}
.have-comment-answer-deploy {
margin-top: 30rpx;
margin-left: 80rpx;
}
.have-comment-answer-line {}
.have-comment-answer-img-1 {
width: 26rpx;
height: 14rpx;
margin-left: 12rpx;
}
.have-comment-answer-img-2 {
width: 26rpx;
height: 14rpx;
margin-left: 12rpx;
transform: scaleY(-1);
}
.have-comment-answer-deploy-1 {
margin-left: 12rpx;
margin-right: 130rpx;
}
.have-comment-answer-uname-img {
width: 14rpx;
height: 24rpx;
margin: 0 8rpx;
}
.have-comment-line {
width: 686rpx;
height: 2rpx;
border-radius: 1rpx 1rpx 1rpx 1rpx;
background: #f4f5f6;
margin: 36rpx 0;
}
</style>