From 12af499e64f38b7ff3a79fcc5bf527855cf359f3 Mon Sep 17 00:00:00 2001
From: xiangpei <xiangpei@timesnew.cn>
Date: 星期二, 03 六月 2025 16:41:49 +0800
Subject: [PATCH] 视频主页基本信息接口对接

---
 api/user.js                 |   16 +++
 api/video.js                |   13 ++
 pages/tabbar/index/home.vue |    7 
 pages/video/home-page.vue   |  232 ++++++++++++++++++++++++++++++++-------------
 4 files changed, 196 insertions(+), 72 deletions(-)

diff --git a/api/user.js b/api/user.js
index 1f1ebaf..5dc926a 100644
--- a/api/user.js
+++ b/api/user.js
@@ -33,3 +33,19 @@
 	params: params
   });
 }
+
+
+/**
+ * 鑾峰彇瑙嗛涓婚〉-浣滆�呮敹钘忕殑瑙嗛鍒嗛〉
+ * 
+ * @param params
+ */
+ export function getAuthorCollectVideoPage(params) {
+  return http.request({
+    url: "/lmk/video/author-collect-video-page",
+    method: Method.GET,
+    needToken: true,
+	params: params
+  });
+}
+
diff --git a/api/video.js b/api/video.js
index c46c6b9..f3a56c8 100644
--- a/api/video.js
+++ b/api/video.js
@@ -62,6 +62,19 @@
 }
 
 /**
+ * 鍙栨秷鍏虫敞浣滆��
+ * 
+ * @param params
+ */
+ export function unSubscribe(authorId) {
+  return http.request({
+    url: "/lmk/my-subscribe/unSubscribe/" + authorId,
+    method: Method.POST,
+    needToken: true
+  });
+}
+
+/**
  * 鑾峰彇瑙嗛璇勮
  * 
  * @param params
diff --git a/pages/tabbar/index/home.vue b/pages/tabbar/index/home.vue
index d6a2f29..356bd51 100644
--- a/pages/tabbar/index/home.vue
+++ b/pages/tabbar/index/home.vue
@@ -75,16 +75,16 @@
 		   <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)">
+			   <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)">
+          <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)">
+         <view class="action-item" @click="() => showComments(item)">
             <text class="iconfont">&#xe7f7;</text>
             <text style="font-size: 10px;font-weight: lighter;">{{item.commentNum}}</text>
           </view>
@@ -495,7 +495,6 @@
     async loadVideos() {
       if (this.loading) return;
       this.loading = true;
-      
 	  getRecommendVideos({pageNumber: this.page, pageSize: this.pageSize}).then(res => {
 		  console.log(res, "瑙嗛鏁版嵁");
 		  if (this.page === 1) {
diff --git a/pages/video/home-page.vue b/pages/video/home-page.vue
index 9f9ddbf..a16c832 100644
--- a/pages/video/home-page.vue
+++ b/pages/video/home-page.vue
@@ -11,7 +11,7 @@
       <view class="user-info">
         <view class="user-name">{{userInfo.nickName}}</view>
         <view class="user-id">ID: {{userInfo.userId}}</view>
-        <view class="user-desc">{{userInfo.motto || '杩欎釜浜哄緢鎳掞紝浠�涔堥兘娌$暀涓媬'}}</view>
+        <view class="user-desc">{{userInfo.motto || '娌℃湁绛惧悕锛屼篃寰堜釜鎬'}}</view>
       </view>
       <view class="stats-container">
         <view class="stat-item" @click="navigateToFollow('fans')">
@@ -47,7 +47,7 @@
             :class="{active: currentTab === 'works'}" 
             @click="switchTab('works')"
           >
-            浣滃搧
+            浣滃搧{{`(${videoTotal})`}}
           </view>
           <view 
             class="tab-item" 
@@ -59,35 +59,63 @@
         </view>
         
         <!-- 瑙嗛鍒楄〃 -->
-        <view class="video-list">
-          <view 
-            class="video-item" 
-            v-for="(item, index) in videoList" 
-            :key="item.id"
-            @click="playVideo(index)"
-          >
-            <image class="video-cover" :src="item.cover" mode="aspectFill"></image>
-            <view class="video-info">
-              <view class="video-stats">
-                <view class="stat">
-                  <uni-icons type="heart" size="14" color="#fff"></uni-icons>
-                  <text>{{item.collectNum}}</text>
-                </view>
-              </view>
-            </view>
-          </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" 
+				  :key="item.id"
+				  @click="playVideo(index)"
+				>
+				  <image class="video-cover" :src="item.coverUrl" 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>
+				    </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" 
+				  :key="item.id"
+				  @click="playVideo(index)"
+				>
+				  <image class="video-cover" :src="item.coverUrl" 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>
+				    </view>
+				  </view>
+				</view> 
+			</view>
+		</scroll-view>
         
         <!-- 绌虹姸鎬� -->
-        <view class="empty-state" v-if="videoList.length === 0">
-          <image src="/static/images/empty.png" mode="aspectFit" class="empty-image"></image>
-          <text class="empty-text">{{currentTab === 'works' ? '浣犺繕娌℃湁鍙戝竷浣滃搧鍝' : '浣犺繕娌℃湁鐐硅禐浣滃搧鍝'}}</text>
+        <view class="empty-state" v-if="videoList.length === 0 && currentTab === 'works'">
+          <!-- <image src="/static/images/empty.png" mode="aspectFit" class="empty-image"></image> -->
+          <text class="empty-text">杩樻湭鍙戝竷浣滃搧鍝</text>
         </view>
+		<!-- 绌虹姸鎬� -->
+		<view class="empty-state" v-if="collectVideoList.length === 0 && currentTab === 'likes'">
+		  <!-- <image src="/static/images/empty.png" mode="aspectFit" class="empty-image"></image> -->
+		  <text class="empty-text">杩樻病鏈夌偣璧炰綔鍝佸摝~</text>
+		</view>
   </view>
 </template>
 
 <script>
-import {getAuthorInfo, getAuthorVideoPage} from '@/api/user.js'
+import {getAuthorInfo, getAuthorVideoPage, getAuthorCollectVideoPage} from '@/api/user.js'
+import {subscribe, unSubscribe} from '@/api/video.js'
 export default {
   data() {
     return {
@@ -109,7 +137,16 @@
 		  pageNumber: 1,
 		  pageSize: 10
 	  },
-      videoList: []
+	  collectVideoQuery: {
+		  authorId: '',
+		  pageNumber: 1,
+		  pageSize: 10
+	  },
+	  videoTotal: 0,
+      videoList: [], // 浣滃搧
+	  collectVideoList: [], // 鏀惰棌
+	  nomoreVideo: false,
+	  nomoreCollectVideo: false
     }
   },
   onLoad(option) {
@@ -118,63 +155,113 @@
 	this.getAuthorVideoPage();
   },
   methods: {
+	getPage() {
+		if(this.currentTab === 'works') {
+			if(this.nomoreVideo) {
+				return;
+			}
+			getAuthorVideoPage(this.videoQuery).then(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)
+					  ),
+					];
+				}
+				if(res.data.data.length < this.videoQuery.pageSize) {
+					this.nomoreVideo = true;
+				} else {
+					this.videoQuery.pageNumber += 1;
+				}
+			})
+		} else if(this.currentTab === 'likes') {
+			if(this.nomoreCollectVideo) {
+				return;
+			}
+			getAuthorCollectVideoPage(this.collectVideoQuery).then(res => {
+				if(this.collectVideoQuery.pageNumber === 1) {
+					this.collectVideoList = res.data.data
+				} else {
+					this.collectVideoList = [
+					  ...this.collectVideoList,
+					  ...res.data.data.filter(
+					    (newItem) => !this.collectVideoList.some((oldItem) => oldItem.id === newItem.id)
+					  ),
+					];
+				}
+				if(res.data.data.length < this.collectVideoQuery.pageSize) {
+					this.nomoreCollectVideo = true;
+				} else {
+					this.collectVideoQuery.pageNumber += 1;
+				}
+			})
+		}
+	},
 	// 鑾峰彇涓汉淇℃伅
 	async getAuthorInfo() {
 		getAuthorInfo(this.authorId).then(res => {
 			this.userInfo = res.data.data
 		})
 	},
+	// 鑾峰彇浣滆�呬綔鍝�
 	async getAuthorVideoPage() {
 		this.videoQuery.authorId = this.authorId;
 		getAuthorVideoPage(this.videoQuery).then(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.videoList = res.data.data
+			this.videoTotal = res.data.total
 		})
 	},
 	// 鑾峰彇浣滃搧淇℃伅
     // 鍒囨崲鍏虫敞鐘舵��
     toggleFollow() {
-      // 妯℃嫙璇锋眰鏈嶅姟鍣�
-      uni.showLoading({
-        title: '澶勭悊涓�...'
-      });
-      
-      setTimeout(() => {
-        this.isFollowed = !this.isFollowed;
-        
-        // 鏇存柊绮変笣鏁�
-        if(this.isFollowed) {
-          this.userInfo.fansCount++;
-          uni.showToast({
-            title: '鍏虫敞鎴愬姛',
-            icon: 'success'
-          });
-        } else {
-          this.userInfo.fansCount--;
-          uni.showToast({
-            title: '宸插彇娑堝叧娉�',
-            icon: 'none'
-          });
-        }
-        
-        uni.hideLoading();
-      }, 500);
+      if(this.userInfo.hasSub) {
+		  // 鍙栨秷鍏虫敞
+		  unSubscribe(this.authorId).then(res => {
+			  uni.showToast({
+			    title: '宸插彇娑堝叧娉�',
+			    icon: 'none'
+			  });
+			  this.userInfo.hasSub = false
+			  this.userInfo.fansNum -= 1;
+		  })
+	  } else {
+		  // 鍏虫敞
+		  subscribe(this.authorId).then(res => {
+			  uni.showToast({
+			    title: '鍏虫敞鎴愬姛',
+			    icon: 'success'
+			  });
+			  this.userInfo.hasSub = true
+			  this.userInfo.fansNum += 1;
+		  })
+	  }
     },
 	// 鍒囨崲浣滃搧/鍠滄tab
     switchTab(tab) {
+	  if(this.currentTab === tab) {
+		  return
+	  }
       this.currentTab = tab;
-      // 杩欓噷搴旇鏍规嵁tab鍒囨崲璇锋眰涓嶅悓鐨勬暟鎹�
-      // this.loadVideoList();
+	  if(tab === 'works') {
+		  this.collectVideoList = []
+		  this.videoQuery.pageNumber = 1
+		  this.getAuthorVideoPage()
+	  } else if(tab === 'likes') {
+		  this.videoList = []
+		  this.collectVideoQuery.pageNumber = 1
+		  this.getAuthorCollectVideoPage()
+	  }
     },
-    
+	// 鑾峰彇浣滆�呯殑鏀惰棌瑙嗛
+    async getAuthorCollectVideoPage() {
+		this.collectVideoQuery.authorId = this.authorId
+		getAuthorCollectVideoPage(this.collectVideoQuery).then(res => {
+			this.collectVideoList = res.data.data
+		})
+	},
     // 鎾斁瑙嗛
     playVideo(index) {
       const videoItem = this.videoList[index];
@@ -208,9 +295,12 @@
 </script>
 
 <style lang="scss" scoped>
+body {
+	background-color: #fff !important;
+}
 .container {
   padding-bottom: 20rpx;
-  background-color: #f5f5f5;
+  background-color: white;
   min-height: 100vh;
 }
 
@@ -300,7 +390,7 @@
 .tab-bar {
   display: flex;
   background-color: #fff;
-  margin-bottom: 20rpx;
+  padding-bottom: 20rpx;
 }
 
 .tab-item {
@@ -330,9 +420,10 @@
 }
 
 .video-list {
-  display: flex;
-  flex-wrap: wrap;
+  width: calc(100% - 20rpx);
   padding: 0 10rpx;
+  height: calc(100vh - 554rpx);
+  background-color: #fff;
 }
 
 .video-item {
@@ -344,7 +435,7 @@
 
 .video-cover {
   width: 100%;
-  height: 350rpx;
+  height: 500rpx;
   border-radius: 10rpx;
   display: block;
 }
@@ -431,4 +522,9 @@
 .user-header {
   position: relative;
 }
+
+.video-container {
+	display: flex;
+	flex-wrap: wrap
+}
 </style>
\ No newline at end of file

--
Gitblit v1.8.0