绿满眶商城微信小程序-uniapp
peng
2025-07-09 c22e91296d532873b70cb51bf5510bf7738f3f1a
pages/kitchen/KitchenVideo.vue
@@ -1,1336 +1,1615 @@
<template>
   <view class="video-container">
      <!-- 视频列表 -->
      <swiper class="video-swiper" vertical circular :current="currentIndex" @change="onSwiperChange">
         <view class="showLeft" @click="showDrawer('showLeft')" v-if="!showLeft">
            <uni-icons type="right" size="30"></uni-icons>
  <view class="video-container">
     <view class="choosePlatType" :style="{top: menueButton + 'px'}">
        <view class="platTypeItem" v-for="item in choosePlat" :key="item.type" @click="chooseType=item.type">
           <view class="platTypeItenName">
            {{item.name}}
         </view>
         <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="progress-fill" :style="{ width: progress + '%' }"></view>
                     </view>
                  </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-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>
            </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>
         </swiper-item>
      </swiper>
      <!-- 评论弹窗 -->
      <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>
            <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-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>
                  <!-- 回复列表 -->
                  <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 class="platTypeItemChoose" v-if="chooseType===item.type" >
         </view>
      </uni-popup>
      <uni-drawer ref="showLeft" mode="left" width="120" :cus-style="true" height="93vh"
         @change="change($event,'showLeft')" class="navigationLeft">
         <scroll-view class="typeNavigation" :scroll-y="true" :show-scrollbar="false">
            <view class="typeNavigationItem" :class="{typeNavigationItemCheck:currentCategort ==item.id}"
               @click="chooseCategory(item.id)" v-for="item in categoryList" :key="item.id">
               {{item.typeName}}
            </view>
         </scroll-view>
      </uni-drawer>
        </view>
   </view>
     </view>
    <!-- 视频加载 -->
    <zero-loading v-show="videoLoading" type="circle" color="#0ebd57" text=""></zero-loading>
    <view class="showLeft" @click="showDrawer('showLeft')" v-if="!showLeft" :style="{top: buttonHeight+'px'}">
      <uni-icons type="right" size="30"></uni-icons>
    </view>
    <!-- 视频列表 -->
    <swiper v-if="videoList.length > 0"
            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.videoFit"
              :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"
           :style="{bottom: marginBottom + 'px'}"
              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>
        <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="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">{{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>
              </swiper-item>
            </swiper>
          </view>
        </view>
        <!-- 视频信息层 -->
        <view class="video-info" :style="{bottom: marginBottom + 20 + 'px'}">
          <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)" @touchend.stop :src="item.authorAvatar" mode="aspectFill"></image>
            <!-- 关注图标 - 使用绝对定位 -->
            <view v-if="!item.subscribeThisAuthor" class="follow-icon" @touchend.stop @click="subscribeAuth(index, item.authorId)">
             <text class="iconfont">&#xe629;</text>
            </view>
         </view>
           <view class="action-item" @click="toggleThumbsUp(item, index)">
                 <text class="iconfont" v-if="item.thumbsUp">&#xe605;</text>
                 <text class="iconfont" v-else>&#xe601;</text>
                 <text style="font-size: 10px;font-weight: lighter;">{{item.thumbsUpNum}}</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" @click="toggleCollect(item, index)">
          <text class="iconfont" v-if="item.collected">&#xeb9d;</text>
          <text class="iconfont" v-else>&#xe603;</text>
          <text style="font-size: 10px;font-weight: lighter;">{{item.collectNum}}</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>
      </swiper-item>
    </swiper>
    <!-- 评论弹窗 -->
    <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>
        <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-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>
            <!-- 回复列表 -->
            <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>
    <uni-drawer v-if="leftHeight" ref="showLeft" mode="left" width="120" :cus-style="true" :height="`${leftHeight}px`"
                @change="change($event,'showLeft')" class="navigationLeft" :drawerTop="buttonHeight">
      <scroll-view class="typeNavigation" :scroll-y="true" :show-scrollbar="false">
        <view class="typeNavigationItem" :class="{typeNavigationItemCheck:currentCategort ==item.id}"
              @click="chooseCategory(item.id)" v-for="item in categoryList" :key="item.id">
          {{item.typeName}}
        </view>
      </scroll-view>
    </uni-drawer>
    <view v-if="videoList.length===0"  style="display: flex;align-items: center;justify-content: center;background-color: #fff;height: 100%">当前没有可以查看的视频</view>
   <custom-tabbar bgColor="#ffffff" selected="kitchen"></custom-tabbar>
  </view>
</template>
<script>
   import {
      getkitchenTypeList,
      getkitchenVideoList,
      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);
         }
      },
      data() {
         return {
            currentCategort: '',
            categoryList: [],
            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: [
import {
  getkitchenTypeList,
  getkitchenVideoList,
  savePlayRecord,
  subscribe,
  getVideoComments,
  addVideoComment,
  thubmsUpComment,
  cancelThubmsUpComment,
  changeThumbsUp,
  getGoodsSimilarlyVideos
} 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);
    }
  },
  data() {
    return {
      choosePlat:[
         {type:'platForm',name:'平台'},
         {type:'custom',name:'用户'}
      ],
      chooseType:'platForm',
     leftHeight:null,
     menueButton:0,
     buttonHeight:0,
      showLeft:false,
      currentCategort: '',
      categoryList: [],
      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, // 当前播放的视频索引
      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: 'cook'
      },
     goodsSimilarlyQuery: { // 相似视频查询
        pageNumber: 1,
        pageSize: 10,
        videoFrom: 'goodsSimilarly',
        goodsIds: [],
        currentVideoId: ''
     },
     similarlyVideoList: [], // 相似视频
     similarlyNomore: false, // 是否还有更多相似视频
     similaryVideoIndex: 0, // 相似视频的播放位置
     similarlyLoading: false, // 相似视频加载
     marginBottom: 0 // 底部安全区域
    }
  },
  onShow() {
    // this.showDrawer('showLeft')
    this.loadVideos()
    // 如果视频按下暂停后切换页面再回到页面时,只算暂停时间(因为暂停时间和离开页面时间是重复的,只算一个)
    if (this.startHidenTime !== 0 && this.currentVideoIsPlaying) {
      const duration = Date.now() - this.startHidenTime
      this.totalHidenTime += duration
    }
  },
  onHide() {
    this.startHidenTime = Date.now()
  },
  onLoad() {
     this.marginBottom = uni.getSystemInfoSync().safeAreaInsets.bottom
     // 获取状态栏高度
     const systemInfo = uni.getSystemInfoSync();
     console.log('systemInfo------------------------>',systemInfo.windowHeight)
     const menuButtonInfo =  uni.getMenuButtonBoundingClientRect()
     console.log('menuButtonInfo--------------------------->',menuButtonInfo)
     const {top,height} = menuButtonInfo
     this.buttonHeight = systemInfo.statusBarHeight+height;
     this.menueButton = top;
     console.log('systemInfo.safeAreaInsets.bottom>',systemInfo.safeAreaInsets.bottom)
     this.leftHeight = systemInfo.windowHeight - top -50 - systemInfo.safeAreaInsets.bottom -22;
     console.log('-------------leftHeight------------------------>',this.leftHeight)
   this.getKitchenTypeList();
   this.loadVideos();
  },
  methods: {
   // 查询当前视频的关联视频(挂了同一商品的)
   async getGoodsSimilarly() {
           if (this.similarlyLoading || this.similarlyNomore) return Promise.resolve();;
           const video = this.videoList[this.currentIndex];
           if (video.goodsList && video.goodsList.length > 0) {
              this.goodsSimilarlyQuery.goodsIds = video.goodsList.map(goods => goods.goodsId);
              this.goodsSimilarlyQuery.currentVideoId = video.id;
              if (this.similarlyVideoList.length < 1) {
                 this.similarlyVideoList.push(video); // 确保原视频是横向视频的第一个元素
              }
              this.similarlyLoading = true;
              return getGoodsSimilarlyVideos(this.goodsSimilarlyQuery).then(res => {
                         this.similarlyVideoList = [
                           ...this.similarlyVideoList,
                           ...res.data.data.filter(
                            (newItem) => !this.similarlyVideoList.some((oldItem) => oldItem.id === newItem.id)
                           ),
                         ];
                         this.similarlyLoading = false;
                         if(res.data.data.length < this.goodsSimilarlyQuery.pageSize) {
                            this.similarlyNomore = true;
                            return;
                         }
                         this.goodsSimilarlyQuery.pageNumber++;
              })
           }
   },
    async chooseCategory(id) {
      if (this.currentCategort === id) return
      this.currentCategort = id
      this.videoQuery.pageNumber = 1
          this.videoQuery.kitchenTypeId = id;
      this.videoLoading = false;
     this.currentIndex = 0;
            ], // 视频列表数据
            videoContexts: [], // 视频上下文对象集合
            loading: false, // 是否正在加载
            videoQuery: {
               pageNumber: 1,
               pageSize: 6,
               videoFrom: 'recommend',
               videoType: 'cook'
            }
         }
      },
      onShow() {
         this.showDrawer('showLeft')
         this.loadVideos()
         // 如果视频按下暂停后切换页面再回到页面时,只算暂停时间(因为暂停时间和离开页面时间是重复的,只算一个)
         if (this.startHidenTime !== 0 && this.currentVideoIsPlaying) {
            const duration = Date.now() - this.startHidenTime
            this.totalHidenTime += duration
         }
      },
      onHide() {
         this.startHidenTime = Date.now()
      },
      onLoad() {
         this.getKitchenTypeList();
         this.loadVideos();
      },
      onReady() {
         // 初始化视频上下文
         this.initVideoContexts();
      },
      methods: {
         async chooseCategory(id) {
            if (this.currentCategort === id) return
            this.currentCategort = id
            this.videoQuery.pageNumber = 1,
            this.videoQuery.kitchenTypeId = id;
            await this.loadVideos()
         },
         getKitchenTypeList() {
            getkitchenTypeList().then(res => {
               this.categoryList = res.data.data
            })
         },
         showDrawer(e) {
            this.$refs[e].open()
         },
         // 关闭窗口
         closeDrawer(e) {
            this.$refs[e].close()
         },
         // 抽屉状态发生变化触发
         change(e, type) {
            this[type] = e
         },
         // 轮播图变化
         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)
                  ),
               ];
            })
         },
         // 收起回复
         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
            }
            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); // 秒
      await this.loadVideos()
    },
    getKitchenTypeList() {
      getkitchenTypeList().then(res => {
        this.categoryList = res.data.data
      })
    },
    showDrawer(e) {
      this.$refs[e].open()
    },
    // 关闭窗口
    closeDrawer(e) {
      this.$refs[e].close()
    },
    // 抽屉状态发生变化触发
    change(e, type) {
      this[type] = e
    },
    // 轮播图变化
    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)
          ),
        ];
      })
    },
    // 收起回复
    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
      }
      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); // 秒
            if (diff < 60) return '刚刚';
            if (diff < 3600) return `${Math.floor(diff / 60)}分钟前`;
            if (diff < 86400) return `${Math.floor(diff / 3600)}小时前`;
      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()
      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) {
            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'
                  });
               } 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;
            });
         },
          // 如果是评论别人的回复,那么就将这个发布到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) {
      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'
          });
        } else {
          this.videoList.forEach(video => {
            if (video.authorId === authorId) {
              video.subscribeThisAuthor = false
            }
          })
        }
      })
    },
    // 加载视频数据
    async loadVideos() {
      console.log(this.loading, this.videoNoMore,this.videoQuery)
      if (this.videoQuery.pageNumber == 1) {
         // 加载视频数据
         async loadVideos() {
            console.log(this.loading, this.videoNoMore,this.videoQuery)
            if (this.videoQuery.pageNumber == 1) {
      } else if (this.loading || this.videoNoMore) return;
      this.loading = true;
            } else if (this.loading || this.videoNoMore) return;
            this.loading = true;
      getkitchenVideoList(this.videoQuery).then(res => {
        // 新增一个字段用于循环时的key
        const data = res.data.data.map(item => {
           return {
              ...item,
              updateKey: item.id
           }
        })
        if (this.videoQuery.pageNumber === 1) {
          this.videoList = data;
        } else {
          this.videoList = [
            ...this.videoList,
            ...data.filter(
                (newItem) => !this.videoList.some((oldItem) => oldItem.id === newItem.id)
            ),
          ];
        }
        this.loading = false;
        if (data.length < this.videoQuery.pageSize) {
          this.videoNoMore = true;
          return;
        }
        this.videoQuery.pageNumber++;
            getkitchenVideoList(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++;
      })
    },
            })
         },
    // 滑动切换视频
    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.similaryVideoIndex !== 0) {
        this.videoList[oldIndex] = this.similarlyVideoList[0]
     }
     this.similarlyVideoList = [];
     this.similaryVideoIndex = 0;
     this.similarlyNomore = false;
     this.similarlyLoading = false;
     this.goodsSimilarlyQuery = {
        pageNumber: 1,
        pageSize: 6,
        videoFrom: 'goodsSimilarly',
        goodsIds: [],
        currentVideoId: ''
     }
     // 如果剩余视频不足,触发请求获取更多视频
     if (this.videoList.length - 1 < this.currentIndex + this.videoLiveOffset) {
        this.loadVideos()
     }
    },
         // 滑动切换视频
         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)
         }
   // 开始触摸
   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
   },
   // 结束触摸
   async 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 (this.similaryVideoIndex !== 0) {
             // 如果滑动了横向视频,那么右滑就做视频切换而不是跳转商品页
             // 切换下一个视频
             const oldIndex = this.similaryVideoIndex;
             this.similaryVideoIndex = Math.max(this.similaryVideoIndex - 1, 0);
             if (this.similaryVideoIndex < oldIndex) {
                // 把竖向视频的当前播放位置替换为横向视频的当前索引元素
                const video = this.similarlyVideoList[this.similaryVideoIndex];
                video["updateKey"] = video.id + this.similaryVideoIndex
                this.videoList.splice(this.currentIndex, 1, video);
                // this.videoList[this.currentIndex] = video
             }
          }
          else if (item.goodsList && item.goodsList.length > 0) {
             this.jumpToPay(item.id)
          }
         } else {
           console.log('左滑')
          if (this.similarlyVideoList.length < 1 || this.similarlyVideoList.length - this.similaryVideoIndex - 1 <= 3) {
             // 相关视频为空或者剩余视频不足,触发加载相关视频
             await this.getGoodsSimilarly()
          }
          // 切换下一个视频
          const oldIndex = this.similaryVideoIndex;
          this.similaryVideoIndex = Math.min(this.similaryVideoIndex + 1, this.similarlyVideoList.length - 1);
          if (this.similaryVideoIndex > oldIndex) {
             // 把竖向视频的当前播放位置替换为横向视频的当前索引元素
             const video = this.similarlyVideoList[this.similaryVideoIndex];
             video["updateKey"] = video.id + this.similaryVideoIndex
             this.videoList.splice(this.currentIndex, 1, video);
          }
         }
       }
       // 重置坐标
       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
        }
      })
    },
   // 点赞/取消点赞
   toggleThumbsUp(item, index) {
     let data = {
        refId: item.id,
        thumbsUpType: 'video'
     }
     const beforeThumbsUp = item.thumbsUp
     const beforeThumbsUpNum = item.thumbsUpNum
     if(item.thumbsUp) {
        this.videoList[index].thumbsUp = false
        this.videoList[index].thumbsUpNum -= 1
     } else {
        this.videoList[index].thumbsUp = true
        this.videoList[index].thumbsUpNum += 1
     }
     changeThumbsUp(data).then(res => {
        if(res.data.code !== 200) {
           this.videoList[index].thumbsUp = beforeThumbsUp
           this.videoList[index].thumbsUpNum = beforeThumbsUpNum
        }
     })
   },
    // 单击屏幕:暂停或继续播放
    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;
      } else {
        this.currentVideoIsPlaying = true;
        return
      }
      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.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)
    }
  }
}
</script>
<style scoped>
   ::v-deep .custom-tabbar {
      border-top: none !important;
   }
