绿满眶商城微信小程序-uniapp
peng
2025-06-25 cad6ad80c86eba4663d84fd78042c1173361f600
pages/health/healthVideo.vue
@@ -1,910 +1,1034 @@
<template>
   <view class="video-container">
      <!-- 视频列表 -->
      <swiper class="video-swiper" vertical circular :current="currentIndex" @change="onSwiperChange">
         <swiper-item v-for="(item, index) in videoList" :key="item.id">
            <view style="width: 100%;height: 100%;" v-if="item.videoContentType === 'video'">
               <!-- 播放按钮(仅当视频暂停时显示) -->
               <view class="play-icon" @click="togglePlay(index)" v-if="!currentVideoIsPlaying">
                  <image src="/static/video/play.png" style="width: 45px;height: 45px" mode="aspectFit"></image>
               </view>
               <video :id="'video'+index" :ref="'video'+index" :src="item.videoUrl"
                  :autoplay="currentIndex === index" :controls="false" :loop="true" :object-fit="item.objectFit"
                  :enable-progress-gesture="false" class="video-item" @play="onPlay(item.id, index)"
                  @pause="onPause(index)" @ended="onEnded(index)" @click="togglePlay(index)"
                  @timeupdate="onTimeUpdate($event)" @loadedmetadata="onLoadedMetadata($event)"></video>
               <!-- 自定义控制条 -->
               <view @touchstart="handleTouchStart" @touchmove="handleTouchMove" @touchend="handleTouchEnd"
                  class="container">
                  <!-- 进度条 - 整个区域可拖动 -->
                  <view class="process-warp" :style="{ opacity: showProcess ? 1 : 0 }">
                     <!-- 显示当前进度 -->
                     <view class="progress-text">{{ hasPlayTime }}/{{formartDuration[index]}}</view>
                     <view class="progress-bar" id="progressBar">
  <view class="video-container">
   <!-- 视频加载 -->
   <zero-loading v-show="videoLoading" type="circle" color="#0ebd57" text=""></zero-loading>
    <!-- 视频列表 -->
    <swiper
      class="video-swiper"
      vertical
      :current="currentIndex"
      @change="onSwiperChange"
     :duration="250"
     easing-function="linear"
    >
      <swiper-item
      v-for="(item, index) in videoList"
      :key="item.id"
      @touchstart="handleSwiperStart"
      @touchmove="handleSwiperMove"
      @touchend="handleSwiperEnd(item)"
       >
      <view style="width: 100%;height: 100%;" v-if="item.videoContentType === 'video'">
           <!-- 播放按钮(仅当视频暂停时显示) -->
           <view
            class="play-icon"
            @click="togglePlay(index)"
            v-show="!currentVideoIsPlaying"
           >
            <image src="/static/video/play.png" style="width: 45px;height: 45px" mode="aspectFit"></image>
           </view>
           <video
            v-if="index >= currentIndex - videoLiveOffset && index <= currentIndex + videoLiveOffset"
            :id="'video'+index"
            :ref="'video'+index"
            :src="item.videoUrl"
            :autoplay="index === currentIndex"
            :controls="false"
            :loop="true"
            :object-fit="item.objectFit"
            :enable-progress-gesture="false"
            :show-center-play-btn="false"
            class="video-item"
            @play="onPlay(item.id, index)"
            @pause="onPause(index)"
            @ended="onEnded(index)"
            @click="togglePlay(index)"
            @timeupdate="onTimeUpdate($event)"
            @loadedmetadata="onLoadedMetadata($event)"
            @waiting="videoWaiting(index)"
           ></video>
           <!-- 自定义控制条 -->
           <view
            @touchstart.stop="handleTouchStart"
            @touchmove.stop="handleTouchMove"
            @touchend.stop="handleTouchEnd"
            class="container">
            <!-- 进度条 - 整个区域可拖动 -->
            <view class="process-warp" :style="{ opacity: showProcess ? 1 : 0 }">
              <!-- 显示当前进度 -->
              <view class="progress-text">{{ hasPlayTime }}/{{formartDuration}}</view>
              <view
               class="progress-bar"
               id="progressBar"
              >
                        <!-- 已填充部分 -->
                        <view class="progress-fill" :style="{ width: progress + '%' }"></view>
                     </view>
                  </view>
               </view>
               <!-- 已填充部分 -->
               <view class="progress-fill" :style="{ width: progress + '%' }"></view>
              </view>
            </view>
            <view style="width: 100%; height: 100%;" v-else-if="item.videoContentType === 'img'">
               <uni-swiper-dot :info="item.imgs" :current="currentImgIndex" mode="round"
                  style="width: 100%;height: 100%;display: flex;justify-content: center;align-items: center;"
                  :dots-styles="{width: 24, bottom: 24,selectedBackgroundColor: 'green', backgroundColor: 'gray'}">
                  <swiper class="swiper-box" @change="imgChange" :autoplay="true" :interval="3000">
                     <swiper-item v-for="img in item.imgs" :key="img">
                        <view class="swiper-item">
                           <!-- 调整 image 样式,使其居中且按比例缩放 -->
                           <image :src="img" mode="aspectFit"
                              style="width: 100%; height: 100%; display: block; margin: 0 auto;"></image>
                        </view>
                     </swiper-item>
                  </swiper>
               </uni-swiper-dot>
            </view>
           </view>
      </view>
      <view style="width: 100%; height: 100%;" v-else-if="item.videoContentType === 'img'">
        <uni-swiper-dot
         :info="item.imgs"
         :current="currentImgIndex"
         mode="round"
         style="width: 100%;height: 100%;display: flex;justify-content: center;align-items: center;"
         :dots-styles="{width: 24, bottom: 24,selectedBackgroundColor: 'green', backgroundColor: 'gray'}"
         >
          <swiper class="swiper-box" @change="imgChange" :autoplay="true" :interval="3000">
            <swiper-item v-for="img in item.imgs" :key="img">
              <view class="swiper-item">
                <!-- 调整 image 样式,使其居中且按比例缩放 -->
                <image
                  :src="img"
                  mode="aspectFit"
                  style="width: 100%; height: 100%; display: block; margin: 0 auto;"
                ></image>
              </view>
            </swiper-item>
          </swiper>
        </uni-swiper-dot>
      </view>
            <!-- 悬挂商品链接层 -->
            <view class="goods-link-warp" v-if="false">
               <view class="goods-link">
                  <view class="goods-container">
                     <!-- 商品图片 -->
                     <image class="goods-image" :src="item.goods.imageUrl" mode="aspectFill"></image>
      <!-- 悬挂商品链接层 -->
      <view class="goods-link-warp" v-if="item.goodsList.length > 0">
         <view class="goods-link">
           <swiper @change="goodsChange" :autoplay="true" :interval="4000" style="height: 120rpx;">
            <swiper-item v-for="goods in item.goodsList" :key="goods.goodsId">
              <view class="goods-container" @click="jumpToPay(item.id)">
               <!-- 商品图片 -->
               <image class="goods-image" :src="goods.thumbnail" mode="aspectFill"></image>
                     <!-- 商品信息 -->
                     <view class="goods-info">
                        <text class="goods-name">{{item.goods.name}}</text>
                        <view class="price-section">
                           <text class="current-price">¥{{item.goods.price}}</text>
                           <text class="original-price"
                              v-if="item.goods.originalPrice">¥{{item.goods.originalPrice}}</text>
                        </view>
                        <text class="sales-count">{{item.goods.saleNum}}人已购</text>
                     </view>
                     <!-- 购买按钮 -->
                     <view class="buy-button">
                        <text>购买</text>
                     </view>
                  </view>
               <!-- 商品信息 -->
               <view class="goods-info">
                 <text class="goods-name">{{goods.goodsName}}</text>
                 <view class="price-section">
                  <text class="current-price">¥{{goods.price}}</text>
                  <text class="original-price" v-if="goods.originalPrice">¥{{goods.originalPrice}}</text>
                 </view>
               </view>
            </view>
              </view>
            </swiper-item>
           </swiper>
         </view>
      </view>
            <!-- 视频信息层 -->
            <view class="video-info">
               <view>
                  <text class="video-author">@{{item.authorName}}</text>
               </view>
               <view style="width: 100%;word-wrap: break-word;white-space: normal;overflow-wrap: break-word;">
                  <text class="video-title">{{item.title}}</text>
                  <text class="video-tag" v-for="(tag, index) in item.tagList"
                     :key="tag.id">#{{tag.tagName}}</text>
               </view>
            </view>
        <!-- 视频信息层 -->
        <view class="video-info">
        <view>
           <text class="video-author">@{{item.authorName}}</text>
        </view>
          <view style="width: 100%;word-wrap: break-word;white-space: normal;overflow-wrap: break-word;">
           <text class="video-title">{{item.title}}</text>
           <text class="video-tag" v-for="(tag, index) in item.tagList" :key="tag.id">#{{tag.tagName}}</text>
        </view>
        </view>
            <!-- 右侧互动按钮 -->
            <view class="action-buttons" v-if="false">
               <view class="avatar-container">
                  <image class="avatar" @click="jumpToHomePage(item.authorId)" :src="item.authorAvatar"
                     mode="aspectFill"></image>
                  <!-- 关注图标 - 使用绝对定位 -->
                  <view v-if="!item.subscribeThisAuthor" class="follow-icon"
                     @click="subscribeAuth(index, item.authorId)">
                     <text class="iconfont">&#xe629;</text>
                  </view>
               </view>
               <view class="action-item" @click="toggleCollect(item, index)">
                  <text class="iconfont" v-if="item.collected">&#xe605;</text>
                  <text class="iconfont" v-else>&#xe601;</text>
                  <text style="font-size: 10px;font-weight: lighter;">{{item.collectNum}}</text>
               </view>
               <view class="action-item" @click="showComments(item)">
                  <text class="iconfont">&#xe7f7;</text>
                  <text style="font-size: 10px;font-weight: lighter;">{{item.commentNum}}</text>
               </view>
            </view>
        <!-- 右侧互动按钮 -->
       <view class="action-buttons" v-if="false">
         <view class="avatar-container">
            <image class="avatar" @click="jumpToHomePage(item.authorId)" :src="item.authorAvatar" mode="aspectFill"></image>
            <!-- 关注图标 - 使用绝对定位 -->
            <view v-if="!item.subscribeThisAuthor" class="follow-icon" @click="subscribeAuth(index, item.authorId)">
             <text class="iconfont">&#xe629;</text>
            </view>
         </view>
          <view class="action-item" @click="toggleCollect(item, index)">
         <text class="iconfont" v-if="item.collected">&#xe605;</text>
         <text class="iconfont" v-else>&#xe601;</text>
         <text style="font-size: 10px;font-weight: lighter;">{{item.collectNum}}</text>
          </view>
         <view class="action-item" @click="showComments(item)">
            <text class="iconfont">&#xe7f7;</text>
            <text style="font-size: 10px;font-weight: lighter;">{{item.commentNum}}</text>
          </view>
        <view class="action-item">
           <button open-type="share" class="custom-share-btn" :data-obj="item">
                 <text class="iconfont">&#xe602;</text>
               </button>
         </swiper-item>
      </swiper>
        </view>
        </view>
      <!-- 评论弹窗 -->
      <uni-popup ref="commentPopup" type="bottom" :is-mask-click="true" @maskClick="closeCommentPopup">
         <view class="comment-popup">
            <view class="popup-header">
               <text class="popup-title" v-if="!commentForm.replyId">评论({{commentsTotal}})</text>
               <view class="reply-title" v-else>
                  <text>回复 @{{commentForm.replyUserNickname}}</text>
                  <text class="cancel-reply" @click="cancelReply">取消</text>
               </view>
               <text class="iconfont close-icon" @click="closeCommentPopup">&#xe675;</text>
            </view>
      </swiper-item>
    </swiper>
            <scroll-view class="comment-list" scroll-y :show-scrollbar="false" @scrolltolower="getCommentPage">
               <view v-if="commentLoading" class="loading">
                  <uni-load-more status="loading"></uni-load-more>
               </view>
   <!-- 评论弹窗 -->
   <uni-popup ref="commentPopup" type="bottom" :is-mask-click="true" @maskClick="closeCommentPopup">
     <view class="comment-popup">
       <view class="popup-header">
         <text class="popup-title" v-if="!commentForm.replyId">评论({{commentsTotal}})</text>
        <view class="reply-title" v-else>
          <text>回复 @{{commentForm.replyUserNickname}}</text>
          <text class="cancel-reply" @click="cancelReply">取消</text>
        </view>
         <text class="iconfont close-icon" @click="closeCommentPopup">&#xe675;</text>
       </view>
               <view v-else-if="comments.length === 0" class="empty">
                  暂无评论,快来发表第一条评论吧~
               </view>
       <scroll-view class="comment-list" scroll-y :show-scrollbar="false" @scrolltolower="getCommentPage">
         <view v-if="commentLoading" class="loading">
           <uni-load-more status="loading"></uni-load-more>
         </view>
               <view v-else class="comment-item" v-for="(comment, index) in comments" :key="comment.id">
                  <view style="display: flex;">
                     <image class="comment-avatar" :src="comment.userAvatar || '/static/default-avatar.png'">
                     </image>
                     <view class="comment-content">
                        <text class="nickname">{{comment.userNickname}}</text>
                        <text class="content">{{comment.commentContent}}</text>
                        <view style="position: relative;">
                           <text class="time">{{formatTime(comment.createTime)}}</text>
                           <text @click="openReply(comment)" class="reply-btu time">回复</text>
                           <text v-if="!comment.hasThumbsUp" class="thumbs-up time iconfont"
                              @click="thubmsUp(comment.id, index, null)">&#xe614;<text
                                 v-show="comment.thumbsUpNum > 0"
                                 class="thumbs-num">{{comment.thumbsUpNum}}</text></text>
                           <text v-else class="thumbs-up time iconfont"
                              @click="cancelThumbsUp(comment.id, index, null)">&#xe607;<text
                                 v-show="comment.thumbsUpNum > 0"
                                 class="thumbs-num">{{comment.thumbsUpNum}}</text></text>
                        </view>
                     </view>
                  </view>
                  <!-- 回复列表 -->
                  <view class="reply-list" v-if="comment.replies && comment.replies.length > 0">
                     <view class="reply-item" v-for="(reply, replyIndex) in comment.replies" :key="reply.id">
                        <view class="reply-content">
                           <view style="display: flex;">
                              <image class="comment-reply-avatar"
                                 :src="reply.replyUserAvatar || '/static/default-avatar.png'"></image>
                              <text class="nickname">{{reply.userNickname}}</text>
                              <text v-if="reply.replyUserId && reply.masterCommentId !== reply.replyId"
                                 class="reply-to"><text style="margin-right: 10rpx;font-size: 28rpx;"
                                    class="iconfont">&#xe666;</text>{{reply.replyUserNickname}}</text>
                           </view>
                           <text class="content">{{reply.commentContent}}</text>
                           <view class="reply-footer">
                              <text class="time">{{formatTime(reply.createTime)}}</text>
                              <text @click="openReply(comment, reply)" class="reply-btu time">回复</text>
                              <text v-if="!reply.hasThumbsUp" class="thumbs-up time iconfont"
                                 @click="thubmsUp(reply.id, index, replyIndex)">&#xe614;<text
                                    v-show="reply.thumbsUpNum > 0"
                                    class="thumbs-num">{{reply.thumbsUpNum}}</text></text>
                              <text v-else class="thumbs-up time iconfont"
                                 @click="cancelThumbsUp(reply.id, index, replyIndex)">&#xe607;<text
                                    v-show="reply.thumbsUpNum > 0"
                                    class="thumbs-num">{{reply.thumbsUpNum}}</text></text>
                           </view>
                        </view>
                     </view>
                  </view>
                  <view class="view-more-replies" v-if="comment.replyTotalCount > 0 && !comment.expandReply"
                     @click="loadRepliesPage(comment, index)">
                     <text class="line">——</text>展开{{comment.replyTotalCount}}条回复 ↓
                  </view>
                  <view class="reply-op"
                     v-if="comment.replyTotalCount > replyCommentQuery.pageNumber * replyCommentQuery.pageSize && comment.expandReply">
                     <view @click="loadNextPageReply(index)" class="reply-op-item"><text
                           class="line">——</text>展开更多<text class="iconfont textSideIcon">&#xeb8d;</text></view>
                     <view @click="retractReplyComment(index)" class="reply-op-item" style="margin-left: 50rpx;">
                        收起<text class="iconfont textSideIcon">&#xeb9b;</text></view>
                  </view>
                  <view class="reply-op"
                     v-else-if="comment.replyTotalCount <= replyCommentQuery.pageNumber * replyCommentQuery.pageSize && comment.expandReply">
                     <view @click="retractReplyComment(index)" class="reply-op-item"><text
                           class="line">——</text>收起<text class="iconfont textSideIcon">&#xeb9b;</text></view>
                  </view>
               </view>
            </scroll-view>
            <view class="comment-input-area">
               <input ref="commentInput" class="comment-input" v-model="commentForm.commentContent"
                  :placeholder="commentForm.replyId ? `回复 @${commentForm.replyUserNickname}` : '写下你的评论...'"
                  placeholder-class="placeholder" />
               <button class="submit-btn" @click="submitComment"
                  :disabled="!commentForm.commentContent.trim()">发送</button>
         <view v-else-if="comments.length === 0" class="empty">
           暂无评论,快来发表第一条评论吧~
         </view>
         <view v-else class="comment-item" v-for="(comment, index) in comments" :key="comment.id">
         <view style="display: flex;">
            <image class="comment-avatar" :src="comment.userAvatar || '/static/default-avatar.png'"></image>
            <view class="comment-content">
              <text class="nickname">{{comment.userNickname}}</text>
              <text class="content">{{comment.commentContent}}</text>
              <view style="position: relative;">
               <text class="time">{{formatTime(comment.createTime)}}</text>
               <text @click="openReply(comment)" class="reply-btu time">回复</text>
               <text v-if="!comment.hasThumbsUp" class="thumbs-up time iconfont" @click="thubmsUp(comment.id, index, null)">&#xe614;<text v-show="comment.thumbsUpNum > 0" class="thumbs-num">{{comment.thumbsUpNum}}</text></text>
               <text v-else class="thumbs-up time iconfont" @click="cancelThumbsUp(comment.id, index, null)">&#xe607;<text v-show="comment.thumbsUpNum > 0" class="thumbs-num">{{comment.thumbsUpNum}}</text></text>
              </view>
            </view>
         </view>
      </uni-popup>
         <!-- 回复列表 -->
           <view class="reply-list" v-if="comment.replies && comment.replies.length > 0">
            <view class="reply-item" v-for="(reply, replyIndex) in comment.replies" :key="reply.id">
              <view class="reply-content">
               <view style="display: flex;">
                  <image class="comment-reply-avatar" :src="reply.replyUserAvatar || '/static/default-avatar.png'"></image>
                  <text class="nickname">{{reply.userNickname}}</text>
                  <text v-if="reply.replyUserId && reply.masterCommentId !== reply.replyId" class="reply-to"><text style="margin-right: 10rpx;font-size: 28rpx;" class="iconfont">&#xe666;</text>{{reply.replyUserNickname}}</text>
               </view>
               <text class="content">{{reply.commentContent}}</text>
               <view class="reply-footer">
                 <text class="time">{{formatTime(reply.createTime)}}</text>
                 <text @click="openReply(comment, reply)" class="reply-btu time">回复</text>
                 <text v-if="!reply.hasThumbsUp" class="thumbs-up time iconfont" @click="thubmsUp(reply.id, index, replyIndex)">&#xe614;<text v-show="reply.thumbsUpNum > 0" class="thumbs-num">{{reply.thumbsUpNum}}</text></text>
                 <text v-else class="thumbs-up time iconfont" @click="cancelThumbsUp(reply.id, index, replyIndex)">&#xe607;<text v-show="reply.thumbsUpNum > 0" class="thumbs-num">{{reply.thumbsUpNum}}</text></text>
               </view>
              </view>
            </view>
           </view>
           <view class="view-more-replies" v-if="comment.replyTotalCount > 0 && !comment.expandReply" @click="loadRepliesPage(comment, index)">
            <text class="line">——</text>展开{{comment.replyTotalCount}}条回复 ↓
           </view>
           <view class="reply-op" v-if="comment.replyTotalCount > replyCommentQuery.pageNumber * replyCommentQuery.pageSize && comment.expandReply">
              <view @click="loadNextPageReply(index)" class="reply-op-item"><text class="line">——</text>展开更多<text class="iconfont textSideIcon">&#xeb8d;</text></view>
              <view @click="retractReplyComment(index)" class="reply-op-item" style="margin-left: 50rpx;">收起<text class="iconfont textSideIcon">&#xeb9b;</text></view>
           </view>
           <view class="reply-op" v-else-if="comment.replyTotalCount <= replyCommentQuery.pageNumber * replyCommentQuery.pageSize && comment.expandReply">
              <view @click="retractReplyComment(index)" class="reply-op-item"><text class="line">——</text>收起<text class="iconfont textSideIcon">&#xeb9b;</text></view>
           </view>
         </view>
       </scroll-view>
       <view class="comment-input-area">
        <input
         ref="commentInput"
         class="comment-input"
         v-model="commentForm.commentContent"
         :placeholder="commentForm.replyId ? `回复 @${commentForm.replyUserNickname}` : '写下你的评论...'"
         placeholder-class="placeholder"
        />
        <button class="submit-btn" @click="submitComment" :disabled="!commentForm.commentContent.trim()">发送</button>
      </view>
     </view>
   </uni-popup>
   </view>
   <custom-tabbar bgColor="#333333" selected="index" selectedTextColor="#ffffff"></custom-tabbar>
  </view>
