绿满眶商城微信小程序-uniapp
peng
2025-06-27 7673b8272cfd9fc21161b70e35c263e455b59966
pages/video/home-page.vue
@@ -24,57 +24,59 @@
          <text class="stat-label">获赞</text>
        </view>
      </view>
      <!-- 关注按钮 -->
      <view class="follow-btn-container" v-if="!userInfo.self">
        <button
          class="follow-btn"
          :class="{followed: userInfo.hasSub}"
        <button
          class="follow-btn"
          :class="{followed: userInfo.hasSub}"
          @click="toggleFollow"
        >
          {{userInfo.hasSub ? '取消关注' : '关注'}}
        </button>
      </view>
     <view class="edit-icon" @click="editInfo" v-if="userInfo.self">
       <uni-icons type="compose" size="20" color="#666"></uni-icons>编辑主页信息
     </view>
    </view>
        <!-- 作品/喜欢切换 -->
        <view class="tab-bar">
          <view
            class="tab-item"
            :class="{active: currentTab === 'works'}"
          <view
            class="tab-item"
            :class="{active: currentTab === 'works'}"
            @click="switchTab('works')"
          >
            作品{{`(${videoTotal})`}}
          </view>
          <view
            class="tab-item"
            :class="{active: currentTab === 'likes'}"
          <view
            class="tab-item"
            :class="{active: currentTab === 'likes'}"
            @click="switchTab('likes')"
          >
            喜欢
          </view>
        </view>
        <!-- 视频列表 -->
      <scroll-view class="video-list" scroll-y :show-scrollbar="false" @scrolltolower="getPage" v-show="currentTab === 'works' && videoList.length > 0">
         <view class="video-container">
            <view
              class="video-item"
              v-for="(item, index) in videoList"
              class="video-item"
              v-for="(item, index) in videoList"
              :key="item.id"
            >
              <image class="video-cover" @click="playAuthorVideo(index)" :src="item.coverUrl" mode="aspectFill"></image>
              <image class="video-cover" @click="playAuthorVideo(index)" :src="item.videoContentType === 'video' ? item.coverUrl : item.imgs[0]" mode="aspectFill"></image>
              <view class="video-info">
                <view class="video-stats">
                  <view class="stat">
                    <uni-icons type="heart" size="16" color="#fff"></uni-icons>
                    <text>{{item.collectNum}}</text>
                  <view class="more-op">
                  <view class="more-op" v-if="userInfo.self">
                     <dropdown-menu
                     :options="item.options"
                     :data="{id: item.id, title: item.title}"
                     placement="top"
                     theme-color="#07C160"
                     @change="handleChange"
@@ -83,17 +85,18 @@
                  </view>
                </view>
              </view>
            </view>
         </view>
      </scroll-view>
      <scroll-view class="video-list" scroll-y :show-scrollbar="false" @scrolltolower="getPage" v-show="currentTab === 'likes' && collectVideoList.length > 0">
         <view class="video-container">
            <view
              class="video-item"
              v-for="(item, index) in collectVideoList"
              class="video-item"
              v-for="(item, index) in collectVideoList"
              :key="item.id"
              @click="playCollectVideo(index)"
            >
              <image class="video-cover" :src="item.coverUrl" mode="aspectFill"></image>
              <image class="video-cover" :src="item.videoContentType === 'video' ? item.coverUrl : item.imgs[0]" mode="aspectFill"></image>
              <view class="video-info">
                <view class="video-stats">
                  <view class="stat">
@@ -102,10 +105,10 @@
                  </view>
                </view>
              </view>
            </view>
            </view>
         </view>
      </scroll-view>
        <!-- 空状态 -->
        <view class="empty-state" v-if="videoList.length === 0 && currentTab === 'works'">
          <!-- <image src="/static/images/empty.png" mode="aspectFit" class="empty-image"></image> -->
@@ -116,6 +119,18 @@
        <!-- <image src="/static/images/empty.png" mode="aspectFit" class="empty-image"></image> -->
        <text class="empty-text">还没有点赞作品哦~</text>
      </view>
      <!-- 删除视频提醒框 -->
      <uni-popup ref="delDialog" type="dialog">
         <uni-popup-dialog type="error" cancelText="取消" confirmText="删除" title="提醒" :content="`您正在删除:${opVideo.title}`" @confirm="deleteVideo"
            @close="dialogClose"></uni-popup-dialog>
      </uni-popup>
      <!-- 下架视频提醒框 -->
      <uni-popup ref="downDialog" type="dialog">
         <uni-popup-dialog type="error" cancelText="取消" confirmText="下架" title="提醒" :content="`您正在下架:${opVideo.title}`" @confirm="downVideo"
            @close="dialogClose"></uni-popup-dialog>
      </uni-popup>
  </view>
