2025-08-14 18:58:14 +08:00

1104 lines
24 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<uni-nav-bar left-icon="left"
@clickLeft="goBack" title="肝胆视频" fixed color="#8B2316" height="140rpx" :border="false" backgroundColor="#eeeeee"></uni-nav-bar>
<view class="video-page">
<!-- Header -->
<!-- Fixed Banner Swiper -->
<view class="banner-container">
<view class="swipemask">
<view class="banner-subtitle">111111111</view>
<view class="dotbox">
<view class="circle" :class="{active:currentBannerIndex==index} "v-for="(banner, index) in bannerList"
:key="banner.id"></view>
</view>
</view>
<swiper
class="banner-swiper"
:indicator-dots="false"
:autoplay="true"
:interval="5000"
:duration="300"
indicator-color="rgba(255,255,255,0.4)"
indicator-active-color="#fff"
circular
@change="onSwiperChange"
>
<swiper-item
v-for="(banner, index) in bannerList"
:key="banner.id"
@click="playBannerVideo(banner)"
>
<view class="banner-item">
<image
class="banner-image"
:src="banner.thumbnail || '/static/big_background_my.png'"
mode="aspectFill"
></image>
<view class="banner-content">
<view class="doctor-avatar" v-if="banner.doctorAvatar">
<image :src="banner.doctorAvatar" mode="aspectFill"></image>
</view>
<view class="banner-info">
<view class="banner-title">{{banner.title}}</view>
<view class="banner-subtitle">{{banner.subtitle || '专业医学视频教育平台'}}</view>
</view>
</view>
</view>
</swiper-item>
</swiper>
</view>
<!-- Fixed Filter Tabs -->
<view class="filter-tabs-container">
<view class="filter-tabs">
<view
class="tab-item"
@click="showAllVideoPopup=!showAllVideoPopup"
>
<up-image :src="allImg" width="30rpx" height="30rpx" ></up-image>
<text class="tab-text">全部视频</text>
<up-image :src="selectImg" width="30rpx" height="30rpx" ></up-image>
</view>
<view class="right">
<view
class="tab-item"
>
<text class="tab-text">最新</text>
<view class="newbox">
<up-image :src="upImg" width="20rpx" height="26rpx" ></up-image>
</view>
</view>
<view
class="tab-item"
@click="showFilterPopup"
>
<text class="tab-text">筛选</text>
<view class="filterbox">
<up-image :src="isFilterActive ? filterOn : filter" width="30rpx" height="30rpx" ></up-image>
</view>
</view>
</view>
</view>
</view>
<!-- Main Content -->
<scroll-view
class="scroll-view"
scroll-y="true"
refresher-enabled="true"
:refresher-triggered="refreshing"
@refresherrefresh="onRefresh"
@scrolltolower="onLoadMore"
lower-threshold="100"
>
<!-- Video List -->
<view class="video-list">
<view
class="video-item"
v-for="(video, index) in videoList"
:key="video.id"
@click="playVideo(video)"
>
<view class="video-thumbnail">
<image :src="video.thumbnail" mode="aspectFill"></image>
</view>
<view class="video-info">
<view class="video-title">{{video.title}}</view>
<view class="video-meta">
<text class="author">{{video.author}}</text>
<view class="stats">
<uni-icons type="eye" size="14" color="#999"></uni-icons>
<text class="view-count">{{video.viewCount}}</text>
</view>
</view>
</view>
</view>
</view>
<!-- Loading More -->
<uni-load-more
v-if="videoList.length > 0"
:status="loadMoreStatus"
:content-text="{
contentdown: '上拉加载更多',
contentrefresh: '正在加载...',
contentnomore: '没有更多数据了'
}"
></uni-load-more>
<!-- Empty State -->
<view class="empty-state" v-if="videoList.length === 0 && !loading">
<image src="/static/empty-video.png" mode="aspectFit"></image>
<text>暂无视频内容</text>
</view>
</scroll-view>
<view class="btnbox">
<up-image :src="videoImg" width="44rpx" height="44rpx" ></up-image>
患教视频
</view>
<!-- 筛选弹窗 -->
<view class="filter-popup" v-if="showFilter" @click="hideFilterPopup">
<view class="filter-content" @click.stop>
<!-- 筛选标签网格 -->
<view class="filter-tags">
<view
class="tag-item"
v-for="(tag, index) in filterTags"
:key="index"
:class="{ active: tag.selected }"
@click="toggleTag(index)"
>
{{ tag.name }}
</view>
</view>
<!-- 底部按钮 -->
<view class="filter-buttons">
<view class="btn-reset" @click="resetFilter">重置</view>
<view class="btn-confirm" @click="confirmFilter">确定</view>
</view>
</view>
</view>
<!-- 全部视频弹窗 -->
<view class="all-video-popup" v-if="showAllVideoPopup" @click="closeAllVideoPopup">
<view class="popup-content" @click.stop>
<view class="popup-body">
<view class="category-sidebar">
<view
class="category-item"
:class="{ active: selectedCategory === category.value }"
v-for="category in categoryList"
:key="category.value"
@click="selectCategory(category.value)"
>
{{ category.label }}
</view>
</view>
<view class="content-area">
<view class="content-list">
<view
class="content-item"
v-for="item in filteredContent"
:key="item.id"
@click="selectContent(item)"
>
{{ item.title }}
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script setup>
import { ref, onMounted, computed } from 'vue';
import { onShow } from "@dcloudio/uni-app";
import api from '@/api/api.js';
import allImg from "@/static/video_all.png"
import allOnImg from "@/static/video_select.png"
import selectImg from "@/static/all_video.png"
import selectOnImg from "@/static/select_video.png"
import filter from "@/static/cb_screen_no.png"
import filterOn from "@/static/cb_screen_yes.png"
import upImg from "@/static/cb_up.png"
import downImg from "@/static/cb_up.png"
import videoImg from "@/static/patient_video.png"
// 响应式数据
const videoList = ref([]);
const bannerVideo = ref(null);
const activeTab = ref(1); // 默认选中"最新"
const loading = ref(false);
const refreshing = ref(false);
const loadMoreStatus = ref('more'); // more, loading, noMore
const currentPage = ref(1);
const pageSize = ref(10);
const hasMoreData = ref(true);
// Banner相关数据
const bannerList = ref([]);
const currentBannerIndex = ref(0);
const isFilterActive=ref(false)
const showFilter = ref(false);
// 筛选弹窗相关数据
const filterTags = ref([
{ name: '指南解读', selected: false },
{ name: '病例分析', selected: false },
{ name: '学术讲座', selected: false },
{ name: '手术视频', selected: false },
{ name: '研究进展', selected: false },
{ name: '肝病治疗', selected: false },
{ name: '肝癌诊断', selected: false },
{ name: '肝移植', selected: false },
{ name: '微创手术', selected: false },
{ name: '免疫治疗', selected: false },
{ name: '靶向治疗', selected: false },
{ name: '化疗方案', selected: false }
]);
// 全部视频弹窗相关数据
const showAllVideoPopup = ref(false);
const selectedCategory = ref('all');
const categoryList = ref([
{ value: 'all', label: '全部' },
{ value: 'guide', label: '指南解读' },
{ value: 'case', label: '病例分析' },
{ value: 'lecture', label: '学术讲座' },
{ value: 'surgery', label: '手术视频' },
{ value: 'research', label: '研究进展' }
]);
// 分类内容数据
const contentByCategory = ref({
all: [
{ id: 1, title: '《2025年版慢加急性肝衰竭指南》解读' },
{ id: 2, title: '自身免疫性肝病专栏|免疫治疗的双刃剑' },
{ id: 3, title: '徐医感染:硬化出血发热路,关关难过关关过' },
{ id: 4, title: '徐医感染:一场呼吸的迷局' },
{ id: 5, title: '南京市第二医院疑难肝病病理读片会' }
],
guide: [
{ id: 6, title: '《2025年版慢加急性肝衰竭指南》解读' },
{ id: 7, title: '《原发性肝癌诊疗指南》更新要点' },
{ id: 8, title: '《慢性乙型肝炎防治指南》解读' }
],
case: [
{ id: 9, title: '自身免疫性肝病专栏|免疫治疗的双刃剑' },
{ id: 10, title: '徐医感染:硬化出血发热路,关关难过关关过' },
{ id: 11, title: '徐医感染:一场呼吸的迷局' }
],
lecture: [
{ id: 12, title: '南京市第二医院疑难肝病病理读片会' },
{ id: 13, title: '肝胆胰外科手术技巧分享' },
{ id: 14, title: '肝移植围手术期管理' }
],
surgery: [
{ id: 15, title: '腹腔镜肝切除术操作要点' },
{ id: 16, title: '机器人辅助肝切除术' },
{ id: 17, title: '肝移植手术技术进展' }
],
research: [
{ id: 18, title: '肝癌免疫治疗最新研究进展' },
{ id: 19, title: '肝纤维化分子机制研究' },
{ id: 20, title: '肝细胞再生与修复研究' }
]
});
// 页面加载
onMounted(() => {
});
onShow(() => {
// 使用模拟数据初始化列表
currentPage.value = 1;
hasMoreData.value = true;
loadMockVideoData(true);
// 初始化banner数据
bannerList.value = getMockBannerData();
});
// 加载视频数据
const loadVideoData = async (isRefresh = false) => {
if (loading.value && !isRefresh) return;
loading.value = true;
try {
// 调用真实API
const response = await api.getVideoList({
page: currentPage.value,
pageSize: pageSize.value,
category: activeTab.value // 根据选中的标签获取不同类别的视频
});
if (response.data.code === 200) {
const { list, hasMore } = response.data.data;
if (isRefresh) {
videoList.value = list;
currentPage.value = 1;
} else {
videoList.value = [...videoList.value, ...list];
}
// 设置banner视频第一个视频
if (isRefresh || currentPage.value === 1) {
bannerVideo.value = list[0];
}
hasMoreData.value = hasMore;
loadMoreStatus.value = hasMoreData.value ? 'more' : 'noMore';
} else {
throw new Error(response.data.message || '获取数据失败');
}
} catch (error) {
console.error('加载视频失败:', error);
// 如果API失败使用模拟数据作为备用方案
const mockData = await getMockVideoData(currentPage.value, pageSize.value);
if (isRefresh) {
videoList.value = mockData.list;
currentPage.value = 1;
} else {
videoList.value = [...videoList.value, ...mockData.list];
}
// 设置banner视频第一个视频
if (isRefresh || currentPage.value === 1) {
bannerVideo.value = mockData.list[0];
}
hasMoreData.value = mockData.hasMore;
loadMoreStatus.value = hasMoreData.value ? 'more' : 'noMore';
uni.showToast({
title: '网络连接异常,显示离线数据',
icon: 'none'
});
} finally {
loading.value = false;
refreshing.value = false;
}
};
// 使用模拟数据加载视频列表
const loadMockVideoData = async (isRefresh = false) => {
if (loading.value && !isRefresh) return;
loading.value = true;
try {
const mockData = await getMockVideoData(currentPage.value, pageSize.value);
if (isRefresh) {
videoList.value = mockData.list;
currentPage.value = 1;
} else {
videoList.value = [...videoList.value, ...mockData.list];
}
hasMoreData.value = mockData.hasMore;
loadMoreStatus.value = hasMoreData.value ? 'more' : 'noMore';
} finally {
loading.value = false;
refreshing.value = false;
}
};
// 下拉刷新
const onRefresh = () => {
refreshing.value = true;
currentPage.value = 1;
hasMoreData.value = true;
loadMockVideoData(true);
};
// 上拉加载更多
const onLoadMore = () => {
if (!hasMoreData.value || loading.value) return;
loadMoreStatus.value = 'loading';
currentPage.value++;
loadMockVideoData();
};
// 切换标签
const switchTab = (tabIndex) => {
activeTab.value = tabIndex;
// 可以根据标签加载不同的数据
currentPage.value = 1;
hasMoreData.value = true;
loadMockVideoData(true);
};
// 播放视频
const playVideo = (video) => {
uni.navigateTo({
url: `/pages/videoDetail/videoDetail?id=${video.id}`
});
};
// 搜索
const goSearch = () => {
uni.navigateTo({
url: '/pages_app/search/search'
});
};
// Banner相关方法
const getMockBannerData = () => {
return [
{
id: 'banner_1',
title: '《2025年版慢加急性肝衰竭指南》解读',
subtitle: '专业医学视频教育平台',
thumbnail: '/static/big_background_my.png',
doctorAvatar: '/static/doctor-avatar-1.png'
},
{
id: 'banner_2',
title: '自身免疫性肝病专栏|免疫治疗的双刃剑',
subtitle: '专业医学视频教育平台',
thumbnail: '/static/big_background_my.png',
doctorAvatar: '/static/doctor-avatar-2.png'
},
{
id: 'banner_3',
title: '徐医感染:硬化出血发热路,关关难过关关过',
subtitle: '专业医学视频教育平台',
thumbnail: '/static/big_background_my.png',
doctorAvatar: '/static/doctor-avatar-3.png'
}
];
};
const onSwiperChange = (e) => {
currentBannerIndex.value = e.detail.current;
};
const playBannerVideo = (banner) => {
uni.navigateTo({
url: `/pages/videoDetail/videoDetail?id=${banner.id}`
});
};
// 全部视频弹窗相关方法
const openAllVideoPopup = () => {
showAllVideoPopup.value = true;
};
const closeAllVideoPopup = () => {
showAllVideoPopup.value = false;
};
const selectCategory = (categoryValue) => {
selectedCategory.value = categoryValue;
};
const selectContent = (content) => {
// 这里可以根据选中的内容进行相应的操作
console.log('选中内容:', content);
closeAllVideoPopup();
// 可以跳转到对应的视频页面或执行其他操作
};
// 计算属性:根据选中的分类过滤内容
const filteredContent = computed(() => {
return contentByCategory.value[selectedCategory.value] || [];
});
// 筛选弹窗相关方法
const showFilterPopup = () => {
showFilter.value = true;
};
const hideFilterPopup = () => {
showFilter.value = false;
};
const toggleTag = (index) => {
filterTags.value[index].selected = !filterTags.value[index].selected;
isFilterActive.value = filterTags.value.some(tag => tag.selected);
};
const resetFilter = () => {
filterTags.value.forEach(tag => tag.selected = false);
isFilterActive.value = false;
};
const confirmFilter = () => {
const selectedTags = filterTags.value.filter(tag => tag.selected);
console.log('选中的筛选标签:', selectedTags);
hideFilterPopup();
// 这里可以根据选中的标签进行数据筛选
};
// 模拟数据 - 实际开发时替换为真实API
const getMockVideoData = (page, size) => {
return new Promise((resolve) => {
setTimeout(() => {
const mockList = [];
const startIndex = (page - 1) * size;
for (let i = 0; i < size; i++) {
const index = startIndex + i;
mockList.push({
id: `video_${index}`,
title: index === 0 ? '《2025年版慢加急性肝衰竭指南》解读' :
index % 4 === 1 ? '自身免疫性肝病专栏免疫治疗的双刃剑——1例自…' :
index % 4 === 2 ? '徐医感染:硬化出血发热路,关关难过关关过' :
index % 4 === 3 ? '徐医感染:一场呼吸的迷局' :
'南京市第二医院疑难肝病病理读片会暨疑难肝病MDT',
thumbnail: '/static/video-thumb-' + (index % 4 + 1) + '.png',
author: index % 3 === 0 ? '首都医…' :
index % 3 === 1 ? '徐州医…' : '南京市…',
viewCount: Math.floor(Math.random() * 2000) + 100,
duration: '15:30'
});
}
resolve({
list: mockList,
hasMore: page <2 // 模拟5页数据
});
}, 1000);
});
};
// 返回
const goBack = () => {
uni.navigateBack({
fail() {
uni.redirectTo({
url: '/pages/index/index'
});
}
});
}
</script>
<style scoped lang="scss">
$primary-color: #ff6b6b;
$theme-color: #8B2316;
$white: #fff;
$gray-bg: #f5f5f5;
$gray-light: #eee;
$gray-medium: #999;
$gray-dark: #666;
$text-color: #333;
// 尺寸变量
$border-radius: 8px;
$border-radius-small: 6px;
$padding: 15px;
$padding-small: 10px;
.video-page {
background-color: #f5f5f5;
height: 100vh;
display: flex;
overflow: hidden;
flex-direction: column;
.btnbox{
width:100%;
position: fixed;
bottom:0;
height: 100rpx;
background-color: #00cbc0;
display: flex;
justify-content: center;
align-items: center;
color:#fff;
font-size: 30rpx;
}
}
/* Header Styles */
.header {
background-color: #fff;
height: 88rpx;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 30rpx;
box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.1);
position: relative;
z-index: 100;
}
.header-left, .header-right {
display: flex;
align-items: center;
}
.header-title {
font-size: 36rpx;
font-weight: 600;
color: #8B4513;
}
/* Scroll View */
.scroll-view {
position: fixed;
bottom:0rpx;
height: calc(100vh - 618rpx); /* 固定高度减去固定的banner和Filter Tabs空间 */
background-color: #f5f5f5;
margin-bottom: 200rpx;
top: 574rpx; /* 为固定的banner和Filter Tabs留出空间 */
}
/* Banner Styles */
.banner-section {
position: relative;
height: 400rpx;
margin-bottom: 20rpx;
}
.banner-image {
width: 100%;
height: 100%;
}
.banner-overlay {
position: absolute;
bottom: 0;
left: 0;
right: 0;
background: linear-gradient(transparent, rgba(0,0,0,0.7));
padding: 60rpx 30rpx 30rpx;
}
.banner-title {
color: #fff;
font-size: 32rpx;
font-weight: 600;
line-height: 1.4;
}
/* Filter Tabs */
.filter-tabs {
background-color: #fff;
display: flex;
justify-content: space-between;
padding: 30rpx 30rpx;
}
.tab-item {
display: flex;
align-items: center;
margin-right: 60rpx;
padding: 10rpx 0;
}
.tab-item:last-child{
margin-right: 0;
}
.right{
display: flex;
}
.tab-item.active .tab-text {
color: #E74C3C;
font-weight: 600;
}
.tab-text {
margin: 0 8rpx;
font-size: 28rpx;
color: #666;
}
.tab-item:first-child .tab-text{
max-width:600rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* Fixed Banner Container */
.banner-container {
position: fixed;
top: 140rpx; /* uni-nav-bar height */
left: 0;
right: 0;
z-index: 50;
background-color: #fff;
.swipemask{
width:100%;
z-index:3;
box-sizing:border-box;
position: absolute;
bottom:0;
padding:0 20rpx;
height: 80rpx;
display: flex;
align-items: center;
justify-content: space-between;
background-color: rgba(0,0,0,0.7);
.dotbox{
display:flex;
align-items: center;
.circle{
margin:0 4rpx;
width:16rpx;
height:16rpx;
background-color: #eee;
border-radius: 50%;
}
.circle.active{
background-color: #8B2316;
}
}
}
}
/* Fixed Filter Tabs Container */
.filter-tabs-container {
position: fixed;
top: 540rpx; /* banner-container top + banner height */
left: 0;
right: 0;
z-index: 40;
background-color: #fff;
border-bottom: 1rpx solid #f0f0f0;
}
.banner-swiper {
height: 400rpx;
}
.banner-item {
position: relative;
width: 100%;
height: 400rpx;
}
.banner-image {
width: 100%;
height: 100%;
}
.banner-content {
position: absolute;
bottom: 0;
left: 0;
right: 0;
padding: 40rpx 30rpx;
background: linear-gradient(transparent, rgba(0,0,0,0.7));
display: flex;
align-items: flex-end;
}
.doctor-avatar {
width: 80rpx;
height: 80rpx;
border-radius: 50%;
margin-right: 20rpx;
overflow: hidden;
}
.doctor-avatar image {
width: 100%;
height: 100%;
}
.banner-info {
flex: 1;
}
.banner-title {
font-size: 32rpx;
font-weight: 600;
color: #fff;
margin-bottom: 8rpx;
line-height: 1.3;
}
.banner-subtitle {
font-size: 24rpx;
color: rgba(255,255,255,0.8);
}
/* Video List */
.video-list {
padding: 0 20rpx;
margin-top: 100rpx; /* 为固定的Filter Tabs留出空间 */
display: flex;
flex-wrap: wrap;
gap: 16rpx; /* 卡片间距 */
}
.video-item {
background-color: #fff;
border-radius: 16rpx;
margin-bottom: 0;
overflow: hidden;
box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.1);
width: calc(50% - 8rpx); /* 两列布局减半gap */
min-width: 300rpx; /* 确保最小宽度 */
flex-shrink: 0; /* 防止收缩 */
}
.video-thumbnail {
position: relative;
height: 200rpx;
}
.video-thumbnail image {
width: 100%;
height: 100%;
}
.play-icon {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: rgba(0,0,0,0.6);
border-radius: 50%;
width: 60rpx;
height: 60rpx;
display: flex;
align-items: center;
justify-content: center;
}
.video-info {
padding: 24rpx;
}
.video-title {
font-size: 28rpx;
font-weight: 600;
color: #333;
line-height: 1.4;
margin-bottom: 16rpx;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
line-clamp: 2;
overflow: hidden;
}
.video-meta {
display: flex;
justify-content: space-between;
align-items: center;
}
.author {
font-size: 24rpx;
color: #999;
}
.stats {
display: flex;
align-items: center;
}
.view-count {
font-size: 24rpx;
color: #999;
margin-left: 8rpx;
}
/* Empty State */
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 100rpx 0;
}
.empty-state image {
width: 200rpx;
height: 200rpx;
margin-bottom: 30rpx;
opacity: 0.5;
}
.empty-state text {
color: #999;
font-size: 28rpx;
}
.newbox{
margin-top: -12rpx;
}
/* 全部视频弹窗样式 */
.all-video-popup {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 1000;
display: flex;
}
.popup-content {
width: 100%;
margin-top: 650rpx;
height: 80vh;
background-color: #fff;
overflow: scroll;
}
.popup-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 30rpx;
border-bottom: 1rpx solid #f0f0f0;
background-color: #f8f8f8;
}
.header-title {
font-size: 32rpx;
font-weight: 600;
color: #333;
}
.header-right {
padding: 10rpx;
cursor: pointer;
}
.popup-body {
display: flex;
height: 600rpx;
}
.category-sidebar {
width: 200rpx;
background-color: #f8f8f8;
border-right: 1rpx solid #f0f0f0;
overflow-y: auto;
}
.category-item {
padding: 30rpx 20rpx;
font-size: 28rpx;
color: #666;
border-bottom: 1rpx solid #f0f0f0;
cursor: pointer;
transition: all 0.3s ease;
}
.category-item:hover {
background-color: #e8f4fd;
}
.category-item.active {
background-color: #fff;
color: #8B2316;
}
.content-area {
flex: 1;
padding: 20rpx;
overflow-y: auto;
}
.content-list {
display: flex;
flex-direction: column;
gap: 20rpx;
}
.content-item {
padding: 20rpx;
background-color: #f8f8f8;
border-radius: 10rpx;
font-size: 26rpx;
color: #333;
cursor: pointer;
transition: all 0.3s ease;
border: 2rpx solid transparent;
}
.content-item:hover {
background-color: #e8f4fd;
border-color: #4A90E2;
}
.content-item:active {
transform: scale(0.98);
}
// 筛选弹窗样式
.filter-popup {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
// background-color: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
z-index: 9999;
.filter-content {
margin-top:329rpx;
background-color: $white;
// border-radius: 20rpx 20rpx 0 0;
padding: 20rpx 30rpx 60rpx;
width: 100%;
max-height: 80vh;
.filter-tags {
display: flex;
flex-wrap: wrap;
gap: 20rpx;
margin-bottom: 60rpx;
max-height: 65vh;
overflow-y: auto;
.tag-item {
background-color: #f8f8f8;
color: $gray-dark;
padding: 8rpx 24rpx;
border-radius: 30rpx;
font-size: 26rpx;
border: 2rpx solid #efefef;
transition: all 0.3s ease;
&.active {
background-color: #fff;
color: $theme-color;
border-color: $theme-color;
}
}
}
.filter-buttons {
display: flex;
gap: 20rpx;
position: fixed;
bottom: 30rpx;
left: 30rpx;
right: 30rpx;
.btn-reset,
.btn-confirm {
flex: 1;
height: 70rpx;
border-radius: 14rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 32rpx;
font-weight: 500;
}
.btn-reset {
background-color: $white;
color: $theme-color;
border: 2rpx solid $theme-color;
}
.btn-confirm {
border: 2rpx solid $theme-color;
background-color: $theme-color;
color: $white;
}
}
}
}
</style>