</template>
<script>
   import {
      getHealthRecommendVideos,
      savePlayRecord,
      subscribe,
      getVideoComments,
      addVideoComment,
      thubmsUpComment,
      cancelThubmsUpComment
   } from "@/api/video.js";
   import {
      changeCollect
   } from "@/api/collect.js";
   export default {
      computed: {
         hasPlayTime() {
            return this.sliderFormatTime(this.progress > 0 ? this.duration * this.progress / 100 : 0);
import { getHealthRecommendVideos, savePlayRecord, subscribe, getVideoComments, addVideoComment, thubmsUpComment, cancelThubmsUpComment } from "@/api/video.js";
import { changeCollect } from "@/api/collect.js";
import { saveShare, saveShareClickRecord } from "@/api/share.js";
import { silentLogin } from "@/api/connect.js";
import { getUserInfo } from "@/api/members";
import storage from "@/utils/storage.js";
export default {
  computed: {
       hasPlayTime() {
         return this.sliderFormatTime(this.progress > 0 ? this.duration * this.progress / 100 : 0);
       }
  },
  data() {
    return {
      currentImgIndex: 0, // 播放到第几张图--索引
      currentGoodsIndex: 0, // 播放到第几个商品--索引
      currentTime: 0,
      formartDuration: '',
      duration: 0,
      startX: 0,
      progress: 0, // 视频进度
      startProgress : 0, // 开始滑动时的进度
      barLeft: 0, // 进度条左边界位置
      barWidth: 0, // 进度条宽度
      isDragging: false, // 是否正在拖动
      processHidenTimer: null, // 进度条隐藏定时器
      showProcess: false, // 是否显示进度条
      videoNoMore: false, // 是否还有更多视频
      commentNoMore: false, // 是否还有更多评论
      commentQuery: {
         pageNumber: 1,
         pageSize: 5,
         videoId: '',
         masterCommentId: ''
      },
      replyCommentQuery: {
         pageNumber: 1,
         pageSize: 5,
         videoId: '',
         masterCommentId: ''
      },
      commentForm: { // 评论表单数据
         id: '',
         videoId: '',
         commentContent: '',
         replyId: '',
         replyUserId: '',
         replyUserNickname: '',
         replyUserAvatar: '',
         masterCommentId: null
      },
      comments: [],            // 评论列表
      commentsTotal: 0,            // 评论总条数
      commentLoading: false,   // 评论加载状态
      startHidenTime: 0, // 记录切换至其它页面的时间,用于计算视频观看时间减去的部分
      totalHidenTime: 0, // 总共隐藏页面的时间
      startPauseTime: 0, // 开始暂停的时间
      totalPauseTime: 0, // 总共暂停的时间
      playRecord: {
         videoId: null,
         viewDuration: 0, // 这个视频总共观看了多久
         playAt: 0 ,// 这个视频播放到哪了
         startPlayTime: 0 // 这个视频从什么时候开始播放的
      },
      currentVideoIsPlaying: true, // 当前视频是否正在播放
      currentIndex: 0, // 当前播放的视频索引
      videoLoading: false, // 视频缓冲中
      videoList: [],   // 视频列表数据
      videoBufferOffset: 0.1 ,// 视频预加载参数
      videoLiveOffset: 2, // 保留当前视频前后各多少个视频上下文
      touchXY: {  // 监听左滑右滑
         startX: 0,
         endX: 0,
         startY: 0,
         endY: 0
      },
      loading: false,  // 是否正在加载
      videoQuery: {
         pageNumber: 1,
         pageSize: 10,
         videoFrom: 'recommend'
      }
    }
  },
  onShow() {
     // const token = storage.getAccessToken();
     // if (! token) {
       //  this.wxSilentLogin(() => {
         //   this.loadVideos();
       //  })
     // } else {
     //      this.loadVideos();
     // }
     // 如果视频按下暂停后切换页面再回到页面时,只算暂停时间(因为暂停时间和离开页面时间是重复的,只算一个)
     if(this.startHidenTime !== 0 && this.currentVideoIsPlaying) {
        const duration = Date.now() - this.startHidenTime
        this.totalHidenTime += duration
     }
  },
  onHide() {
     this.startHidenTime = Date.now()
  },
  onLoad(option) {
     const token = storage.getAccessToken();
     if (! token) {
        this.wxSilentLogin(() => {
           this.loadVideos();
           // 判断是不是点击分享链接进来的
           if (option.userId && option.videoId) {
              // 保存分享点击记录
              saveShareClickRecord({refId: option.videoId, shareUserId: option.userId})
           }
        })
     } else {
      this.loadVideos();
     }
  },
  onShareAppMessage(e) {
   const userInfo = storage.getUserInfo();
   if(!userInfo) {
      console.log("未登录不能分享");
      return
   }
   const videoInfo = e.target.dataset.obj;
   // 保存分享记录
   const data = {
      shareType: 'video',
      refId: videoInfo.id,
      shareUser: userInfo.id
   }
   saveShare(data)
     return {
        title: videoInfo.title,
        path: `/pages/tabbar/index/home?videoId=${videoInfo.id}&userId=${userInfo.id}`,
        imageUrl: videoInfo.coverUrl
     }
  },
  methods: {
     // 静默登录
     wxSilentLogin(callback) {
        //获取code
        uni.login({
          success: (codeRes) => {
            if(codeRes.errMsg === "login:ok") {
            // 静默登录
            silentLogin({code: codeRes.code}).then(res => {
               storage.setAccessToken(res.data.data.accessToken);
               storage.setRefreshToken(res.data.data.refreshToken);
               //获取用户信息
               getUserInfo().then((user) => {
                 storage.setUserInfo(user.data.result);
                 storage.setHasLogin(true);
                 callback()
               });
            })
            } else {
              uni.showToast({
                title: "系统异常,请联系管理员!"
              })
            }
          },
        });
     },
     // 点击商品跳转
     jumpToPay(videoId) {
      uni.navigateTo({
         url: '/pages/video/video-goods-detail?videoId=' + videoId
      });
     },
     // 轮播图变化
     imgChange(e) {
        this.currentImgIndex = e.detail.current;
     },
     // 商品轮播图变化
     goodsChange(e) {
        this.currentGoodsIndex = e.detail.current;
     },
     // 获取进度条的位置和尺寸
     getBarRect() {
       const query = uni.createSelectorQuery().in(this);
       query.select('#progressBar').boundingClientRect(rect => {
         if (rect) {
           this.barLeft = rect.left;
           this.barWidth = rect.width;
         }
       }).exec();
     },
      // 跳转个人主页
      jumpToHomePage(authorId) {
         uni.navigateTo({
            url: "/pages/video/home-page?authorId=" + authorId
         })
      },
      // 取消点赞
      async cancelThumbsUp(id, commentIndex, replyIndex) {
         const data = {
            refId: id,
            thumbsUpType: 'video_comment'
         }
         cancelThubmsUpComment(data).then(res => {
            if(replyIndex != null) {
               this.comments[commentIndex].replies[replyIndex].hasThumbsUp = false;
               this.comments[commentIndex].replies[replyIndex].thumbsUpNum -= 1;
            } else {
               this.comments[commentIndex].hasThumbsUp = false;
               this.comments[commentIndex].thumbsUpNum -= 1;
            }
         })
      },
      // 评论点赞
      async thubmsUp(id, commentIndex, replyIndex) {
         const data = {
            refId: id,
            thumbsUpType: 'video_comment'
         }
         thubmsUpComment(data).then(res => {
            if(replyIndex != null) {
               this.comments[commentIndex].replies[replyIndex].hasThumbsUp = true;
               this.comments[commentIndex].replies[replyIndex].thumbsUpNum += 1;
            } else {
               this.comments[commentIndex].hasThumbsUp = true;
               this.comments[commentIndex].thumbsUpNum += 1;
            }
         })
      },
      // 加载下一页回复
      loadNextPageReply(index) {
         this.replyCommentQuery.pageNumber++;
         getVideoComments(this.replyCommentQuery).then(res => {
            this.comments[index].replies = [
              ...this.comments[index].replies,
              ...res.data.data.filter(
                (newItem) => !this.comments[index].replies.some((oldItem) => oldItem.id === newItem.id)
              ),
            ];
         })
      },
      // 收起回复
      retractReplyComment(index) {
         this.comments[index].expandReply = false;
         this.comments[index].replies = [];
      },
      // 加载回复
      loadRepliesPage(comment, index) {
         this.replyCommentQuery.pageNumber = 1;
         this.replyCommentQuery.masterCommentId = comment.id
          getVideoComments(this.replyCommentQuery).then(res => {
            this.comments[index].replies = res.data.data;
            this.comments[index].expandReply = true;
         })
      },
      resetCommentForm() {
         const videoId = this.commentForm.videoId;
         this.commentForm = { // 评论表单数据
            id: '',
            videoId: videoId,
            commentContent: '',
            replyId: '',
            replyUserId: '',
            replyUserNickname: '',
            replyUserAvatar: '',
            masterCommentId: null
         }
      },
      data() {
         return {
            currentImgIndex: 0, // 播放到第几张图--索引
            currentTime: 0,
            formartDuration: [],
            duration: 0,
            startX: 0,
            progress: 0, // 视频进度
            startProgress: 0, // 开始滑动时的进度
            barLeft: 0, // 进度条左边界位置
            barWidth: 0, // 进度条宽度
            isDragging: false, // 是否正在拖动
            processHidenTimer: null, // 进度条隐藏定时器
            showProcess: false, // 是否显示进度条
            videoNoMore: false, // 是否还有更多视频
            commentNoMore: false, // 是否还有更多评论
            commentQuery: {
               pageNumber: 1,
               pageSize: 5,
               videoId: '',
               masterCommentId: ''
            },
            replyCommentQuery: {
               pageNumber: 1,
               pageSize: 5,
               videoId: '',
               masterCommentId: ''
            },
            commentForm: { // 评论表单数据
               id: '',
               videoId: '',
               commentContent: '',
               replyId: '',
               replyUserId: '',
               replyUserNickname: '',
               replyUserAvatar: '',
               masterCommentId: null
            },
            comments: [], // 评论列表
            commentsTotal: 0, // 评论总条数
            commentLoading: false, // 评论加载状态
            startHidenTime: 0, // 记录切换至其它页面的时间,用于计算视频观看时间减去的部分
            totalHidenTime: 0, // 总共隐藏页面的时间
            startPauseTime: 0, // 开始暂停的时间
            totalPauseTime: 0, // 总共暂停的时间
            playRecord: {
               videoId: null,
               viewDuration: 0, // 这个视频总共观看了多久
               playAt: 0, // 这个视频播放到哪了
               startPlayTime: 0 // 这个视频从什么时候开始播放的
            },
            currentVideoIsPlaying: true, // 当前视频是否正在播放
            isFullScreen: false,
            windowHeight: 0,
            currentIndex: 0, // 当前播放的视频索引
            videoList: [
       // 取消回复
       cancelReply() {
           this.resetCommentForm()
         },
      // 打开回复框
      openReply(comment, reply = null) {
        if(reply) {
         comment = reply
        }
        this.commentForm.masterCommentId = comment.masterCommentId ? comment.masterCommentId : comment.id;
        this.commentForm.replyId = comment.id;
        this.commentForm.replyUserId = comment.userId;
        this.commentForm.replyUserNickname = comment.userNickname;
        this.commentForm.replyUserAvatar = comment.userAvatar;
        // 自动聚焦输入框
        this.$nextTick(() => {
         const input = this.$refs.commentInput;
         if (input) input.focus();
        });
      },
      // 进度条时间格式化 (00:00)
      sliderFormatTime(seconds) {
        const mins = Math.floor(seconds / 60);
        const secs = Math.floor(seconds % 60);
        return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
      },
      // 格式化时间
       formatTime(time) {
         const date = new Date(time);
         const now = new Date();
         const diff = Math.floor((now - date) / 1000); // 秒
            ], // 视频列表数据
            videoContexts: [], // 视频上下文对象集合
            loading: false, // 是否正在加载
            videoQuery: {
               pageNumber: 1,
               pageSize: 6,
               videoFrom: 'recommend',
               videoType: 'health'
            }
         if (diff < 60) return '刚刚';
         if (diff < 3600) return `${Math.floor(diff / 60)}分钟前`;
         if (diff < 86400) return `${Math.floor(diff / 3600)}小时前`;
         return `${date.getMonth() + 1}月${date.getDate()}日`;
       },
      // 提交评论
       async submitComment() {
         if (!this.commentForm.commentContent.trim()) {
           uni.showToast({
             title: '评论内容不能为空',
             icon: 'none'
           });
           return;
         }
        // 发表评论
         addVideoComment(this.commentForm).then(res => {
           if(res.data.code === 200) {
              this.resetCommentForm()
              // 如果是评论别人的回复,那么就将这个发布到replies里面
              if(res.data.data.replyId) {
                 for (const [index, item] of this.comments.entries()) {
                   if (item.id === res.data.data.replyId) {
                     item.replies.unshift(res.data.data);
                     // this.loadRepliesPage(item, index)
                     break; // 跳出循环
                   }
                 }
              } else {
               this.comments.unshift(res.data.data);
              }
              console.log("新增后",this.comments);
              uni.showToast({
                title: '评论成功'
              });
              // 当前视频评论数加一
              this.commentsTotal += 1;
              this.videoList[this.currentIndex].commentNum += 1;
           } else {
              uni.showToast({
                      title: res.data.msg,
                      icon: 'none'
                    });
           }
        }).catch(() => {
           uni.showToast({
                   title: '评论失败',
                   icon: 'none'
                 });
        })
       },
       // 关闭评论弹窗
       closeCommentPopup() {
        this.$refs.commentPopup.close()
         this.showCommentPopup = false;
         this.comments = [];
         this.resetCommentForm()
        this.commentQuery.pageNumber = 1;
        this.commentNoMore = false;
       },
      // 下滑评论区加载评论
      async getCommentPage() {
         if(this.commentNoMore) {
            return;
         }
      },
      onShow() {
         this.loadVideos()
         // 如果视频按下暂停后切换页面再回到页面时,只算暂停时间(因为暂停时间和离开页面时间是重复的,只算一个)
         if (this.startHidenTime !== 0 && this.currentVideoIsPlaying) {
            const duration = Date.now() - this.startHidenTime
            this.totalHidenTime += duration
         }
      },
      onHide() {
         this.startHidenTime = Date.now()
      },
      onLoad() {
         this.loadVideos();
      },
      onReady() {
         // 初始化视频上下文
         this.initVideoContexts();
      },
      methods: {
         // 轮播图变化
         imgChange(e) {
            this.currentImgIndex = e.detail.current;
         },
         // 获取进度条的位置和尺寸
         getBarRect() {
            const query = uni.createSelectorQuery().in(this);
            query.select('#progressBar').boundingClientRect(rect => {
               if (rect) {
                  this.barLeft = rect.left;
                  this.barWidth = rect.width;
               }
            }).exec();
         },
         // 跳转个人主页
         jumpToHomePage(authorId) {
            uni.navigateTo({
               url: "/pages/video/home-page?authorId=" + authorId
            })
         },
         // 取消点赞
         async cancelThumbsUp(id, commentIndex, replyIndex) {
            const data = {
               refId: id,
               thumbsUpType: 'video_comment'
            }
            cancelThubmsUpComment(data).then(res => {
               if (replyIndex != null) {
                  this.comments[commentIndex].replies[replyIndex].hasThumbsUp = false;
                  this.comments[commentIndex].replies[replyIndex].thumbsUpNum -= 1;
               } else {
                  this.comments[commentIndex].hasThumbsUp = false;
                  this.comments[commentIndex].thumbsUpNum -= 1;
               }
            })
         },
         // 评论点赞
         async thubmsUp(id, commentIndex, replyIndex) {
            const data = {
               refId: id,
               thumbsUpType: 'video_comment'
            }
            thubmsUpComment(data).then(res => {
               if (replyIndex != null) {
                  this.comments[commentIndex].replies[replyIndex].hasThumbsUp = true;
                  this.comments[commentIndex].replies[replyIndex].thumbsUpNum += 1;
               } else {
                  this.comments[commentIndex].hasThumbsUp = true;
                  this.comments[commentIndex].thumbsUpNum += 1;
               }
            })
         },
         // 加载下一页回复
         loadNextPageReply(index) {
            this.replyCommentQuery.pageNumber++;
            getVideoComments(this.replyCommentQuery).then(res => {
               this.comments[index].replies = [
                  ...this.comments[index].replies,
                  ...res.data.data.filter(
                     (newItem) => !this.comments[index].replies.some((oldItem) => oldItem.id === newItem
                        .id)
                  ),
         getVideoComments(this.commentQuery).then(res => {
            if(this.commentQuery.pageNumber === 1) {
               this.comments = res.data.data
            } else {
               this.comments = [
                 ...this.comments,
                 ...res.data.data.filter(
                   (newItem) => !this.comments.some((oldItem) => oldItem.id === newItem.id)
                 ),
               ];
            })
         },
         // 收起回复
         retractReplyComment(index) {
            this.comments[index].expandReply = false;
            this.comments[index].replies = [];
         },
         // 加载回复
         loadRepliesPage(comment, index) {
            this.replyCommentQuery.pageNumber = 1;
            this.replyCommentQuery.masterCommentId = comment.id
            getVideoComments(this.replyCommentQuery).then(res => {
               this.comments[index].replies = res.data.data;
               this.comments[index].expandReply = true;
            })
         },
         resetCommentForm() {
            const videoId = this.commentForm.videoId;
            this.commentForm = { // 评论表单数据
               id: '',
               videoId: videoId,
               commentContent: '',
               replyId: '',
               replyUserId: '',
               replyUserNickname: '',
               replyUserAvatar: '',
               masterCommentId: null
            }
         },
         // 取消回复
         cancelReply() {
            this.resetCommentForm()
         },
         // 打开回复框
         openReply(comment, reply = null) {
            if (reply) {
               comment = reply
            if (res.data.data.length < this.commentQuery.pageSize) {
               this.commentNoMore = true;
               return;
            }
            this.commentForm.masterCommentId = comment.masterCommentId ? comment.masterCommentId : comment.id;
            this.commentForm.replyId = comment.id;
            this.commentForm.replyUserId = comment.userId;
            this.commentForm.replyUserNickname = comment.userNickname;
            this.commentForm.replyUserAvatar = comment.userAvatar;
            // 自动聚焦输入框
            this.$nextTick(() => {
               const input = this.$refs.commentInput;
               if (input) input.focus();
            this.commentQuery.pageNumber++;
         })
      },
       // 显示评论弹窗
       async showComments(item) {
         this.commentForm.videoId = item.id;
         this.$refs.commentPopup.open();
         this.commentLoading = true;
         this.commentQuery.videoId = item.id
         this.replyCommentQuery.videoId = item.id
        // 首次加载评论分页大小增加一倍,以产生滚动条,后续可触发
        this.commentQuery.pageSize *= 2;
        getVideoComments(this.commentQuery).then(res => {
           this.commentsTotal = res.data.total;
           this.comments = res.data.data;
           this.commentQuery.pageNumber += 2;
           this.commentQuery.pageSize /= 2;
        }).catch(() => {
           uni.showToast({
             title: '获取评论失败',
             icon: 'none'
           });
        }).finally(() => {
           this.commentLoading = false;
        })
       },
     // 关注作者
     subscribeAuth(index, authorId) {
      this.videoList.forEach(video => {
         if(video.authorId === authorId) {
            video.subscribeThisAuthor = true
         }
      })
      subscribe(authorId).then(res => {
         if(res.data.code === 200) {
            uni.showToast({
              title: '关注成功~',
              icon: 'none'
            });
         },
         // 进度条时间格式化 (00:00)
         sliderFormatTime(seconds) {
            const mins = Math.floor(seconds / 60);
            const secs = Math.floor(seconds % 60);
            return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
         },
         // 格式化时间
         formatTime(time) {
            const date = new Date(time);
            const now = new Date();
            const diff = Math.floor((now - date) / 1000); // 秒
            if (diff < 60) return '刚刚';
            if (diff < 3600) return `${Math.floor(diff / 60)}分钟前`;
            if (diff < 86400) return `${Math.floor(diff / 3600)}小时前`;
            return `${date.getMonth() + 1}月${date.getDate()}日`;
         },
         // 提交评论
         async submitComment() {
            if (!this.commentForm.commentContent.trim()) {
               uni.showToast({
                  title: '评论内容不能为空',
                  icon: 'none'
               });
               return;
            }
            // 发表评论
            addVideoComment(this.commentForm).then(res => {
               if (res.data.code === 200) {
                  this.resetCommentForm()
                  // 如果是评论别人的回复,那么就将这个发布到replies里面
                  if (res.data.data.replyId) {
                     for (const [index, item] of this.comments.entries()) {
                        if (item.id === res.data.data.replyId) {
                           item.replies.unshift(res.data.data);
                           // this.loadRepliesPage(item, index)
                           break; // 跳出循环
                        }
                     }
                  } else {
                     this.comments.unshift(res.data.data);
                  }
                  console.log("新增后", this.comments);
                  uni.showToast({
                     title: '评论成功'
                  });
                  // 当前视频评论数加一
                  this.commentsTotal += 1;
                  this.videoList[this.currentIndex].commentNum += 1;
               } else {
                  uni.showToast({
                     title: res.data.msg,
                     icon: 'none'
                  });
               }
            }).catch(() => {
               uni.showToast({
                  title: '评论失败',
                  icon: 'none'
               });
            })
         },
         // 关闭评论弹窗
         closeCommentPopup() {
            this.$refs.commentPopup.close()
            this.showCommentPopup = false;
            this.comments = [];
            this.resetCommentForm()
            this.commentQuery.pageNumber = 1;
            this.commentNoMore = false;
         },
         // 下滑评论区加载评论
         async getCommentPage() {
            if (this.commentNoMore) {
               return;
            }
            getVideoComments(this.commentQuery).then(res => {
               if (this.commentQuery.pageNumber === 1) {
                  this.comments = res.data.data
               } else {
                  this.comments = [
                     ...this.comments,
                     ...res.data.data.filter(
                        (newItem) => !this.comments.some((oldItem) => oldItem.id === newItem.id)
                     ),
                  ];
               }
               if (res.data.data.length < this.commentQuery.pageSize) {
                  this.commentNoMore = true;
                  return;
               }
               this.commentQuery.pageNumber++;
            })
         },
         // 显示评论弹窗
         async showComments(item) {
            this.commentForm.videoId = item.id;
            this.$refs.commentPopup.open();
            this.commentLoading = true;
            this.commentQuery.videoId = item.id
            this.replyCommentQuery.videoId = item.id
            // 首次加载评论分页大小增加一倍,以产生滚动条,后续可触发
            this.commentQuery.pageSize *= 2;
            getVideoComments(this.commentQuery).then(res => {
               this.commentsTotal = res.data.total;
               this.comments = res.data.data;
               this.commentQuery.pageNumber += 2;
               this.commentQuery.pageSize /= 2;
            }).catch(() => {
               uni.showToast({
                  title: '获取评论失败',
                  icon: 'none'
               });
            }).finally(() => {
               this.commentLoading = false;
            })
         },
         // 关注作者
         subscribeAuth(index, authorId) {
         } else {
            this.videoList.forEach(video => {
               if (video.authorId === authorId) {
                  video.subscribeThisAuthor = true
               if(video.authorId === authorId) {
                  video.subscribeThisAuthor = false
               }
            })
            subscribe(authorId).then(res => {
               if (res.data.code === 200) {
                  uni.showToast({
                     title: '关注成功~',
                     icon: 'none'
                  });
               } else {
                  this.videoList.forEach(video => {
                     if (video.authorId === authorId) {
                        video.subscribeThisAuthor = false
                     }
                  })
               }
            })
         },
         // 初始化视频上下文
         initVideoContexts() {
            this.videoContexts = this.videoList.map((_, index) => {
               let videoContent = uni.createVideoContext(`video${index}`, this);
               return videoContent;
            });
         },
         }
      })
     },
         // 加载视频数据
         async loadVideos() {
            if (this.loading || this.videoNoMore) return;
            this.loading = true;
    // 加载视频数据
    async loadVideos() {
      if (this.loading || this.videoNoMore) return;
      this.loading = true;
            getHealthRecommendVideos(this.videoQuery).then(res => {
               console.log(res, "视频数据");
               if (this.videoQuery.pageNumber === 1) {
                  this.videoList = res.data.data;
               } else {
                  this.videoList = [
                     ...this.videoList,
                     ...res.data.data.filter(
                        (newItem) => !this.videoList.some((oldItem) => oldItem.id === newItem.id)
                     ),
                  ];
               }
               this.$nextTick(() => {
                  this.initVideoContexts();
               });
               this.loading = false;
               if (res.data.data.length < this.videoQuery.pageSize) {
                  this.videoNoMore = true;
                  return;
               }
               this.videoQuery.pageNumber++;
      getHealthRecommendVideos(this.videoQuery).then(res => {
        console.log(res, "视频数据");
        if (this.videoQuery.pageNumber === 1) {
          this.videoList = res.data.data;
        } else {
         this.videoList = [
           ...this.videoList,
           ...res.data.data.filter(
             (newItem) => !this.videoList.some((oldItem) => oldItem.id === newItem.id)
           ),
         ];
        }
        this.loading = false;
        if(res.data.data.length < this.videoQuery.pageSize) {
           this.videoNoMore = true;
           return;
        }
        this.videoQuery.pageNumber++;
            })
         },
     })
    },
         // 滑动切换视频
         onSwiperChange(e) {
            // 如果视频处于暂停状态往下刷视频,那么需要再计算一次暂停时间
            if (!this.currentVideoIsPlaying) {
               if (this.startPauseTime !== 0) {
                  const duration = Date.now() - this.startPauseTime
                  this.totalPauseTime += duration
               }
            }
            // 保存上一个视频的播放记录
            this.savePlayRecord()
            const oldIndex = this.currentIndex;
            this.currentIndex = e.detail.current;
            // 暂停上一个视频
            if (this.videoContexts[oldIndex]) {
               this.videoContexts[oldIndex].pause();
            }
            this.startPauseTime = 0;
            // 播放当前视频
            if (this.videoContexts[this.currentIndex]) {
               this.videoContexts[this.currentIndex].play();
            }
         },
         // 收藏/取消收藏
         toggleCollect(item, index) {
            let data = {
               refId: item.id,
               collectType: 'video'
            }
            const beforeCollected = item.collected
            const beforeCollectNum = item.collectNum
            if (item.collected) {
               this.videoList[index].collected = false
               this.videoList[index].collectNum -= 1
            } else {
               this.videoList[index].collected = true
               this.videoList[index].collectNum += 1
            }
            changeCollect(data).then(res => {
               if (res.data.code !== 200) {
                  this.videoList[index].collected = beforeCollected
                  this.videoList[index].collectNum = beforeCollectNum
               }
            })
         },
         // 单击屏幕:暂停或继续播放
         togglePlay(index) {
            console.log("单击视频", index, this.videoContexts);
            if (this.currentVideoIsPlaying) {
               this.videoContexts[index].pause();
            } else {
               this.videoContexts[index].play();
            }
         },
         // 视频播放事件
         onPlay(id, index) {
            this.getBarRect()
            this.progress = 0
            console.log(id, index, "触发播放");
            if (index === this.currentIndex) {
               this.currentVideoIsPlaying = true;
            } else {
               this.currentVideoIsPlaying = false;
               return
            }
            this.playRecord.videoId = id;
            // 没初始化才赋值,因为一个视频重复播放onPlay会重复触发
            if (this.playRecord.startPlayTime === 0) {
               this.playRecord.startPlayTime = Date.now();
            }
            if (this.startPauseTime !== 0) {
               const duration = Date.now() - this.startPauseTime
               this.totalPauseTime += duration
            }
         },
         // 视频暂停事件
         onPause(index) {
            console.log(index, "触发暂停");
            if (index === this.currentIndex) {
               this.currentVideoIsPlaying = false;
            } else {
               this.currentVideoIsPlaying = true;
               return
            }
            this.startPauseTime = Date.now()
         },
         // 视频结束事件
         onEnded(index) {
            // this.currentVideoIsPlaying = false;
         },
         // 记录播放时长
         onTimeUpdate(e) {
            this.playRecord.playAt = e.detail.currentTime;
            this.currentTime = e.detail.currentTime;
            this.progress = (e.detail.currentTime / this.duration) * 100
         },
         // 触摸开始
         handleTouchStart(e) {
            this.isDragging = true;
            this.showProcess = true;
            this.startProgress = this.progress; // 记录开始时的进度
            this.startX = e.touches[0].pageX;
            console.log("记录开始时的进度", this.startProgress);
            this.videoContexts[this.currentIndex].pause()
            // this.updateProgress(e);
         },
         // 触摸移动
         handleTouchMove(e) {
            if (!this.isDragging || !this.barWidth) return;
            clearTimeout(this.processHidenTimer)
            this.videoContexts[this.currentIndex].pause()
            this.updateProgress(e);
         },
         // 触摸结束
         handleTouchEnd() {
            this.isDragging = false;
            console.log("滑动结束", this.duration * this.progress);
            this.videoContexts[this.currentIndex].seek(this.duration * this.progress / 100)
            this.videoContexts[this.currentIndex].play()
            this.processHidenTimer = setTimeout(() => {
               this.showProcess = false;
            }, 1000);
         },
         // 更新进度
         updateProgress(e) {
            // 获取当前触摸点X坐标
            const currentX = e.touches[0].pageX;
            // 计算滑动距离(像素)
            const deltaX = currentX - this.startX;
            // 将像素距离转换为进度增量
            const deltaProgress = (deltaX / this.barWidth) * 100;
            console.log("进度增量", deltaProgress);
            // 计算新进度 = 开始时的进度 + 滑动增量
            let newProgress = this.startProgress + deltaProgress;
            // 限制范围在0-100之间
            newProgress = Math.max(0, Math.min(100, newProgress));
            this.progress = newProgress;
         },
         // 获取视频总时长
         onLoadedMetadata(e) {
            this.duration = e.detail.duration;
            this.formartDuration.push(this.sliderFormatTime(this.duration));
            console.log("视频总时长", this.duration);
         },
         // 保存播放记录
         async savePlayRecord() {
            console.log(Date.now(), this.playRecord.startPlayTime, this.totalHidenTime);
            const data = {
               videoId: this.playRecord.videoId,
               viewDuration: Date.now() - this.playRecord.startPlayTime - this.totalHidenTime - this
                  .totalPauseTime,
               playAt: this.playRecord.playAt
            }
            this.playRecord = {
               videoId: null,
               viewDuration: 0, // 这个视频总共观看了多久
               playAt: 0, // 这个视频播放到哪了
               startPlayTime: 0 // 这个视频从什么时候开始播放的
            }
            this.totalHidenTime = 0
            this.totalPauseTime = 0
            savePlayRecord(data)
    // 滑动切换视频
    onSwiperChange(e) {
      this.videoLoading = false
      // 如果视频处于暂停状态往下刷视频,那么需要再计算一次暂停时间
      if(!this.currentVideoIsPlaying) {
         if(this.startPauseTime !== 0) {
            const duration = Date.now() - this.startPauseTime
            this.totalPauseTime += duration
         }
      }
      // 保存上一个视频的播放记录
      this.savePlayRecord()
      const oldIndex = this.currentIndex;
      this.currentIndex = e.detail.current;
      const videoContext = uni.createVideoContext(`video${oldIndex}`, this);
      // 暂停上一个视频
      videoContext.pause();
      this.startPauseTime = 0;
      // 设置当前播放视频的总时长
      this.duration = this.videoList[this.currentIndex].videoDuration;
      this.formartDuration = this.sliderFormatTime(this.duration);
      // 播放当前视频
      const videoContext1 = uni.createVideoContext(`video${this.currentIndex}`, this);
      videoContext1.play()
      // 如果剩余视频不足,触发请求获取更多视频
      if (this.videoList.length - 1 < this.currentIndex + this.videoLiveOffset) {
         this.loadVideos()
      }
    },
   // 开始触摸
   handleSwiperStart(e) {
      console.log("开始触摸", e);
       this.touchXY.startX = e.touches[0].pageX
       this.touchXY.startY = e.touches[0].pageY
   },
   // 触摸中
   handleSwiperMove(e) {
       this.touchXY.endX = e.touches[0].pageX
       this.touchXY.endY = e.touches[0].pageY
   },
   // 结束触摸
   handleSwiperEnd(item) {
      // 防止滑动滚动条也触发跳转
      if (this.showProcess) {
         return
      }
       const diffX = this.touchXY.endX - this.touchXY.startX
       const diffY = this.touchXY.endY - this.touchXY.startY
       // 判断是否是横向滑动(X轴变化大于Y轴变化)
       if (Math.abs(diffX) > Math.abs(diffY)) {
         if (diffX > 0) {
           console.log('右滑')
         if (item.goodsList && item.goodsList.length > 0) {
            this.jumpToPay(item.id)
         }
         } else {
           console.log('左滑')
         }
       }
       // 重置坐标
       this.touchXY = {
         startX: 0,
         endX: 0,
         startY: 0,
         endY: 0
      }
   },
    // 收藏/取消收藏
    toggleCollect(item, index) {
     let data = {
        refId: item.id,
        collectType: 'video'
     }
     const beforeCollected = item.collected
     const beforeCollectNum = item.collectNum
     if(item.collected) {
        this.videoList[index].collected = false
        this.videoList[index].collectNum -= 1
     } else {
        this.videoList[index].collected = true
        this.videoList[index].collectNum += 1
     }
      changeCollect(data).then(res => {
        if(res.data.code !== 200) {
           this.videoList[index].collected = beforeCollected
           this.videoList[index].collectNum = beforeCollectNum
        }
     })
    },
    // 单击屏幕:暂停或继续播放
   togglePlay(index) {
      console.log("单击视频", index);
      const videoContext = uni.createVideoContext(`video${index}`, this);
      if(this.currentVideoIsPlaying) {
         videoContext.pause();
      } else {
         videoContext.play();
      }
   },
    // 视频播放事件
    onPlay(id, index) {
      if(index === this.currentIndex) {
         this.currentVideoIsPlaying = true;
         if(! this.duration) {
            // 设置当前播放视频的总时长
            this.duration = this.videoList[this.currentIndex].videoDuration;
            this.formartDuration = this.sliderFormatTime(this.duration);
         }
      } else {
         return
      }
      this.getBarRect()
      this.progress = 0
      console.log(id, index, "触发播放");
      this.playRecord.videoId = id;
      // 没初始化才赋值,因为一个视频重复播放onPlay会重复触发
      if(this.playRecord.startPlayTime === 0) {
         this.playRecord.startPlayTime = Date.now();
      }
      if(this.startPauseTime !== 0) {
         const duration = Date.now() - this.startPauseTime
         this.totalPauseTime += duration
      }
      this.videoLoading = false
    },
    // 视频暂停事件
    onPause(index) {
      console.log(index, "触发暂停");
      if(index === this.currentIndex) {
         this.currentVideoIsPlaying = false;
         this.startPauseTime = Date.now()
      }
    },
    // 视频结束事件
    onEnded(index) {
      // this.currentVideoIsPlaying = false;
    },
   // 记录播放时长
   onTimeUpdate(e) {
      this.videoLoading = false
      this.playRecord.playAt = e.detail.currentTime;
      this.currentTime = e.detail.currentTime;
      this.progress = (e.detail.currentTime / this.duration) * 100
   },
   // 触摸开始
   handleTouchStart(e) {
     this.isDragging = true;
     this.showProcess = true;
     this.startProgress = this.progress; // 记录开始时的进度
     this.startX = e.touches[0].pageX;
     console.log("记录开始时的进度", this.startProgress);
     const videoContext = uni.createVideoContext(`video${this.currentIndex}`, this);
     videoContext.pause()
     // this.updateProgress(e);
   },
   // 触摸移动
   handleTouchMove(e) {
     if (!this.isDragging || !this.barWidth) return;
     clearTimeout(this.processHidenTimer)
     this.updateProgress(e);
   },
   // 触摸结束
   handleTouchEnd() {
     this.isDragging = false;
     console.log("滑动结束", this.duration * this.progress);
     const videoContext = uni.createVideoContext(`video${this.currentIndex}`, this);
     videoContext.seek(this.duration * this.progress / 100)
     videoContext.play()
     this.processHidenTimer = setTimeout(() => {
        this.showProcess = false;
      }, 1000);
   },
   // 更新进度
   updateProgress(e) {
      // 获取当前触摸点X坐标
      const currentX = e.touches[0].pageX;
      // 计算滑动距离(像素)
      const deltaX = currentX - this.startX;
      // 将像素距离转换为进度增量
      const deltaProgress = (deltaX / this.barWidth) * 100;
      // 计算新进度 = 开始时的进度 + 滑动增量
      let newProgress = this.startProgress + deltaProgress;
      // 限制范围在0-100之间
      newProgress = Math.max(0, Math.min(100, newProgress));
      this.progress = newProgress;
   },
   // 视频缓冲
   videoWaiting(index) {
      if (index === this.currentIndex) {
         console.log("视频缓冲中。。。");
         this.videoLoading = true;
      }
   },
   // 获取视频总时长
   onLoadedMetadata(e) {
     // this.duration = e.detail.duration;
     // this.formartDuration = this.sliderFormatTime(this.duration);
     // console.log("视频总时长", this.duration);
   },
   // 保存播放记录
   async savePlayRecord() {
      console.log(Date.now(), this.playRecord.startPlayTime, this.totalHidenTime);
      const data = {
         videoId: this.playRecord.videoId,
         viewDuration: Date.now() - this.playRecord.startPlayTime - this.totalHidenTime - this.totalPauseTime,
         playAt: this.playRecord.playAt
      }
      this.playRecord = {
         videoId: null,
         viewDuration: 0, // 这个视频总共观看了多久
         playAt: 0 ,// 这个视频播放到哪了
         startPlayTime: 0 // 这个视频从什么时候开始播放的
      }
      this.totalHidenTime = 0
      this.totalPauseTime = 0
      savePlayRecord(data)
   }
  }
}
</script>
<style scoped>
   ::v-deep .custom-tabbar {
      border-top: none !important;
   }
   .video-container {
      width: 100%;
      height: 100vh;
      background-color: #000;
     width: 100%;
     height: 100vh;
     background-color: #000;
   }
   .video-swiper {
      width: 100%;
      height: calc(100% - 50px);
     width: 100%;
     height: calc(100% - 50px);
   }
   .video-item {
      width: 100%;
      height: 100%;
      object-fit: cover;
     width: 100%;
     height: 100%;
     /* object-fit: cover; */
   }
   .play-icon {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      width: 45px;
      height: 45px;
      z-index: 10;
      opacity: 0.6;
     position: absolute;
     top: 50%;
     left: 50%;
     transform: translate(-50%, -50%);
     width: 45px;
     height: 45px;
     z-index: 10;
     opacity: 0.6;
   }
   .video-info {
      width: 70%;
      position: absolute;
      bottom: 70px;
      left: 20px;
      color: #f8f8f8;
      z-index: 10;
      letter-spacing: 1px;
     width: 70%;
     position: absolute;
     bottom: 20px;
     left: 20px;
     color: #f8f8f8;
     z-index: 10;
     letter-spacing: 1px;
   }
   .action-buttons {
      position: absolute;
      right: 20px;
      bottom: 150px;
      display: flex;
      flex-direction: column;
      align-items: center;
      z-index: 10;
     position: absolute;
     right: 20px;
     bottom: 150px;
     display: flex;
     flex-direction: column;
     align-items: center;
     z-index: 10;
   }
   .action-item {
      margin-bottom: 18px;
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      color: #fff;
     margin-bottom: 18px;
     display: flex;
     flex-direction: column;
     justify-content: center;
     align-items: center;
     color: #fff;
   }
   .avatar-container {
      margin-bottom: 27px;
      position: relative;
      /* 为绝对定位的子元素提供定位上下文 */
      width: 40px;
      height: 40px;
      display: inline-block;
      /* 使容器根据内容调整大小 */
     margin-bottom: 27px;
     position: relative;  /* 为绝对定位的子元素提供定位上下文 */
     width: 40px;
     height: 40px;
     display: inline-block; /* 使容器根据内容调整大小 */
   }
   .avatar {
      border: 2px solid #FFFFFF;
      box-sizing: border-box;
      width: 100%;
      height: 100%;
      border-radius: 50%;
      /* 关键属性,设置为50%即可实现圆形 */
      overflow: hidden;
      /* 确保图片不会超出圆形边界 */
      display: block;
     border: 2px solid #FFFFFF;
     box-sizing: border-box;
     width: 100%;
     height: 100%;
     border-radius: 50%;  /* 关键属性,设置为50%即可实现圆形 */
     overflow: hidden;    /* 确保图片不会超出圆形边界 */
     display: block;
   }
   .follow-icon {
      position: absolute;
      bottom: 0;
      /* 定位到底部 */
      left: 50%;
      /* 水平居中开始位置 */
      transform: translate(-50%, 50%);
      /* 水平居中并向下移动50% */
     position: absolute;
     bottom: 0;  /* 定位到底部 */
     left: 50%;  /* 水平居中开始位置 */
     transform: translate(-50%, 50%); /* 水平居中并向下移动50% */
      width: 18px;
      /* 图标大小 */
      height: 18px;
      background-color: #FF5A5F;
      /* 图标背景色 */
      border-radius: 50%;
      display: flex;
      justify-content: center;
      align-items: center;
      box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
      /* 轻微阴影 */
     width: 18px;  /* 图标大小 */
     height: 18px;
     background-color: #FF5A5F; /* 图标背景色 */
     border-radius: 50%;
     display: flex;
     justify-content: center;
     align-items: center;
     box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); /* 轻微阴影 */
   }
   .video-tag {
      margin-left: 5px;
      font-weight: bold;
      color: #eeeeee;
   }
   .video-author {
      font-size: 1.2em;
   }
   /* 商品链接悬挂层样式 */
   .goods-link-warp {
      position: absolute;
@@ -913,127 +1037,128 @@
      color: #f8f8f8;
      z-index: 10;
   }
   .goods-link {
      position: relative;
      margin: 20rpx 0;
      padding: 12rpx;
      background-color: rgba(255, 255, 255, 0.9);
      border-radius: 12rpx;
      box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
     position: relative;
     width: 450rpx;
     margin: 20rpx 0;
     padding: 12rpx;
     background-color: rgba(255, 255, 255, 0.9);
     border-radius: 12rpx;
     box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
   }
   .goods-container {
      display: flex;
      align-items: center;
     width: 100%;
     display: flex;
     align-items: center;
   }
   .goods-image {
      width: 120rpx;
      height: 120rpx;
      border-radius: 8rpx;
      margin-right: 20rpx;
     width: 120rpx;
     height: 120rpx;
     border-radius: 8rpx;
     margin-right: 20rpx;
   }
   .goods-info {
      flex: 1;
      display: flex;
      flex-direction: column;
      justify-content: center;
     flex: 1;
     display: flex;
     flex-direction: column;
     justify-content: center;
   }
   .goods-name {
      font-size: 28rpx;
      color: #333;
      font-weight: bold;
      display: -webkit-box;
      -webkit-line-clamp: 2;
      -webkit-box-orient: vertical;
      overflow: hidden;
      margin-bottom: 8rpx;
     font-size: 28rpx;
     color: #333;
     font-weight: bold;
     -webkit-line-clamp: 2;
     -webkit-box-orient: vertical;
     margin-bottom: 8rpx;
     width: 280rpx; /* 需要指定宽度 */
     overflow: hidden;
     white-space: nowrap;
     text-overflow: ellipsis;
   }
   .price-section {
      display: flex;
      align-items: center;
      margin-bottom: 6rpx;
     display: flex;
     align-items: center;
     margin-bottom: 6rpx;
   }
   .current-price {
      font-size: 32rpx;
      color: #ff2e4d;
      font-weight: bold;
      margin-right: 12rpx;
     font-size: 32rpx;
     color: #ff2e4d;
     font-weight: bold;
     margin-right: 12rpx;
   }
   .original-price {
      font-size: 28rpx;
      color: #999;
      text-decoration: line-through;
     font-size: 28rpx;
     color: #999;
     text-decoration: line-through;
   }
   .sales-count {
      font-size: 22rpx;
      color: #999;
     font-size: 22rpx;
     color: #999;
   }
   .buy-button {
      background: linear-gradient(to right, #ff5a5f, #ff2e4d);
      color: white;
      padding: 10rpx 28rpx;
      border-radius: 20rpx;
      font-size: 26rpx;
      font-weight: bold;
     background: linear-gradient(to right, #ff5a5f, #ff2e4d);
     color: white;
     padding: 10rpx 28rpx;
     border-radius: 20rpx;
     font-size: 26rpx;
     font-weight: bold;
   }
   /* 评论弹窗样式 */
   .comment-popup {
      background-color: #fff;
      border-radius: 20rpx 20rpx 0 0;
      padding-bottom: env(safe-area-inset-bottom);
      height: 60vh;
      display: flex;
      flex-direction: column;
     background-color: #fff;
     border-radius: 20rpx 20rpx 0 0;
     padding-bottom: env(safe-area-inset-bottom);
     height: 60vh;
     display: flex;
     flex-direction: column;
   }
   .popup-header {
      padding: 30rpx;
      display: flex;
      justify-content: space-between;
      align-items: center;
      border-bottom: 1rpx solid #f5f5f5;
     padding: 30rpx;
     display: flex;
     justify-content: space-between;
     align-items: center;
     border-bottom: 1rpx solid #f5f5f5;
   }
   .popup-title {
      font-size: 32rpx;
      font-weight: bold;
     font-size: 32rpx;
     font-weight: bold;
   }
   .close-icon {
      /* font-size: 36rpx; */
      color: #999;
     /* font-size: 36rpx; */
     color: #999;
   }
   .comment-list {
      flex: 1;
      padding: 0rpx 20rpx 20rpx 20rpx;
      box-sizing: border-box;
      height: calc(60vh - 260rpx);
     flex: 1;
     padding: 0rpx 20rpx 20rpx 20rpx;
     box-sizing: border-box;
     height: calc(60vh - 260rpx);
   }
   .comment-item {
      display: flex;
      flex-direction: column;
      padding: 10rpx 0 20rpx 0;
     display: flex;
     flex-direction: column;
     padding: 10rpx 0 20rpx 0;
   }
   .comment-avatar {
      width: 70rpx;
      height: 70rpx;
      border-radius: 50%;
      margin-right: 10rpx;
     width: 70rpx;
     height: 70rpx;
     border-radius: 50%;
     margin-right: 10rpx;
   }
   .comment-reply-avatar {
      width: 40rpx;
      height: 40rpx;
@@ -1042,71 +1167,68 @@
   }
   .comment-content {
      flex: 1;
     flex: 1;
   }
   .nickname {
      font-size: 28rpx;
      color: #666;
      display: block;
      margin-bottom: 10rpx;
     font-size: 28rpx;
     color: #666;
     display: block;
     margin-bottom: 10rpx;
   }
   .content {
      font-size: 28rpx;
      color: #333;
      display: block;
      margin-bottom: 10rpx;
     font-size: 28rpx;
     color: #333;
     display: block;
     margin-bottom: 10rpx;
   }
   .time {
      font-size: 28rpx;
      color: #999;
     font-size: 28rpx;
     color: #999;
   }
   .comment-input-area {
      display: flex;
      padding: 20rpx 30rpx;
      align-items: center;
     display: flex;
     padding: 20rpx 30rpx;
     align-items: center;
   }
   .comment-input {
      flex: 1;
      background-color: #fff;
      height: 80rpx;
      border: 1px solid #dcdcdc;
      border-radius: 40rpx;
      padding: 0 30rpx;
      font-size: 28rpx;
     flex: 1;
     background-color: #fff;
     height: 80rpx;
     border: 1px solid #dcdcdc;
     border-radius: 40rpx;
     padding: 0 30rpx;
     font-size: 28rpx;
   }
   .placeholder {
      color: #ccc;
     color: #ccc;
   }
   .submit-btn {
      margin-left: 20rpx;
      background-color: #07c160;
      color: #fff;
      border-radius: 40rpx;
      padding: 0 30rpx;
      height: 80rpx;
      line-height: 80rpx;
      font-size: 28rpx;
     margin-left: 20rpx;
     background-color: #07c160;
     color: #fff;
     border-radius: 40rpx;
     padding: 0 30rpx;
     height: 80rpx;
     line-height: 80rpx;
     font-size: 28rpx;
   }
   .loading,
   .empty {
      padding: 40rpx 0;
      text-align: center;
      color: #999;
   .loading, .empty {
     padding: 40rpx 0;
     text-align: center;
     color: #999;
   }
   .reply-list {
      margin-top: 20rpx;
      padding-left: 80rpx;
     margin-top: 20rpx;
     padding-left: 80rpx;
   }
   .reply-op {
      margin-top: 10rpx;
      padding-left: 80rpx;
@@ -1114,7 +1236,6 @@
      font-size: 28rpx;
      color: #333;
   }
   .reply-op-item {
      display: flex;
      align-items: center;
@@ -1122,125 +1243,122 @@
   }
   .reply-item {
      display: flex;
      margin-bottom: 20rpx;
     display: flex;
     margin-bottom: 20rpx;
   }
   .reply-content {
      flex: 1;
     flex: 1;
   }
   .reply-to {
      color: #576b95;
      margin: 0 10rpx;
      font-size: 28rpx;
     color: #576b95;
     margin: 0 10rpx;
     font-size: 28rpx;
   }
   .reply-title {
      display: flex;
      align-items: center;
      font-size: 28rpx;
      color: #333;
     display: flex;
     align-items: center;
     font-size: 28rpx;
     color: #333;
   }
   .cancel-reply {
      margin-left: 20rpx;
      color: #576b95;
      font-size: 28rpx;
      padding: 6rpx 12rpx;
      background: #f5f5f5;
      border-radius: 20rpx;
     margin-left: 20rpx;
     color: #576b95;
     font-size: 28rpx;
     padding: 6rpx 12rpx;
     background: #f5f5f5;
     border-radius: 20rpx;
   }
   .view-more-replies {
      color: #576b95;
      font-size: 28rpx;
      padding: 10rpx 0;
      padding-left: 80rpx;
     color: #576b95;
     font-size: 28rpx;
     padding: 10rpx 0;
     padding-left: 80rpx;
   }
   .comment-footer,
   .reply-footer {
      display: flex;
      align-items: center;
      font-size: 28rpx;
      color: #999;
   .comment-footer, .reply-footer {
     display: flex;
     align-items: center;
     font-size: 28rpx;
     color: #999;
   }
   .reply-btu {
      margin-left: 30rpx;
   }
   .thumbs-up {
      position: absolute;
      right: 20rpx;
      font-size: 32rpx;
      width: 120rpx;
   }
   .textSideIcon {
      font-size: 36rpx;
      margin-left: 5rpx;
   }
   .line {
      margin-right: 10rpx;
      color: #cccccc;
   }
   .thumbs-num {
      margin-left: 4rpx;
   }
   .container {
      display: flex;
      flex-direction: column;
      align-items: center;
      position: absolute;
      bottom: 0;
      width: 100%;
     display: flex;
     flex-direction: column;
     align-items: center;
     position: absolute;
     bottom: 0;
     width: 100%;
   }
   .progress-bar {
      position: relative;
      width: 100%;
      height: 16px;
      background-color: #eee;
      overflow: hidden;
     position: relative;
     width: 100%;
     height: 16px;
     background-color: #eee;
     overflow: hidden;
   }
   .progress-fill {
      position: absolute;
      left: 0;
      top: 0;
      height: 100%;
      background-color: lightgray;
      transition: width 0.1s;
     position: absolute;
     left: 0;
     top: 0;
     height: 100%;
     background-color: lightgray;
     transition: width 0.1s;
   }
   .process-warp {
      width: 100%;
      display: flex;
      flex-direction: column;
      align-items: center;
   }
   .progress-text {
      margin-top: 10px;
      font-size: 14px;
      color: #666;
     margin-top: 10px;
     font-size: 14px;
     color: #666;
   }
   .swiper-box {
      width: 100%;
      height: 1400rpx;
     width: 100%;
     height: 1400rpx;
   }
   .swiper-item {
      display: flex;
      justify-content: center;
      align-items: center;
      width: 100%;
      height: 100%;
     display: flex;
     justify-content: center;
     align-items: center;
     width: 100%;
     height: 100%;
   }
</style>
   .custom-share-btn {
     font-size: unset;
     background: none;
     padding: 0;
     margin: 0;
     line-height: normal;
     border: none;
   }
   .custom-share-btn::after {
     border: none;
   }
</style>