::v-deep .custom-tabbar {
  border-top: none !important;
}
.choosePlatType{
   display: flex;
   align-items: center;
   justify-content: center;
   position: fixed;
   z-index: 9999;
   left: 0;
   right: 0;
}
.platTypeItem{
   width: 80rpx;
   display: flex;
   align-items: center;
   flex-direction: column;
   height: 60rpx;
}
.platTypeItem:nth-child(n+1){
   margin-left: 32rpx;
}
.platTypeItemChoose{
   margin-top: 15rpx;
   width: 40%;
   display: flex;
   align-items: center;
   justify-content: center;
   background-color: #fff;
   height: 4rpx;
   border-radius: 5rpx;
}
.platTypeItenName{
   color: #fff;
   font-weight: bold;
   font-size: 32rpx;
}
.video-container {
  position: relative;
  width: 100%;
  height: 100vh;
  background-color: #000;
}
   .video-container {
      position: relative;
      width: 100%;
      height: 100vh;
      background-color: #000;
   }
.showLeft {
  display: flex;
  left: 0;
  align-items: center;
  justify-content: flex-start;
  background-color: #b6b6b6;
  opacity: 0.8;
  position: fixed;
  z-index: 99999;
  height: 70rpx;
  width: 50rpx;
  border-radius: 0 50% 50% 0;
}
   .showLeft {
      display: flex;
      top: 50rpx;
      left: 0;
      align-items: center;
      justify-content: flex-start;
      background-color: #b6b6b6;
      opacity: 0.8;
      position: fixed;
      z-index: 999;
      height: 70rpx;
      width: 50rpx;
      border-radius: 0 50% 50% 0;
   }
