添加基地概况,科学研究页面

This commit is contained in:
2025-10-24 11:52:18 +08:00
parent 3e023ed937
commit 294c9ccf4c
16 changed files with 1138 additions and 464 deletions

13
web/package-lock.json generated
View File

@@ -4661,10 +4661,11 @@
"dev": true
},
"node_modules/vite": {
"version": "7.1.9",
"resolved": "https://registry.npmmirror.com/vite/-/vite-7.1.9.tgz",
"integrity": "sha512-4nVGliEpxmhCL8DslSAUdxlB6+SMrhB0a1v5ijlh1xB1nEPuy1mxaHxysVucLHuWryAxLWg6a5ei+U4TLn/rFg==",
"version": "7.1.12",
"resolved": "https://registry.npmjs.org/vite/-/vite-7.1.12.tgz",
"integrity": "sha512-ZWyE8YXEXqJrrSLvYgrRP7p62OziLW7xI5HYGWFzOvupfAlrLvURSzv/FyGyy0eidogEM3ujU+kUG1zuHgb6Ug==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"esbuild": "^0.25.0",
@@ -8105,9 +8106,9 @@
"dev": true
},
"vite": {
"version": "7.1.9",
"resolved": "https://registry.npmmirror.com/vite/-/vite-7.1.9.tgz",
"integrity": "sha512-4nVGliEpxmhCL8DslSAUdxlB6+SMrhB0a1v5ijlh1xB1nEPuy1mxaHxysVucLHuWryAxLWg6a5ei+U4TLn/rFg==",
"version": "7.1.12",
"resolved": "https://registry.npmjs.org/vite/-/vite-7.1.12.tgz",
"integrity": "sha512-ZWyE8YXEXqJrrSLvYgrRP7p62OziLW7xI5HYGWFzOvupfAlrLvURSzv/FyGyy0eidogEM3ujU+kUG1zuHgb6Ug==",
"dev": true,
"peer": true,
"requires": {

View File

@@ -1,5 +1,5 @@
<template>
<HomeView></HomeView>
<router-view />
<FooterView></FooterView>
</template>

View File

@@ -1,23 +1,61 @@
import { createRouter, createWebHistory } from 'vue-router'
import { createRouter, createWebHistory , createWebHashHistory} from 'vue-router'
import HomeView from '../views/HomeView.vue'
import AboutView from '@/views/AboutView.vue';
import BaseOverview from '@/views/BaseOverview.vue';
import ScientificResearch from '@/views/ScientificResearch.vue';
import AcademicExchange from '@/views/AcademicExchange.vue';
import SocialService from '@/views/SocialService.vue';
import CaseResources from '@/views/CaseResources.vue';
import HomeContent from '@/views/HomeContent.vue';
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
history: createWebHashHistory(import.meta.env.BASE_URL),
routes: [
{
path: '/',
name: 'home',
component: HomeView,
children: [
{
path: '', // ✅ 默认子路由:访问 / 时显示首页内容
name: 'home-content',
component: HomeContent
},
{
path: 'base-overview',
name: 'BaseOverview',
component: BaseOverview
},
{
path: 'scientific-research',
name: 'ScientificResearch',
component: ScientificResearch
},
{
path: 'academic-exchange',
name: 'AcademicExchange',
component: AcademicExchange
},
{
path: 'social-service',
name: 'SocialService',
component: SocialService
},
{
path: 'case-resources',
name: 'CaseResources',
component: CaseResources
}
]
},
{
path: '/about',
name: 'about',
// route level code-splitting
// this generates a separate chunk (About.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import('../views/AboutView.vue'),
},
],
component: AboutView
}
]
})
export default router

View File

@@ -0,0 +1,5 @@
<template>
<div>
基地概况
</div>
</template>

View File

