cloudroam
7 天以前 c31a8def0ac90d86b8e8e345441bd28002a9ef2f
sub-pages/film-list/film-detail.vue
@@ -1,6 +1,7 @@
<template>
    <view>
        <view class="page">
            <up-sticky bgColor="#fff">
                <view class="card-footer">
                    <view class="user-info">
@@ -11,7 +12,7 @@
                    </view>
                    <view class="opera-info">
                        <button class="custom-btn">关注</button>
                        <up-icon name="/static/common/share2.png" size="40rpx" color="#999" />
                        <up-icon name="/static/common/share2.png" size="40rpx" color="#999" @click="openSharePopup" />
                    </view>
                </view>
            </up-sticky>
@@ -59,10 +60,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>
@@ -72,15 +90,46 @@
                    <view class="comment-input" @click="showCommentLayer">
                        <up-text size="12px" text="说点什么......" margin="0 0 0 20rpx" color="#B9B9B9" />
                    </view>
                    <up-icon name="heart" size="60rpx" color="#B9B9B9" label="11" />
                    <up-icon name="star" size="60rpx" color="#B9B9B9" label="22" />
                    <up-icon name="chat" size="60rpx" color="#B9B9B9" label="33" />
<!--                    <up-icon name="heart" size="60rpx" color="#B9B9B9" label="11" />-->
<!--                    <up-icon name="star" size="60rpx" color="#B9B9B9" label="22" />-->
                        <up-icon
                            name="heart"
                            size="60rpx"
                            :color="liked ? '#FF0000' : '#B9B9B9'"
                            :label="filmInfo?.voLikeCount || 0"
                            @click="toggleLike"
                        />
                        <up-icon
                            name="star"
                            size="60rpx"
                            :color="collected ? '#FFD700' : '#B9B9B9'"
                            :label="filmInfo?.voCollectCount || 0"
                            @click="toggleFavorite"
                        />
                  <up-icon
                      name="chat"
                      size="60rpx"
                      color="#B9B9B9"
                      :label="filmInfo?.voCommentCount || 0"
                      @click="showCommentLayer"
                  />
                    <!-- <up-icon name="chat" size="60rpx" color="#B9B9B9" label="33" /> -->
                </view>
            </view>
        </view>
        <comment-popup v-model="commentShow" :film-id="filmInfo?.id" :parent-id="commentParendId"
            @success="handleCommentSuccess" />
        <!-- 自定义分享弹窗 -->
        <share-popup
            v-model:show="showSharePopup"
            :share-data="shareData"
        />
    </view>
