完成学术交流web页面
This commit is contained in:
@@ -14,7 +14,77 @@
|
||||
<el-button type="primary" size="small" @click="fetchMeetings">重新加载</el-button>
|
||||
</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
|
||||
:offset="100"
|
||||
@@ -29,7 +99,7 @@
|
||||
<el-anchor-link href="#review" title="往届回顾" />
|
||||
</el-anchor>
|
||||
|
||||
<!-- 头部横幅(当前会议信息) -->
|
||||
<!-- 头部横幅(当前会议信息)- 宽度设置为屏幕宽度 -->
|
||||
<div
|
||||
class="header-banner"
|
||||
id="conference"
|
||||
@@ -46,7 +116,6 @@
|
||||
<span class="meta-label">时间 / TIME</span>
|
||||
<span class="meta-value">{{ formatMeetingTime(currentMeeting.start_time, currentMeeting.end_time) }}</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -83,14 +152,16 @@
|
||||
</div>
|
||||
|
||||
<div class="schedule-image-container">
|
||||
<!-- 点击图片触发放大查看 -->
|
||||
<img
|
||||
:src="currentMeeting.schedule_image_url"
|
||||
alt="会议议程安排"
|
||||
class="schedule-image"
|
||||
loading="lazy"
|
||||
@click="showEnlargedImage(currentMeeting.schedule_image_url)"
|
||||
>
|
||||
<p class="schedule-caption">
|
||||
点击图片可查看高清议程 | Click to view high-resolution schedule
|
||||
点击图片可放大
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
@@ -116,7 +187,7 @@
|
||||
|
||||
<!-- 无嘉宾数据 -->
|
||||
<div v-else-if="speakersList.length === 0" class="no-speakers">
|
||||
暂无演讲嘉宾信息
|
||||
无演讲嘉宾数据
|
||||
</div>
|
||||
|
||||
<!-- 嘉宾列表 -->
|
||||
@@ -136,27 +207,33 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 往届回顾(第2-4个会议) -->
|
||||
<!-- 往届回顾(当前会议之外的最近3个会议) -->
|
||||
<section class="review-section" id="review" ref="reviewRef">
|
||||
<div class="section-header">
|
||||
<h2>往届回顾</h2>
|
||||
<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 class="review-content">
|
||||
<!-- 往届会议卡片 - 添加点击事件 -->
|
||||
<div
|
||||
class="review-card"
|
||||
v-for="(meeting, index) in pastMeetings"
|
||||
:key="meeting.id"
|
||||
@click="viewMeetingDetails(meeting)"
|
||||
>
|
||||
<img :src="meeting.cover_url" :alt="meeting.theme" class="review-image">
|
||||
<div class="review-info">
|
||||
<h4>{{ meeting.theme }}</h4>
|
||||
<p>{{meeting.subtitle}}}</p>
|
||||
<div class="review-desc" >{{ formatMeetingTime(meeting.start_time, meeting.end_time) }}</div>
|
||||
<p>{{ meeting.subtitle }}</p>
|
||||
<div class="review-desc">{{ formatMeetingTime(meeting.start_time, meeting.end_time) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 无往届会议时显示提示 -->
|
||||
<div v-if="pastMeetings.length === 0" class="no-past-meetings">
|
||||
暂无更多往届会议数据
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -181,30 +258,67 @@
|
||||
</div>
|
||||
</div>
|
||||
</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>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted, computed } from 'vue'
|
||||
import { ElAnchor, ElAnchorLink, ElDialog, ElLoading, ElButton } from 'element-plus'
|
||||
import { ref, onMounted, computed, watch } from 'vue'
|
||||
import { ElAnchor, ElAnchorLink, ElDialog, ElLoading, ElButton, ElPagination, ElInput } from 'element-plus'
|
||||
import axios from 'axios'
|
||||
|
||||
// 页面状态控制
|
||||
const isAllMeetingsPage = ref(false) // 控制显示会议列表页还是主页面
|
||||
|
||||
// 基础配置 - 固定baseurl
|
||||
const baseUrl = 'http://localhost:8080/api'
|
||||
|
||||
// 顶部横幅封面图URL
|
||||
const pageImageUrl = ref('')
|
||||
|
||||
// 会议数据状态
|
||||
const meetings = ref([])
|
||||
const currentMeeting = ref(null) // 当前(最新)会议
|
||||
const pastMeetings = ref([]) // 往届会议(第2-4个)
|
||||
const meetings = ref([]) // 所有会议数据(用于筛选往届会议)
|
||||
const currentMeeting = ref(null) // 当前(正在展示的)会议
|
||||
const pastMeetings = ref([]) // 往届会议(当前会议之外的最近3个)
|
||||
const loading = ref(true) // 全局加载状态
|
||||
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 speakersLoading = ref(false) // 嘉宾加载状态
|
||||
const speakersError = ref(null) // 嘉宾加载错误
|
||||
|
||||
// 图片放大查看相关状态
|
||||
const imageDialogVisible = ref(false) // 图片弹窗显示控制
|
||||
const enlargedImageUrl = ref('') // 放大查看的图片URL
|
||||
|
||||
// 元素引用
|
||||
const conferenceRef = ref<HTMLElement>()
|
||||
const reportRef = ref<HTMLElement>()
|
||||
@@ -225,11 +339,26 @@ const currentSpeaker = ref({
|
||||
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(() => ({
|
||||
backgroundImage: currentMeeting.value
|
||||
? `url(${currentMeeting.value.cover_url})`
|
||||
: 'url(https://picsum.photos/id/1059/1920/600)'
|
||||
backgroundImage: pageImageUrl.value
|
||||
? `url(${pageImageUrl.value})`
|
||||
: currentMeeting.value && currentMeeting.value.cover_url
|
||||
? `url(${currentMeeting.value.cover_url})`
|
||||
: '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')}`
|
||||
}
|
||||
|
||||
// 获取会议列表
|
||||
// 获取所有会议数据(用于首页和筛选往届会议)
|
||||
const fetchMeetings = async () => {
|
||||
try {
|
||||
loading.value = true
|
||||
error.value = null
|
||||
|
||||
// 先获取封面图
|
||||
await fetchCoverImage()
|
||||
|
||||
const response = await axios.post(`${baseUrl}/meetings/list`, {
|
||||
page: 1,
|
||||
page_size: 10
|
||||
page_size: 100 // 加载足够多的会议数据,确保能筛选出最近3个往届会议
|
||||
})
|
||||
|
||||
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()
|
||||
)
|
||||
|
||||
meetings.value = sortedMeetings
|
||||
currentMeeting.value = sortedMeetings[0] // 最新会议
|
||||
pastMeetings.value = sortedMeetings.slice(1, 4) // 第2-4个会议
|
||||
meetings.value = sortedMeetings // 保存所有会议数据
|
||||
|
||||
// 如果当前没有选中的会议,默认选中最新的会议
|
||||
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) {
|
||||
@@ -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获取演讲嘉宾
|
||||
const fetchSpeakers = async (meetingId: number) => {
|
||||
try {
|
||||
@@ -314,7 +509,8 @@ const fetchSpeakers = async (meetingId: number) => {
|
||||
// 按sort字段排序(升序)
|
||||
speakersList.value = [...response.data.speakers].sort((a, b) => a.sort - b.sort)
|
||||
} else {
|
||||
speakersError.value = '未获取到演讲嘉宾数据'
|
||||
// 接口调用成功但无数据时,不设置错误信息,由空列表状态处理
|
||||
speakersList.value = []
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取演讲嘉宾失败:', err)
|
||||
@@ -357,11 +553,71 @@ const showSpeakerInfo = (speaker: any) => {
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
// 关闭弹窗
|
||||
// 关闭嘉宾详情弹窗
|
||||
const handleClose = () => {
|
||||
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(() => {
|
||||
fetchMeetings()
|
||||
@@ -375,6 +631,151 @@ onMounted(() => {
|
||||
color: #333;
|
||||
line-height: 1.6;
|
||||
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;
|
||||
}
|
||||
|
||||
/* 头部横幅样式 */
|
||||
/* 头部横幅样式 - 设置为屏幕宽度 */
|
||||
.header-banner {
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
@@ -449,6 +850,9 @@ onMounted(() => {
|
||||
min-height: 400px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100vw; /* 设置宽度为视口宽度 */
|
||||
margin-left: calc(-50vw + 50%); /* 使元素居中并充满屏幕宽度 */
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.banner-mask {
|
||||
@@ -457,7 +861,7 @@ onMounted(() => {
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: transparent;
|
||||
background-color: rgba(0, 0, 0, 0.4);
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
@@ -467,6 +871,7 @@ onMounted(() => {
|
||||
padding: 0 20px;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
width: 100%; /* 确保内容区域在横幅内正确显示 */
|
||||
}
|
||||
|
||||
.hdic-logo {
|
||||
@@ -491,18 +896,19 @@ onMounted(() => {
|
||||
gap: 25px;
|
||||
}
|
||||
|
||||
.meta-item {
|
||||
/* 注意:这里只修改会议列表中的创建时间样式,不影响头部横幅的meta样式 */
|
||||
.conference-meta .meta-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.meta-label {
|
||||
.conference-meta .meta-label {
|
||||
font-size: 0.9rem;
|
||||
margin-bottom: 5px;
|
||||
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.8);
|
||||
}
|
||||
|
||||
.meta-value {
|
||||
.conference-meta .meta-value {
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.8);
|
||||
@@ -616,8 +1022,8 @@ onMounted(() => {
|
||||
height: auto;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 10px 30px rgba(0,0,0,0.2);
|
||||
transition: transform 0.3s ease;
|
||||
cursor: pointer;
|
||||
transition: transform 0.3s ease, cursor 0.3s;
|
||||
cursor: zoom-in; /* 显示放大镜图标,提示可点击放大 */
|
||||
}
|
||||
|
||||
.schedule-image:hover {
|
||||
@@ -711,22 +1117,30 @@ onMounted(() => {
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
/* 往届会议卡片样式 - 添加鼠标悬停效果提示可点击 */
|
||||
.review-card {
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
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 {
|
||||
transform: translateY(-5px);
|
||||
box-shadow: 0 10px 30px rgba(0,0,0,0.15); /* 增强阴影效果 */
|
||||
}
|
||||
|
||||
.review-image {
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
object-fit: cover;
|
||||
transition: transform 0.3s;
|
||||
}
|
||||
|
||||
.review-card:hover .review-image {
|
||||
transform: scale(1.05); /* 图片轻微放大效果 */
|
||||
}
|
||||
|
||||
.review-info {
|
||||
@@ -739,24 +1153,25 @@ onMounted(() => {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.review-date {
|
||||
color: #409eff;
|
||||
font-size: 0.9rem;
|
||||
.review-info p {
|
||||
color: #7f8c8d;
|
||||
margin: 0 0 15px;
|
||||
font-style: italic;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.review-desc {
|
||||
color: #666;
|
||||
margin: 0;
|
||||
line-height: 1.6;
|
||||
max-height: 100px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.review-desc p {
|
||||
margin: 0;
|
||||
font-size: 0.95rem;
|
||||
/* 无往届会议提示 */
|
||||
.no-past-meetings {
|
||||
grid-column: 1 / -1;
|
||||
text-align: center;
|
||||
padding: 60px 20px;
|
||||
color: #909399;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
/* 嘉宾详情弹窗样式 */
|
||||
@@ -809,11 +1224,29 @@ onMounted(() => {
|
||||
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) {
|
||||
.speakers-grid {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
.meeting-content {
|
||||
grid-template-columns: 250px 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
@@ -823,6 +1256,12 @@ onMounted(() => {
|
||||
.speakers-grid {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
.meeting-content {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
.meeting-img {
|
||||
height: 300px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
@@ -855,5 +1294,16 @@ onMounted(() => {
|
||||
flex-direction: column;
|
||||
gap: 15px;
|
||||
}
|
||||
.review-content {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
.meeting-header {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 10px;
|
||||
}
|
||||
.meeting-img {
|
||||
height: 200px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user