From c9928dd4f6d25e2339ea1400f59ec58674a927a7 Mon Sep 17 00:00:00 2001 From: zxl <763096477@qq.com> Date: 星期四, 19 六月 2025 20:07:42 +0800 Subject: [PATCH] Merge remote-tracking branch 'origin/dev' into dev --- pages/video/home-page.vue | 398 +++++++++++++++++++++++++++++++++++++++++++------------- 1 files changed, 301 insertions(+), 97 deletions(-) diff --git a/pages/video/home-page.vue b/pages/video/home-page.vue index 9f9ddbf..5ce3063 100644 --- a/pages/video/home-page.vue +++ b/pages/video/home-page.vue @@ -4,14 +4,11 @@ <view class="user-header"> <view class="user-avatar-container"> <image class="user-avatar" :src="userInfo.avatar" mode="aspectFill"></image> - <view class="edit-icon" @click="editProfile" v-if="isSelf"> - <uni-icons type="compose" size="20" color="#666"></uni-icons> - </view> </view> <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')"> @@ -38,6 +35,10 @@ {{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> <!-- 浣滃搧/鍠滄鍒囨崲 --> @@ -47,7 +48,7 @@ :class="{active: currentTab === 'works'}" @click="switchTab('works')" > - 浣滃搧 + 浣滃搧{{`(${videoTotal})`}} </view> <view class="tab-item" @@ -59,38 +60,98 @@ </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" + > + <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" v-if="userInfo.self"> + <dropdown-menu + :options="item.options" + :data="{id: item.id, title: item.title}" + placement="top" + theme-color="#07C160" + @change="handleChange" + ></dropdown-menu> + </view> + </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="playCollectVideo(index)" + > + <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"> + <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> + + <!-- 鍒犻櫎瑙嗛鎻愰啋妗� --> + <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> <script> -import {getAuthorInfo, getAuthorVideoPage} from '@/api/user.js' +import DropdownMenu from '@/components/dropdown-menu.vue' + +import {getAuthorInfo, getAuthorVideoPage, getAuthorCollectVideoPage} from '@/api/user.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: '骞垮窞' } + ], + opVideo: { // 姝e湪鎿嶄綔鐨勮棰� + id: '', + title: '' + }, currentTab: 'works', // works: 浣滃搧, likes: 鍠滄 authorId: '', userInfo: { @@ -109,8 +170,20 @@ pageNumber: 1, pageSize: 10 }, - videoList: [] + collectVideoQuery: { + authorId: '', + pageNumber: 1, + pageSize: 10 + }, + videoTotal: 0, + videoList: [], // 浣滃搧 + collectVideoList: [], // 鏀惰棌 + nomoreVideo: false, + nomoreCollectVideo: false } + }, + onShow() { + this.getAuthorInfo(); }, onLoad(option) { this.authorId = option.authorId; @@ -118,75 +191,196 @@ this.getAuthorVideoPage(); }, methods: { + 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) { + 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 + if(res.data.data.length < this.videoQuery.pageSize) { + this.nomoreVideo = true; } }) }, - // 鑾峰彇浣滃搧淇℃伅 // 鍒囨崲鍏虫敞鐘舵�� 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() + } }, - - // 鎾斁瑙嗛 - playVideo(index) { - const videoItem = this.videoList[index]; + // 鑾峰彇浣滆�呯殑鏀惰棌瑙嗛 + async getAuthorCollectVideoPage() { + this.collectVideoQuery.authorId = this.authorId + getAuthorCollectVideoPage(this.collectVideoQuery).then(res => { + this.collectVideoList = res.data.data + if(res.data.data.length < this.collectVideoQuery.pageSize) { + this.nomoreCollectVideo = true; + } + }) + }, + // 鎾斁浣滆�呰棰� + playAuthorVideo(index) { + const playInfo = { + videoList: this.videoList, + nomore: this.nomoreVideo, + pageNumber: this.videoQuery.pageNumber, + playIndex: index + } + uni.setStorageSync("playInfo", playInfo) uni.navigateTo({ - url: `/pages/video/play?id=${videoItem.id}` + url: `/pages/video/video-play?authorId=${this.authorId}&videoFrom=author` }); }, - - // 缂栬緫涓汉璧勬枡 - editProfile() { + // 鎾斁鏀惰棌瑙嗛 + playCollectVideo(index) { + const playInfo = { + videoList: this.collectVideoList, + nomore: this.nomoreCollectVideo, + pageNumber: this.collectVideoQuery.pageNumber, + playIndex: index + } + uni.setStorageSync("playInfo", playInfo) uni.navigateTo({ - url: '/pages/user/edit' + url: `/pages/video/video-play?authorId=${this.authorId}&videoFrom=collect` + }); + }, + // 缂栬緫涓汉璧勬枡 + editInfo() { + uni.navigateTo({ + url: `/pages/video/home-page-edit?authorId=${this.authorId}&avatar=${this.userInfo.avatar}&motto=${this.userInfo.motto || ''}&nickName=${this.userInfo.nickName}` }); }, @@ -208,9 +402,12 @@ </script> <style lang="scss" scoped> +body { + background-color: #fff !important; +} .container { padding-bottom: 20rpx; - background-color: #f5f5f5; + background-color: white; min-height: 100vh; } @@ -238,16 +435,13 @@ .edit-icon { position: absolute; - right: 0; - bottom: 0; + right: 30rpx; + top: 30rpx; background-color: #fff; - border-radius: 50%; - width: 40rpx; height: 40rpx; display: flex; justify-content: center; align-items: center; - box-shadow: 0 0 10rpx rgba(0, 0, 0, 0.1); } .user-info { @@ -300,7 +494,7 @@ .tab-bar { display: flex; background-color: #fff; - margin-bottom: 20rpx; + padding-bottom: 20rpx; } .tab-item { @@ -330,32 +524,38 @@ } .video-list { + width: 100%; + padding: 0 10rpx; + height: calc(100vh - 554rpx); + background-color: #fff; +} + +.video-container { display: flex; flex-wrap: wrap; - padding: 0 10rpx; + justify-content: space-between; } .video-item { - width: 50%; - padding: 10rpx; - box-sizing: border-box; + width: 49%; + margin-bottom: 20rpx; position: relative; } .video-cover { width: 100%; - height: 350rpx; + height: 500rpx; border-radius: 10rpx; display: block; } .video-info { position: absolute; - bottom: 20rpx; - left: 20rpx; - right: 20rpx; - color: #fff; - font-size: 24rpx; + bottom: 10rpx; + left: 0; + right: 0; + padding: 0 10rpx; + box-sizing: border-box; } .video-title { @@ -369,17 +569,25 @@ .video-stats { display: flex; + width: 100%; } .stat { display: flex; + width: 100%; align-items: center; - margin-right: 20rpx; - text-shadow: 0 0 5rpx rgba(0, 0, 0, 0.5); + position: relative; +} + +.more-op { + position: absolute; + right: 0; } .stat text { margin-left: 5rpx; + color: #fff; + font-size: 14px; } .empty-state { @@ -427,8 +635,4 @@ } } -/* 濡傛灉鏄嚜宸辩殑涓婚〉锛岄殣钘忓叧娉ㄦ寜閽� */ -.user-header { - position: relative; -} </style> \ No newline at end of file -- Gitblit v1.8.0