.video-swiper {
  width: 100%;
  height: calc(100% - 50px);
}
   .video-swiper {
      width: 100%;
      height: calc(100% - 50px);
   }
.video-item {
  width: 100%;
  height: 100%;
}
   .video-item {
      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;
}
   .play-icon {
      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;
}
   .video-info {
      width: 70%;
      position: absolute;
      bottom: 70px;
      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;
}
   .action-buttons {
      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;
}
   .action-item {
      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;
  /* 使容器根据内容调整大小 */
}
   .avatar-container {
      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;
}
   .avatar {
      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% */
   .follow-icon {
      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-tag {
      margin-left: 5px;
      font-weight: bold;
      color: #eeeeee;
   }
.video-author {
  font-size: 1.2em;
}
   .video-author {
      font-size: 1.2em;
   }
/* 商品链接悬挂层样式 */
.goods-link-warp {
  position: absolute;
  bottom: 160px;
  left: 20px;
  color: #f8f8f8;
  z-index: 10;
}
   /* 商品链接悬挂层样式 */
   .goods-link-warp {
      position: absolute;
      bottom: 160px;
      left: 20px;
      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);
}
   .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);
   }
.goods-container {
  display: flex;
  align-items: center;
}
   .goods-container {
      display: flex;
      align-items: center;
   }
