From be80b22a4a0fcd33e1b17ebdb86eba91cc7de4d2 Mon Sep 17 00:00:00 2001 From: peng <peng.com> Date: 星期三, 02 七月 2025 18:59:06 +0800 Subject: [PATCH] Merge remote-tracking branch 'origin/dev' into dev --- pages.json | 7 + pages/video/video-search.vue | 307 +++++++++++++++++++++++++++++++++++++++++++++++++++ api/video.js | 14 ++ pages/video/video-play.vue | 20 ++ pages/tabbar/index/home.vue | 8 + 5 files changed, 352 insertions(+), 4 deletions(-) diff --git a/api/video.js b/api/video.js index 926527f..cbe9a13 100644 --- a/api/video.js +++ b/api/video.js @@ -250,3 +250,17 @@ needToken: true }); } + +/** + * 瑙嗛鎼滅储 + * + * @param params + */ + export function videoSearch(params) { + return http.request({ + url: "/lmk/video/es/search", + method: Method.GET, + params: params, + needToken: true + }); +} diff --git a/pages.json b/pages.json index 48cdf4f..99b0f4d 100644 --- a/pages.json +++ b/pages.json @@ -1038,6 +1038,13 @@ "u-button": "view" } } + }, + { + "path" : "video-search", + "style" : + { + "navigationBarTitleText" : "" + } } ] }, diff --git a/pages/tabbar/index/home.vue b/pages/tabbar/index/home.vue index 87916dc..4589ccd 100644 --- a/pages/tabbar/index/home.vue +++ b/pages/tabbar/index/home.vue @@ -121,7 +121,7 @@ <!-- 瑙嗛淇℃伅灞� --> <view class="video-info" :style="{bottom: marginBottom + 20 + 'px'}"> <view> - <text class="video-author">@{{item.authorName}}</text> + <text class="video-author" @click="jumpToSearch">@{{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> @@ -399,6 +399,12 @@ } }, methods: { + jumpToSearch() { + uni.navigateTo({ + url: '/pages/video/video-search' + }); + }, + // 鍒囨崲椤堕儴瀵艰埅鏍� topBarChange(titleObj) { if (titleObj.index === 'home') { uni.switchTab({ diff --git a/pages/video/video-play.vue b/pages/video/video-play.vue index c11b7d2..cb2bb48 100644 --- a/pages/video/video-play.vue +++ b/pages/video/video-play.vue @@ -331,7 +331,8 @@ pageNumber: 1, pageSize: 10, authorId: '', - videoFrom: '' + videoFrom: '', + keyword: '' }, marginBottom: 0, // 搴曢儴瀹夊叏鍖哄煙 windowHeight: 0 // 鍙娇鐢ㄥ睆骞曢珮搴� @@ -350,6 +351,7 @@ }, onUnload() { uni.removeStorageSync("playInfo"); + uni.removeStorageSync("searchPlayInfo"); }, onReady() { @@ -357,11 +359,11 @@ onLoad(option) { this.marginBottom = uni.getSystemInfoSync().safeAreaInsets.bottom this.windowHeight = uni.getSystemInfoSync().windowHeight - const playInfo = uni.getStorageSync("playInfo", playInfo); + const playInfo = uni.getStorageSync("playInfo"); + const searchPlayInfo = uni.getStorageSync("searchPlayInfo"); if(playInfo) { this.currentIndex = playInfo.playIndex; this.videoList = playInfo.videoList; - console.log("鎷垮埌鏁版嵁浜�",playInfo); this.videoQuery.pageNumber = playInfo.pageNumber; this.videoNoMore = playInfo.nomore; this.videoQuery.authorId = option.authorId; @@ -371,6 +373,18 @@ const videoContext = uni.createVideoContext(`video${this.currentIndex}`, this); videoContext.play() }) + } else if (searchPlayInfo) { // 鎼滅储椤佃烦杞繃鏉ョ殑鏁版嵁鐣ユ湁涓嶅悓 + this.currentIndex = searchPlayInfo.playIndex; + this.videoList = searchPlayInfo.videoList; + this.videoQuery.pageNumber = searchPlayInfo.pageNumber; + this.videoNoMore = searchPlayInfo.nomore; + this.videoQuery.keyword = searchPlayInfo.keyword; + this.videoQuery.videoFrom = option.videoFrom; + this.currentVideoIsPlaying = true; + this.$nextTick(() => { + const videoContext = uni.createVideoContext(`video${this.currentIndex}`, this); + videoContext.play() + }) } else { this.videoQuery.videoFrom = 'recommend'; this.loadVideos(); diff --git a/pages/video/video-search.vue b/pages/video/video-search.vue new file mode 100644 index 0000000..4ade5f1 --- /dev/null +++ b/pages/video/video-search.vue @@ -0,0 +1,307 @@ +<template> + <view class="search-page"> + <!-- 鎼滅储鍖哄煙 --> + <view class="search-bar"> + <input + class="search-input" + v-model="searchQuery.keyword" + placeholder="璇疯緭鍏ユ悳绱㈠叧閿瘝" + placeholder-class="placeholder-style" + @confirm="handleSearch" + /> + <button class="search-btn" @click="handleSearch">鎼滅储</button> + </view> + + <!-- 鐎戝竷娴佽棰戝垪琛� --> + <view class="waterfall-container"> + <view class="waterfall-left"> + <view + class="video-item" + v-for="(item, index) in leftList" + :key="item.id" + @click="playVideo(item)" + > + <image class="video-cover" :src="item.coverUrl" mode="widthFix"></image> + <view class="video-info"> + <text class="video-title">{{item.title}}</text> + <view class="video-tags"> + <text class="tag" v-for="(tag, i) in item.tagList" :key="i">{{tag.tagName}}</text> + </view> + <view class="video-stats"> + <text class="like-count">鉂わ笍 {{item.thumbsUpNum}}</text> + </view> + </view> + </view> + </view> + + <view class="waterfall-right"> + <view + class="video-item" + v-for="(item, index) in rightList" + :key="item.id" + @click="playVideo(item)" + > + <image class="video-cover" :src="item.coverUrl" mode="widthFix"></image> + <view class="video-info"> + <text class="video-title">{{item.title}}</text> + <view class="video-tags"> + <text class="tag" v-for="(tag, i) in item.tagList" :key="i">{{tag.tagName}}</text> + </view> + <view class="video-stats"> + <text class="like-count">鉂わ笍 {{item.thumbsUpNum}}</text> + </view> + </view> + </view> + </view> + </view> + + <!-- 鍔犺浇鏇村鎻愮ず --> + <view class="load-more" v-if="loading"> + <text>鍔犺浇涓�...</text> + </view> + <view class="load-more" v-if="noMore"> + <text>娌℃湁鏇村浜�</text> + </view> + </view> +</template> + +<script> + import {videoSearch} from "@/api/video.js" +export default { + data() { + return { + videoList: [], // 鎵�鏈夎棰戞暟鎹� + leftList: [], // 宸︿晶鍒楄棰� + rightList: [], // 鍙充晶鍒楄棰� + searchQuery: { + keyword: '', + pageNumber: 1, // 铏界劧es鏄粠绗�0椤靛紑濮嬬殑锛屼絾鏄负浜嗗湪璺宠浆鍒皏ideo-play椤典箣鍚庡拰鍏跺畠绫诲瀷鐨勬煡璇繚鎸佷竴鑷达紝杩欓噷浠�1寮�濮嬶紝鍚庣榛樿-1 + pageSize: 10 + }, + loading: false, + noMore: false + } + }, + onLoad() { + // 鍒濆鍔犺浇涓�浜涙暟鎹� + this.loadVideos(); + }, + methods: { + handleSearch() { + if (!this.searchQuery.keyword.trim()) { + uni.showToast({ + title: '璇疯緭鍏ユ悳绱㈠叧閿瘝', + icon: 'none' + }); + return; + } + + // 閲嶇疆鏁版嵁 + this.searchQuery.pageNumber = 1; + this.videoList = []; + this.leftList = []; + this.rightList = []; + this.noMore = false; + + // 鎵ц鎼滅储 + this.loadVideos(); + }, + + async loadVideos() { + if (this.loading || this.noMore) return; + + this.loading = true; + uni.showLoading({ title: '鍔犺浇涓�' }); + + try { + videoSearch(this.searchQuery).then(res => { + if (this.searchQuery.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.distributeWaterfall(); + + if (res.data.data.length < this.searchQuery.pageSize) { + this.noMore = true + } else { + this.searchQuery.pageNumber += 1 + } + }) + } catch (error) { + console.error('鍔犺浇瑙嗛澶辫触:', error); + uni.showToast({ + title: '鍔犺浇澶辫触', + icon: 'none' + }); + } finally { + this.loading = false; + uni.hideLoading(); + } + }, + + // 鍒嗛厤鐎戝竷娴佸乏鍙冲垪 + distributeWaterfall() { + let leftHeight = this.getColumnHeight(this.leftList); + let rightHeight = this.getColumnHeight(this.rightList); + + // 浠庡綋鍓峷ideoList涓湭鍒嗛厤鐨勫紑濮� + const startIndex = this.leftList.length + this.rightList.length; + + for (let i = startIndex; i < this.videoList.length; i++) { + const item = this.videoList[i]; + item["index"] = i; + // 璁$畻杩欎釜item鐨勫ぇ姒傞珮搴︼紙鏍规嵁灏侀潰姣斾緥锛� + const itemHeight = 200 + Math.random() * 50; // 绠�鍗曟ā鎷熼珮搴﹀樊寮� + + if (leftHeight <= rightHeight) { + this.leftList.push(item); + leftHeight += itemHeight; + } else { + this.rightList.push(item); + rightHeight += itemHeight; + } + } + }, + + // 鑾峰彇鍒楃殑楂樺害锛堢畝鍗曞疄鐜帮級 + getColumnHeight(list) { + return list.length * 250; // 鍋囪姣忎釜item澶х害250楂樺害 + }, + + // 鎾斁瑙嗛 + playVideo(item) { + const searchPlayInfo = { + videoList: this.videoList, + nomore: this.noMore, + pageNumber: this.searchQuery.pageNumber, + playIndex: item.index, + keyword: this.searchQuery.keyword + } + uni.setStorageSync("searchPlayInfo", searchPlayInfo) + uni.navigateTo({ + url: `/pages/video/video-play?videoFrom=search` + }); + }, + }, + + // 涓婃媺鍔犺浇鏇村 + onReachBottom() { + this.loadVideos(); + } +} +</script> + +<style scoped> +.search-page { + padding: 20rpx; +} + +.search-bar { + display: flex; + align-items: center; + margin-bottom: 20rpx; +} + +.search-input { + flex: 1; + height: 70rpx; + padding: 0 20rpx; + background-color: #efefef; + border-radius: 35rpx; + font-size: 28rpx; +} + +.placeholder-style { + color: #999; +} + +.search-btn { + width: 120rpx; + height: 70rpx; + margin-left: 20rpx; + line-height: 70rpx; + font-size: 28rpx; + background-color: #07c160; + color: white; + border-radius: 35rpx; +} + +.waterfall-container { + display: flex; + justify-content: space-between; +} + +.waterfall-left, +.waterfall-right { + width: 48%; +} + +.video-item { + margin-bottom: 20rpx; + background: #fff; + border-radius: 12rpx; + overflow: hidden; + box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05); +} + +.video-cover { + width: 100%; + display: block; +} + +.video-info { + padding: 16rpx; +} + +.video-title { + font-size: 28rpx; + color: #333; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + overflow: hidden; + line-height: 1.4; +} + +.video-tags { + margin-top: 10rpx; + display: flex; + flex-wrap: wrap; + gap: 20rpx; +} + +.tag { + font-size: 24rpx; + color: #07c160; + background: #e8f5e9; + border-radius: 20rpx; + flex: 1 1 calc(50% - 20rpx); /* 鑰冭檻gap鐨勫搴� */ + min-width: calc(50% - 20rpx); + max-width: 100%; +} + +.video-stats { + margin-top: 10rpx; + display: flex; + align-items: center; +} + +.like-count { + font-size: 24rpx; + color: #666; +} + +.load-more { + text-align: center; + padding: 20rpx; + font-size: 24rpx; + color: #999; +} +</style> \ No newline at end of file -- Gitblit v1.8.0