uniapp-app/pages/meeting/meeting.vue
2025-09-05 17:38:14 +08:00

1257 lines
31 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 title="肝胆会议" fixed color="#8B2316" height="140rpx" :border="false" backgroundColor="#eeeeee"></uni-nav-bar>
<view class="page">
<!-- 筛选标签栏 -->
<view class="filter-bar">
<view class="filter-item active" @click="showTimePopup">
<text>会议时间</text>
<up-image :src="select" width="26rpx" height="26rpx" ></up-image>
</view>
<view class="filter-divider"></view>
<view class="filter-item" @click="showLocationPopup">
<text>会议地点</text>
<up-image :src="select" width="26rpx" height="26rpx" ></up-image>
</view>
<view class="filter-divider"></view>
<view class="filter-item">
<text>会议回放</text>
</view>
</view>
<!-- 可滚动内容区域 -->
<scroll-view
ref="scrollView"
class="scroll-content"
scroll-y="true"
refresher-enabled="true"
:refresher-triggered="isRefreshing"
:refresher-threshold="100"
@refresherrefresh="onRefresh"
@scrolltolower="onLoadMore"
:lower-threshold="100"
:scroll-top="scrollTop"
:enable-back-to-top="true"
>
<!-- 时间标题 -->
<view class="time-header">2025年08月</view>
<!-- 会议列表 -->
<view class="meeting-list">
<view class="meeting-item" v-for="(item, index) in meetingList" :key="index">
<!-- 左侧日期标识 -->
<view class="date-tag" :style="{backgroundColor: item.tagColor}">
<text class="date-text">{{ item.date }}</text>
</view>
<!-- 会议内容 -->
<view class="meeting-content">
<view class="meeting-title">{{ item.title }}</view>
<view class="meeting-poster" @click="playVideo(item)">
<image :src="getImageUrl(item.poster)" class="poster-image" mode="aspectFill"></image>
<view class="play-btn" v-if="item.status !== 3">
<up-image :src="playImg" width="108rpx" height="108rpx" ></up-image>
</view>
<view class="status-tag" :class="getStatusClass(item.status)">
{{ getStatusText(item.status) }}
</view>
</view>
<view class="meeting-info">
<view class="info-item">
<view class="timebox">
<up-image :src="timeImg" width="24rpx" height="24rpx" ></up-image>
</view>
<text class="info-text">{{ item.time }}</text>
</view>
<view class="info-item">
<uni-icons type="location" size="14" color="#999"></uni-icons>
<text class="info-text">{{ item.location }}</text>
</view>
</view>
</view>
</view>
</view>
<!-- 加载更多提示 -->
<view class="load-more" v-if="showLoadMore">
<view class="load-more-content" v-if="isLoadingMore">
<uni-icons type="spinner-cycle" size="20" color="#999"></uni-icons>
<text class="load-more-text">加载中...</text>
</view>
<view class="load-more-content" v-else-if="hasMoreData">
<text class="load-more-text">上拉加载更多</text>
</view>
<view class="load-more-content" v-else>
<text class="load-more-text">没有更多数据了</text>
</view>
</view>
</scroll-view>
<!-- 时间选择弹窗 -->
<view class="time-popup" v-if="isTimePopupShow" @click="hideTimePopup">
<view class="popup-mask"></view>
<view class="time-popup-content" @click.stop>
<view class="time-list">
<view
class="time-item"
v-for="(month, index) in monthList"
:key="index"
:class="{ active: selectedMonth === month.value }"
@click="selectMonth(month)"
>
<text>{{ month.label }}</text>
</view>
</view>
</view>
</view>
<!-- 地区选择弹窗 -->
<view class="location-popup" v-if="isLocationPopupShow" @click="hideLocationPopup">
<view class="popup-mask"></view>
<view class="popup-content" @click.stop>
<view class="location-grid">
<view
class="location-item"
v-for="(province, index) in provinceList"
:key="index"
:class="{ active: selectedProvince === province.code }"
@click="selectProvince(province)"
>
<text>{{ province.name }}</text>
</view>
</view>
</view>
</view>
<!-- 过往会议提示 -->
<view class="history-tip">
<view class="tip-icon">
<up-icon name="clock" color="#00cbc0" size="28"></up-icon>
</view>
<text class="tip-text">过往会议</text>
</view>
<!-- 底部导航栏 -->
<CustomTabbar></CustomTabbar>
</view>
</template>
<script setup>
import { ref,nextTick, onMounted} from 'vue';
import { onShow } from "@dcloudio/uni-app";
import CustomTabbar from '@/components/tabBar/tabBar.vue';
import select from "@/static/triangle_normal.png"
import selectOn from "@/static/triangle_normal.png"
import playImg from "@/static/bofang.png"
import timeImg from "@/static/play_long.png"
import api from '@/api/api';
import docUrl from '@/utils/docUrl';
// 弹窗状态
const isTimePopupShow = ref(false);
const isLocationPopupShow = ref(false);
const selectedMonth = ref('all');
const selectedProvince = ref('');
// 下拉刷新和上拉加载状态
const isRefreshing = ref(false);
const isLoadingMore = ref(false);
const hasMoreData = ref(true);
const showLoadMore = ref(true);
const currentPage = ref(1);
const pageSize = ref(10);
const scrollTop = ref(0);
// 动态生成月份数据当前月份往后12个月
const monthList = ref([]);
// 生成月份列表
const generateMonthList = () => {
const months = [];
const currentDate = new Date();
const currentMonth = currentDate.getMonth() + 1; // 当前月份 (1-12)
const currentYear = currentDate.getFullYear();
// 添加"所有"选项
months.push({ value: 'all', label: '所有' });
// 从当前月份到12月
for (let month = currentMonth; month <= 12; month++) {
let monthLabel = '';
if (month === currentMonth) {
monthLabel = `${month}月(本月)`;
} else if (month === currentMonth + 1) {
monthLabel = `${month}月(下月)`;
} else {
monthLabel = `${month}`;
}
months.push({
value: month.toString(),
label: monthLabel,
year: currentYear,
month: month
});
}
// 从1月到当前月份不包括当前月份避免重复
for (let month = 1; month < currentMonth; month++) {
months.push({
value: month.toString(),
label: `${month}`,
year: currentYear + 1, // 下一年的月份
month: month
});
}
monthList.value = months;
console.log('生成的月份列表:', monthList.value);
};
// 省份数据
const provinceList = ref([
{ code: '全国', name: '全国' },
{ code: '北京市', name: '北京市' },
{ code: '天津市', name: '天津市' },
{ code: '河北省', name: '河北省' },
{ code: '山西省', name: '山西省' },
{ code: '内蒙古自治区', name: '内蒙古自治区' },
{ code: '辽宁省', name: '辽宁省' },
{ code: '吉林省', name: '吉林省' },
{ code: '黑龙江省', name: '黑龙江省' },
{ code: '上海市', name: '上海市' },
{ code: '江苏省', name: '江苏省' },
{ code: '浙江省', name: '浙江省' },
{ code: '安徽省', name: '安徽省' },
{ code: '福建省', name: '福建省' },
{ code: '江西省', name: '江西省' },
{ code: '山东省', name: '山东省' },
{ code: '河南省', name: '河南省' },
{ code: '湖北省', name: '湖北省' },
{ code: '湖南省', name: '湖南省' },
{ code: '广东省', name: '广东省' },
{ code: '广西壮族自治区', name: '广西壮族自治区' },
{ code: '海南省', name: '海南省' },
{ code: '重庆市', name: '重庆市' },
{ code: '四川省', name: '四川省' },
{ code: '贵州省', name: '贵州省' },
{ code: '云南省', name: '云南省' },
{ code: '西藏自治区', name: '西藏自治区' },
{ code: '陕西省', name: '陕西省' },
{ code: '甘肃省', name: '甘肃省' },
{ code: '青海省', name: '青海省' },
{ code: '宁夏回族自治区', name: '宁夏回族自治区' },
{ code: '新疆维吾尔自治区', name: '新疆维吾尔自治区' },
{ code: '台湾省', name: '台湾省' },
{ code: '香港特别行政区', name: '香港特别行政区' },
{ code: '澳门特别行政区', name: '澳门特别行政区' }
]);
// 会议列表数据
const meetingList = ref([
{
date: '13',
tagColor: '#FF4444',
title: '"天山论·见"—疑难危重病患维训练营',
poster: '/static/meeting-poster-1.jpg',
time: '2025.08.13',
location: '线上'
},
{
date: '13',
tagColor: '#FFA500',
title: '护肝新声大咖谈',
poster: '/static/meeting-poster-2.jpg',
time: '2025.08.13',
location: '线上'
},
{
date: '15',
tagColor: '#00BCD4',
title: '小罐医生讲HIV和感染专题二:抗菌药物-抗真菌药物特性解读',
poster: '/static/meeting-poster-3.jpg',
time: '2025.08.15',
location: '线上'
}
]);
// 显示时间选择弹窗
const showTimePopup = () => {
isTimePopupShow.value = !isTimePopupShow.value;
};
// 隐藏时间选择弹窗
const hideTimePopup = () => {
isTimePopupShow.value = false;
};
// 选择月份
const selectMonth = (month) => {
selectedMonth.value = month.value;
console.log('选择月份:', month.label, month);
// 重置页码
currentPage.value = 1;
// 构建筛选参数
const filters = {};
// 月份参数:选择"所有"时传空字符串,否则传具体月份
filters.month = month.value === 'all' ? '' : month.value;
// 地点参数:如果已选择省份,添加到筛选参数
if (selectedProvince.value && selectedProvince.value !== '全国') {
filters.location = selectedProvince.value;
} else {
filters.location = ''; // 选择"全国"时传空字符串
}
// 调用搜索筛选接口
meetingListBySearchU(filters);
hideTimePopup();
};
// 显示地区选择弹窗
const showLocationPopup = () => {
isLocationPopupShow.value = !isLocationPopupShow.value;
};
// 隐藏地区选择弹窗
const hideLocationPopup = () => {
isLocationPopupShow.value = false;
};
// 选择省份
const selectProvince = (province) => {
selectedProvince.value = province.code;
console.log('选择省份:', province.name);
// 重置页码
currentPage.value = 1;
// 构建筛选参数
const filters = {};
// 月份参数:如果已选择月份,添加到筛选参数
if (selectedMonth.value && selectedMonth.value !== 'all') {
filters.month = selectedMonth.value;
} else {
filters.month = ''; // 选择"所有"时传空字符串
}
// 地点参数:选择"全国"时传空字符串,否则传具体省份
filters.location = province.code === '全国' ? '' : province.code;
// 调用搜索筛选接口
meetingListBySearchU(filters);
hideLocationPopup();
};
// 播放视频
const playVideo = (item) => {
console.log('播放视频:', item.title, item);
// 如果会议已结束,跳转到详情页
if (item.status === 3) {
if (item.path) {
// 跳转到会议详情页
uni.navigateTo({
url: `/pages/webview/webview?url=${encodeURIComponent(item.path)}&title=${encodeURIComponent(item.title)}`
});
}
return;
}
// 如果会议正在进行或预告中,尝试播放直播
if (item.liveUrl) {
// 检查直播URL是否有效
if (item.liveUrl.includes('zhibo.igandan.com')) {
// 跳转到直播页面
uni.navigateTo({
url: `/pages/webview/webview?url=${encodeURIComponent(item.liveUrl)}&title=${encodeURIComponent(item.title)}`
});
} else {
uni.showToast({
title: '直播链接无效',
icon: 'error',
duration: 2000
});
}
} else {
uni.showToast({
title: '暂无直播链接',
icon: 'error',
duration: 2000
});
}
};
// 下拉刷新
const onRefresh = () => {
isRefreshing.value = true;
currentPage.value = 1;
hasMoreData.value = true;
// 构建筛选参数
const filters = {};
// 月份参数:选择"所有"时传空字符串,否则传具体月份
filters.month = selectedMonth.value === 'all' ? '' : selectedMonth.value;
// 地点参数:选择"全国"时传空字符串,否则传具体省份
filters.location = selectedProvince.value === '全国' ? '' : selectedProvince.value;
// 调用搜索筛选接口刷新数据
meetingListBySearchU(filters).then(() => {
uni.showToast({
title: '刷新成功',
icon: 'success',
duration: 1500
});
});
};
// 上拉加载更多
const onLoadMore = () => {
console.log('上拉加载');
if (isLoadingMore.value || !hasMoreData.value) return;
isLoadingMore.value = true;
currentPage.value++;
// 构建筛选参数
const filters = {};
// 月份参数:选择"所有"时传空字符串,否则传具体月份
filters.month = selectedMonth.value === 'all' ? '' : selectedMonth.value;
// 地点参数:选择"全国"时传空字符串,否则传具体省份
filters.location = selectedProvince.value === '全国' ? '' : selectedProvince.value;
// 调用搜索筛选接口加载更多数据
meetingListBySearchU(filters).then(() => {
// 强制更新页面确保scroll-view可以正常滚动
nextTick(() => {
console.log('数据加载完成,列表长度:', meetingList.value.length);
});
});
};
const loadMeetingList = async () => {
try {
const response = await api.meetingListV2U({
page: currentPage.value,
});
console.log('会议列表API原始响应:', response);
// 检查API响应状态
if (response.code === 200 && response.data) {
const { list, total, pageNum, pages, isLastPage } = response.data;
// 转换API数据为页面所需格式
const formattedMeetings = list.map(item => {
// 解析开始日期
const beginDate = new Date(item.begin_date);
const day = beginDate.getDate().toString().padStart(2, '0');
const month = (beginDate.getMonth() + 1).toString().padStart(2, '0');
const year = beginDate.getFullYear();
// 生成时间标签颜色(可以根据状态或日期生成不同颜色)
const tagColor = getTagColor(item.status, beginDate);
// 格式化时间显示
const timeStr = `${year}.${month}.${day}`;
return {
id: item.id,
date: day,
tagColor: tagColor,
title: item.title,
poster: docUrl + item.liveimg || '/static/meeting-poster-default.jpg',
time: timeStr,
location: item.location || '线上',
// 保留原始数据用于其他功能
originalData: item,
beginDate: item.begin_date,
endDate: item.end_date,
liveUrl: item.liveurl,
spareUrl: item.spareurl,
status: item.status,
path: item.path
};
});
// 如果是第一页,直接替换数据;否则追加数据
if (currentPage.value === 1) {
meetingList.value = formattedMeetings;
} else {
meetingList.value.push(...formattedMeetings);
}
// 更新分页状态
hasMoreData.value = !isLastPage;
showLoadMore.value = total > 0;
console.log('处理后的会议列表:', meetingList.value);
console.log('分页信息:', { currentPage: currentPage.value, total, pages, hasMore: hasMoreData.value });
} else {
console.error('API返回错误:', response.msg || '未知错误');
uni.showToast({
title: response.msg || '获取会议列表失败',
icon: 'error',
duration: 2000
});
}
} catch (error) {
console.error('获取会议列表失败:', error);
uni.showToast({
title: '网络请求失败',
icon: 'error',
duration: 2000
});
} finally {
// 重置加载状态
isLoadingMore.value = false;
isRefreshing.value = false;
}
};
// 按月份筛选会议列表
const loadMeetingListByMonth = async (monthValue) => {
try {
// 解析月份值格式2025-01
const [year, month] = monthValue.split('-');
const startDate = `${year}-${month}-01 00:00:00`;
// 计算下个月的第一天
const nextMonth = new Date(parseInt(year), parseInt(month), 1);
nextMonth.setMonth(nextMonth.getMonth() + 1);
const endDate = `${nextMonth.getFullYear()}-${(nextMonth.getMonth() + 1).toString().padStart(2, '0')}-01 00:00:00`;
console.log('按月份筛选:', { monthValue, startDate, endDate });
const response = await api.meetingListV2U({
page: currentPage.value,
startDate: startDate,
endDate: endDate
});
console.log('按月份筛选的API响应:', response);
// 处理响应数据(复用原有的数据处理逻辑)
if (response.code === 200 && response.data) {
const { list, total, pageNum, pages, isLastPage } = response.data;
// 转换API数据为页面所需格式
const formattedMeetings = list.map(item => {
// 解析开始日期
const beginDate = new Date(item.begin_date);
const day = beginDate.getDate().toString().padStart(2, '0');
const month = beginDate.getMonth() + 1;
const year = beginDate.getFullYear();
// 生成时间标签颜色
const tagColor = getTagColor(item.status, beginDate);
// 格式化时间显示
const timeStr = `${year}.${month.toString().padStart(2, '0')}.${day}`;
return {
id: item.id,
date: day,
tagColor: tagColor,
title: item.title,
poster: docUrl + item.liveimg || '/static/meeting-poster-default.jpg',
time: timeStr,
location: item.location || '线上',
// 保留原始数据用于其他功能
originalData: item,
beginDate: item.begin_date,
endDate: item.end_date,
liveUrl: item.liveurl,
spareUrl: item.spareurl,
status: item.status,
path: item.path
};
});
// 如果是第一页,直接替换数据;否则追加数据
if (currentPage.value === 1) {
meetingList.value = formattedMeetings;
} else {
meetingList.value.push(...formattedMeetings);
}
// 更新分页状态
hasMoreData.value = !isLastPage;
showLoadMore.value = total > 0;
console.log('按月份筛选后的会议列表:', meetingList.value);
} else {
console.error('按月份筛选API返回错误:', response.msg || '未知错误');
uni.showToast({
title: response.msg || '获取会议列表失败',
icon: 'error',
duration: 2000
});
}
} catch (error) {
console.error('按月份筛选会议列表失败:', error);
uni.showToast({
title: '网络请求失败',
icon: 'error',
duration: 2000
});
} finally {
// 重置加载状态
isLoadingMore.value = false;
isRefreshing.value = false;
}
};
// 根据会议状态和日期生成标签颜色
const getTagColor = (status, beginDate) => {
const now = new Date();
const meetingDate = new Date(beginDate);
// 如果会议已结束
if (status === 3) {
return '#999999'; // 灰色
}
// 如果会议正在进行中
if (status === 2) {
return '#FF4444'; // 红色
}
// 如果会议即将开始7天内
const daysDiff = Math.ceil((meetingDate - now) / (1000 * 60 * 60 * 24));
if (daysDiff <= 7 && daysDiff > 0) {
return '#FF9800'; // 橙色
}
// 默认颜色
const colors = ['#FF4444', '#FFA500', '#00BCD4', '#9C27B0', '#4CAF50', '#FF9800'];
return colors[Math.floor(Math.random() * colors.length)];
};
// 处理图片URL
const getImageUrl = (imagePath) => {
if (!imagePath) return '/static/meeting-poster-default.jpg';
// 如果是完整的URL直接返回
if (imagePath.startsWith('http://') || imagePath.startsWith('https://')) {
return imagePath;
}
// 如果是相对路径添加基础URL
// 这里可以根据实际情况调整基础URL
return `https://dev-wx.igandan.com/${imagePath}`;
};
// 获取状态文本
const getStatusText = (status) => {
switch (status) {
case 1: return '预告';
case 2: return '直播中';
case 3: return '已结束';
default: return '预告';
}
};
// 获取状态样式类
const getStatusClass = (status) => {
switch (status) {
case 1: return 'status-preview';
case 2: return 'status-live';
case 3: return 'status-ended';
default: return 'status-preview';
}
};
// 通过搜索和筛选接口获取会议列表
const meetingListBySearchU = async (filters = {}) => {
try {
const params = {
page: currentPage.value,
...filters
};
console.log('搜索筛选参数:', params);
const response = await api.meetingListBySearchU(params);
console.log('搜索筛选API原始响应:', response);
// 检查API响应状态
if (response.code === 200 && response.data) {
const { list, total, pageNum, pages, isLastPage } = response.data;
// 转换API数据为页面所需格式
const formattedMeetings = list.map(item => {
// 解析开始日期
const beginDate = new Date(item.begin_date);
const day = beginDate.getDate().toString().padStart(2, '0');
const month = beginDate.getMonth() + 1;
const year = beginDate.getFullYear();
// 生成时间标签颜色
const tagColor = getTagColor(item.status, beginDate);
// 格式化时间显示
const timeStr = `${year}.${month.toString().padStart(2, '0')}.${day}`;
return {
id: item.id,
date: day,
tagColor: tagColor,
title: item.title,
poster: docUrl + item.liveimg || '/static/meeting-poster-default.jpg',
time: timeStr,
location: item.location || '线上',
// 保留原始数据用于其他功能
originalData: item,
beginDate: item.begin_date,
endDate: item.end_date,
liveUrl: item.liveurl,
spareUrl: item.spareurl,
status: item.status,
path: item.path
};
});
// 如果是第一页,直接替换数据;否则追加数据
if (currentPage.value === 1) {
meetingList.value = formattedMeetings;
} else {
meetingList.value.push(...formattedMeetings);
}
// 更新分页状态
hasMoreData.value = !isLastPage;
showLoadMore.value = total > 0;
console.log('搜索筛选后的会议列表:', meetingList.value);
console.log('分页信息:', { currentPage: currentPage.value, total, pages, hasMore: hasMoreData.value });
return response;
} else {
console.error('搜索筛选API返回错误:', response.msg || '未知错误');
uni.showToast({
title: response.msg || '获取会议列表失败',
icon: 'error',
duration: 2000
});
}
} catch (error) {
console.error('搜索筛选会议列表失败:', error);
uni.showToast({
title: '网络请求失败',
icon: 'error',
duration: 2000
});
} finally {
// 重置加载状态
isLoadingMore.value = false;
isRefreshing.value = false;
}
};
// 格式化日期函数,包含年月
const formatDate = (date, format = 'YYYY-MM') => {
if (!date) return '';
// 如果传入的是字符串转换为Date对象
const dateObj = typeof date === 'string' ? new Date(date) : date;
// 检查日期是否有效
if (isNaN(dateObj.getTime())) {
console.error('无效的日期:', date);
return '';
}
const year = dateObj.getFullYear();
const month = (dateObj.getMonth() + 1).toString().padStart(2, '0');
const day = dateObj.getDate().toString().padStart(2, '0');
const hours = dateObj.getHours().toString().padStart(2, '0');
const minutes = dateObj.getMinutes().toString().padStart(2, '0');
const seconds = dateObj.getSeconds().toString().padStart(2, '0');
// 根据格式参数返回不同格式
switch (format) {
case 'YYYY-MM':
return `${year}-${month}`;
case 'YYYY-MM-DD':
return `${year}-${month}-${day}`;
case 'YYYY-MM-DD HH:mm':
return `${year}-${month}-${day} ${hours}:${minutes}`;
case 'YYYY-MM-DD HH:mm:ss':
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
case 'YYYY年MM月':
return `${year}${month}`;
case 'YYYY年MM月DD日':
return `${year}${month}${day}`;
case 'MM月':
return `${month}`;
case 'MM月DD日':
return `${month}${day}`;
default:
return `${year}-${month}`;
}
};
onShow(() => {
// 生成月份列表
generateMonthList();
// 加载会议列表
loadMeetingList();
});
</script>
<style lang="scss" scoped>
// 颜色变量
$primary-color: #D32F2F;
$secondary-color: #8B2316;
$background-color: #f5f5f5;
$white: #ffffff;
$gray-light: #f0f0f0;
$gray: #666;
$gray-dark: #333;
$gray-text: #999;
$border-color: #e0e0e0;
$green-accent: #00D4AA;
$shadow: 0 2px 8px rgba(0,0,0,0.1);
.page {
background-color: $background-color;
min-height: 100vh;
padding-bottom: 120rpx;
}
// 可滚动内容区域
.scroll-content {
position: fixed;
top: 228rpx; // 导航栏140rpx + 筛选栏88rpx
left: 0;
right: 0;
bottom: 120rpx; // 底部导航栏高度
width: 100%;
}
// 筛选标签栏
.filter-bar {
position:fixed ;
top:140rpx;
width:100%;
z-index:2;
background-color: $white;
height: 88rpx;
display: flex;
align-items: center;
padding: 0 30rpx;
border-bottom: 2rpx solid $gray-light;
.filter-item {
flex:1;
display: flex;
align-items: center;
padding: 0 20rpx;
font-size: 28rpx;
color: $gray;
text{
margin-right: 10rpx;
}
&.active {
color: $gray-dark;
}
}
.filter-divider {
width: 2rpx;
height: 32rpx;
background-color: $border-color;
margin: 0 10rpx;
}
}
// 时间选择弹窗
.time-popup {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 1000;
display: flex;
.popup-mask {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.time-popup-content {
margin-top: 231rpx;
position: relative;
background-color: $white;
width: 100%;
height: calc(100vh - 348rpx);
.time-list {
padding: 0;
height: 100%;
overflow-y: auto;
.time-item {
padding: 25rpx 60rpx;
font-size: 32rpx;
color: #666;
border-bottom: 2rpx solid #f0f0f0;
cursor: pointer;
transition: all 0.3s ease;
display: flex;
align-items: center;
&:hover {
background-color: #f8f8f8;
}
&.active {
background-color: #f8f8f8;
color: $primary-color;
text {
font-weight: 500;
}
}
&:last-child {
border-bottom: none;
}
text {
display: block;
width: 100%;
}
}
}
}
}
// 地区选择弹窗
.location-popup {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 1000;
display: flex;
.popup-mask {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.popup-content {
margin-top: 231rpx;
position: relative;
background-color: $white;
width: 100%;
height: calc(100vh - 433rpx);
padding:40rpx;
.popup-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
.popup-title {
font-size: 18px;
font-weight: 500;
color: $gray-dark;
}
.close-btn {
width: 30px;
height: 30px;
background-color: $gray-light;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 20px;
color: $gray;
cursor: pointer;
}
}
.location-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 30rpx;
height: 100%;
overflow-y: auto;
.location-item {
padding: 16rpx;
background-color: $background-color;
border-radius: 16rpx;
text-align: center;
font-size: 28rpx;
color: #999;
border: 2rpx solid #999;
cursor: pointer;
transition: all 0.3s ease;
&:hover {
background-color: lighten($primary-color, 45%);
}
&.active {
background-color: lighten($primary-color, 40%);
border-color: $primary-color;
color: $primary-color;
}
text {
display: block;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
word-break: break-all;
}
}
}
}
}
// 时间标题
.time-header {
text-align: center;
padding: 30rpx 0;
font-size: 32rpx;
color: $gray;
background-color: $background-color;
}
// 会议列表
.meeting-list {
padding: 0 30rpx;
.meeting-item {
display: flex;
margin-bottom: 30rpx;
background-color: $white;
border-radius: 16rpx;
overflow: hidden;
box-shadow: $shadow;
// 日期标识
.date-tag {
width: 50rpx;
display: flex;
align-items: center;
justify-content: center;
position:relative;
.date-text {
background: $white;
position:absolute;
top:50%;
color:red;
transform:translateY(-50%);
font-size: 32rpx;
width:40rpx;
display: flex;
justify-content: center;
align-items: center;
left: 35rpx;
height: 40rpx;
border-radius:50%;
}
}
// 会议内容
.meeting-content {
flex: 1;
padding: 30rpx;
.meeting-title {
font-size: 32rpx;
font-weight: 500;
color: $gray-dark;
margin-bottom: 20rpx;
line-height: 1.4;
}
.meeting-poster {
position: relative;
height: 240rpx;
border-radius: 12rpx;
overflow: hidden;
margin-bottom: 20rpx;
.poster-image {
width: 100%;
height: 100%;
object-fit: cover;
}
.play-btn {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width:210rpx;
height:210rpx;
opacity: 0.3;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
.status-tag {
position: absolute;
top: 16rpx;
right: 16rpx;
padding: 8rpx 16rpx;
border-radius: 20rpx;
font-size: 24rpx;
font-weight: 500;
border: 2rpx solid #fff;
box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.2);
&.status-preview {
background-color: #FF9800;
color: $white;
}
&.status-live {
background-color: #FF4444;
color: $white;
}
&.status-ended {
background-color: #999999;
color: $white;
}
}
}
.meeting-info {
display: flex;
justify-content: space-between;
.info-item {
display: flex;
align-items: center;
.timebox{
margin-top: -19rpx;
}
.info-text {
font-size: 24rpx;
color: $gray-text;
margin-left: 8rpx;
}
}
}
}
}
}
// 加载更多提示
.load-more {
padding: 30rpx;
.load-more-content {
display: flex;
align-items: center;
justify-content: center;
.load-more-text {
font-size: 28rpx;
color: $gray-text;
margin-left: 10rpx;
}
}
}
// 过往会议提示
.history-tip {
position: fixed;
bottom:200rpx;
z-index:9;
right:0;
border-radius: 50rpx 0 0 50rpx;
background:#00cbc0;
display: flex;
align-items: center;
justify-content: center;
padding: 10rpx 10rpx;
.tip-icon {
padding:10rpx;
background-color: #fff;
margin-right: 10rpx;
border-radius: 50%;
}
.tip-text {
width: 60rpx;
font-size: 26rpx;
color:#fff;
}
}
// 底部导航栏
.bottom-nav {
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 60px;
background-color: $white;
display: flex;
border-top: 1px solid $gray-light;
.nav-item {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 5px 0;
.nav-text {
font-size: 10px;
color: $gray-text;
margin-top: 2px;
&.active {
color: $primary-color;
}
}
}
}
</style>