完成学术交流web页面
This commit is contained in:
@@ -14,7 +14,77 @@
|
|||||||
<el-button type="primary" size="small" @click="fetchMeetings">重新加载</el-button>
|
<el-button type="primary" size="small" @click="fetchMeetings">重新加载</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<template v-if="!loading && !error && currentMeeting">
|
<!-- 会议列表页面 -->
|
||||||
|
<template v-if="isAllMeetingsPage && !loading && !error">
|
||||||
|
<div class="page-header">
|
||||||
|
<div class="back-button">
|
||||||
|
<el-button icon="ArrowLeft" @click="navigateBack">返回会议首页</el-button>
|
||||||
|
</div>
|
||||||
|
<h1 class="page-title">所有会议列表</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 会议列表加载状态 -->
|
||||||
|
<div v-if="allMeetingsLoading" class="all-meetings-loading">
|
||||||
|
<el-loading text="加载所有会议中..." />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 会议列表错误提示 -->
|
||||||
|
<div v-else-if="allMeetingsError" class="all-meetings-error">
|
||||||
|
{{ allMeetingsError }}
|
||||||
|
<el-button type="primary" size="small" @click="fetchAllMeetings">重新加载</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 无会议数据 -->
|
||||||
|
<div v-else-if="allMeetingsList.length === 0" class="no-all-meetings">
|
||||||
|
暂无会议数据
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 会议列表内容 -->
|
||||||
|
<div v-else class="all-meetings-container">
|
||||||
|
<div class="meeting-item" v-for="(meeting, index) in allMeetingsList" :key="meeting.id">
|
||||||
|
<div class="meeting-header">
|
||||||
|
<h2 class="meeting-theme">{{ meeting.theme }}</h2>
|
||||||
|
<div class="meeting-date">{{ formatMeetingTime(meeting.start_time, meeting.end_time) }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="meeting-content">
|
||||||
|
<div class="meeting-image">
|
||||||
|
<img :src="meeting.cover_url || 'https://picsum.photos/id/1059/600/400'" :alt="meeting.theme" class="meeting-img">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="meeting-details">
|
||||||
|
<h3 class="meeting-subtitle">{{ meeting.subtitle }}</h3>
|
||||||
|
<div class="meeting-intro" v-html="meeting.intro"></div>
|
||||||
|
|
||||||
|
<div class="meeting-meta">
|
||||||
|
<div class="meta-item">
|
||||||
|
<span class="meta-label">创建时间:</span>
|
||||||
|
<span class="meta-value">{{ formatDate(meeting.create_time) }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-button type="primary" size="small" @click="viewMeetingDetails(meeting)">查看详情</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 分页组件 -->
|
||||||
|
<div class="all-meetings-pagination">
|
||||||
|
<el-pagination
|
||||||
|
@size-change="handlePageSizeChange"
|
||||||
|
@current-change="handleCurrentPageChange"
|
||||||
|
:current-page="currentPage"
|
||||||
|
:page-sizes="[5, 10, 15, 20]"
|
||||||
|
:page-size="pageSize"
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
:total="totalMeetings"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 主会议页面 -->
|
||||||
|
<template v-if="!isAllMeetingsPage && !loading && !error && currentMeeting">
|
||||||
<!-- 锚点导航 -->
|
<!-- 锚点导航 -->
|
||||||
<el-anchor
|
<el-anchor
|
||||||
:offset="100"
|
:offset="100"
|
||||||
@@ -29,7 +99,7 @@
|
|||||||
<el-anchor-link href="#review" title="往届回顾" />
|
<el-anchor-link href="#review" title="往届回顾" />
|
||||||
</el-anchor>
|
</el-anchor>
|
||||||
|
|
||||||
<!-- 头部横幅(当前会议信息) -->
|
<!-- 头部横幅(当前会议信息)- 宽度设置为屏幕宽度 -->
|
||||||
<div
|
<div
|
||||||
class="header-banner"
|
class="header-banner"
|
||||||
id="conference"
|
id="conference"
|
||||||
@@ -46,7 +116,6 @@
|
|||||||
<span class="meta-label">时间 / TIME</span>
|
<span class="meta-label">时间 / TIME</span>
|
||||||
<span class="meta-value">{{ formatMeetingTime(currentMeeting.start_time, currentMeeting.end_time) }}</span>
|
<span class="meta-value">{{ formatMeetingTime(currentMeeting.start_time, currentMeeting.end_time) }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -83,14 +152,16 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="schedule-image-container">
|
<div class="schedule-image-container">
|
||||||
|
<!-- 点击图片触发放大查看 -->
|
||||||
<img
|
<img
|
||||||
:src="currentMeeting.schedule_image_url"
|
:src="currentMeeting.schedule_image_url"
|
||||||
alt="会议议程安排"
|
alt="会议议程安排"
|
||||||
class="schedule-image"
|
class="schedule-image"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
|
@click="showEnlargedImage(currentMeeting.schedule_image_url)"
|
||||||
>
|
>
|
||||||
<p class="schedule-caption">
|
<p class="schedule-caption">
|
||||||
点击图片可查看高清议程 | Click to view high-resolution schedule
|
点击图片可放大
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
@@ -116,7 +187,7 @@
|
|||||||
|
|
||||||
<!-- 无嘉宾数据 -->
|
<!-- 无嘉宾数据 -->
|
||||||
<div v-else-if="speakersList.length === 0" class="no-speakers">
|
<div v-else-if="speakersList.length === 0" class="no-speakers">
|
||||||
暂无演讲嘉宾信息
|
无演讲嘉宾数据
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 嘉宾列表 -->
|
<!-- 嘉宾列表 -->
|
||||||
@@ -136,27 +207,33 @@
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- 往届回顾(第2-4个会议) -->
|
<!-- 往届回顾(当前会议之外的最近3个会议) -->
|
||||||
<section class="review-section" id="review" ref="reviewRef">
|
<section class="review-section" id="review" ref="reviewRef">
|
||||||
<div class="section-header">
|
<div class="section-header">
|
||||||
<h2>往届回顾</h2>
|
<h2>往届回顾</h2>
|
||||||
<p>Previous Review</p>
|
<p>Previous Review</p>
|
||||||
<a href="javascript:void(0)" class="more-link">More</a>
|
<a href="javascript:void(0)" class="more-link" @click="goToAllMeetingsPage">More</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="review-content">
|
<div class="review-content">
|
||||||
|
<!-- 往届会议卡片 - 添加点击事件 -->
|
||||||
<div
|
<div
|
||||||
class="review-card"
|
class="review-card"
|
||||||
v-for="(meeting, index) in pastMeetings"
|
v-for="(meeting, index) in pastMeetings"
|
||||||
:key="meeting.id"
|
:key="meeting.id"
|
||||||
|
@click="viewMeetingDetails(meeting)"
|
||||||
>
|
>
|
||||||
<img :src="meeting.cover_url" :alt="meeting.theme" class="review-image">
|
<img :src="meeting.cover_url" :alt="meeting.theme" class="review-image">
|
||||||
<div class="review-info">
|
<div class="review-info">
|
||||||
<h4>{{ meeting.theme }}</h4>
|
<h4>{{ meeting.theme }}</h4>
|
||||||
<p>{{meeting.subtitle}}}</p>
|
<p>{{ meeting.subtitle }}</p>
|
||||||
<div class="review-desc" >{{ formatMeetingTime(meeting.start_time, meeting.end_time) }}</div>
|
<div class="review-desc">{{ formatMeetingTime(meeting.start_time, meeting.end_time) }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- 无往届会议时显示提示 -->
|
||||||
|
<div v-if="pastMeetings.length === 0" class="no-past-meetings">
|
||||||
|
暂无更多往届会议数据
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
@@ -181,30 +258,67 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
|
<!-- 图片放大查看弹窗 -->
|
||||||
|
<el-dialog
|
||||||
|
v-model="imageDialogVisible"
|
||||||
|
title="会议日程详情"
|
||||||
|
width="90%"
|
||||||
|
:before-close="handleImageDialogClose"
|
||||||
|
:modal="true"
|
||||||
|
:close-on-click-modal="true"
|
||||||
|
>
|
||||||
|
<div class="enlarged-image-container">
|
||||||
|
<img
|
||||||
|
:src="enlargedImageUrl"
|
||||||
|
alt="会议日程详情"
|
||||||
|
class="enlarged-image"
|
||||||
|
:style="{ maxHeight: `calc(100vh - 150px)` }"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, onMounted, computed } from 'vue'
|
import { ref, onMounted, computed, watch } from 'vue'
|
||||||
import { ElAnchor, ElAnchorLink, ElDialog, ElLoading, ElButton } from 'element-plus'
|
import { ElAnchor, ElAnchorLink, ElDialog, ElLoading, ElButton, ElPagination, ElInput } from 'element-plus'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
|
||||||
|
// 页面状态控制
|
||||||
|
const isAllMeetingsPage = ref(false) // 控制显示会议列表页还是主页面
|
||||||
|
|
||||||
// 基础配置 - 固定baseurl
|
// 基础配置 - 固定baseurl
|
||||||
const baseUrl = 'http://localhost:8080/api'
|
const baseUrl = 'http://localhost:8080/api'
|
||||||
|
|
||||||
|
// 顶部横幅封面图URL
|
||||||
|
const pageImageUrl = ref('')
|
||||||
|
|
||||||
// 会议数据状态
|
// 会议数据状态
|
||||||
const meetings = ref([])
|
const meetings = ref([]) // 所有会议数据(用于筛选往届会议)
|
||||||
const currentMeeting = ref(null) // 当前(最新)会议
|
const currentMeeting = ref(null) // 当前(正在展示的)会议
|
||||||
const pastMeetings = ref([]) // 往届会议(第2-4个)
|
const pastMeetings = ref([]) // 往届会议(当前会议之外的最近3个)
|
||||||
const loading = ref(true) // 全局加载状态
|
const loading = ref(true) // 全局加载状态
|
||||||
const error = ref(null) // 全局错误信息
|
const error = ref(null) // 全局错误信息
|
||||||
|
|
||||||
|
// 所有会议列表(分页)状态
|
||||||
|
const allMeetingsList = ref([]) // 所有会议列表数据
|
||||||
|
const allMeetingsLoading = ref(false) // 加载状态
|
||||||
|
const allMeetingsError = ref(null) // 错误信息
|
||||||
|
const currentPage = ref(1) // 当前页码
|
||||||
|
const pageSize = ref(10) // 每页条数
|
||||||
|
const totalMeetings = ref(0) // 总会议数
|
||||||
|
|
||||||
// 演讲嘉宾状态
|
// 演讲嘉宾状态
|
||||||
const speakersList = ref([]) // 嘉宾列表
|
const speakersList = ref([]) // 嘉宾列表
|
||||||
const speakersLoading = ref(false) // 嘉宾加载状态
|
const speakersLoading = ref(false) // 嘉宾加载状态
|
||||||
const speakersError = ref(null) // 嘉宾加载错误
|
const speakersError = ref(null) // 嘉宾加载错误
|
||||||
|
|
||||||
|
// 图片放大查看相关状态
|
||||||
|
const imageDialogVisible = ref(false) // 图片弹窗显示控制
|
||||||
|
const enlargedImageUrl = ref('') // 放大查看的图片URL
|
||||||
|
|
||||||
// 元素引用
|
// 元素引用
|
||||||
const conferenceRef = ref<HTMLElement>()
|
const conferenceRef = ref<HTMLElement>()
|
||||||
const reportRef = ref<HTMLElement>()
|
const reportRef = ref<HTMLElement>()
|
||||||
@@ -225,9 +339,24 @@ const currentSpeaker = ref({
|
|||||||
is_delete: 0
|
is_delete: 0
|
||||||
})
|
})
|
||||||
|
|
||||||
// 头部背景样式(使用当前会议封面图)
|
// 从后端获取封面图
|
||||||
|
const fetchCoverImage = async () => {
|
||||||
|
try {
|
||||||
|
const response = await axios.post('http://localhost:8080/api/page-image/get', { page: 'AcademicExchange' });
|
||||||
|
if (response.data.message === '查询成功' && response.data.images && response.data.images.length > 0) {
|
||||||
|
pageImageUrl.value = response.data.images[0].image_url;
|
||||||
|
}
|
||||||
|
console.log("获取封面成功:", response.data);
|
||||||
|
} catch (error) {
|
||||||
|
console.log('封面图加载失败,使用默认图', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 头部背景样式(优先使用从接口获取的封面图,其次使用当前会议封面图,最后使用默认图)
|
||||||
const headerBackgroundStyle = computed(() => ({
|
const headerBackgroundStyle = computed(() => ({
|
||||||
backgroundImage: currentMeeting.value
|
backgroundImage: pageImageUrl.value
|
||||||
|
? `url(${pageImageUrl.value})`
|
||||||
|
: currentMeeting.value && currentMeeting.value.cover_url
|
||||||
? `url(${currentMeeting.value.cover_url})`
|
? `url(${currentMeeting.value.cover_url})`
|
||||||
: 'url(https://picsum.photos/id/1059/1920/600)'
|
: 'url(https://picsum.photos/id/1059/1920/600)'
|
||||||
}))
|
}))
|
||||||
@@ -260,15 +389,18 @@ const formatMeetingTime = (startTime: string, endTime: string) => {
|
|||||||
return `${start.toLocaleString('zh-CN')} - ${end.toLocaleString('zh-CN')}`
|
return `${start.toLocaleString('zh-CN')} - ${end.toLocaleString('zh-CN')}`
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取会议列表
|
// 获取所有会议数据(用于首页和筛选往届会议)
|
||||||
const fetchMeetings = async () => {
|
const fetchMeetings = async () => {
|
||||||
try {
|
try {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
error.value = null
|
error.value = null
|
||||||
|
|
||||||
|
// 先获取封面图
|
||||||
|
await fetchCoverImage()
|
||||||
|
|
||||||
const response = await axios.post(`${baseUrl}/meetings/list`, {
|
const response = await axios.post(`${baseUrl}/meetings/list`, {
|
||||||
page: 1,
|
page: 1,
|
||||||
page_size: 10
|
page_size: 100 // 加载足够多的会议数据,确保能筛选出最近3个往届会议
|
||||||
})
|
})
|
||||||
|
|
||||||
if (response.data.message === '查询成功' && response.data.meetings && response.data.meetings.length > 0) {
|
if (response.data.message === '查询成功' && response.data.meetings && response.data.meetings.length > 0) {
|
||||||
@@ -277,9 +409,23 @@ const fetchMeetings = async () => {
|
|||||||
(a, b) => new Date(b.create_time).getTime() - new Date(a.create_time).getTime()
|
(a, b) => new Date(b.create_time).getTime() - new Date(a.create_time).getTime()
|
||||||
)
|
)
|
||||||
|
|
||||||
meetings.value = sortedMeetings
|
meetings.value = sortedMeetings // 保存所有会议数据
|
||||||
currentMeeting.value = sortedMeetings[0] // 最新会议
|
|
||||||
pastMeetings.value = sortedMeetings.slice(1, 4) // 第2-4个会议
|
// 如果当前没有选中的会议,默认选中最新的会议
|
||||||
|
if (!currentMeeting.value) {
|
||||||
|
currentMeeting.value = sortedMeetings[0]
|
||||||
|
} else {
|
||||||
|
// 如果已有选中的会议,确保它是最新的或保持选中状态
|
||||||
|
const existingMeeting = sortedMeetings.find(item => item.id === currentMeeting.value.id)
|
||||||
|
if (existingMeeting) {
|
||||||
|
currentMeeting.value = existingMeeting
|
||||||
|
} else {
|
||||||
|
currentMeeting.value = sortedMeetings[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 筛选往届会议:排除当前会议,取剩下的最近3个
|
||||||
|
filterPastMeetings()
|
||||||
|
|
||||||
// 自动获取当前会议的嘉宾
|
// 自动获取当前会议的嘉宾
|
||||||
if (currentMeeting.value.id) {
|
if (currentMeeting.value.id) {
|
||||||
@@ -296,6 +442,55 @@ const fetchMeetings = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 筛选往届会议:排除当前会议,取剩下的最近3个
|
||||||
|
const filterPastMeetings = () => {
|
||||||
|
if (!meetings.value.length || !currentMeeting.value) {
|
||||||
|
pastMeetings.value = []
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 过滤掉当前会议,然后取前3个(按创建时间排序后的)
|
||||||
|
const filtered = meetings.value.filter(meeting => meeting.id !== currentMeeting.value.id)
|
||||||
|
pastMeetings.value = filtered.slice(0, 3) // 取最近的3个
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听currentMeeting变化,重新筛选往届会议
|
||||||
|
watch(currentMeeting, () => {
|
||||||
|
filterPastMeetings()
|
||||||
|
})
|
||||||
|
|
||||||
|
// 获取所有会议(分页)
|
||||||
|
const fetchAllMeetings = async () => {
|
||||||
|
try {
|
||||||
|
allMeetingsLoading.value = true
|
||||||
|
allMeetingsError.value = null
|
||||||
|
|
||||||
|
const params = {
|
||||||
|
page: currentPage.value,
|
||||||
|
page_size: pageSize.value
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await axios.post(`${baseUrl}/meetings/list`, params)
|
||||||
|
|
||||||
|
if (response.data.message === '查询成功') {
|
||||||
|
// 按创建时间排序(最新在前)
|
||||||
|
const sortedMeetings = [...response.data.meetings].sort(
|
||||||
|
(a, b) => new Date(b.create_time).getTime() - new Date(a.create_time).getTime()
|
||||||
|
)
|
||||||
|
|
||||||
|
allMeetingsList.value = sortedMeetings
|
||||||
|
totalMeetings.value = response.data.total || sortedMeetings.length
|
||||||
|
} else {
|
||||||
|
allMeetingsError.value = '未获取到会议数据'
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error('获取所有会议失败:', err)
|
||||||
|
allMeetingsError.value = '获取会议列表失败,请重试'
|
||||||
|
} finally {
|
||||||
|
allMeetingsLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 根据会议ID获取演讲嘉宾
|
// 根据会议ID获取演讲嘉宾
|
||||||
const fetchSpeakers = async (meetingId: number) => {
|
const fetchSpeakers = async (meetingId: number) => {
|
||||||
try {
|
try {
|
||||||
@@ -314,7 +509,8 @@ const fetchSpeakers = async (meetingId: number) => {
|
|||||||
// 按sort字段排序(升序)
|
// 按sort字段排序(升序)
|
||||||
speakersList.value = [...response.data.speakers].sort((a, b) => a.sort - b.sort)
|
speakersList.value = [...response.data.speakers].sort((a, b) => a.sort - b.sort)
|
||||||
} else {
|
} else {
|
||||||
speakersError.value = '未获取到演讲嘉宾数据'
|
// 接口调用成功但无数据时,不设置错误信息,由空列表状态处理
|
||||||
|
speakersList.value = []
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('获取演讲嘉宾失败:', err)
|
console.error('获取演讲嘉宾失败:', err)
|
||||||
@@ -357,11 +553,71 @@ const showSpeakerInfo = (speaker: any) => {
|
|||||||
dialogVisible.value = true
|
dialogVisible.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// 关闭弹窗
|
// 关闭嘉宾详情弹窗
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
dialogVisible.value = false
|
dialogVisible.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 显示放大的图片
|
||||||
|
const showEnlargedImage = (imageUrl: string) => {
|
||||||
|
if (imageUrl) {
|
||||||
|
enlargedImageUrl.value = imageUrl
|
||||||
|
imageDialogVisible.value = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭图片放大弹窗
|
||||||
|
const handleImageDialogClose = () => {
|
||||||
|
imageDialogVisible.value = false
|
||||||
|
enlargedImageUrl.value = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
// 跳转到所有会议列表页面
|
||||||
|
const goToAllMeetingsPage = async () => {
|
||||||
|
isAllMeetingsPage.value = true
|
||||||
|
// 初始化页码
|
||||||
|
currentPage.value = 1
|
||||||
|
// 加载第一页数据
|
||||||
|
await fetchAllMeetings()
|
||||||
|
// 滚动到页面顶部
|
||||||
|
window.scrollTo(0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回会议首页
|
||||||
|
const navigateBack = () => {
|
||||||
|
isAllMeetingsPage.value = false
|
||||||
|
// 滚动到页面顶部
|
||||||
|
window.scrollTo(0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查看会议详情 - 复用此方法处理所有会议卡片的点击
|
||||||
|
const viewMeetingDetails = (meeting: any) => {
|
||||||
|
// 切换到主页面并显示选中的会议
|
||||||
|
currentMeeting.value = meeting
|
||||||
|
isAllMeetingsPage.value = false
|
||||||
|
// 加载该会议的嘉宾
|
||||||
|
if (meeting.id) {
|
||||||
|
fetchSpeakers(meeting.id)
|
||||||
|
}
|
||||||
|
// 重新获取封面图(确保显示正确的封面)
|
||||||
|
fetchCoverImage()
|
||||||
|
// 滚动到页面顶部
|
||||||
|
window.scrollTo(0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分页大小改变
|
||||||
|
const handlePageSizeChange = async (size: number) => {
|
||||||
|
pageSize.value = size
|
||||||
|
currentPage.value = 1 // 重置为第一页
|
||||||
|
await fetchAllMeetings()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 当前页码改变
|
||||||
|
const handleCurrentPageChange = async (page: number) => {
|
||||||
|
currentPage.value = page
|
||||||
|
await fetchAllMeetings()
|
||||||
|
}
|
||||||
|
|
||||||
// 初始化加载会议数据
|
// 初始化加载会议数据
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
fetchMeetings()
|
fetchMeetings()
|
||||||
@@ -375,6 +631,151 @@ onMounted(() => {
|
|||||||
color: #333;
|
color: #333;
|
||||||
line-height: 1.6;
|
line-height: 1.6;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
max-width: 1400px;
|
||||||
|
margin: 0 auto;
|
||||||
|
/* 移除默认padding,避免影响全屏横幅 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 页面切换相关样式 */
|
||||||
|
.page-header {
|
||||||
|
padding: 30px 20px;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-button {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-title {
|
||||||
|
margin: 0;
|
||||||
|
color: #2c3e50;
|
||||||
|
font-size: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 会议列表样式 */
|
||||||
|
.all-meetings-container {
|
||||||
|
padding: 10px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meeting-item {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
|
||||||
|
margin-bottom: 30px;
|
||||||
|
overflow: hidden;
|
||||||
|
transition: transform 0.3s, box-shadow 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meeting-item:hover {
|
||||||
|
transform: translateY(-5px);
|
||||||
|
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.meeting-header {
|
||||||
|
background: #f8f9fa;
|
||||||
|
padding: 20px 30px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meeting-theme {
|
||||||
|
margin: 0;
|
||||||
|
color: #2c3e50;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meeting-date {
|
||||||
|
color: #409eff;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meeting-content {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 300px 1fr;
|
||||||
|
gap: 30px;
|
||||||
|
padding: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meeting-image {
|
||||||
|
border-radius: 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meeting-img {
|
||||||
|
width: 100%;
|
||||||
|
height: 200px;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meeting-details {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meeting-subtitle {
|
||||||
|
margin: 0;
|
||||||
|
color: #34495e;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meeting-intro {
|
||||||
|
line-height: 1.8;
|
||||||
|
color: #555;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meeting-intro p {
|
||||||
|
margin: 0 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meeting-meta {
|
||||||
|
margin-top: 10px;
|
||||||
|
padding-top: 15px;
|
||||||
|
border-top: 1px dashed #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meeting-meta .meta-item {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 修改创建时间样式 - 移除阴影和灰白效果 */
|
||||||
|
.meeting-meta .meta-label {
|
||||||
|
color: #333; /* 改为深色,移除灰白效果 */
|
||||||
|
font-size: 0.9rem;
|
||||||
|
text-shadow: none; /* 移除阴影 */
|
||||||
|
font-weight: 500; /* 稍微加粗,提高可见度 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.meeting-meta .meta-value {
|
||||||
|
color: #333; /* 改为深色,移除灰白效果 */
|
||||||
|
font-size: 0.95rem;
|
||||||
|
text-shadow: none; /* 移除阴影 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.all-meetings-pagination {
|
||||||
|
margin: 40px 20px 60px;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 会议列表状态样式 */
|
||||||
|
.all-meetings-loading, .all-meetings-error, .no-all-meetings {
|
||||||
|
text-align: center;
|
||||||
|
padding: 80px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.all-meetings-error {
|
||||||
|
color: #f56c6c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-all-meetings {
|
||||||
|
color: #909399;
|
||||||
|
font-size: 1.2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 错误提示样式 */
|
/* 错误提示样式 */
|
||||||
@@ -438,7 +839,7 @@ onMounted(() => {
|
|||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 头部横幅样式 */
|
/* 头部横幅样式 - 设置为屏幕宽度 */
|
||||||
.header-banner {
|
.header-banner {
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
background-position: center;
|
background-position: center;
|
||||||
@@ -449,6 +850,9 @@ onMounted(() => {
|
|||||||
min-height: 400px;
|
min-height: 400px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
width: 100vw; /* 设置宽度为视口宽度 */
|
||||||
|
margin-left: calc(-50vw + 50%); /* 使元素居中并充满屏幕宽度 */
|
||||||
|
left: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.banner-mask {
|
.banner-mask {
|
||||||
@@ -457,7 +861,7 @@ onMounted(() => {
|
|||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background-color: transparent;
|
background-color: rgba(0, 0, 0, 0.4);
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -467,6 +871,7 @@ onMounted(() => {
|
|||||||
padding: 0 20px;
|
padding: 0 20px;
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
|
width: 100%; /* 确保内容区域在横幅内正确显示 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.hdic-logo {
|
.hdic-logo {
|
||||||
@@ -491,18 +896,19 @@ onMounted(() => {
|
|||||||
gap: 25px;
|
gap: 25px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.meta-item {
|
/* 注意:这里只修改会议列表中的创建时间样式,不影响头部横幅的meta样式 */
|
||||||
|
.conference-meta .meta-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
.meta-label {
|
.conference-meta .meta-label {
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.8);
|
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.8);
|
||||||
}
|
}
|
||||||
|
|
||||||
.meta-value {
|
.conference-meta .meta-value {
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.8);
|
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.8);
|
||||||
@@ -616,8 +1022,8 @@ onMounted(() => {
|
|||||||
height: auto;
|
height: auto;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
box-shadow: 0 10px 30px rgba(0,0,0,0.2);
|
box-shadow: 0 10px 30px rgba(0,0,0,0.2);
|
||||||
transition: transform 0.3s ease;
|
transition: transform 0.3s ease, cursor 0.3s;
|
||||||
cursor: pointer;
|
cursor: zoom-in; /* 显示放大镜图标,提示可点击放大 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.schedule-image:hover {
|
.schedule-image:hover {
|
||||||
@@ -711,22 +1117,30 @@ onMounted(() => {
|
|||||||
margin-top: 40px;
|
margin-top: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 往届会议卡片样式 - 添加鼠标悬停效果提示可点击 */
|
||||||
.review-card {
|
.review-card {
|
||||||
background: white;
|
background: white;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
box-shadow: 0 5px 20px rgba(0,0,0,0.1);
|
box-shadow: 0 5px 20px rgba(0,0,0,0.1);
|
||||||
transition: transform 0.3s;
|
transition: transform 0.3s, box-shadow 0.3s;
|
||||||
|
cursor: pointer; /* 显示手型指针提示可点击 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.review-card:hover {
|
.review-card:hover {
|
||||||
transform: translateY(-5px);
|
transform: translateY(-5px);
|
||||||
|
box-shadow: 0 10px 30px rgba(0,0,0,0.15); /* 增强阴影效果 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.review-image {
|
.review-image {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 200px;
|
height: 200px;
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
|
transition: transform 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.review-card:hover .review-image {
|
||||||
|
transform: scale(1.05); /* 图片轻微放大效果 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.review-info {
|
.review-info {
|
||||||
@@ -739,24 +1153,25 @@ onMounted(() => {
|
|||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.review-date {
|
.review-info p {
|
||||||
color: #409eff;
|
color: #7f8c8d;
|
||||||
font-size: 0.9rem;
|
|
||||||
margin: 0 0 15px;
|
margin: 0 0 15px;
|
||||||
font-style: italic;
|
font-size: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.review-desc {
|
.review-desc {
|
||||||
color: #666;
|
color: #666;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
line-height: 1.6;
|
line-height: 1.6;
|
||||||
max-height: 100px;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.review-desc p {
|
/* 无往届会议提示 */
|
||||||
margin: 0;
|
.no-past-meetings {
|
||||||
font-size: 0.95rem;
|
grid-column: 1 / -1;
|
||||||
|
text-align: center;
|
||||||
|
padding: 60px 20px;
|
||||||
|
color: #909399;
|
||||||
|
font-size: 1.2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 嘉宾详情弹窗样式 */
|
/* 嘉宾详情弹窗样式 */
|
||||||
@@ -809,11 +1224,29 @@ onMounted(() => {
|
|||||||
text-align: justify;
|
text-align: justify;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 图片放大查看样式 */
|
||||||
|
.enlarged-image-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
padding: 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.enlarged-image {
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
object-fit: contain;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
/* 响应式适配 */
|
/* 响应式适配 */
|
||||||
@media (max-width: 1200px) {
|
@media (max-width: 1200px) {
|
||||||
.speakers-grid {
|
.speakers-grid {
|
||||||
grid-template-columns: repeat(3, 1fr);
|
grid-template-columns: repeat(3, 1fr);
|
||||||
}
|
}
|
||||||
|
.meeting-content {
|
||||||
|
grid-template-columns: 250px 1fr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 1024px) {
|
@media (max-width: 1024px) {
|
||||||
@@ -823,6 +1256,12 @@ onMounted(() => {
|
|||||||
.speakers-grid {
|
.speakers-grid {
|
||||||
grid-template-columns: repeat(2, 1fr);
|
grid-template-columns: repeat(2, 1fr);
|
||||||
}
|
}
|
||||||
|
.meeting-content {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
.meeting-img {
|
||||||
|
height: 300px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
@@ -855,5 +1294,16 @@ onMounted(() => {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 15px;
|
gap: 15px;
|
||||||
}
|
}
|
||||||
|
.review-content {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
.meeting-header {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
.meeting-img {
|
||||||
|
height: 200px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user