绿满眶商城微信小程序-uniapp
peng
2025-06-25 cad6ad80c86eba4663d84fd78042c1173361f600
pages/health/healthVideo.vue
@@ -1,26 +1,66 @@
<template>
   <view class="video-container">
   <!-- 视频加载 -->
   <zero-loading v-show="videoLoading" type="circle" color="#0ebd57" text=""></zero-loading>
      <!-- 视频列表 -->
      <swiper class="video-swiper" vertical circular :current="currentIndex" @change="onSwiperChange">
         <swiper-item v-for="(item, index) in videoList" :key="item.id">
    <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-if="!currentVideoIsPlaying">
           <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 :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>
           <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="handleTouchStart" @touchmove="handleTouchMove" @touchend="handleTouchEnd"
           <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[index]}}</view>
                     <view class="progress-bar" id="progressBar">
              <view class="progress-text">{{ hasPlayTime }}/{{formartDuration}}</view>
              <view
               class="progress-bar"
               id="progressBar"
              >
                        <!-- 已填充部分 -->
                        <view class="progress-fill" :style="{ width: progress + '%' }"></view>
@@ -29,15 +69,22 @@
               </view>
            </view>
            <view style="width: 100%; height: 100%;" v-else-if="item.videoContentType === 'img'">
               <uni-swiper-dot :info="item.imgs" :current="currentImgIndex" mode="round"
        <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'}">
         :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>
                <image
                  :src="img"
                  mode="aspectFit"
                  style="width: 100%; height: 100%; display: block; margin: 0 auto;"
                ></image>
                        </view>
                     </swiper-item>
                  </swiper>
@@ -46,28 +93,25 @@
            <!-- 悬挂商品链接层 -->
            <view class="goods-link-warp" v-if="false">
      <view class="goods-link-warp" v-if="item.goodsList.length > 0">
               <view class="goods-link">
                  <view class="goods-container">
           <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="item.goods.imageUrl" mode="aspectFill"></image>
               <image class="goods-image" :src="goods.thumbnail" mode="aspectFill"></image>
                     <!-- 商品信息 -->
                     <view class="goods-info">
                        <text class="goods-name">{{item.goods.name}}</text>
                 <text class="goods-name">{{goods.goodsName}}</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>
                  <text class="current-price">¥{{goods.price}}</text>
                  <text class="original-price" v-if="goods.originalPrice">¥{{goods.originalPrice}}</text>
                     </view>
                  </view>
              </view>
            </swiper-item>
           </swiper>
               </view>
            </view>
@@ -79,19 +123,16 @@
               </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>
           <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>
            <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)">
            <view v-if="!item.subscribeThisAuthor" class="follow-icon" @click="subscribeAuth(index, item.authorId)">
                     <text class="iconfont">&#xe629;</text>
                  </view>
               </view>
@@ -103,6 +144,12 @@
               <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>
               </view>
            </view>
@@ -132,22 +179,15 @@
               <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>
            <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>
               <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>
