cloudroam
2025-06-12 e04d6a8904fd0c93b931551d8feea0943bae8eac
add: 评论回复
已修改4个文件
201 ■■■■ 文件已修改
components/comment/comment-item.vue 30 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
components/comment/comment-popup.vue 70 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
components/comment/comment-sub-item.vue 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
sub-pages/film-list/film-detail.vue 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
components/comment/comment-item.vue
@@ -19,7 +19,12 @@
          </view>
        </view>
        <view class="comment-opeartor">
          <up-icon name="heart" size="30rpx" />
          <up-icon
            name="heart"
            size="30rpx"
            :color="isLiked ? '#FF0000' : '#B9B9B9'"
             @click="handleLike(props.id)"
          />
          <view class="comment-opeartor-heart-number">{{ likes }}</view>
        </view>
      </view>
@@ -29,6 +34,7 @@
    <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"
@@ -37,7 +43,10 @@
        :date="item.createTime" 
        address="湖北" 
         :likes="item.likeCount"
        @reply="emitReply"
        :isLiked="item.isLike"
        :id="item.id"
        @reply="handleSubReply"
        @like="handleLike"
        :filmInfo="filmInfo"
        />
    </view>
@@ -58,12 +67,15 @@
  likes: number
  child: CommentDTO[]
  filmInfo: CommentDTO
  isLiked: boolean
  id: number
}
const props = defineProps<Props>()
const emit = defineEmits<{
  (e: 'reply'): void
  (e: 'reply', id?: number): void
  (e: 'like', id: number): void
}>()
@@ -83,11 +95,17 @@
const onReply = () => {
  emit('reply')
  emit('reply', props.id) // ✅ 传递父评论ID
}
const emitReply = () => {
  emit('reply')
const handleSubReply = (commentId: number) => {
    console.log("commentId",commentId)
  emit('reply', commentId)
}
const handleLike = (commentId: number) => {
  console.log('handleLike', commentId)
  emit('like', commentId)
}
</script>
components/comment/comment-popup.vue
@@ -169,29 +169,65 @@
  fileList.value.splice(index, 1);
};
// const sendComment = async () => {
//   if (!canSend.value) return;
//   try {
//     const res = await $http.request('post', '/api/comment/create', {
//       data: comment.value
//     })
//     if (res.code == 0) {
//       emit('success')
//       emit('update:modelValue', false)
//       // 清除评论内容
//       comment.value.content = ''
//       fileList.value = []
//       pictureList.value = []
//     } else {
//       $message.showToast('评论失败')
//     }
//   } catch (error) {
//     console.error('评论失败:', error)
//     $message.showToast('评论失败')
//   }
// }
const sendComment = async () => {
  if (!canSend.value) return;
  console.log("评论添加:", comment.value)
  const {
    code, data
  } = await $http.request('post', '/api/comment/create', {
    data: comment.value
  })
  if (code == 0) {
    // 保存成功,返回评论?
    console.log("评论新增成功")
    emit('success'); // 告诉父组件刷新列表
    emit('update:modelValue', false); // 关闭弹窗
  } else {
    $message.showToast('系统异常,无法获取当前微信是否已经绑定过账号')
  try {
    // 构建评论数据
    const commentData = {
      ...comment.value,
      parentId: props.parentId || undefined, // 如果有parentId则使用,没有则为undefined
      filmId: props.filmId,
      content: comment.value.content,
      fileList: comment.value.fileList,
      filmPictures: comment.value.filmPictures
  }
      console.log("commentData",commentData);
    console.log("当前 parentId:", props.parentId); // 检查是否收到值
    const res = await $http.request('post', '/api/comment/create', {
      data: commentData
    })
  fileList.value = [];
  // handleClose();
};
    if (res.code == 0) {
      emit('success')
      emit('update:modelValue', false)
      // 清除评论内容
      comment.value.content = ''
      fileList.value = []
      pictureList.value = []
    } else {
      $message.showToast('评论失败')
    }
  } catch (error) {
    console.error('评论失败:', error)
    $message.showToast('评论失败')
  }
}
const submitComment = async () => {
  
components/comment/comment-sub-item.vue
@@ -19,7 +19,12 @@
          </view>
        </view>
        <view class="comment-opeartor">
          <up-icon name="heart" size="30rpx" />
          <up-icon
              name="heart"
              size="30rpx"
              :color="isLiked ? '#FF0000' : '#B9B9B9'"
              @click="() => handleLike(props.id)"
          />
          <view class="comment-opeartor-heart-number">{{ likes }}</view>
        </view>
      </view>
@@ -39,14 +44,23 @@
  address: string
  likes: number
  filmInfo: CommentDTO
  isLiked: boolean
  id: number
}>()
const emit = defineEmits<{
  (e: 'reply'): void
  (e: 'reply', id: number): void
  (e: 'like', id: number): void
}>()
const onReply = () => {
  emit('reply')
  console.log("onReply",props)
  emit('reply', props.id)
}
const handleLike = (id: number) => {  // 添加参数
  console.log("handleLike", id)
  emit('like', id)
}
</script>
sub-pages/film-list/film-detail.vue
@@ -59,10 +59,27 @@
                    </view>
                    <!-- 示例评论项,comment-item 可替换为实际组件 -->
                    <comment-item v-for="(item, index) in commentList" :avatar="item.picture"
                        :nickname="item.commentUserName" :isAuthor="item.createBy === filmInfo.createBy"
                        :content="item.content" :images="getImageList(item)" :date="item.createTime" address="湖北"
                        :likes="item.likeCount" :child="item.child" :filmInfo="filmInfo" @reply="showCommentLayer" />