</template>
@@ -109,6 +158,45 @@
    username: '图墙精选',
    avatar: 'https://img.yzcdn.cn/vant/cat.jpeg'
})
const liked = ref(false)      // 是否已点赞
const collected = ref(false)  // 是否已收藏
const sharePopupShow = ref(false)
import SharePopup from '@/components/share-popup.vue'
// 分享弹窗控制
const showSharePopup = ref(false)
const shareData = ref({
  title: '',
  desc: '',
  image: '',
  url: ''
})
// 打开分享弹窗
const openSharePopup = () => {
  // 设置分享内容
  shareData.value = {
    title: filmInfo.value?.coverTitle || '分享内容',
    desc: filmInfo.value?.filmContent?.substring(0, 50) || '',
    image: filmPictureList.value[0] || '',
    url: `https://您的域名/sub-pages/film-list/film-detail?id=${filmInfo.value?.id}`
  }
  showSharePopup.value = true
}
// 复制链接
const copyLink = () => {
  sharePopupShow.value = false
  uni.setClipboardData({
    data: `https://你的域名/sub-pages/film-list/film-detail?id=${filmInfo.value?.id}`,
    success: () => $message.showToast('链接已复制')
  })
}
onLoad((options: any) => {
@@ -164,20 +252,74 @@
    })
}
const showCommentLayer = () => {
    commentShow.value = true
// 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>()
@@ -193,6 +335,10 @@
    if (code == 0) {
        filmInfo.value = data
        console.log("详情", filmInfo.value)
      // 设置初始状态
      console.log("filmInfo.value.isLiked",  data.liked)
        liked.value =data.liked || false
        collected.value = data.collected || false
        if (data && data.filmPictures) {
            // 只获取里面的url
            // filmPictureList.value=JSON.parse(data.filmPictures) as Array<FilmPicture>
@@ -214,6 +360,77 @@
        return null;
    }
}
const toggleLike = async () => {
  console.log("toggleLike",filmInfo.value)
  if (!filmInfo.value) return
  const api = liked.value ? '/v2/film-likes/filmLikes/edit' : '/v2/film-likes/filmLikes/edit'
  try {
    const res = await $http.request('post', api, {
      data: { filmId: filmInfo.value.id }
    })
    if (res.code === 0) {
      // 更新本地状态
      liked.value = !liked.value
      filmInfo.value.voLikeCount += liked.value ? 1 : -1
      // 提示信息
      $message.showToast(liked.value ? '点赞成功' : '取消点赞')
    }
  } catch (error) {
    console.error('点赞失败:', error)
    $message.showToast('操作失败')
  }
}
const toggleFavorite = async () => {
  console.log("toggleFavorite",filmInfo.value)
  if (!filmInfo.value) return
  const api = collected.value ? '/v2/film-collects/filmCollects/edit' : '/v2/film-collects/filmCollects/edit'
  try {
    const res = await $http.request('post', api, {
      data: { filmId: filmInfo.value.id }
    })
    if (res.code === 0) {
      // 更新本地状态
      collected.value = !collected.value
      filmInfo.value.voCollectCount += collected.value ? 1 : -1
      // 提示信息
      $message.showToast(collected.value ? '收藏成功' : '取消收藏')
    }
  } catch (error) {
    console.error('收藏失败:', error)
    $message.showToast('操作失败')
  }
}
// 小程序分享配置
defineExpose({
  onShareAppMessage() {
    return {
      title: filmInfo.value?.coverTitle || '分享内容',
      path: `/sub-pages/film-list/film-detail?id=${filmInfo.value?.id}`,
      imageUrl: filmPictureList.value[0] || '',
      desc: filmInfo.value?.filmContent?.substring(0, 50) || ''
    }
  },
  // 分享到朋友圈
  onShareTimeline() {
    return {
      title: filmInfo.value?.coverTitle || '分享内容',
      query: `id=${filmInfo.value?.id}`,
      imageUrl: filmPictureList.value[0] || ''
    }
  }
})
</script>
@@ -443,4 +660,92 @@
    padding-bottom: 180rpx;
    /* 留出评论区高度,避免遮挡 */
}
.share-popup {
  background: #fff;
  padding: 30rpx;
  border-top-left-radius: 20rpx;
  border-top-right-radius: 20rpx;
  min-height: 300rpx;
}
.share-title {
  text-align: center;
  font-size: 32rpx;
  margin-bottom: 30rpx;
  color: #333;
}
.share-options {
  display: flex;
  justify-content: space-around;
  margin-bottom: 30rpx;
  padding: 20rpx 0;
}
.share-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 120rpx;
}
.share-icon {
  width: 80rpx;
  height: 80rpx;
  margin-bottom: 10rpx;
}
.share-btn text {
  font-size: 24rpx;
  color: #666;
  margin-top: 10rpx;
}
.share-cancel {
  text-align: center;
  color: #888;
  font-size: 28rpx;
  padding: 20rpx 0;
  border-top: 1px solid #eee;
  margin-top: 20rpx;
}
</style>
<style lang="scss" scoped>
// 分享按钮样式
.share-btn {
  background: none;
  border: none;
  padding: 0;
  margin: 0;
  line-height: normal;
  &::after {
    border: none;
  }
}
// 分享弹窗样式
.share-popup {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 9999;
  .share-mask {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.5);
  }
  .share-content {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    background: #fff;
    border-radius: 20rpx 20rpx 0 0;
    padding: 30rpx;
  }
}
</style>