绿满眶商城微信小程序-uniapp
xiangpei
2025-05-26 1076d3e64cfb8648e429b3d7a3399e4593affc0c
pages/tabbar/index/home.vue
@@ -9,9 +9,18 @@
      @change="onSwiperChange"
    >
      <swiper-item v-for="(item, index) in videoList" :key="item.id">
      <!-- 播放按钮(仅当视频暂停时显示) -->
      <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"
          :src="item.url"
        :ref="'video'+index"
          :src="item.videoUrl"
          :autoplay="currentIndex === index"
          :controls="false"
          :loop="true"
@@ -20,6 +29,7 @@
          @play="onPlay(index)"
          @pause="onPause(index)"
          @ended="onEnded(index)"
        @click="togglePlay(index)"
        ></video>
      
      <!-- 悬挂商品链接层 -->
@@ -27,7 +37,7 @@
         <view class="goods-link">
           <view class="goods-container">
             <!-- 商品图片 -->
             <image class="goods-image" :src="item.goods.image" mode="aspectFill"></image>
             <image class="goods-image" :src="item.goods.imageUrl" mode="aspectFill"></image>
             
             <!-- 商品信息 -->
             <view class="goods-info">
@@ -36,7 +46,7 @@
                 <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.sales}}人已购</text>
               <text class="sales-count">{{item.goods.saleNum}}人已购</text>
             </view>
             
             <!-- 购买按钮 -->
@@ -51,11 +61,11 @@
        <!-- 视频信息层 -->
        <view class="video-info">
        <view>
           <text class="video-author">@{{item.author}}</text>
           <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.tags" :key="tag">#{{tag}}</text>
           <text class="video-tag" v-for="(tag, index) in item.tagList" :key="tag">#{{tag.tagName}}</text>
        </view>
        </view>
        
@@ -68,15 +78,14 @@
             <text class="iconfont">&#xe629;</text>
            </view>
         </view>
          <view class="action-item" @click="toggleCollect(item)">
            <!-- <image :src="item.isCollected ? '/static/collected.png' : '/static/collect.png'"></image> -->
          <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.collectCount}}</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.commentCount}}</text>
            <text style="font-size: 10px;font-weight: lighter;">{{item.commentNum}}</text>
          </view>
        </view>
      </swiper-item>
@@ -86,49 +95,17 @@
</template>
<script>
import { getRecommendVideos } from "@/api/video.js";
import { changeCollect } from "@/api/collect.js";
export default {
  data() {
    return {
     currentVideoIsPlaying: false, // 当前视频是否正在播放
     isFullScreen: false,
     windowHeight: 0,
      currentIndex: 0, // 当前播放的视频索引
      videoList: [
        {
            url: 'http://vjs.zencdn.net/v/oceans.mp4',
            objectFit: 'contain',
            title: '我了个',
            author: 'xp',
            authorAvatar: 'https://picsum.photos/200/200?random=2',
            collected: true,
            commentCount: 12,
            collectCount: 45,
            tags: ["五一", "爱美食", "士大夫速度和粉红色的恢复速度的口袋空空"],
            goods: {
               name: '推流',
               price: '10',
               originalPrice: '48.9',
               sales: 1988,
               image: 'https://picsum.photos/200/200?random=2'
            }
         },
        {
           url: 'https://videos.pexels.com/video-files/30900524/13210612_1080_1920_30fps.mp4',
           objectFit: 'cover',
            title: '我了个',
            author: 'xp',
             authorAvatar: 'https://picsum.photos/200/200?random=2',
              collected: false,
               commentCount: 6,
               collectCount: 45,
                tags: ["我喜欢"],
                goods: {
                               name: '推流',
                               price: '10',
                               originalPrice: '48.9',
                               sales: 1988,
                              image: 'https://picsum.photos/200/200?random=2'
                }
          },
     ],   // 视频列表数据
      videoContexts: [], // 视频上下文对象集合
      loading: false,  // 是否正在加载
@@ -136,8 +113,11 @@
      pageSize: 10     // 每页数量
    }
  },
  onShow() {
    this.loadVideos();
  },
  onLoad() {
    // this.loadVideos();
     this.loadVideos();
  },
  onReady() {
    // 初始化视频上下文
@@ -148,7 +128,6 @@
    initVideoContexts() {
      this.videoContexts = this.videoList.map((_, index) => {
        let videoContent = uni.createVideoContext(`video${index}`, this);
        // videoContent.requestFullScreen({ direction: 0 });
        return videoContent;
      });
    },
@@ -158,30 +137,20 @@
      if (this.loading) return;
      this.loading = true;
      
      try {
        const res = await uni.request({
          url: 'https://your-api.com/videos',
          data: {
            page: this.page,
            pageSize: this.pageSize
          }
        });
        if (this.page === 1) {
          this.videoList = res.data.list;
        } else {
          this.videoList = [...this.videoList, ...res.data.list];
        }
        this.page++;
        this.$nextTick(() => {
          this.initVideoContexts();
        });
      } catch (e) {
        console.error('加载视频失败', e);
      } finally {
        this.loading = false;
      }
     getRecommendVideos({pageNumber: this.page, pageSize: this.pageSize}).then(res => {
        console.log(res, "视频数据");
        if (this.page === 1) {
          this.videoList = res.data.data;
        } else {
          this.videoList = [...this.videoList, ...res.data.data];
        }
        this.page++;
        this.$nextTick(() => {
          this.initVideoContexts();
        });
        this.loading = false;
     })
    },
    
    // 滑动切换视频
@@ -200,34 +169,49 @@
      }
    },
    
    // 点赞/取消点赞
    toggleLike(item) {
      item.isLiked = !item.isLiked;
      item.likeCount += item.isLiked ? 1 : -1;
      uni.request({
        url: `https://your-api.com/video/${item.id}/like`,
        method: item.isLiked ? 'POST' : 'DELETE'
      });
    // 收藏/取消收藏
    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) {
      if(this.currentVideoIsPlaying) {
         this.videoContexts[index].pause();
      } else {
         this.videoContexts[index].play();
      }
   },
    // 视频播放事件
    onPlay(index) {
      console.log(`视频 ${index} 开始播放`);
      this.currentVideoIsPlaying = true;
    },
    
    // 视频暂停事件
    onPause(index) {
      console.log(`视频 ${index} 暂停`);
      this.currentVideoIsPlaying = false;
    },
    
    // 视频结束事件
    onEnded(index) {
      console.log(`视频 ${index} 播放结束`);
      // 自动播放下一个(如果不在最后一个)
      if (index < this.videoList.length - 1) {
        this.currentIndex = index + 1;
      }
      this.currentVideoIsPlaying = false;
    }
  }
}
@@ -253,6 +237,16 @@
     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;
   }
   
   .video-info {
     width: 70%;