</template>
@@ -123,16 +138,20 @@
import DropdownMenu from '@/components/dropdown-menu.vue'
import {getAuthorInfo, getAuthorVideoPage, getAuthorCollectVideoPage} from '@/api/user.js'
import {subscribe, unSubscribe} from '@/api/video.js'
import {subscribe, unSubscribe, delVideo, updateVideo, userDownVideo} from '@/api/video.js'
export default {
  components: {DropdownMenu},
  data() {
    return {
      options: [
              { command: 1, label: '北京' },
              { command: 2, label: '上海' },
              { command: 3, label: '广州' }
            ],
     options: [
         { command: 1, label: '北京' },
         { command: 2, label: '上海' },
         { command: 3, label: '广州' }
        ],
     opVideo: { // 正在操作的视频
        id: '',
        title: ''
     },
      currentTab: 'works', // works: 作品, likes: 喜欢
      authorId: '',
      userInfo: {
@@ -172,9 +191,54 @@
   this.getAuthorVideoPage();
  },
  methods: {
     handleChange(value) {
           console.log('选中值:', value)
         },
   dialogClose() {
      this.opVideo = {
         id: '',
         title: ''
      }
   },
   // 下架视频
   downVideo() {
      userDownVideo(this.opVideo.id).then(res => {
         uni.showToast({
            title: '下架成功',
            duration: 2000
         });
         // 刷新数据
         this.videoList = [];
         this.videoQuery.pageNumber = 1;
         this.getAuthorVideoPage();
      })
   },
   // 删除视频
   deleteVideo() {
      delVideo(this.opVideo.id).then(res => {
         uni.showToast({
            title: '删除成功',
            duration: 2000
         });
         // 刷新数据
         this.videoList = [];
         this.videoQuery.pageNumber = 1;
         this.getAuthorVideoPage();
      })
   },
   // 触发视频操作
   handleChange(value, data) {
       console.log('选中值:', value)
      this.opVideo.id = data.id;
      this.opVideo.title = data.title;
      if (value === 'DELETE') {
         this.$refs.delDialog.open()
      } else if (value === 'DOWN') {
         this.$refs.downDialog.open()
      } else if (value === 'EDIT') {
         // 跳转编辑视频页面
         uni.navigateTo({
           url: `/pages/video/video-edit?id=${this.opVideo.id}`
         });
      }
   },
   getPage() {
      if(this.currentTab === 'works') {
         if(this.nomoreVideo) {
@@ -301,7 +365,7 @@
      });
    },
    // 播放收藏视频
    playAuthorVideo(index) {
    playCollectVideo(index) {
      const playInfo = {
         videoList: this.collectVideoList,
         nomore: this.nomoreCollectVideo,
@@ -319,14 +383,14 @@
        url: `/pages/video/home-page-edit?authorId=${this.authorId}&avatar=${this.userInfo.avatar}&motto=${this.userInfo.motto || ''}&nickName=${this.userInfo.nickName}`
      });
    },
    // 跳转到粉丝/关注列表
    navigateToFollow(type) {
      uni.navigateTo({
        url: `/pages/user/follow?type=${type}`
      });
    },
    // 跳转到点赞列表
    navigateToLike() {
      uni.navigateTo({
@@ -460,16 +524,21 @@
}
.video-list {
  width: calc(100% - 20rpx);
  padding: 0 10rpx;
  height: calc(100vh - 554rpx);
  background-color: #fff;
  width: 100%;
    padding: 0 10rpx;
    height: calc(100vh - 554rpx);
    background-color: #fff;
}
.video-container {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
}
.video-item {
  width: 50%;
  padding: 10rpx;
  box-sizing: border-box;
  width: 49%;
  margin-bottom: 20rpx;
  position: relative;
}
@@ -481,15 +550,12 @@
}
.video-info {
  display: flex;
  height: 60rpx;
  align-items: center;
  font-size: 24rpx;
  width: 100%;
  padding-right: 20rpx;
  box-sizing: border-box;
  position: absolute;
  bottom: 20rpx;
  bottom: 10rpx;
  left: 0;
  right: 0;
  padding: 0 10rpx;
  box-sizing: border-box;
}
.video-title {
@@ -558,19 +624,15 @@
  height: 70rpx;
  line-height: 70rpx;
  padding: 0 40rpx;
  &::after {
    border: none;
  }
  &.followed {
    background-color: #f5f5f5;
    color: #666;
  }
}
.video-container {
   display: flex;
   flex-wrap: wrap
}
</style>
</style>