- <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>
|