.goods-image {
  width: 120rpx;
  height: 120rpx;
  border-radius: 8rpx;
  margin-right: 20rpx;
}
   .goods-image {
      width: 120rpx;
      height: 120rpx;
      border-radius: 8rpx;
      margin-right: 20rpx;
   }
.goods-info {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
   .goods-info {
      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;
}
   .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;
   }
.price-section {
  display: flex;
  align-items: center;
  margin-bottom: 6rpx;
}
   .price-section {
      display: flex;
      align-items: center;
      margin-bottom: 6rpx;
   }
.current-price {
  font-size: 32rpx;
  color: #ff2e4d;
  font-weight: bold;
  margin-right: 12rpx;
}
   .current-price {
      font-size: 32rpx;
      color: #ff2e4d;
      font-weight: bold;
      margin-right: 12rpx;
   }
.original-price {
  font-size: 28rpx;
  color: #999;
  text-decoration: line-through;
}
   .original-price {
      font-size: 28rpx;
      color: #999;
      text-decoration: line-through;
   }
.sales-count {
  font-size: 22rpx;
  color: #999;
}
   .sales-count {
      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;
}
   .buy-button {
      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;
}
   /* 评论弹窗样式 */
   .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;
   }
.popup-header {
  padding: 30rpx;
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-bottom: 1rpx solid #f5f5f5;
}
   .popup-header {
      padding: 30rpx;
      display: flex;
      justify-content: space-between;
      align-items: center;
      border-bottom: 1rpx solid #f5f5f5;
   }