@@ -0,0 +1,270 @@
<template>
<div class="base-overview-container">
<!-- 页面标题区域 -->
<div class="page-header">
<h1 class="main-title">基地概况</h1>
<p class="english-title">Base Overview</p>
</div>
<!-- 导航标签区域 -->
<el-tabs
v-model="activeTab"
class="content-tabs"
:border="false"
>
<el-tab-pane label="基地简介" name="introduction">
<div class="tab-content">
<div class="content-layout">
<div class="content-left">
<h2 class="section-title">基地简介</h2>
<p class="section-english">Base Introduction</p>
</div>
<div class="content-right">
<div class="text-content">
<p>探索健康设计的新路径引领知识创新的新范式共同描绘人类健康的未来图景探索健康设计的新路径引领知识创新的新范式共同描绘人类健康的未来图景探索健康设计的新路径引领知识创新的新范式共同描绘人类健康的未来图景</p>
<p>探索健康设计的新路径引领知识创新的新范式共同描绘人类健康的未来图景探索健康设计的新路径引领知识创新的新范式共同描绘人类健康的未来图景探索健康设计的新路径引领知识创新的新范式共同描绘人类健康的未来图景</p>
<p>探索健康设计的新路径引领知识创新的新范式共同描绘人类健康的未来图景探索健康设计的新路径引领知识创新的新范式共同描绘人类健康的未来图景探索健康设计的新路径引领知识创新的新范式共同描绘人类健康的未来图景</p>
</div>
</div>
</div>
</div>
</el-tab-pane>
<el-tab-pane label="基地成员" name="members">
<div class="tab-content">
<div class="content-layout">
<div class="content-left">
<h2 class="section-title">基地成员</h2>
<p class="section-english">Members</p>
</div>
<div class="content-right">
<div class="text-content">
<p><strong>主任</strong> 张三</p>
<p><strong>副主任</strong> 李四</p>
<p><strong>研究人员</strong> 王五赵六孙七 等20余人</p>
</div>
</div>
</div>
</div>
</el-tab-pane>
<el-tab-pane label="规章制度" name="regulations">
<div class="tab-content">
<div class="content-layout">
<div class="content-left">
<h2 class="section-title">规章制度</h2>
<p class="section-english">Regulations</p>
</div>
<div class="content-right">
<div class="text-content">
<p><strong>1. 科研项目管理办法</strong>规范中心科研项目的申报立项实施验收等全流程管理确保项目质量和成果产出</p>
<p><strong>2. 学术活动管理规定</strong>鼓励开展高水平学术交流活动提升中心学术影响力和社会知名度</p>
<p><strong>3. 经费使用管理办法</strong>严格规范科研经费的使用确保经费专款专用合理高效</p>
<p><strong>4. 成果管理办法</strong>对科研成果的鉴定登记转化等进行规范管理促进成果应用和社会效益发挥</p>
</div>
</div>
</div>
</div>
</el-tab-pane>
<el-tab-pane label="联系我们" name="contact">
<div class="tab-content">
<div class="content-layout">
<div class="content-left">
<h2 class="section-title">联系我们</h2>
<p class="section-english">Contact Us</p>
</div>
<div class="content-right">
<div class="text-content">
<p><strong>地址</strong> 湖北省武汉市江夏区阳光大道1号 武汉纺织大学 设计学院</p>
<p><strong>邮编</strong> 430200</p>
<p><strong>电话</strong> 027-87186XXX</p>
<p><strong>邮箱</strong> hldrcenter@wtu.edu.cn</p>
<p><strong>网站</strong> <a href="http://www.wtu.edu.cn/hldrcenter" target="_blank">http://www.wtu.edu.cn/hldrcenter</a></p>
</div>
</div>
</div>
</div>
</el-tab-pane>
</el-tabs>
<!-- 底部二维码区域 -->
<div class="qrcode-container">
<div class="qrcode-item">
<img src="https://picsum.photos/100/100?random=1" alt="微信公众号" class="qrcode-img">
</div>
<div class="qrcode-item">
<img src="https://picsum.photos/100/100?random=2" alt="官方网站" class="qrcode-img">
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { ElTabs, ElTabPane } from 'element-plus';
// 控制当前激活的标签页,默认显示基地简介
const activeTab = ref('introduction');
</script>
<style scoped>
.base-overview-container {
max-width: 1200px;
margin: 0 auto;
padding: 40px 20px;
box-sizing: border-box;
}
/* 页面标题样式 */
.page-header {
margin-bottom: 40px;
padding-bottom: 15px;
border-bottom: 1px solid #e0e0e0;
}
.main-title {
font-size: 28px;
color: #333;
margin: 0 0 8px 0;
font-weight: 500;
}
.english-title {
font-size: 16px;
color: #999;
margin: 0;
text-transform: uppercase;
letter-spacing: 0.5px;
}
/* 标签页样式 */
.content-tabs {
margin-bottom: 40px;
border-bottom: 1px solid #e0e0e0;
}
:deep(.el-tabs__nav) {
margin: 0 auto;
display: flex;
justify-content: center;
}
:deep(.el-tabs__item) {
font-size: 16px;
color: #666;
padding: 0 20px;
margin-right: 10px;
}
:deep(.el-tabs__item.is-active) {
color: #b50009;
font-weight: 500;
}
:deep(.el-tabs__active-bar) {
background-color: #b50009;
}
/* 内容区域样式 */
.tab-content {
padding: 30px 0;
}
/* 左侧标题 + 右侧内容的布局 */
.content-layout {
display: grid;
grid-template-columns: 280px 1fr; /* 左侧固定宽度,右侧自适应 */
gap: 30px;
align-items: start;
}
.content-left {
padding-right: 20px;
border-right: 1px solid #e0e0e0;
}
.section-title {
font-size: 24px;
color: #333;
margin: 0 0 10px 0;
font-weight: 500;
}
.section-english {
font-size: 16px;
color: #999;
margin: 0 0 20px 0;
text-transform: uppercase;
}
.text-content {
line-height: 1.8;
color: #555;
font-size: 16px;
}
.text-content p {
margin: 0 0 20px 0;
text-align: justify;
}
.text-content a {
color: #b50009;
text-decoration: none;
}
.text-content a:hover {
text-decoration: underline;
}
/* 底部二维码区域 - 靠右对齐 */
.qrcode-container {
display: flex;
justify-content: flex-end; /* 靠右显示 */
gap: 30px;
margin-top: 50px;
padding-top: 20px;
border-top: 1px solid #e0e0e0;
}
.qrcode-item {
width: 100px;
height: 100px;
}
.qrcode-img {
width: 100%;
height: 100%;
object-fit: cover;
border: 1px solid #eee;
padding: 4px;
}
/* 响应式调整 */
@media (max-width: 768px) {
.content-layout {
grid-template-columns: 1fr; /* 移动端单列布局 */
}
.content-left {
border-right: none;
border-bottom: 1px solid #e0e0e0;
padding-bottom: 15px;
margin-bottom: 20px;
}
.qrcode-container {
justify-content: center; /* 移动端居中显示二维码 */
}
.main-title {
font-size: 24px;
}
.text-content {
font-size: 14px;
}
}
</style>

