|
|
@ -0,0 +1,269 @@ |
|
|
|
<template> |
|
|
|
<view class="comment-list" v-if="comments && comments.length > 0"> |
|
|
|
<view class="comment-header"> |
|
|
|
<view class="comment-icon">💬</view> |
|
|
|
<text class="comment-count">评论</text> |
|
|
|
</view> |
|
|
|
|
|
|
|
<view class="comment-container"> |
|
|
|
<view |
|
|
|
class="comment-item" |
|
|
|
v-for="(comment, index) in comments" |
|
|
|
:key="index" |
|
|
|
> |
|
|
|
<view class="comment-user"> |
|
|
|
<image |
|
|
|
class="user-avatar" |
|
|
|
:src="comment.userHead || '/static/image/center/default-avatar.png'" |
|
|
|
@click.stop="previewImage([comment.userHead])" |
|
|
|
mode="aspectFill" |
|
|
|
></image> |
|
|
|
<view class="comment-content"> |
|
|
|
<view class="user-info"> |
|
|
|
<text class="username">{{ comment.userName }}</text> |
|
|
|
<text class="comment-time">{{ formatTime(comment.createTime) }}</text> |
|
|
|
</view> |
|
|
|
<view class="comment-text" v-html="$utils.stringFormatHtml(comment.userValue)"> |
|
|
|
</view> |
|
|
|
|
|
|
|
<!-- 评论图片 --> |
|
|
|
<view class="comment-images" v-if="getCommentImages(comment).length > 0"> |
|
|
|
<view |
|
|
|
class="comment-image" |
|
|
|
v-for="(img, imgIndex) in getCommentImages(comment)" |
|
|
|
:key="imgIndex" |
|
|
|
@click.stop="previewImage(getCommentImages(comment), imgIndex)" |
|
|
|
> |
|
|
|
<image :src="img" mode="aspectFill"></image> |
|
|
|
</view> |
|
|
|
</view> |
|
|
|
</view> |
|
|
|
</view> |
|
|
|
</view> |
|
|
|
|
|
|
|
<!-- 查看更多评论按钮 --> |
|
|
|
<view |
|
|
|
class="more-btn" |
|
|
|
v-if="hasMoreComments" |
|
|
|
@click="goToDetail" |
|
|
|
> |
|
|
|
<text>查看更多评论</text> |
|
|
|
<text class="more-icon">→</text> |
|
|
|
</view> |
|
|
|
</view> |
|
|
|
</view> |
|
|
|
</template> |
|
|
|
|
|
|
|
<script> |
|
|
|
export default { |
|
|
|
name: 'CommentList', |
|
|
|
props: { |
|
|
|
comments: { |
|
|
|
type: Array, |
|
|
|
default: () => [] |
|
|
|
}, |
|
|
|
hasMoreComments: { |
|
|
|
type: Boolean, |
|
|
|
default: false |
|
|
|
} |
|
|
|
}, |
|
|
|
data() { |
|
|
|
return { |
|
|
|
|
|
|
|
} |
|
|
|
}, |
|
|
|
computed: { |
|
|
|
|
|
|
|
}, |
|
|
|
methods: { |
|
|
|
goToDetail() { |
|
|
|
this.$emit('goToDetail') |
|
|
|
}, |
|
|
|
|
|
|
|
getCommentImages(comment) { |
|
|
|
if (!comment.userImage) { |
|
|
|
return [] |
|
|
|
} |
|
|
|
return comment.userImage.split(',').filter(img => img.trim()) |
|
|
|
}, |
|
|
|
|
|
|
|
formatTime(time) { |
|
|
|
if (!time) return '' |
|
|
|
|
|
|
|
// 如果时间已经包含"发布",直接返回 |
|
|
|
if (time.includes && time.includes('发布')) { |
|
|
|
return time |
|
|
|
} |
|
|
|
|
|
|
|
// 使用dayjs格式化时间戳 |
|
|
|
if (typeof time === 'number' || (typeof time === 'string' && /^\d+$/.test(time))) { |
|
|
|
const timestamp = Number(time) |
|
|
|
const now = this.$dayjs() |
|
|
|
const commentTime = this.$dayjs(timestamp) |
|
|
|
|
|
|
|
// 计算时间差 |
|
|
|
const diffMinutes = now.diff(commentTime, 'minute') |
|
|
|
const diffHours = now.diff(commentTime, 'hour') |
|
|
|
const diffDays = now.diff(commentTime, 'day') |
|
|
|
|
|
|
|
if (diffMinutes < 1) { |
|
|
|
return '刚刚' |
|
|
|
} else if (diffMinutes < 60) { |
|
|
|
return `${diffMinutes}分钟前` |
|
|
|
} else if (diffHours < 24) { |
|
|
|
return `${diffHours}小时前` |
|
|
|
} else if (diffDays < 7) { |
|
|
|
return `${diffDays}天前` |
|
|
|
} else { |
|
|
|
return commentTime.format('MM-DD HH:mm') |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 否则添加"发布"后缀 |
|
|
|
return time + '发布' |
|
|
|
}, |
|
|
|
|
|
|
|
previewImage(images, current = 0) { |
|
|
|
if (!images || images.length === 0) return |
|
|
|
|
|
|
|
uni.previewImage({ |
|
|
|
urls: images, |
|
|
|
current: current |
|
|
|
}) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
</script> |
|
|
|
|
|
|
|
<style scoped lang="scss"> |
|
|
|
.comment-list { |
|
|
|
margin-top: 20rpx; |
|
|
|
background-color: #f8f8f8; |
|
|
|
border-radius: 12rpx; |
|
|
|
overflow: hidden; |
|
|
|
|
|
|
|
.comment-header { |
|
|
|
display: flex; |
|
|
|
align-items: center; |
|
|
|
padding: 20rpx 30rpx 15rpx; |
|
|
|
background-color: #f0f0f0; |
|
|
|
border-bottom: 1rpx solid #e5e5e5; |
|
|
|
|
|
|
|
.comment-icon { |
|
|
|
font-size: 28rpx; |
|
|
|
margin-right: 10rpx; |
|
|
|
} |
|
|
|
|
|
|
|
.comment-count { |
|
|
|
font-size: 26rpx; |
|
|
|
color: #666; |
|
|
|
font-weight: 500; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
.comment-container { |
|
|
|
padding: 0 30rpx 20rpx; |
|
|
|
|
|
|
|
.comment-item { |
|
|
|
padding: 20rpx 0; |
|
|
|
border-bottom: 1rpx solid #f0f0f0; |
|
|
|
|
|
|
|
&:last-child { |
|
|
|
border-bottom: none; |
|
|
|
} |
|
|
|
|
|
|
|
.comment-user { |
|
|
|
display: flex; |
|
|
|
align-items: flex-start; |
|
|
|
|
|
|
|
.user-avatar { |
|
|
|
width: 60rpx; |
|
|
|
height: 60rpx; |
|
|
|
border-radius: 50%; |
|
|
|
margin-right: 20rpx; |
|
|
|
flex-shrink: 0; |
|
|
|
} |
|
|
|
|
|
|
|
.comment-content { |
|
|
|
flex: 1; |
|
|
|
|
|
|
|
.user-info { |
|
|
|
display: flex; |
|
|
|
align-items: center; |
|
|
|
margin-bottom: 8rpx; |
|
|
|
|
|
|
|
.username { |
|
|
|
font-size: 26rpx; |
|
|
|
color: #576b95; |
|
|
|
font-weight: 500; |
|
|
|
margin-right: 20rpx; |
|
|
|
} |
|
|
|
|
|
|
|
.comment-time { |
|
|
|
font-size: 22rpx; |
|
|
|
color: #999; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
.comment-text { |
|
|
|
font-size: 28rpx; |
|
|
|
color: #333; |
|
|
|
line-height: 1.5; |
|
|
|
word-break: break-all; |
|
|
|
margin-bottom: 10rpx; |
|
|
|
} |
|
|
|
|
|
|
|
.comment-images { |
|
|
|
display: flex; |
|
|
|
flex-wrap: wrap; |
|
|
|
margin-top: 15rpx; |
|
|
|
|
|
|
|
.comment-image { |
|
|
|
margin-right: 10rpx; |
|
|
|
margin-bottom: 10rpx; |
|
|
|
|
|
|
|
image { |
|
|
|
width: 100rpx; |
|
|
|
height: 100rpx; |
|
|
|
border-radius: 8rpx; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
.expand-btn { |
|
|
|
display: flex; |
|
|
|
align-items: center; |
|
|
|
justify-content: center; |
|
|
|
padding: 15rpx 0; |
|
|
|
margin-top: 10rpx; |
|
|
|
color: #576b95; |
|
|
|
font-size: 26rpx; |
|
|
|
|
|
|
|
.expand-icon { |
|
|
|
margin-left: 10rpx; |
|
|
|
font-size: 20rpx; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
.more-btn { |
|
|
|
display: flex; |
|
|
|
align-items: center; |
|
|
|
justify-content: center; |
|
|
|
padding: 15rpx 0; |
|
|
|
margin-top: 10rpx; |
|
|
|
color: #576b95; |
|
|
|
font-size: 26rpx; |
|
|
|
background-color: #f5f5f5; |
|
|
|
border-radius: 8rpx; |
|
|
|
|
|
|
|
.more-icon { |
|
|
|
margin-left: 10rpx; |
|
|
|
font-size: 24rpx; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
</style> |