瑶都万能墙
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

333 lines
7.5 KiB

<template>
<view class="comment">
<view class="comment-header">
<view class="avatar">
<image :src="item.userHead"
@click.stop="previewImage([item.userHead])"
mode="aspectFill"></image>
</view>
<view class="user-info">
<view class="username">{{ item.userName }}</view>
<view class="comment-content" v-html="$utils.stringFormatHtml(item.userValue)"></view>
<view class="comment-meta">
<text class="time">{{ $timeUtils.formatTime(item.createTime) }}</text>
<!-- <text class="location">贵州</text> -->
<text class="reply-btn" @click.stop="handleReply(0)">回复</text>
</view>
</view>
</view>
<!-- 主评论图片 -->
<view class="images" v-if="images && images.length > 0">
<view class="image"
@click.stop="previewImage(images, i)"
:key="i" v-for="(img, i) in images">
<image :src="img" mode="aspectFill"></image>
</view>
</view>
<!-- 子评论列表 -->
<view class="sub-comments-list" v-if="subComments && subComments.length > 0">
<view class="sub-comment-item" v-for="(subComment, index) in subComments" :key="subComment.id">
<view class="sub-comment-header">
<view class="sub-avatar">
<image :src="subComment.userHead" mode="aspectFill" @click.stop="previewImage([subComment.userHead])"></image>
</view>
<view class="sub-user-info">
<view class="sub-username">
<text>{{ subComment.userName }}</text>
<!-- 显示回复信息 -->
<text class="reply-to" v-if="subComment.replyToName">回复 @{{ subComment.replyToName }}:</text>
</view>
<view class="sub-comment-content" v-html="$utils.stringFormatHtml(subComment.userValue)"></view>
<view class="sub-comment-meta">
<text class="sub-time">{{ $timeUtils.formatTime(subComment.createTime) }}</text>
<!-- <text class="location">贵州</text> -->
<text class="sub-reply-btn" @click.stop="handleSubReply(subComment)">回复</text>
</view>
</view>
</view>
<!-- 子评论图片 -->
<view class="sub-comment-images" v-if="subComment.userImage">
<view class="sub-image"
@click.stop="previewImage(subComment.userImage.split(','), i)"
:key="i" v-for="(img, i) in subComment.userImage.split(',')">
<image :src="img" mode="aspectFill"></image>
</view>
</view>
</view>
</view>
<!-- 加载更多子评论按钮 -->
<view class="load-more-section" v-if="item.replyNum && item.replyNum > 0 && (!subComments || subComments.length === 0)">
<view class="load-more-btn" @click.stop="loadSubComments">
<text class="load-more-text">查看{{item.replyNum}}条回复</text>
</view>
</view>
</view>
</template>
<script>
export default {
props : ['item', 'parentId', 'sourceType', 'sourceId', 'subComments'],
data() {
return {
isLoadingSubComments: false // 添加加载状态
}
},
computed : {
images(){
if(!this.item.userImage){
return []
}
return this.item.userImage.split(',')
}
},
methods: {
// 导航到子评论详情
navigateToSubComment(comment) {
uni.navigateTo({
url: `/pages_order/comment/commentDetail?id=${comment.id}&parentId=${this.parentId}&sourceType=${this.sourceType}&sourceId=${this.sourceId}`
});
},
// 加载子评论
loadSubComments() {
if (this.isLoadingSubComments) return; // 防止重复加载
this.isLoadingSubComments = true;
uni.showLoading({
title: '加载中...'
});
this.$emit('loadSubComments', this.item);
// 模拟加载完成后的状态重置
setTimeout(() => {
this.isLoadingSubComments = false;
uni.hideLoading();
}, 1000);
},
// 处理回复
handleReply() {
this.$emit('reply', {
item : this.item,
level : 0,
});
},
// 处理子评论回复
handleSubReply(subComment) {
this.$emit('reply', {
item : subComment,
level : 1,
});
}
}
}
</script>
<style scoped lang="scss">
.comment {
background-color: #fff;
padding: 26.25rpx 35rpx;
margin-bottom: 1.75rpx;
border-bottom: 1.75rpx solid #f5f5f5;
.comment-header {
display: flex;
align-items: flex-start;
.avatar {
width: 70rpx;
height: 70rpx;
border-radius: 50%;
overflow: hidden;
margin-right: 17.5rpx;
flex-shrink: 0;
image {
width: 100%;
height: 100%;
}
}
.user-info {
flex: 1;
.username {
font-size: 24.5rpx;
font-weight: 600;
color: $uni-text-color;
margin-bottom: 7rpx;
}
.comment-content {
font-size: 26.25rpx;
line-height: 1.5;
color: $uni-text-color;
margin-bottom: 10.5rpx;
word-break: break-all;
}
.comment-meta {
display: flex;
align-items: center;
font-size: 21rpx;
color: $uni-text-color-grey;
.time {
margin-right: 17.5rpx;
}
.location {
margin-right: 17.5rpx;
}
.reply-btn {
color: $uni-text-color-grey;
padding: 7rpx 14rpx;
background-color: #f5f5f5;
border-radius: 17.5rpx;
font-size: 19.25rpx;
margin-left: auto;
}
}
}
}
.images {
display: flex;
flex-wrap: wrap;
margin-top: 17.5rpx;
margin-left: 87.5rpx;
.image {
margin: 8.75rpx;
image {
height: 105rpx;
width: 105rpx;
border-radius: 10.5rpx;
}
}
}
// 子评论列表样式
.sub-comments-list {
margin-top: 17.5rpx;
margin-left: 87.5rpx;
.sub-comment-item {
margin-bottom: 26.25rpx;
&:last-child {
margin-bottom: 0;
}
.sub-comment-header {
display: flex;
align-items: flex-start;
.sub-avatar {
width: 52.5rpx;
height: 52.5rpx;
border-radius: 50%;
overflow: hidden;
margin-right: 14rpx;
flex-shrink: 0;
image {
width: 100%;
height: 100%;
}
}
.sub-user-info {
flex: 1;
.sub-username {
font-size: 22.75rpx;
font-weight: 600;
color: $uni-text-color;
margin-bottom: 5.25rpx;
.reply-to {
font-size: 21rpx;
color: $uni-color-primary;
font-weight: 500;
margin-left: 8.75rpx;
}
}
.sub-comment-content {
font-size: 24.5rpx;
line-height: 1.5;
color: $uni-text-color;
margin-bottom: 8.75rpx;
word-break: break-all;
}
.sub-comment-meta {
display: flex;
align-items: center;
font-size: 19.25rpx;
color: $uni-text-color-grey;
.sub-time {
margin-right: 14rpx;
}
.sub-location {
margin-right: 14rpx;
}
.sub-reply-btn {
color: $uni-text-color-grey;
padding: 5.25rpx 10.5rpx;
background-color: #f5f5f5;
border-radius: 14rpx;
font-size: 17.5rpx;
margin-left: auto;
}
}
}
}
.sub-comment-images {
display: flex;
flex-wrap: wrap;
margin-top: 10.5rpx;
margin-left: 66.5rpx;
.sub-image {
margin-right: 7rpx;
margin-bottom: 7rpx;
image {
width: 84rpx;
height: 84rpx;
border-radius: 7rpx;
}
}
}
}
}
.load-more-section {
margin-left: 87.5rpx;
.load-more-btn {
display: inline-flex;
align-items: center;
padding: 7rpx 14rpx;
background-color: #f5f5f5;
border-radius: 17.5rpx;
font-size: 21rpx;
color: $uni-text-color-grey;
}
}
}
</style>