修改显示处理逻辑

master
于肖磊 2025-09-16 18:01:40 +08:00
parent b372cc3423
commit afc67f6d91
4 changed files with 602 additions and 21 deletions

View File

@ -1,5 +1,6 @@
<template>
<view class="search-bar">
<view class="search-bar pr">
<view v-if="propsIsDisabled" class="search-mask" @tap="disabled_search"></view>
<iconfont name="icon-search-fine"></iconfont>
<input type="text" v-model="search_query" placeholder="请输入您的搜索内容" @input="handle_search" />
<view class="search-line"></view>
@ -13,6 +14,10 @@ export default {
propsSearchQuery: {
type: String,
default: ''
},
propsIsDisabled: {
type: Boolean,
default: false
}
},
data() {
@ -45,6 +50,9 @@ export default {
perform_search() {
//
this.$emit('search', this.search_query);
},
disabled_search() {
this.$emit('disabledSearch');
}
}
}
@ -84,5 +92,13 @@ export default {
line-height: 20px;
padding: 16rpx 30rpx 16rpx 20rpx;
}
.search-mask {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
}
}
</style>

View File

@ -5,7 +5,7 @@
<!-- 搜索框 -->
<view class="header-top">
<view class="wh-auto ht-auto" :style="top_content_style">
<search-component :propsSearchQuery="search_query" @search="handle_search" />
<search-component :propsSearchQuery="search_query" :propsIsDisabled="true" @disabledSearch="handle_search"/>
</view>
<!-- 导航栏 -->
<view class="nav-tabs">
@ -40,7 +40,7 @@
</template>
<script>
import SearchComponent from '@/pages/plugins/video/components/search.vue';
import searchComponent from '@/pages/plugins/video/components/search.vue';
const app = getApp();
//
var bar_height = parseInt(app.globalData.get_system_info('statusBarHeight', 0));
@ -49,7 +49,7 @@ bar_height = 0;
// #endif
export default {
components: {
SearchComponent
searchComponent
},
data() {
return {
@ -118,13 +118,9 @@ export default {
// #endif
// #endif
},
handle_search(e) {
this.search_query = e;
if (this.search_query.trim() == '') {
app.globalData.url_open(`/pages/plugins/video/search/search-record`, false);
} else {
app.globalData.url_open(`/pages/plugins/video/search/search?search_query=${this.search_query}`, false);
}
handle_search() {
//
app.globalData.url_open(`/pages/plugins/video/search/search-record`, false);
},
switch_tab(e) {
const index = e.currentTarget.dataset.index;

View File

@ -0,0 +1,401 @@
<template>
<view class="wh-auto ht pr search-record-container">
<!-- 搜索框 -->
<view class="header-top flex-row align-c">
<view class="cp" @tap="handle_back">
<iconfont name="icon-arrow-left " size="32rpx" color="#333" class="mr-10"></iconfont>
</view>
<view class="wh-auto ht-auto" :style="top_content_style">
<search-component :propsSearchQuery="search_query" @search="handle_search" />
</view>
</view>
<!-- 搜索历史记录 -->
<view class="search-history flex-col jc-c align-c">
<view v-for="(history, index) in search_history" :key="index" class="wh-auto history-item flex-row align-c jc-sb">
<view class="flex-row align-c search-history-title cp" :data-value="history.text" @tap.stop="perform_search">
<iconfont name="icon-time" size="32rpx"></iconfont>
<text>{{ history.text }}</text>
</view>
<iconfont name="icon-close-line" size="24rpx" :data-index="index" @tap="delete_history"></iconfont>
</view>
<!-- 查看更多 -->
<template v-if="is_view_more">
<view class="more-history-btn cp flex-row align-c">
<view class="more-history-btn-icon margin-right-xs">
<iconfont name="icon-reset" size="28rpx" color="#999"></iconfont>
</view>
<text>加载中</text>
</view>
</template>
<template v-else>
<view class="more-history-btn cp" @tap="view_more_history"></view>
</template>
</view>
<!-- 热搜列表 -->
<view class="hot-search">
<view class="hot-tabs">
<scroll-view scroll-x :show-scrollbar="false" class="tabs-scroll" style="white-space: nowrap;">
<view class="tabs-scroll-content">
<view v-for="(tab, index) in hot_tabs" :key="index" class="hot-tab-item cp" :class="{ active: hot_current_tab === index }" :data-index="index" @tap="switch_hot_tab">{{ tab }}</view>
</view>
</scroll-view>
</view>
<view class="hot-list flex-col align-c gap-10">
<view v-for="(item, index) in hot_list" :key="index" :class="`cp wh-auto flex-row align-c jc-sb hot-item ${index < 3 ? `hot-item-top` : ''}`" :data-value="item.title" @tap.stop="perform_search">
<view class="flex-row align-c gap-10">
<view class="hot-num flex-row align-c jc-c">
<view :class="index < 3 ? `hexagon-top hexagon-top-${index + 1}` : 'hexagon-no-top'"><span>{{ index + 1 }}</span></view>
</view>
<view class="hot-title">{{ item.title }}</view>
</view>
<view class="hot-hotness">热度 {{ item.hotness }}</view>
</view>
</view>
</view>
</view>
</template>
<script>
import searchComponent from '@/pages/plugins/video/components/search.vue';
const app = getApp();
var system = app.globalData.get_system_info(null, null, true);
//
var bar_height = parseInt(app.globalData.get_system_info('statusBarHeight', 0));
// #ifdef MP-TOUTIAO
bar_height = 0;
// #endif
export default {
components: {
searchComponent
},
data() {
return {
// 5,7,0 10 ,bar_height
// #ifdef MP
top_content_style: 'padding-top:' + (bar_height + 5) + 'px;padding-bottom:10px;',
// #endif
// #ifdef H5 || MP-TOUTIAO
top_content_style: 'padding-top:' + (bar_height + 7) + 'px;padding-bottom:10px;',
// #endif
// #ifdef APP
top_content_style: 'padding-top:' + bar_height + 'px;padding-bottom:10px;',
// #endif
search_query: '',
search_history: [
{ text: '软件升级规则' },
{ text: '进销存管理系统提升效率' },
{ text: '任何人的错都是我的错' },
{ text: '心中无敌,方能无敌于天下' }
],
hot_tabs: ['今日热搜', '点赞热榜', '评论热榜', '分享热榜', '分享热榜', '分享热榜', '分享热榜'],
hot_current_tab: 0,
hot_list: [
{ title: '国家补贴至高补贴20%', hotness: '811.2万' },
{ title: '夏季高质量睡眠秘诀', hotness: '2100' },
{ title: '不要总认为自己比别人聪明', hotness: '311' },
{ title: '今天最好的表现是明天最低的要求', hotness: '311' },
{ title: '今天最好的表现是明天最低的要求', hotness: '311' },
{ title: '今天最好的表现是明天最低的要求', hotness: '311' },
{ title: '今天最好的表现是明天最低的要求', hotness: '311' },
{ title: '今天最好的表现是明天最低的要求', hotness: '311' },
{ title: '今天最好的表现是明天最低的要求', hotness: '311' }
],
is_view_more: false
};
},
created() {
this.init();
},
methods: {
init() {
//
let menu_button_info = 'max-width:100%';
// #ifndef MP-TOUTIAO
// #ifdef MP
//
const is_current_single_page = app.globalData.is_current_single_page();
//
if (is_current_single_page == 0) {
const custom = uni.getMenuButtonBoundingClientRect();
menu_button_info = `max-width:calc(100% - ${custom.width + 10}px);`;
}
// #endif
// #endif
},
//
handle_back() {
uni.navigateBack();
},
handle_search(e) {
this.search_query = e;
app.globalData.url_open(`/pages/plugins/video/search/search?search_query=${this.search_query}`, false);
},
perform_search(e) {
this.search_query = e.currentTarget.dataset.value;
// uni.navigateTo({
// url: `/pages/plugins/video/search/search?search_query=${this.search_query}`
// });
},
delete_history(e) {
const index = e.currentTarget.dataset.index;
this.search_history.splice(index, 1);
},
view_more_history() {
//
this.is_view_more = true;
setTimeout(() => {
this.is_view_more = false;
}, 3000);
},
switch_hot_tab(e) {
this.setData({
hot_current_tab: e.currentTarget.dataset.index,
});
//
}
}
};
</script>
<style>
.search-record-container {
background: #fff;
}
.header-top {
position: sticky;
top: 0;
background: #fff;
z-index: 9;
padding-left: 40rpx;
}
/* #ifdef MP-WEIXIN | APP-PLUS */
.tabs-scroll {
::v-deep ::-webkit-scrollbar
{
width: 0rpx!important;
height: 0rpx!important;
background-color: transparent;
}
}
/* #endif */
/* 推荐视频列表 */
.recommend-videos {
padding: 0 16rpx 20rpx 16rpx;
.video-grid {
column-count: 2;
column-gap: 10px;
}
.video-card {
background-color: #fff;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
border-radius: 4px;
overflow: hidden;
break-inside: avoid;
margin-bottom: 10px;
width: 100%;
}
.video-thumbnail {
width: 100%;
object-fit: contain;
}
.video-info {
padding: 20rpx;
padding-top: 10rpx;
gap: 20rpx;
}
.video-title {
font-weight: 500;
font-size: 28rpx;
color: #333333;
line-height: 40rpx;
}
.video-date,
.video-likes {
font-weight: 400;
font-size: 24rpx;
color: #999999;
line-height: 34rpx;
}
}
.search-history {
padding: 20rpx 40rpx 24rpx 40rpx;
gap: 40rpx;
border-bottom: 2rpx solid #EDEDED;
.search-history-title {
font-weight: 500;
font-size: 28rpx;
color: #666666;
line-height: 40rpx;
gap: 20rpx;
}
.more-history-btn {
font-weight: 400;
font-size: 28rpx;
color: #999999;
line-height: 40rpx;
margin-top: 40rpx;
}
.more-history-btn-icon {
animation: rotate 1s linear infinite;
}
}
/* 旋转动画 */
@keyframes rotate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
/* 热门搜索 */
.hot-search {
padding: 40rpx;
}
.hot-tabs {
display: flex;
margin-bottom: 20rpx;
.tabs-scroll-content {
display: flex;
align-items: center;
gap: 40rpx;
}
}
.hot-tab-item {
flex: 1;
position: relative;
text-align: center;
font-size: 28rpx;
color: #666;
padding: 10rpx 0;
}
.hot-tab-item::after {
content: '';
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 0;
height: 4px;
background-color: #333;
transition: width 0.6s ease;
}
.hot-tab-item.active::after {
width: 100%;
}
.hot-tab-item.active {
color: #333;
}
.hot-item {
height: 72rpx;
padding-left: 20rpx;
box-sizing: border-box;
background: linear-gradient( 90deg, #F4F4F4 0%, #FFFFFF 100%);
border-radius: 8px;
}
.hot-hotness {
font-weight: 400;
font-size: 24rpx;
color: #999999;
line-height: 34rpx;
}
.hot-item-top {
background: linear-gradient( 90deg, #FFF5E9 0%, #FFFFFF 100%);
border-radius: 8px;
}
.hot-num {
width: 40rpx;
height: 40rpx;
font-weight: 500;
font-size: 28rpx;
color: #999999;
line-height: 40rpx;
}
/* 修改六边形样式 */
.hexagon-top {
position: relative;
width: 40rpx;
height: 20rpx !important;
border-radius: 2rpx;
}
.hexagon-top::before,
.hexagon-top::after {
content: "";
position: absolute;
left: 0;
width: 0;
height: 0;
border-left: 20rpx solid transparent;
border-right: 20rpx solid transparent;
}
.hexagon-top::before {
bottom: 100%;
border-bottom: 10rpx solid #E93633;
}
.hexagon-top::after {
top: 100%;
border-top: 10rpx solid #E93633;
}
.hexagon-top span {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: white;
font-weight: 500;
font-size: 20rpx;
line-height: 28rpx;
}
.hexagon-top-1 {
background: #E93633;
}
.hexagon-top-2 {
background: #F5C242;
}
.hexagon-top-2::before {
border-bottom: 10rpx solid #F5C242;
}
.hexagon-top-2::after {
border-top: 10rpx solid #F5C242;
}
.hexagon-top-3 {
background: #F19F58;
}
.hexagon-top-3::before {
border-bottom: 10rpx solid #F19F58;
}
.hexagon-top-3::after {
border-top: 10rpx solid #F19F58;
}
</style>

View File

@ -1,6 +1,6 @@
<template>
<view class="wh-auto ht-auto pr video-container">
<scroll-view scroll-y :show-scrollbar="false" class="ht" @scrolltolower="on_scroll_lower_event" @scrolltoupper="on_scroll_upper_event" lower-threshold="60" scroll-with-animation="true">
<scroll-view scroll-y :show-scrollbar="false" class="ht" @scrolltolower="on_scroll_lower_event" @scrolltoupper="on_scroll_upper_event" lower-threshold="60" scroll-with-animation="true">
<view class="wh-auto ht-auto pr">
<!-- 搜索框 -->
<view class="header-top">
@ -8,12 +8,13 @@
<search-component :propsSearchQuery="search_query" @search="handle_search" />
</view>
<!-- 导航栏 -->
<view class="nav-tabs">
<scroll-view scroll-x :show-scrollbar="false" class="tabs-scroll" style="white-space: nowrap;">
<view class="tabs-scroll-content">
<view v-for="(tab, index) in tabs" :key="index" class="tab-item" :class="{ active: currentTab === index }" :data-index="index" @click="switch_tab">{{ tab }}</view>
</view>
</scroll-view>
<view class="nav-tabs flex-row align-s jc-sb gap-10">
<view class="tabs-scroll-content">
<view v-for="(tab, index) in tabs" :key="index" class="tab-item" :class="{ active: currentTab === index }" :data-index="index" @click="switch_tab">{{ tab }}</view>
</view>
<view class="nav-tabs-filter" @click="toggleFilterPopup">
<iconfont name="icon-filter" size="32rpx"></iconfont>
</view>
</view>
</view>
<!-- 推荐视频卡片区域 -->
@ -36,11 +37,55 @@
</view>
</view>
</scroll-view>
<!-- 选项卡更多弹窗 -->
<componentPopup :propShow="filterPopupStatus" propPosition="top" :propMask="true" @onclose="closeFilterPopup">
<view :class="'padding-bottom-lg ' + (['toutiao', 'app', 'h5'].includes(platform) ? 'padding-top-lg' : 'padding-top')" :style="{ 'padding-top': popup_top }">
<view class="divider-b">
<view class="nav-list-more">
<view class="flex-row flex-wrap align-c">
<!-- 排序依据 -->
<view class="filter-group">
<view class="filter-title">排序依据</view>
<view class="filter-options">
<view v-for="(option, index) in sort_options" :key="index" class="filter-option" @click="selectSortOption(option)">{{ option }}</view>
</view>
</view>
<!-- 发布时间 -->
<view class="filter-group">
<view class="filter-title">发布时间</view>
<view class="filter-options">
<view v-for="(option, index) in publish_time_options" :key="index" class="filter-option" @click="selectPublishTimeOption(option)">{{ option }}</view>
</view>
</view>
<!-- 视频时长 -->
<view class="filter-group">
<view class="filter-title">视频时长</view>
<view class="filter-options">
<view v-for="(option, index) in video_duration_options" :key="index" class="filter-option" @click="selectVideoDurationOption(option)">{{ option }}</view>
</view>
</view>
<!-- 搜索范围 -->
<view class="filter-group">
<view class="filter-title">搜索范围</view>
<view class="filter-options">
<view v-for="(option, index) in search_range_options" :key="index" class="filter-option" @click="selectSearchRangeOption(option)">{{ option }}</view>
</view>
</view>
</view>
</view>
</view>
<view class="tc padding-top-lg flex-row jc-c align-c" @tap="closeFilterPopup">
<text class="padding-right-sm">{{ $t('nav-more.nav-more.h9g4b1') }}</text>
<iconfont name="icon-arrow-top" color="#ccc" propContainerDisplay="flex"></iconfont>
</view>
</view>
</componentPopup>
</view>
</template>
<script>
import SearchComponent from '@/pages/plugins/video/components/search.vue';
import searchComponent from '@/pages/plugins/video/components/search.vue';
import componentPopup from '@/components/popup/popup';
const app = getApp();
//
var bar_height = parseInt(app.globalData.get_system_info('statusBarHeight', 0));
@ -49,7 +94,8 @@ bar_height = 0;
// #endif
export default {
components: {
SearchComponent
searchComponent,
componentPopup
},
data() {
return {
@ -96,9 +142,24 @@ export default {
detailId: '4'
},
],
isLoadingMore: false
isLoadingMore: false,
params: null,
filterPopupStatus: false,
popup_top: '0rpx',
platform: app.globalData.application_client_type(),
sort_options: ['综合排序', '最新发布', '最多点赞'],
publish_time_options: ['不限', '一天内', '一周内', '半年内'],
video_duration_options: ['不限', '1分钟以下', '1-5分钟', '5分钟以上'],
search_range_options: ['不限', '最近看过', '还未看过']
};
},
onLoad(params) {
//
this.setData({
search_query: params.search_query || '',
params: app.globalData.launch_params_handle(params),
});
},
created() {
this.init();
},
@ -117,6 +178,21 @@ export default {
}
// #endif
// #endif
setTimeout(() => {
const query = uni.createSelectorQuery().in(this);
//
query
.select('.header-top')
.boundingClientRect((res) => {
if ((res || null) != null) {
// data
this.setData({
popup_top: res.height * 2 + 'rpx',
});
}
})
.exec(); //
}, 500);
},
handle_search(e) {
this.search_query = e;
@ -166,6 +242,32 @@ export default {
recommend_videos: data
});
}, 200);
},
toggleFilterPopup() {
this.filterPopupStatus = !this.filterPopupStatus;
},
closeFilterPopup() {
this.filterPopupStatus = false;
},
selectSortOption(option) {
//
console.log('Selected sort option:', option);
this.closeFilterPopup();
},
selectPublishTimeOption(option) {
//
console.log('Selected publish time option:', option);
this.closeFilterPopup();
},
selectVideoDurationOption(option) {
//
console.log('Selected video duration option:', option);
this.closeFilterPopup();
},
selectSearchRangeOption(option) {
//
console.log('Selected search range option:', option);
this.closeFilterPopup();
}
}
};
@ -183,15 +285,23 @@ export default {
position: relative;
width: 100%;
padding: 0 16rpx 20rpx 16rpx;
box-sizing: border-box;
.tabs-scroll-content {
display: flex;
align-items: center;
overflow: hidden;
overflow-x: auto;
gap: 48rpx;
}
.nav-tabs-filter {
padding-top: 8rpx;
box-sizing: border-box;
}
.tab-item {
position: relative;
white-space: nowrap;
padding-bottom: 8rpx;
box-sizing: border-box;
font-weight: 500;
font-size: 28rpx;
color: #666666;
@ -223,6 +333,15 @@ export default {
}
}
@media (max-width: 500px) {
.nav-tabs {
align-items: center;
.nav-tabs-filter {
padding-top: 0;
}
}
}
/* #ifdef MP-WEIXIN | APP-PLUS */
.tabs-scroll {
::v-deep ::-webkit-scrollbar
@ -277,4 +396,53 @@ export default {
line-height: 34rpx;
}
}
/* 筛选条件弹窗样式 */
.filter-group {
margin-bottom: 40rpx;
}
.filter-title {
font-weight: 400;
font-size: 24rpx;
color: #666666;
line-height: 34rpx;
margin-bottom: 24rpx;
}
.filter-options {
display: flex;
flex-wrap: wrap;
gap: 20rpx;
}
.filter-option {
font-weight: 400;
font-size: 24rpx;
color: #666666;
line-height: 34rpx;
padding: 10rpx 32rpx;
background-color: #e8e8e8;
border-radius: 4rpx;
cursor: pointer;
transition: background-color 0.3s ease;
}
.filter-option:hover {
background-color: #e0e0e0;
}
.filter-option.active {
color: #333;
}
.nav-list-more {
padding: 20rpx 40rpx;
}
::v-deep .popup {
.popup-mask {
z-index: 8 !important;
}
.popup-content {
z-index: 8 !important;
}
}
</style>