@@ -156,74 +196,57 @@
                     <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>
                  <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>
                  <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>
                 <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)">
           <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 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 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"
        <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>
         placeholder-class="placeholder"
        />
        <button class="submit-btn" @click="submitComment" :disabled="!commentForm.commentContent.trim()">发送</button>
            </view>
         </view>
      </uni-popup>
   <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";
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() {
@@ -233,8 +256,9 @@
      data() {
         return {
            currentImgIndex: 0, // 播放到第几张图--索引
      currentGoodsIndex: 0, // 播放到第几个商品--索引
            currentTime: 0,
            formartDuration: [],
      formartDuration: '',
            duration: 0,
            startX: 0,
            progress: 0, // 视频进度
@@ -282,24 +306,34 @@
               startPlayTime: 0 // 这个视频从什么时候开始播放的
            },
            currentVideoIsPlaying: true, // 当前视频是否正在播放
            isFullScreen: false,
            windowHeight: 0,
            currentIndex: 0, // 当前播放的视频索引
            videoList: [
            ], // 视频列表数据
            videoContexts: [], // 视频上下文对象集合
      videoLoading: false, // 视频缓冲中
      videoList: [],   // 视频列表数据
      videoBufferOffset: 0.1 ,// 视频预加载参数
      videoLiveOffset: 2, // 保留当前视频前后各多少个视频上下文
      touchXY: {  // 监听左滑右滑
         startX: 0,
         endX: 0,
         startY: 0,
         endY: 0
      },
            loading: false, // 是否正在加载
            videoQuery: {
               pageNumber: 1,
               pageSize: 6,
               videoFrom: 'recommend',
               videoType: 'health'
         pageSize: 10,
         videoFrom: 'recommend'
            }
         }
      },
      onShow() {
         this.loadVideos()
     // 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
@@ -309,17 +343,80 @@
      onHide() {
         this.startHidenTime = Date.now()
      },
      onLoad() {
  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();
     }
      },
      onReady() {
         // 初始化视频上下文
         this.initVideoContexts();
  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() {
@@ -376,8 +473,7 @@
               this.comments[index].replies = [
                  ...this.comments[index].replies,
                  ...res.data.data.filter(
                     (newItem) => !this.comments[index].replies.some((oldItem) => oldItem.id === newItem
                        .id)
                (newItem) => !this.comments[index].replies.some((oldItem) => oldItem.id === newItem.id)
                  ),
               ];
            })
