From c31a8def0ac90d86b8e8e345441bd28002a9ef2f Mon Sep 17 00:00:00 2001 From: cloudroam <cloudroam> Date: 星期一, 16 六月 2025 20:14:52 +0800 Subject: [PATCH] add: 分享 --- components/comment/comment-item.vue | 313 ++++++++++++++++++++++++++++----------------------- 1 files changed, 172 insertions(+), 141 deletions(-) diff --git a/components/comment/comment-item.vue b/components/comment/comment-item.vue index b905df7..5d18656 100644 --- a/components/comment/comment-item.vue +++ b/components/comment/comment-item.vue @@ -1,161 +1,192 @@ <template> - <view class="comment-item"> - <view class="comment-item-header"> - <view class="comment-item-header-left"> - <view class="avatar"> - <up-avatar :src="avatar" size="50rpx" shape="circle" /> + <view class="comment-item"> + <view class="comment-item-header"> + <view class="comment-item-header-left"> + <view class="avatar"> + <up-avatar :src="avatar" size="50rpx" shape="circle" /> + </view> + <view class="comment-content"> + <view class="author"> + <text class="nickname">{{ nickname }}</text> + <view v-if="isAuthor" class="author-flag">作者</view> </view> - <view class="comment-content"> - <view class="author"> - <text class="nickname">{{ nickname }}</text> - <view v-if="isAuthor" class="author-flag">作者</view> - </view> - <view class="comment-content-text"> - <text>{{ content }}</text> - <up-album :urls="images" multipleSize="180rpx" singleSize="500rpx" /> - <text class="date">{{ date }}</text> - <text class="address">{{ address }}</text> - <text class="reply" @click="onReply">回复</text> - </view> - </view> - <view class="comment-opeartor"> - <up-icon name="heart" size="30rpx" /> - <view class="comment-opeartor-heart-number">{{ likes }}</view> + <view class="comment-content-text"> + <text>{{ content }}</text> + <up-album :urls="images" multipleSize="180rpx" singleSize="500rpx" /> + <text class="date">{{ date }}</text> + <text class="address">{{ address }}</text> + <text class="reply" @click="onReply">回复</text> </view> </view> - </view> - - <!-- 子评论区域 --> - <view class="sub-comment"> - <comment-sub-item - avatar="https://img.yzcdn.cn/vant/cat.jpeg" - nickname="图墙精选" - :isAuthor="true" - content="如果路线里全是常规景区,没一个特殊的点位..." - :images="urls2" - date="2天前" - address="湖北" - :likes="30" - @reply="emitReply" - /> + <view class="comment-opeartor"> + <up-icon + name="heart" + size="30rpx" + :color="isLiked ? '#FF0000' : '#B9B9B9'" + @click="handleLike(props.id)" + /> + <view class="comment-opeartor-heart-number">{{ likes }}</view> + </view> </view> </view> - </template> - - <script setup lang="ts"> - import { ref, onMounted } from 'vue' - interface Props { - avatar: string - nickname: string - isAuthor: boolean - content: string - images: string[] - date: string - address: string - likes: number + + <!-- 子评论区域 --> + <view class="sub-comment"> + <comment-sub-item + v-for="(item, index) in child" + :key="index" + :avatar="item.picture" + :nickname="item.commentUserName" + :isAuthor="item.createBy === filmInfo.createBy" + :content="item.content" + :images="getImageList(item)" + :date="item.createTime" + address="湖北" + :likes="item.likeCount" + :isLiked="item.isLike" + :id="item.id" + @reply="handleSubReply" + @like="handleLike" + :filmInfo="filmInfo" + /> + </view> + </view> +</template> + +<script setup lang="ts"> +import { ref, onMounted } from 'vue' +import { CommentDTO } from '@/types/index' +interface Props { + avatar: string + nickname: string + isAuthor: boolean + content: string + images: string[] + date: string + address: string + likes: number + child: CommentDTO[] + filmInfo: CommentDTO + isLiked: boolean + id: number +} + +const props = defineProps<Props>() + +const emit = defineEmits<{ + (e: 'reply', id?: number): void + (e: 'like', id: number): void +}>() + + +const getImageList = (item: any): string[] => { + if (!item || !item.filmPictures || typeof item.filmPictures !== 'string') { + return []; } - - const props = defineProps<Props>() - - const emit = defineEmits<{ - (e: 'reply'): void - }>() - - const urls2 = ref<string[]>([ - 'https://img.yzcdn.cn/vant/cat.jpeg', - 'https://img.yzcdn.cn/vant/cat.jpeg', - 'https://img.yzcdn.cn/vant/cat.jpeg', - 'https://img.yzcdn.cn/vant/cat.jpeg', - 'https://img.yzcdn.cn/vant/cat.jpeg' - ]) - - const onReply = () => { - emit('reply') + + try { + const pictures = JSON.parse(item.filmPictures); + return Array.isArray(pictures) ? pictures.map((p: any) => p.url) : []; + } catch (e) { + console.error('filmPictures JSON parse error:', e, item.filmPictures); + return []; } - - const emitReply = () => { - emit('reply') - } - </script> - - <style lang="scss" scoped> - .comment-item { - .comment-item-header { +}; + + +const onReply = () => { + emit('reply', props.id) // ✅ 传递父评论ID +} + +const handleSubReply = (commentId: number) => { + console.log("commentId",commentId) + emit('reply', commentId) +} + +const handleLike = (commentId: number) => { + console.log('handleLike', commentId) + emit('like', commentId) +} +</script> + +<style lang="scss" scoped> +.comment-item { + .comment-item-header { + display: flex; + align-items: center; + + .comment-item-header-left { display: flex; - align-items: center; - - .comment-item-header-left { + width: 100%; + + .avatar { + margin-right: 10rpx; + } + + .comment-content { + width: 92%; display: flex; - width: 100%; - - .avatar { - margin-right: 10rpx; - } - - .comment-content { - width: 92%; + flex-direction: column; + + .author { display: flex; - flex-direction: column; - - .author { - display: flex; - align-items: center; - - .nickname { - font-size: 30rpx; - color: #858585; - } - - .author-flag { - font-size: 18rpx; - color: #ff4d4f; - font-weight: bold; - border-radius: 50rpx; - padding: 5rpx 10rpx; - background-color: rgba(219, 19, 22, 0.219); - margin-left: 10rpx; - height: 25rpx; - } + align-items: center; + + .nickname { + font-size: 30rpx; + color: #858585; } - - .comment-content-text { - margin-top: 10rpx; - font-size: 26rpx; - letter-spacing: 1rpx; - line-height: 1.5; - - .date, - .address { - font-size: 20rpx; - padding: 10rpx; - color: #858585; - } - - .reply { - font-size: 24rpx; - padding: 10rpx; - color: #2979ff; - } + + .author-flag { + font-size: 18rpx; + color: #ff4d4f; + font-weight: bold; + border-radius: 50rpx; + padding: 5rpx 10rpx; + background-color: rgba(219, 19, 22, 0.219); + margin-left: 10rpx; + height: 25rpx; } } - - .comment-opeartor { - display: flex; - flex-direction: column; - align-items: flex-start; - - .comment-opeartor-heart-number { - text-align: center; + + .comment-content-text { + margin-top: 10rpx; + font-size: 26rpx; + letter-spacing: 1rpx; + line-height: 1.5; + + .date, + .address { font-size: 20rpx; + padding: 10rpx; + color: #858585; + } + + .reply { + font-size: 24rpx; + padding: 10rpx; + color: #2979ff; } } } - } - - .sub-comment { - margin-left: 60rpx; - margin-top: 10rpx; + + .comment-opeartor { + display: flex; + flex-direction: column; + align-items: flex-start; + + .comment-opeartor-heart-number { + width: 100%; + text-align: center; + font-size: 20rpx; + } + } } } - </style> - \ No newline at end of file + + .sub-comment { + margin-left: 60rpx; + margin-top: 10rpx; + } +} +</style> \ No newline at end of file -- Gitblit v1.9.3