View File

@@ -0,0 +1,5 @@
<template>
<div>
基地概况
</div>
</template>

View File

@@ -0,0 +1,328 @@
<template>
<div class="home-content">
<!-- 轮播图 -->
<el-carousel
class="carousel-container"
height="400px"
autoplay
arrow="always"
>
<el-carousel-item>
<div class="carousel-item">
<img src="https://picsum.photos/1920/400?random=1" alt="健康生活研究" class="carousel-img">
<div class="carousel-caption">
<h3>健康生活环境设计研究成果展</h3>
<p>探索健康设计新路径引领人居环境创新</p>
</div>
</div>
</el-carousel-item>
<el-carousel-item>
<div class="carousel-item">
<img src="https://picsum.photos/1920/400?random=2" alt="学术研讨会" class="carousel-img">
<div class="carousel-caption">
<h3>2025健康设计国际学术研讨会</h3>
<p>汇聚全球专家智慧共话健康人居未来</p>
</div>
</div>
</el-carousel-item>
<el-carousel-item>
<div class="carousel-item">
<img src="https://picsum.photos/1920/400?random=3" alt="社区服务案例" class="carousel-img">
<div class="carousel-caption">
<h3>社区健康服务创新实践</h3>
<p>以设计赋能社区提升居民生活品质</p>
</div>
</div>
</el-carousel-item>
</el-carousel>
<!-- 新闻动态 -->
<div class="news-section">
<div class="section-header">
<h2>新闻动态 <span class="en-title">News</span></h2>
<el-link class="more-btn" :to="{ path: '/news-more' }">More</el-link>
</div>
<div class="news-cards">
<el-card
class="news-card"
v-for="(news, index) in newsList"
:key="index"
shadow="hover"
:body-style="{ padding: '0px' }"
>
<img :src="news.imageUrl" alt="新闻图片" class="card-img">
<div class="card-content">
<h3 class="card-title">{{ news.title }}</h3>
<p class="card-desc">{{ news.desc }}</p>
<el-button type="text" class="detail-btn">
<el-icon><ArrowRight /></el-icon> 详情
</el-button>
</div>
</el-card>
</div>
</div>
<!-- 案例资源 -->
<div class="news-section">
<div class="section-header">
<h2>案例资源 <span class="en-title">Resource</span></h2>
<el-link class="more-btn" :to="{ path: '/resource-more' }">More</el-link>
</div>
<div class="news-cards">
<el-card
class="news-card"
v-for="(resource, index) in resourceList"
:key="index"
shadow="hover"
:body-style="{ padding: '0px' }"
>
<img :src="resource.imageUrl" alt="案例资源图片" class="card-img">
<div class="card-content">
<h3 class="card-title">{{ resource.title }}</h3>
<p class="card-desc">{{ resource.desc }}</p>
<el-button type="text" class="detail-btn">
<el-icon><ArrowRight /></el-icon> 详情
</el-button>
</div>
</el-card>
</div>
</div>
<!-- 社区服务 -->
<div class="news-section">
<div class="section-header">
<h2>社区服务 <span class="en-title">Community</span></h2>
<el-link class="more-btn" :to="{ path: '/community-more' }">More</el-link>
</div>
<div class="news-cards">
<el-card
class="news-card"
v-for="(service, index) in communityList"
:key="index"
shadow="hover"
:body-style="{ padding: '0px' }"
>
<img :src="service.imageUrl" alt="社区服务图片" class="card-img">
<div class="card-content">
<h3 class="card-title">{{ service.title }}</h3>
<p class="card-desc">{{ service.desc }}</p>
<el-button type="text" class="detail-btn">
<el-icon><ArrowRight /></el-icon> 详情
</el-button>
</div>
</el-card>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted } from 'vue';
import { ElCarousel, ElCarouselItem, ElLink, ElCard, ElButton, ElIcon } from 'element-plus';
import { ArrowRight } from '@element-plus/icons-vue';
// 数据结构
interface NewsItem {
imageUrl: string;
title: string;
desc: string;
}
interface Article {
id: number;
title: string;
cover: string;
excerpt: string;
}
// 响应式数据
const newsList = ref<NewsItem[]>([]);
const resourceList = ref<NewsItem[]>([]);
const communityList = ref<NewsItem[]>([]);
// HTML转纯文本工具函数
function stripHtml(htmlStr: string): string {
if (!htmlStr) return '';
const doc = new DOMParser().parseFromString(htmlStr, 'text/html');
return doc.body.textContent || "";
}
// 通用请求函数
const fetchArticlesByTopic = async (topic: string): Promise<NewsItem[]> => {
try {
const response = await fetch('http://localhost:8080/api/articles/getarticle', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ page: 1, size: 3, topic })
});
if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
const data = await response.json();
if (data && Array.isArray(data.Article_list)) {
return data.Article_list.map((article: Article) => {
const plainTextDesc = stripHtml(article.excerpt);
const truncatedDesc = plainTextDesc.length > 100 ? `${plainTextDesc.substring(0, 100)}...` : plainTextDesc;
return {
imageUrl: article.cover,
title: article.title,
desc: truncatedDesc,
};
});
}
return [];
} catch (error) {
console.error(`Failed to fetch ${topic}:`, error);
return [];
}
};
// 挂载时请求数据
onMounted(async () => {
const [newsData, resourceData, communityData] = await Promise.all([
fetchArticlesByTopic('新闻'),
fetchArticlesByTopic('案例资源'),
fetchArticlesByTopic('社区服务')
]);
newsList.value = newsData;
resourceList.value = resourceData;
communityList.value = communityData;
});
</script>
<style scoped>
/* 轮播图样式 */
.carousel-container {
width: 100%;
overflow: hidden;
}
.carousel-item {
position: relative;
width: 100%;
height: 100%;
}
.carousel-img {
width: 100%;
height: 100%;
object-fit: cover;
}
.carousel-caption {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
text-align: center;
color: #fff;
text-shadow: 0 2px 4px rgba(0,0,0,0.7);
width: 80%;
}
.carousel-caption h3 {
font-size: 32px;
margin-bottom: 15px;
font-weight: 500;
}
.carousel-caption p {
font-size: 18px;
}
/* 新闻列表样式 */
.news-section {
max-width: 1200px;
margin: 50px auto;
padding: 0 20px;
}
.section-header {
display: flex;
justify-content: space-between;
align-items: flex-end;
margin-bottom: 30px;
border-bottom: 1px solid #e0e0e0;
padding-bottom: 10px;
}
.section-header h2 {
font-size: 26px;
margin: 0;
font-weight: 400;
}
.en-title {
font-size: 16px;
color: #999;
margin-left: 10px;
text-transform: uppercase;
}
.more-btn {
color: #999;
font-size: 14px;
}
.more-btn:hover {
color: #b50009;
}
/* 卡片样式 */
.news-cards {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 25px;
}
.news-card {
border: 1px solid #e0e0e0;
transition: all 0.3s ease;
display: flex;
flex-direction: column;
}
.news-card:hover {
transform: translateY(-5px);
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
}
.card-img {
width: 100%;
height: 200px;
object-fit: cover;
display: block;
}
.card-content {
padding: 20px;
display: flex;
flex-direction: column;
flex-grow: 1;
}
.card-title {
font-size: 18px;
margin: 0 0 10px 0;
font-weight: 500;
color: #333;
}
.card-desc {
font-size: 14px;
color: #666;
line-height: 1.7;
flex-grow: 1;
margin-bottom: 15px;
}
.detail-btn {
color: #b50009 !important;
display: flex;
align-items: center;
gap: 5px;
padding: 0 !important;
align-self: flex-start;
}
/* 响应式调整 */
@media (max-width: 992px) {
.news-cards {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 768px) {
.carousel-caption h3 {
font-size: 20px;
}
.carousel-caption p {
font-size: 14px;
}
.news-cards {
grid-template-columns: 1fr;
}
}
</style>

View File

@@ -1,5 +1,5 @@
<template>
<div class="header-with-carousel">
<div class="home-view">
<header class="top-navigation">
<div class="nav-left">
<div class="nav-title">湖北健康生活与康居环境设计研究中心</div>
@@ -13,476 +13,61 @@
active-text-color="#ffd700"
:default-active="activeIndex"
@select="handleSelect"
router
>
<el-menu-item index="1">首页</el-menu-item>
<el-menu-item index="2">基地概况</el-menu-item>
<el-menu-item index="3">科学研究</el-menu-item>
<el-menu-item index="4">学术交流</el-menu-item>
<el-menu-item index="5">社会服务</el-menu-item>
<el-menu-item index="6">案例资源</el-menu-item>
<el-menu-item index="/">首页</el-menu-item>
<el-menu-item index="/base-overview">基地概况</el-menu-item>
<el-menu-item index="/scientific-research">科学研究</el-menu-item>
<el-menu-item index="/academic-exchange">学术交流</el-menu-item>
<el-menu-item index="/social-service">社会服务</el-menu-item>
<el-menu-item index="/case-resources">案例资源</el-menu-item>
<el-menu-item index="/about">关于我们</el-menu-item>
</el-menu>
</header>
<el-carousel
class="carousel-container"
height="400px"
autoplay
arrow="always"
>
<el-carousel-item>
<div class="carousel-item">
<img
src="https://picsum.photos/1920/400?random=1"
alt="健康生活研究"
class="carousel-img"
>
<div class="carousel-caption">
<h3>健康生活环境设计研究成果展</h3>
<p>探索健康设计新路径引领人居环境创新</p>
</div>
</div>
</el-carousel-item>
<el-carousel-item>
<div class="carousel-item">
<img
src="https://picsum.photos/1920/400?random=2"
alt="学术研讨会"
class="carousel-img"
>
<div class="carousel-caption">
<h3>2025健康设计国际学术研讨会</h3>
<p>汇聚全球专家智慧共话健康人居未来</p>
</div>
</div>
</el-carousel-item>
<el-carousel-item>
<div class="carousel-item">
<img
src="https://picsum.photos/1920/400?random=3"
alt="社区服务案例"
class="carousel-img"
>
<div class="carousel-caption">
<h3>社区健康服务创新实践</h3>
<p>以设计赋能社区提升居民生活品质</p>
</div>
</div>
</el-carousel-item>
</el-carousel>
</div>
<div class="news-section">
<div class="section-header">
<h2>新闻动态 <span class="en-title">News</span></h2>
<el-link class="more-btn">More</el-link>
</div>
<div class="news-cards">
<el-card
class="news-card"
v-for="(news, index) in newsList"
:key="index"
shadow="hover"
:body-style="{ padding: '0px' }"
>
<img :src="news.imageUrl" alt="新闻图片" class="card-img">
<div class="card-content">
<h3 class="card-title">{{ news.title }}</h3>
<p class="card-desc">{{ news.desc }}</p>
<el-button type="text" class="detail-btn">
<el-icon><ArrowRight /></el-icon> 详情
</el-button>
</div>
</el-card>
</div>
</div>
<div class="news-section">
<div class="section-header">
<h2>案例资源 <span class="en-title">Resource</span></h2>
<el-link class="more-btn">More</el-link>
</div>
<div class="news-cards">
<el-card
class="news-card"
v-for="(resource, index) in resourceList"
:key="index"
shadow="hover"
:body-style="{ padding: '0px' }"
>
<img :src="resource.imageUrl" alt="案例资源图片" class="card-img">
<div class="card-content">
<h3 class="card-title">{{ resource.title }}</h3>
<p class="card-desc">{{ resource.desc }}</p>
<el-button type="text" class="detail-btn">
<el-icon><ArrowRight /></el-icon> 详情
</el-button>
</div>
</el-card>
</div>
</div>
<div class="news-section">
<div class="section-header">
<h2>社区服务 <span class="en-title">Community</span></h2>
<el-link class="more-btn">More</el-link>
</div>
<div class="news-cards">
<el-card
class="news-card"
v-for="(service, index) in communityList"
:key="index"
shadow="hover"
:body-style="{ padding: '0px' }"
>
<img :src="service.imageUrl" alt="社区服务图片" class="card-img">
<div class="card-content">
<h3 class="card-title">{{ service.title }}</h3>
<p class="card-desc">{{ service.desc }}</p>
<el-button type="text" class="detail-btn">
<el-icon><ArrowRight /></el-icon> 详情
</el-button>
</div>
</el-card>
</div>
<router-view />
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted } from 'vue';
import {
ElMenu,
ElMenuItem,
ElCarousel,
ElCarouselItem,
ElLink,
ElCard,
ElButton,
ElIcon
} from 'element-plus';
import { ArrowRight } from '@element-plus/icons-vue';
import { ref, watch } from 'vue';
import { useRoute } from 'vue-router';
import { ElMenu, ElMenuItem } from 'element-plus';
const route = useRoute();
const activeIndex = ref('/');
// 导航菜单激活项
const activeIndex = ref('1');
const handleSelect = (index: string) => {
activeIndex.value = index;
};
// --- Data Structures ---
interface NewsItem {
imageUrl: string;
title: string;
desc: string;
}
interface Article {
id: number;
title: string;
cover: string;
excerpt: string;
}
// **修改点1: 为每个版块创建独立的响应式数组**
const newsList = ref<NewsItem[]>([]);
const resourceList = ref<NewsItem[]>([]);
const communityList = ref<NewsItem[]>([]);
// --- Utility Function ---
/**
* @description 将HTML字符串转换为纯文本
* @param htmlStr HTML字符串
* @returns 纯文本字符串
*/
function stripHtml(htmlStr: string): string {
if (!htmlStr) return '';
const doc = new DOMParser().parseFromString(htmlStr, 'text/html');
return doc.body.textContent || "";
}
// **修改点2: 创建一个通用的、可复用的 fetch 函数**
/**
* @description 根据主题从后端获取文章列表
* @param topic 文章主题 (e.g., "新闻", "案例资源")
* @returns 处理过的文章列表
*/
const fetchArticlesByTopic = async (topic: string): Promise<NewsItem[]> => {
try {
const response = await fetch('http://8.155.160.224:8080/api/articles/getarticle', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
page: 1,
size: 3, // 只请求需要的前3条数据
topic: topic
})
});
if (!response.ok) {
throw new Error(`HTTP error for topic ${topic}! status: ${response.status}`);
}
const data = await response.json();
if (data && Array.isArray(data.Article_list)) {
const articles: Article[] = data.Article_list;
return articles.map(article => {
const plainTextDesc = stripHtml(article.excerpt);
const truncatedDesc = plainTextDesc.length > 100
? plainTextDesc.substring(0, 100) + '...'
: plainTextDesc;
return {
imageUrl: article.cover,
title: article.title,
desc: truncatedDesc,
};
});
} else {
console.error(`API response for topic ${topic} is not in the expected format:`, data);
return []; // 返回空数组以防错误
}
} catch (error) {
console.error(`Failed to fetch articles for topic ${topic}:`, error);
return []; // 发生错误时返回空数组
}
};
// **修改点3: 在组件挂载时,并行获取所有版块的数据**
onMounted(async () => {
// 使用 Promise.all 来同时触发所有API请求提高加载效率
const [newsData, resourceData, communityData] = await Promise.all([
fetchArticlesByTopic('新闻'),
fetchArticlesByTopic('案例资源'),
fetchArticlesByTopic('社区服务')
]);
// 将获取到的数据赋值给对应的列表
newsList.value = newsData;
resourceList.value = resourceData;
communityList.value = communityData;
});
watch(
() => route.path,
(newPath) => {
activeIndex.value = newPath;
},
{ immediate: true }
);
</script>
<style scoped>
.header-with-carousel {
width: 100%;
}
/* 顶部导航样式 */
<style scoped>
.top-navigation {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 50px; /* 增加左右边距 */
padding: 10px 50px;
color: #fff;
background-color: #b50009;
width: 100%;
box-sizing: border-box;
}
.nav-left {
display: flex;
flex-direction: column;
line-height: 1.4;
}
.nav-title {
font-size: 18px; /* 稍大一些 */
font-weight: bold;
}
.nav-subtitle {
font-size: 12px; /* 稍小一些,形成对比 */
opacity: 0.9;
}
.nav-right {
display: flex;
align-items: center;
}
/* ⭐️ 移除 el-menu 组件自带的边框 */
.el-menu--horizontal {
border-bottom: none;
}
/* 上面这行代码有时可能因为scoped的限制而不生效
因此更推荐、更可靠的方式是使用 :deep()
*/
:deep(.el-menu--horizontal) {
border-bottom: none !important;
}
.el-menu-item {
padding: 0 20px !important; /* 增加菜单项间距 */
font-size: 16px;
}
/* 轮播图样式 */
.carousel-container {
width: 100%;
overflow: hidden;
}
.carousel-item {
position: relative;
width: 100%;
height: 100%;
}
.carousel-img {
width: 100%;
height: 100%;
object-fit: cover; /* 保持图片比例并填充容器 */
}
.carousel-caption {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
text-align: center;
color: #fff;
text-shadow: 0 2px 4px rgba(0,0,0,0.7); /* 加深阴影 */
width: 80%;
}
.carousel-caption h3 {
font-size: 32px; /* 加大标题字号 */
margin-bottom: 15px;
font-weight: 500;
}
.carousel-caption p {
font-size: 18px;
}
/* --- 新闻动态部分 --- */
.news-section {
max-width: 1200px; /* 内容居中,限制最大宽度 */
margin: 50px auto; /* 增加上下外边距 */
padding: 0 20px;
}
/* 标题栏 */
.section-header {
display: flex;
justify-content: space-between;
align-items: flex-end;
margin-bottom: 30px; /* 增加标题和内容间距 */
border-bottom: 1px solid #e0e0e0;
padding-bottom: 10px;
}
.section-header h2 {
font-size: 26px; /* 加大标题字号 */
margin: 0;
font-weight: 400;
}
.en-title {
font-size: 16px;
color: #999;
margin-left: 10px;
text-transform: uppercase; /* 英文大写 */
}
.more-btn {
color: #999;
font-size: 14px;
}
.more-btn:hover {
color: #b50009;
}
/* 新闻卡片列表 */
.news-cards {
display: grid; /* 使用 Grid 布局,更灵活 */
grid-template-columns: repeat(3, 1fr);
gap: 25px; /* 卡片之间的间距 */
}
.news-card {
border: 1px solid #e0e0e0; /* 添加一个细微的边框 */
transition: all 0.3s ease;
display: flex;
flex-direction: column;
}
.news-card:hover {
transform: translateY(-5px);
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
}
.card-img {
width: 100%;
height: 200px;
object-fit: cover;
display: block;
}
.card-content {
padding: 20px;
display: flex;
flex-direction: column;
flex-grow: 1; /* 让内容区域填满卡片剩余空间 */
}
.card-title {
font-size: 18px;
margin: 0 0 10px 0;
font-weight: 500;
color: #333;
}
.card-desc {
font-size: 14px;
color: #666;
line-height: 1.7;
flex-grow: 1; /* 让描述文本占满,将按钮推到底部 */
margin-bottom: 15px;
}
.detail-btn {
color: #b50009 !important; /* 按钮文字为红色主色调 */
display: flex;
align-items: center;
gap: 5px; /* 图标与文字间距 */
padding: 0 !important; /* 去除按钮默认 padding */
align-self: flex-start; /* 让按钮在左侧 */
}
/* --- 响应式调整 --- */
@media (max-width: 992px) {
.news-cards {
grid-template-columns: repeat(2, 1fr); /* 平板:一行两个 */
}
}
.nav-left { display: flex; flex-direction: column; line-height: 1.4; }
.nav-title { font-size: 18px; font-weight: bold; }
.nav-subtitle { font-size: 12px; opacity: 0.9; }
.nav-right { display: flex; align-items: center; }
:deep(.el-menu--horizontal) { border-bottom: none !important; }
.el-menu-item { padding: 0 20px !important; font-size: 16px; }
@media (max-width: 768px) {
.top-navigation {
flex-direction: column;
padding: 15px;
}
.nav-left {
margin-bottom: 15px;
text-align: center;
}
.carousel-caption h3 {
font-size: 20px;
}
.carousel-caption p {
font-size: 14px;
}
.news-cards {
grid-template-columns: 1fr; /* 手机:一行一个 */
}
.top-navigation { flex-direction: column; padding: 15px; }
.nav-left { margin-bottom: 15px; text-align: center; }
}
</style>
</style>