<!--                    <comment-item v-for="(item, index) in commentList" :avatar="item.picture"-->
<!--                        :nickname="item.commentUserName" :isAuthor="item.createBy === filmInfo.createBy"-->
<!--                        :content="item.content" :images="getImageList(item)" :date="item.createTime" address="湖北"-->
<!--                        :likes="item.likeCount" :child="item.child" :filmInfo="filmInfo" @reply="showCommentLayer" />-->
                  <comment-item
                      v-for="(item, index) in commentList"
                      :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"
                      :child="item.child"
                      :filmInfo="filmInfo"
                      @reply="(id) => showCommentLayer(id)"
                      @like="handleCommentLike"
                  />
                </view>
            </scroll-view>
@@ -189,21 +206,75 @@
    })
}
const showCommentLayer = () => {
// film-detail.vue
const showCommentLayer = (parentId?: number) => {
  console.log('点击了评论按钮',parentId)
    commentShow.value = true
  // 如果有parentId,说明是回复评论,需要设置parentId
  // 如果没有parentId,说明是直接评论,不需要设置parentId
  commentParendId.value = parentId ? String(parentId) : ''
}
const handleCommentSuccess = (data) => {
    // 例如重新请求评论列表
    //   fetchCommentList();
    // 重新获取评论列表
    getCommentList(filmId.value)
    commentShow.value = false
    commentParendId.value = '' // 清除父评论ID
};
onShow(() => {
});
// 处理评论点赞
const handleCommentLike = async (commentId: number) => {
  console.log('点击了评论点赞', commentId)
  try {
    const res = await $http.request('post', '/v2/comment-likes/commentLikes/edit', {
      data: { commentId }
    })
    if (res.code === 0) {
      // 更新评论列表中的点赞状态和数量
      const updateCommentLike = (comments: CommentDTO[]) => {
        comments.forEach(comment => {
          if (comment.id === commentId) {
            comment.isLike = !comment.isLike
            comment.likeCount += comment.isLike ? 1 : -1
          }
          if (comment.child && comment.child.length > 0) {
            updateCommentLike(comment.child)
          }
        })
      }
      updateCommentLike(commentList.value)
      // 根据当前点赞状态显示对应提示
      const comment = findCommentById(commentList.value, commentId)
      $message.showToast(comment?.isLike ? '点赞成功' : '取消点赞')
    }
  } catch (error) {
    console.error('评论点赞失败:', error)
    $message.showToast('操作失败')
  }
}
// 添加一个辅助函数来查找评论
const findCommentById = (comments: CommentDTO[], id: number): CommentDTO | undefined => {
  for (const comment of comments) {
    if (comment.id === id) {
      return comment
    }
    if (comment.child && comment.child.length > 0) {
      const found = findCommentById(comment.child, id)
      if (found) return found
    }
  }
  return undefined
}
const filmInfo = ref<FilmInfo>()
const filmPictureList = ref<string[]>([])