@@ -570,13 +666,6 @@
               }
            })
         },
         // 初始化视频上下文
         initVideoContexts() {
            this.videoContexts = this.videoList.map((_, index) => {
               let videoContent = uni.createVideoContext(`video${index}`, this);
               return videoContent;
            });
         },
         // 加载视频数据
         async loadVideos() {
@@ -595,9 +684,6 @@
                     ),
                  ];
               }
               this.$nextTick(() => {
                  this.initVideoContexts();
               });
               this.loading = false;
               if (res.data.data.length < this.videoQuery.pageSize) {
                  this.videoNoMore = true;
@@ -610,6 +696,7 @@
         // 滑动切换视频
         onSwiperChange(e) {
      this.videoLoading = false
            // 如果视频处于暂停状态往下刷视频,那么需要再计算一次暂停时间
            if (!this.currentVideoIsPlaying) {
               if (this.startPauseTime !== 0) {
@@ -621,16 +708,61 @@
            this.savePlayRecord()
            const oldIndex = this.currentIndex;
            this.currentIndex = e.detail.current;
      const videoContext = uni.createVideoContext(`video${oldIndex}`, this);
            // 暂停上一个视频
            if (this.videoContexts[oldIndex]) {
               this.videoContexts[oldIndex].pause();
            }
      videoContext.pause();
            this.startPauseTime = 0;
      // 设置当前播放视频的总时长
      this.duration = this.videoList[this.currentIndex].videoDuration;
      this.formartDuration = this.sliderFormatTime(this.duration);
            // 播放当前视频
            if (this.videoContexts[this.currentIndex]) {
               this.videoContexts[this.currentIndex].play();
      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
            }
         },
@@ -658,24 +790,29 @@
         },
         // 单击屏幕:暂停或继续播放
         togglePlay(index) {
            console.log("单击视频", index, this.videoContexts);
      console.log("单击视频", index);
      const videoContext = uni.createVideoContext(`video${index}`, this);
            if (this.currentVideoIsPlaying) {
               this.videoContexts[index].pause();
         videoContext.pause();
            } else {
               this.videoContexts[index].play();
         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, "触发播放");
            if (index === this.currentIndex) {
               this.currentVideoIsPlaying = true;
            } else {
               this.currentVideoIsPlaying = false;
               return
            }
            this.playRecord.videoId = id;
            // 没初始化才赋值,因为一个视频重复播放onPlay会重复触发
            if (this.playRecord.startPlayTime === 0) {
@@ -685,6 +822,7 @@
               const duration = Date.now() - this.startPauseTime
               this.totalPauseTime += duration
            }
      this.videoLoading = false
         },
         // 视频暂停事件
@@ -692,11 +830,8 @@
            console.log(index, "触发暂停");
            if (index === this.currentIndex) {
               this.currentVideoIsPlaying = false;
            } else {
               this.currentVideoIsPlaying = true;
               return
            }
            this.startPauseTime = Date.now()
      }
         },
         // 视频结束事件
         onEnded(index) {
@@ -705,6 +840,7 @@
         // 记录播放时长
         onTimeUpdate(e) {
      this.videoLoading = false
            this.playRecord.playAt = e.detail.currentTime;
            this.currentTime = e.detail.currentTime;
@@ -717,7 +853,8 @@
            this.startProgress = this.progress; // 记录开始时的进度
            this.startX = e.touches[0].pageX;
            console.log("记录开始时的进度", this.startProgress);
            this.videoContexts[this.currentIndex].pause()
     const videoContext = uni.createVideoContext(`video${this.currentIndex}`, this);
     videoContext.pause()
            // this.updateProgress(e);
         },
@@ -725,7 +862,6 @@
         handleTouchMove(e) {
            if (!this.isDragging || !this.barWidth) return;
            clearTimeout(this.processHidenTimer)
            this.videoContexts[this.currentIndex].pause()
            this.updateProgress(e);
         },
@@ -733,8 +869,9 @@
         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()
     const videoContext = uni.createVideoContext(`video${this.currentIndex}`, this);
     videoContext.seek(this.duration * this.progress / 100)
     videoContext.play()
            this.processHidenTimer = setTimeout(() => {
               this.showProcess = false;
            }, 1000);
@@ -750,7 +887,6 @@
            // 将像素距离转换为进度增量
            const deltaProgress = (deltaX / this.barWidth) * 100;
            console.log("进度增量", deltaProgress);
            // 计算新进度 = 开始时的进度 + 滑动增量
            let newProgress = this.startProgress + deltaProgress;
@@ -759,11 +895,18 @@
            this.progress = newProgress;
         },
   // 视频缓冲
   videoWaiting(index) {
      if (index === this.currentIndex) {
         console.log("视频缓冲中。。。");
         this.videoLoading = true;
      }
   },
         // 获取视频总时长
         onLoadedMetadata(e) {
            this.duration = e.detail.duration;
            this.formartDuration.push(this.sliderFormatTime(this.duration));
            console.log("视频总时长", this.duration);
     // this.duration = e.detail.duration;
     // this.formartDuration = this.sliderFormatTime(this.duration);
     // console.log("视频总时长", this.duration);
         },
         // 保存播放记录
         async savePlayRecord() {
@@ -771,8 +914,7 @@
            const data = {
               videoId: this.playRecord.videoId,
               viewDuration: Date.now() - this.playRecord.startPlayTime - this.totalHidenTime - this
                  .totalPauseTime,
         viewDuration: Date.now() - this.playRecord.startPlayTime - this.totalHidenTime - this.totalPauseTime,
               playAt: this.playRecord.playAt
            }
            this.playRecord = {
@@ -793,7 +935,6 @@
   ::v-deep .custom-tabbar {
      border-top: none !important;
   }
   .video-container {
      width: 100%;
      height: 100vh;
@@ -808,9 +949,8 @@
   .video-item {
      width: 100%;
      height: 100%;
      object-fit: cover;
     /* object-fit: cover; */
   }
   .play-icon {
      position: absolute;
      top: 50%;
@@ -825,7 +965,7 @@
   .video-info {
      width: 70%;
      position: absolute;
      bottom: 70px;
     bottom: 20px;
      left: 20px;
      color: #f8f8f8;
      z-index: 10;
@@ -850,61 +990,45 @@
      align-items: center;
      color: #fff;
   }
   .avatar-container {
      margin-bottom: 27px;
      position: relative;
      /* 为绝对定位的子元素提供定位上下文 */
     position: relative;  /* 为绝对定位的子元素提供定位上下文 */
      width: 40px;
      height: 40px;
      display: inline-block;
      /* 使容器根据内容调整大小 */
     display: inline-block; /* 使容器根据内容调整大小 */
   }
   .avatar {
      border: 2px solid #FFFFFF;
      box-sizing: border-box;
      width: 100%;
      height: 100%;
      border-radius: 50%;
      /* 关键属性,设置为50%即可实现圆形 */
      overflow: hidden;
      /* 确保图片不会超出圆形边界 */
     border-radius: 50%;  /* 关键属性,设置为50%即可实现圆形 */
     overflow: hidden;    /* 确保图片不会超出圆形边界 */
      display: block;
   }
   .follow-icon {
      position: absolute;
      bottom: 0;
      /* 定位到底部 */
      left: 50%;
      /* 水平居中开始位置 */
      transform: translate(-50%, 50%);
      /* 水平居中并向下移动50% */
     bottom: 0;  /* 定位到底部 */
     left: 50%;  /* 水平居中开始位置 */
     transform: translate(-50%, 50%); /* 水平居中并向下移动50% */
      width: 18px;
      /* 图标大小 */
     width: 18px;  /* 图标大小 */
      height: 18px;
      background-color: #FF5A5F;
      /* 图标背景色 */
     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);
      /* 轻微阴影 */
     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,9 +1037,9 @@
      color: #f8f8f8;
      z-index: 10;
   }
   .goods-link {
      position: relative;
     width: 450rpx;
      margin: 20rpx 0;
      padding: 12rpx;
      background-color: rgba(255, 255, 255, 0.9);
@@ -924,6 +1048,7 @@
   }
   .goods-container {
     width: 100%;
      display: flex;
      align-items: center;
   }
@@ -946,11 +1071,13 @@
      font-size: 28rpx;
      color: #333;
      font-weight: bold;
      display: -webkit-box;
      -webkit-line-clamp: 2;
      -webkit-box-orient: vertical;
      overflow: hidden;
      margin-bottom: 8rpx;
     width: 280rpx; /* 需要指定宽度 */
     overflow: hidden;
     white-space: nowrap;
     text-overflow: ellipsis;
   }
   .price-section {
@@ -985,7 +1112,6 @@
      font-size: 26rpx;
      font-weight: bold;
   }
   /* 评论弹窗样式 */
   .comment-popup {
      background-color: #fff;
@@ -1033,7 +1159,6 @@
      border-radius: 50%;
      margin-right: 10rpx;
   }
   .comment-reply-avatar {
      width: 40rpx;
      height: 40rpx;
@@ -1095,18 +1220,15 @@
      font-size: 28rpx;
   }
   .loading,
   .empty {
   .loading, .empty {
      padding: 40rpx 0;
      text-align: center;
      color: #999;
   }
   .reply-list {
      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;
@@ -1135,7 +1256,6 @@
      margin: 0 10rpx;
      font-size: 28rpx;
   }
   .reply-title {
      display: flex;
      align-items: center;
@@ -1151,47 +1271,38 @@
      background: #f5f5f5;
      border-radius: 20rpx;
   }
   .view-more-replies {
      color: #576b95;
      font-size: 28rpx;
      padding: 10rpx 0;
      padding-left: 80rpx;
   }
   .comment-footer,
   .reply-footer {
   .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;
@@ -1217,25 +1328,21 @@
      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;
   }
   .swiper-box {
      width: 100%;
      height: 1400rpx;
   }
   .swiper-item {
      display: flex;
      justify-content: center;
@@ -1243,4 +1350,15 @@
      width: 100%;
      height: 100%;
   }
   .custom-share-btn {
     font-size: unset;
     background: none;
     padding: 0;
     margin: 0;
     line-height: normal;
     border: none;
   }
   .custom-share-btn::after {
     border: none;
   }
</style>