.popup-title {
  font-size: 32rpx;
  font-weight: bold;
}
   .popup-title {
      font-size: 32rpx;
      font-weight: bold;
   }
.close-icon {
  /* font-size: 36rpx; */
  color: #999;
}
.comment-list {
  flex: 1;
  padding: 0rpx 20rpx 20rpx 20rpx;
  box-sizing: border-box;
  height: calc(60vh - 260rpx);
}
   .close-icon {
      /* font-size: 36rpx; */
      color: #999;
   }
.comment-item {
  display: flex;
  flex-direction: column;
  padding: 10rpx 0 20rpx 0;
}
   .comment-list {
      flex: 1;
      padding: 0rpx 20rpx 20rpx 20rpx;
      box-sizing: border-box;
      height: calc(60vh - 260rpx);
   }
.comment-avatar {
  width: 70rpx;
  height: 70rpx;
  border-radius: 50%;
  margin-right: 10rpx;
}
   .comment-item {
      display: flex;
      flex-direction: column;
      padding: 10rpx 0 20rpx 0;
   }
.comment-reply-avatar {
  width: 40rpx;
  height: 40rpx;
  border-radius: 50%;
  margin-right: 10rpx;
}
   .comment-avatar {
      width: 70rpx;
      height: 70rpx;
      border-radius: 50%;
      margin-right: 10rpx;
   }