View File

@@ -0,0 +1,5 @@
<template>
<div>
基地概况
</div>
</template>

View File

@@ -0,0 +1,164 @@
<template>
<div class="scientific-research-page">
<!-- 页面标题区域 -->
<div class="page-header">
<h1 class="main-title">科学研究</h1>
<p class="english-title">Base Overview</p>
</div>
<!-- 导航标签区域 -->
<div class="nav-tabs">
<el-tabs v-model="activeTab" class="tabs-container">
<el-tab-pane label="科学研究" name="research"></el-tab-pane>
<el-tab-pane label="基地开放项目管理制度" name="management"></el-tab-pane>
<el-tab-pane label="基地开放项目立项结果" name="approval"></el-tab-pane>
<el-tab-pane label="基地开放项目中期检查" name="midterm"></el-tab-pane>
<el-tab-pane label="基地开放项目成果" name="results"></el-tab-pane>
</el-tabs>
</div>
<!-- 内容区域 -->
<div class="content-area">
<div class="content-title">
<h2 class="chinese-title">基地开放项目管理制度</h2>
<p class="english-subtitle">Base Open Project Management System</p>
</div>
<div class="content-text">
<p>探索健康设计的新路径引领知识创新的新范式共同描绘人类健康的未来图景探索健康设计的新路径引领知识创新的新范式共同描绘人类健康的未来图景探索健康设计的新路径引领知识创新的新范式共同描绘人类健康的未来图景</p>
<p>探索健康设计的新路径引领知识创新的新范式共同描绘人类健康的未来图景探索健康设计的新路径引领知识创新的新范式共同描绘人类健康的未来图景探索健康设计的新路径引领知识创新的新范式共同描绘人类健康的未来图景</p>
<p>探索健康设计的新路径引领知识创新的新范式共同描绘人类健康的未来图景探索健康设计的新路径引领知识创新的新范式共同描绘人类健康的未来图景探索健康设计的新路径引领知识创新的新范式共同描绘人类健康的未来图景探索健康设计的新路径引领知识创新的新范式共同描绘人类健康的未来图景</p>
<p>探索健康设计的新路径引领知识创新的新范式共同描绘人类健康的未来图景探索健康设计的新路径引领知识创新的新范式共同描绘人类健康的未来图景探索健康设计的新路径引领知识创新的新范式共同描绘人类健康的未来图景</p>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { ElTabs, ElTabPane } from 'element-plus';
// 控制当前激活的标签页
const activeTab = ref('management');
</script>
<style scoped>
.scientific-research-page {
max-width: 1200px;
margin: 0 auto;
padding: 40px 20px;
box-sizing: border-box;
}
/* 页面标题样式 */
.page-header {
background-color: #f5f5f5;
padding: 60px 40px;
margin-bottom: 30px;
text-align: left;
}
.main-title {
font-size: 36px;
color: #333;
margin: 0 0 10px 0;
font-weight: 500;
}
.english-title {
font-size: 18px;
color: #666;
margin: 0;
text-transform: uppercase;
letter-spacing: 1px;
}
/* 导航标签样式 */
.nav-tabs {
border-bottom: 1px solid #e0e0e0;
margin-bottom: 40px;
}
:deep(.el-tabs__nav) {
display: flex;
justify-content: flex-start;
}
:deep(.el-tabs__item) {
font-size: 16px;
color: #666;
padding: 0 20px;
margin-right: 10px;
height: 50px;
line-height: 50px;
}
:deep(.el-tabs__item.is-active) {
color: #333;
font-weight: 500;
}
:deep(.el-tabs__active-bar) {
background-color: #333;
height: 2px;
}
/* 内容区域样式 */
.content-area {
padding: 0 10px;
}
.content-title {
margin-bottom: 30px;
padding-bottom: 15px;
border-bottom: 1px solid #e0e0e0;
}
.chinese-title {
font-size: 24px;
color: #333;
margin: 0 0 10px 0;
font-weight: 500;
}
.english-subtitle {
font-size: 16px;
color: #999;
margin: 0;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.content-text {
line-height: 1.8;
color: #555;
font-size: 16px;
column-count: 2; /* 双列布局 */
column-gap: 40px;
}
.content-text p {
margin: 0 0 20px 0;
text-align: justify;
}
/* 响应式调整 */
@media (max-width: 768px) {
.page-header {
padding: 40px 20px;
}
.main-title {
font-size: 28px;
}
.content-text {
column-count: 1; /* 移动端单列显示 */
}
:deep(.el-tabs__item) {
font-size: 14px;
padding: 0 10px;
}
}
</style>

View File

@@ -0,0 +1,5 @@
<template>
<div>
基地概况
</div>
</template>