.comment-content {
  flex: 1;
}
   .comment-reply-avatar {
      width: 40rpx;
      height: 40rpx;
      border-radius: 50%;
      margin-right: 10rpx;
   }
.nickname {
  font-size: 28rpx;
  color: #666;
  display: block;
  margin-bottom: 10rpx;
}
   .comment-content {
      flex: 1;
   }
.content {
  font-size: 28rpx;
  color: #333;
  display: block;
  margin-bottom: 10rpx;
}
   .nickname {
      font-size: 28rpx;
      color: #666;
      display: block;
      margin-bottom: 10rpx;
   }
.time {
  font-size: 28rpx;
  color: #999;
}
   .content {
      font-size: 28rpx;
      color: #333;
      display: block;
      margin-bottom: 10rpx;
   }
.comment-input-area {
  display: flex;
  padding: 20rpx 30rpx;
  align-items: center;
}
   .time {
      font-size: 28rpx;
      color: #999;
   }
.comment-input {
  flex: 1;
  background-color: #fff;
  height: 80rpx;
  border: 1px solid #dcdcdc;
  border-radius: 40rpx;
  padding: 0 30rpx;
  font-size: 28rpx;
}
   .comment-input-area {
      display: flex;
      padding: 20rpx 30rpx;
      align-items: center;
   }
.placeholder {
  color: #ccc;
}
   .comment-input {
      flex: 1;
      background-color: #fff;
      height: 80rpx;
      border: 1px solid #dcdcdc;
      border-radius: 40rpx;
      padding: 0 30rpx;
      font-size: 28rpx;
   }
.submit-btn {
  margin-left: 20rpx;
  background-color: #07c160;
  color: #fff;
  border-radius: 40rpx;
  padding: 0 30rpx;
  height: 80rpx;
  line-height: 80rpx;
  font-size: 28rpx;
}
   .placeholder {
      color: #ccc;
   }
.loading,
.empty {
  padding: 40rpx 0;
  text-align: center;
  color: #999;
}
   .submit-btn {
      margin-left: 20rpx;
      background-color: #07c160;
      color: #fff;
      border-radius: 40rpx;
      padding: 0 30rpx;
      height: 80rpx;
      line-height: 80rpx;
      font-size: 28rpx;
   }
.reply-list {
  margin-top: 20rpx;
  padding-left: 80rpx;
}
   .loading,
   .empty {
      padding: 40rpx 0;
      text-align: center;
      color: #999;
   }
.reply-op {
  margin-top: 10rpx;
  padding-left: 80rpx;
  display: flex;
  font-size: 28rpx;
  color: #333;
}
   .reply-list {
      margin-top: 20rpx;
      padding-left: 80rpx;
   }
.reply-op-item {
  display: flex;
  align-items: center;
  height: 40rpx;
}
   .reply-op {
      margin-top: 10rpx;
      padding-left: 80rpx;
      display: flex;
      font-size: 28rpx;
      color: #333;
   }
.reply-item {
  display: flex;
  margin-bottom: 20rpx;
}
   .reply-op-item {
      display: flex;
      align-items: center;
      height: 40rpx;
   }
.reply-content {
  flex: 1;
}
   .reply-item {
      display: flex;
      margin-bottom: 20rpx;
   }
.reply-to {
  color: #576b95;
  margin: 0 10rpx;
  font-size: 28rpx;
}
   .reply-content {
      flex: 1;
   }
.reply-title {
  display: flex;
  align-items: center;
  font-size: 28rpx;
  color: #333;
}
   .reply-to {
      color: #576b95;
      margin: 0 10rpx;
      font-size: 28rpx;
   }
.cancel-reply {
  margin-left: 20rpx;
  color: #576b95;
  font-size: 28rpx;
  padding: 6rpx 12rpx;
  background: #f5f5f5;
  border-radius: 20rpx;
}
   .reply-title {
      display: flex;
      align-items: center;
      font-size: 28rpx;
      color: #333;
   }
.view-more-replies {
  color: #576b95;
  font-size: 28rpx;
  padding: 10rpx 0;
  padding-left: 80rpx;
}
   .cancel-reply {
      margin-left: 20rpx;
      color: #576b95;
      font-size: 28rpx;
      padding: 6rpx 12rpx;
      background: #f5f5f5;
      border-radius: 20rpx;
   }
.comment-footer,
.reply-footer {
  display: flex;
  align-items: center;
  font-size: 28rpx;
  color: #999;
}
   .view-more-replies {
      color: #576b95;
      font-size: 28rpx;
      padding: 10rpx 0;
      padding-left: 80rpx;
   }
.reply-btu {
  margin-left: 30rpx;
}
   .comment-footer,
   .reply-footer {
      display: flex;
      align-items: center;
      font-size: 28rpx;
      color: #999;
   }
.thumbs-up {
  position: absolute;
  right: 20rpx;
  font-size: 32rpx;
  width: 120rpx;
}
   .reply-btu {
      margin-left: 30rpx;
   }
.textSideIcon {
  font-size: 36rpx;
  margin-left: 5rpx;
}
   .thumbs-up {
      position: absolute;
      right: 20rpx;
      font-size: 32rpx;
      width: 120rpx;
   }
.line {
  margin-right: 10rpx;
  color: #cccccc;
}
   .textSideIcon {
      font-size: 36rpx;
      margin-left: 5rpx;
   }
.thumbs-num {
  margin-left: 4rpx;
}
   .line {
      margin-right: 10rpx;
      color: #cccccc;
   }
.container {
  display: flex;
  flex-direction: column;
  align-items: center;
  position: absolute;
  bottom: 0;
  width: 100%;
}
   .thumbs-num {
      margin-left: 4rpx;
   }
.progress-bar {
  position: relative;
  width: 100%;
  height: 16px;
  background-color: #eee;
  overflow: hidden;
}
   .container {
      display: flex;
      flex-direction: column;
      align-items: center;
      position: absolute;
      bottom: 0;
      width: 100%;
   }
.progress-fill {
  position: absolute;
  left: 0;
  top: 0;
  height: 100%;
  background-color: lightgray;
  transition: width 0.1s;
}
   .progress-bar {
      position: relative;
      width: 100%;
      height: 16px;
      background-color: #eee;
      overflow: hidden;
   }
.process-warp {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
}
   .progress-fill {
      position: absolute;
      left: 0;
      top: 0;
      height: 100%;
      background-color: lightgray;
      transition: width 0.1s;
   }
.progress-text {
  margin-top: 10px;
  font-size: 14px;
  color: #fff;
}
   .process-warp {
      width: 100%;
      display: flex;
      flex-direction: column;
      align-items: center;
   }
.swiper-box {
  width: 100%;
  height: 1400rpx;
}
   .progress-text {
      margin-top: 10px;
      font-size: 14px;
      color: #666;
   }
.swiper-item {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 100%;
}
   .swiper-box {
      width: 100%;
      height: 1400rpx;
   }
.currentCategort {
  padding: 10rpx;
}
   .swiper-item {
      display: flex;
      justify-content: center;
      align-items: center;
      width: 100%;
      height: 100%;
   }
.typeNavigation {
  height: 100%;
  padding: 10rpx;
  box-sizing: border-box;
}
   .currentCategort {
      padding: 10rpx;
   }
.typeNavigationItem {
   padding: 24rpx;
   font-size: 28rpx;
   color: black;
   margin-top: 10rpx;
}
   .typeNavigation {
      height: 100%;
      padding: 10rpx;
      box-sizing: border-box;
   }
   .typeNavigationItem {
      padding: 24rpx;
      font-size: 28rpx;
      color: black;
      margin-top: 10rpx;
      border-radius: 12rpx;
      border: 1rpx solid gray;
   }
.typeNavigationItemCheck {
   color: #ef321e;
   font-size: 32rpx;
   font-weight: bold;
   border: 0;
}
   .typeNavigationItemCheck {
      background-color: #42b993;
      color: #fff;
      border: 0;
   }
.container ::v-deep .navigationLeft .uni-drawer__content {
  height: 300rpx !important;
  top: 100rpx !important;
  background-color: lightpink !important;
   .container ::v-deep .navigationLeft .uni-drawer__content {
      height: 300rpx !important;
      top: 100rpx !important;
      background-color: lightpink !important;
}
   }
</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>