Files
jczxw-pc/app/pages/index.vue
2026-04-29 10:05:55 +08:00

905 lines
21 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>
<div class="home-page">
<PortalHeader />
<main class="container page-main">
<section class="headline-grid">
<div class="headline-left">
<NuxtLink to="/article/1" class="headline-image-card">
<img src="/images/video-poster.jpg" alt="中心赴南宁宁宁区调研" />
<div class="headline-image-title">经桂通平台推广应用培训会在南宁召开</div>
<div class="headline-image-date">2026-03-09</div>
</NuxtLink>
</div>
<div class="headline-center">
<NuxtLink to="/article/2" class="feature-title">
中心赴南宁市邕宁区调研县域数字经济发展情况
</NuxtLink>
<NuxtLink to="/article/2" class="feature-image-wrap">
<img src="/images/video-poster.jpg" alt="调研现场" />
</NuxtLink>
</div>
<div class="headline-right">
<div class="subnav-strip" :style="{ backgroundImage: `url(${subnavStripImage})` }">
<span>党中央国务院信息</span>
<span>自治区党委政府</span>
<span>其他厅厅委信息</span>
</div>
<div class="news-links">
<NuxtLink v-for="item in heroNews" :key="item.id" :to="getArticleLink(item.id)">{{ item.title }}</NuxtLink>
</div>
</div>
</section>
<section class="ad-banner scenic" />
<section class="section-block">
<div class="section-heading image-heading">
<img :src="promoBannerImage" alt="决策咨询" />
</div>
<div class="article-columns two">
<div class="article-panel" v-for="group in consultingGroups" :key="group.title">
<div class="panel-heading">
<span>{{ group.title }}</span>
<NuxtLink :to="group.more">更多&gt;&gt;</NuxtLink>
</div>
<div class="article-list">
<NuxtLink v-for="item in group.items" :key="item.id || item.title" :to="item.id ? getArticleLink(item.id) : group.more" class="article-row">
<div class="article-text">
<h3>{{ item.title }}</h3>
<p>{{ item.summary }}</p>
<span>{{ item.date }}</span>
</div>
<img src="/images/video-poster.jpg" alt="文章配图" />
</NuxtLink>
</div>
</div>
</div>
</section>
<section class="ad-banner blue">
<div>广告位</div>
</section>
<section class="section-block">
<div class="article-columns two">
<div class="article-panel" v-for="group in referenceGroups" :key="group.title">
<div class="panel-heading">
<span>{{ group.title }}</span>
<NuxtLink :to="group.more">更多&gt;&gt;</NuxtLink>
</div>
<div class="article-list">
<NuxtLink v-for="item in group.items" :key="item.id || item.title" :to="item.id ? getArticleLink(item.id) : group.more" class="article-row">
<div class="article-text">
<h3>{{ item.title }}</h3>
<p>{{ item.summary }}</p>
<span>{{ item.date }}</span>
</div>
<img src="/images/video-poster.jpg" alt="文章配图" />
</NuxtLink>
</div>
</div>
</div>
</section>
<section class="experts-section">
<div class="section-heading experts-heading" :style="{ backgroundImage: `url(${expertSectionBgImage})` }">
<img class="experts-heading-title" :src="expertSectionTitleImage" alt="专家资讯" />
</div>
<div class="experts-tabs">
<div class="experts-tabs-left">
<button
type="button"
class="experts-tab-btn"
:class="{ active: activeExpertTab === 'viewpoint' }"
@click="activeExpertTab = 'viewpoint'"
>
专家试点
</button>
<button
type="button"
class="experts-tab-btn"
:class="{ active: activeExpertTab === 'dynamic' }"
@click="activeExpertTab = 'dynamic'"
>
专家动态
</button>
</div>
<NuxtLink to="/expert/apply" class="expert-apply-btn">
<img :src="expertApplyImage" alt="专家申请" />
</NuxtLink>
</div>
<div class="experts-grid">
<NuxtLink v-for="item in filteredExpertCards" :key="item.id" :to="getArticleLink(item.id)" class="expert-card">
<img :src="item.image" :alt="item.title" />
<div class="expert-card-body">
<h3>{{ item.title }}</h3>
<p>{{ item.date }}</p>
</div>
</NuxtLink>
</div>
</section>
<section class="ad-banner image-banner">
<img :src="promoBannerImage" alt="单位企业广告" />
</section>
<section class="section-block">
<div class="article-columns two">
<div class="article-panel" v-for="group in thinkTankGroups" :key="group.title">
<div class="panel-heading">
<span>{{ group.title }}</span>
<NuxtLink :to="group.more">更多&gt;&gt;</NuxtLink>
</div>
<div class="article-list" :class="{ 'logo-list-wrap': group.type === 'logos' }">
<template v-if="group.type === 'logos'">
<NuxtLink
v-for="item in group.items"
:key="item.title"
:to="group.more"
class="logo-card"
>
<div class="logo-circle">LOGO</div>
<span>{{ item.title }}</span>
</NuxtLink>
</template>
<template v-else>
<NuxtLink v-for="item in group.items" :key="item.id || item.title" :to="item.id ? getArticleLink(item.id) : group.more" class="article-row">
<div class="article-text">
<h3>{{ item.title }}</h3>
<p>{{ item.summary }}</p>
<span>{{ item.date }}</span>
</div>
<img src="/images/video-poster.jpg" alt="文章配图" />
</NuxtLink>
</template>
</div>
</div>
</div>
</section>
<section class="action-grid">
<NuxtLink v-for="item in actionLinks" :key="item.title" :to="item.to" class="action-card" :class="item.theme">
<span class="action-icon">{{ item.icon }}</span>
<span>{{ item.title }}</span>
</NuxtLink>
</section>
</main>
<footer class="site-footer">
<div class="footer-nav">
<div class="container footer-nav-inner">
<NuxtLink to="/about">友情链接</NuxtLink>
<NuxtLink to="/consultation">咨询服务</NuxtLink>
<NuxtLink to="/reference">决策成果研究文库</NuxtLink>
<NuxtLink to="/expert">政府智库学者库</NuxtLink>
</div>
</div>
<PortalFooter />
</footer>
</div>
</template>
<script setup lang="ts">
import { usePageSeo } from '@/composables/usePageSeo'
definePageMeta({
layout: 'blank'
})
usePageSeo({
title: '首页',
description: '广西决策咨询网首页'
})
const promoBannerImage = '/images/%E6%88%AA%E5%B1%8F2026-04-28%2021.38.43.png'
const subnavStripImage = '/images/%E5%9B%BE%E5%B1%82%2050.png'
const expertSectionTitleImage = '/images/zjzx.png'
const expertSectionBgImage = '/images/zjzxBg.png'
const expertApplyImage = '/images/zjsq.png'
type TextItem = {
id?: number
title: string
summary: string
date: string
}
type Group = {
title: string
more: string
items: TextItem[]
type?: 'logos'
}
const heroNews = [
{ id: 3, title: '数字广西建设“十五五”规划编制工作座谈会在南宁召开' },
{ id: 4, title: '广西发布县域数字经济试点“成绩单”,桂北七城重点突破' },
{ id: 5, title: '中国一东盟人工智能创新合作加快构建' },
{ id: 6, title: '“桂链”平台入选国家数据局数据基础设施试点典型案例' }
]
const createItems = (prefix: string, startId: number): TextItem[] => ([
{ id: startId, title: `${prefix}标题案例一`, summary: '标题案例标题案例标题案例标题案例标题案例标题案例...', date: '2026-03-19' },
{ id: startId + 1, title: `${prefix}标题案例二`, summary: '标题案例标题案例标题案例标题案例标题案例标题案例...', date: '2026-03-19' },
{ id: startId + 2, title: `${prefix}标题案例三`, summary: '标题案例标题案例标题案例标题案例标题案例标题案例...', date: '2026-03-19' }
])
function getArticleLink(id: number) {
return `/article/${id}`
}
const consultingGroups: Group[] = [
{ title: '市县决策', more: '/consultation?type=city', items: createItems('市县决策', 101) },
{ title: '前沿观察', more: '/consultation?type=frontier', items: createItems('前沿观察', 111) },
{ title: '行业资讯', more: '/consultation?type=industry', items: createItems('行业资讯', 121) },
{ title: '企业动态', more: '/consultation?type=enterprise', items: createItems('企业动态', 131) }
]
const referenceGroups: Group[] = [
{ title: '政策原文', more: '/reference?type=policy', items: createItems('政策原文', 201) },
{ title: '东盟研究', more: '/reference?type=asean', items: createItems('东盟研究', 211) },
{ title: '翰墨文谈', more: '/hanmo', items: createItems('翰墨文谈', 221) },
{ title: '会员单位', more: '/membership', items: [
{ title: '华东科技', summary: '', date: '' },
{ title: '华西科技', summary: '', date: '' },
{ title: '华南科技', summary: '', date: '' },
{ title: '华北科技', summary: '', date: '' },
{ title: '华中科技', summary: '', date: '' },
{ title: '华海科技', summary: '', date: '' },
{ title: '华广科技', summary: '', date: '' },
{ title: '华创科技', summary: '', date: '' }
], type: 'logos' }
]
const thinkTankGroups: Group[] = [
{ title: '智库观察', more: '/think-tank?type=view', items: createItems('智库观察', 301) },
{ title: '建言献策', more: '/suggestions', items: createItems('建言献策', 311) },
{ title: '翰墨观察', more: '/hanmo', items: createItems('翰墨文谈', 321) },
{ title: '支撑单位', more: '/about', items: [
{ title: '华东科技', summary: '', date: '' },
{ title: '华西科技', summary: '', date: '' },
{ title: '华南科技', summary: '', date: '' },
{ title: '华北科技', summary: '', date: '' },
{ title: '华中科技', summary: '', date: '' }
], type: 'logos' }
]
type ExpertTab = 'viewpoint' | 'dynamic'
type ExpertCard = {
id: number
title: string
date: string
image: string
tab: ExpertTab
}
const activeExpertTab = ref<ExpertTab>('viewpoint')
const expertCards: ExpertCard[] = [
{ id: 401, title: '专家试点一', date: '2026-03-19', image: '/images/video-poster.jpg', tab: 'viewpoint' },
{ id: 402, title: '专家试点二', date: '2026-03-18', image: '/images/video-poster.jpg', tab: 'viewpoint' },
{ id: 403, title: '专家试点三', date: '2026-03-17', image: '/images/video-poster.jpg', tab: 'viewpoint' },
{ id: 404, title: '专家试点四', date: '2026-03-16', image: '/images/video-poster.jpg', tab: 'viewpoint' },
{ id: 405, title: '专家动态一', date: '2026-03-15', image: '/images/video-poster.jpg', tab: 'dynamic' },
{ id: 406, title: '专家动态二', date: '2026-03-14', image: '/images/video-poster.jpg', tab: 'dynamic' },
{ id: 407, title: '专家动态三', date: '2026-03-13', image: '/images/video-poster.jpg', tab: 'dynamic' },
{ id: 408, title: '专家动态四', date: '2026-03-12', image: '/images/video-poster.jpg', tab: 'dynamic' }
]
const filteredExpertCards = computed(() => expertCards.filter(item => item.tab === activeExpertTab.value))
const actionLinks = [
{ title: '资料下载', to: '/reference', icon: '⇩', theme: 'cyan' },
{ title: '申报模板', to: '/about/consultation', icon: '▣', theme: 'blue' },
{ title: '成果摘编', to: '/reference', icon: '▤', theme: 'green' },
{ title: '联系我们', to: '/contact', icon: '✆', theme: 'red' }
]
</script>
<style scoped>
.home-page {
min-height: 100vh;
background: #ffffff;
color: #1f2d3d;
}
.container {
width: min(1200px, calc(100% - 32px));
margin: 0 auto;
}
.page-main {
padding: 14px 0 40px;
}
.headline-grid {
display: grid;
grid-template-columns: 220px 1.45fr 1fr;
gap: 16px;
align-items: start;
margin-bottom: 28px;
}
.headline-left,
.headline-center,
.headline-right,
.article-panel,
.experts-section {
background: #fff;
}
.headline-image-card {
display: block;
padding: 0;
background: #fff;
}
.headline-image-card img,
.feature-image-wrap img {
width: 100%;
display: block;
object-fit: cover;
}
.headline-image-card img {
height: 254px;
}
.headline-image-title {
margin-top: 12px;
color: #2d2d2d;
font-size: 14px;
font-weight: 700;
line-height: 1.7;
padding: 0 10px;
}
.headline-image-date {
margin-top: 8px;
color: #999;
font-size: 12px;
padding: 0 10px 10px;
}
.headline-center {
padding: 14px;
}
.feature-title {
display: block;
margin-bottom: 12px;
color: #1b58a3;
font-size: 34px;
font-weight: 700;
line-height: 1.4;
}
.feature-image-wrap img {
height: 356px;
}
.headline-right {
padding: 12px 14px;
}
.subnav-strip {
display: flex;
flex-wrap: wrap;
gap: 6px;
margin-bottom: 14px;
padding: 8px 10px;
background-position: center;
background-repeat: no-repeat;
background-size: 100% 100%;
color: #fff;
font-size: 12px;
min-height: 35px;
}
.news-links {
display: flex;
flex-direction: column;
gap: 14px;
}
.news-links a {
color: #1f2d3d;
font-size: 14px;
line-height: 1.7;
border-bottom: 1px dashed #dfdfdf;
padding-bottom: 12px;
}
.ad-banner {
display: flex;
align-items: center;
justify-content: center;
min-height: 90px;
margin: 0 0 28px;
font-size: 20px;
letter-spacing: 1px;
}
.image-banner {
min-height: 0;
background: transparent;
}
.image-banner img,
.image-heading img {
width: 100%;
display: block;
}
.ad-banner.soft {
background:
linear-gradient(155deg, rgba(217, 15, 34, 0.95) 0 18%, transparent 18%),
linear-gradient(180deg, #fff4eb, #fff8f1);
color: #333;
}
.ad-banner.blue {
min-height: 74px;
background: #67add6;
color: #fff;
}
.ad-banner.scenic {
min-height: 110px;
background:
linear-gradient(rgba(48, 142, 205, 0.22), rgba(48, 142, 205, 0.22)),
url('/images/banner.png') center 62%/cover;
color: #fff;
}
.section-block {
margin-bottom: 28px;
}
.section-heading {
display: flex;
align-items: center;
justify-content: center;
position: relative;
margin-bottom: 20px;
}
.image-heading {
margin-bottom: 22px;
}
.section-heading-title {
position: relative;
padding: 0 26px;
text-align: center;
}
.section-heading-title::before,
.section-heading-title::after {
content: '';
position: absolute;
top: 14px;
width: 120px;
height: 1px;
background: #bfd5ea;
}
.section-heading-title::before {
right: 100%;
}
.section-heading-title::after {
left: 100%;
}
.section-heading-title span {
display: block;
color: #2f6da8;
font-size: 28px;
font-weight: 700;
line-height: 1.1;
}
.section-heading-title small {
color: #a6b9ca;
font-size: 11px;
letter-spacing: 2px;
}
.article-columns.two {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 22px;
}
.article-panel {
padding: 4px 0 0;
}
.panel-heading {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 0 10px;
border-bottom: 1px solid #e6eef5;
}
.panel-heading span {
color: #2c6eaa;
font-size: 20px;
font-weight: 700;
}
.panel-heading a {
color: #9aa3aa;
font-size: 12px;
}
.article-list {
padding-top: 6px;
}
.article-row {
display: grid;
grid-template-columns: 1fr 105px;
gap: 16px;
padding: 12px 0;
border-bottom: 1px dashed #e8edf2;
}
.article-row:last-child {
border-bottom: 0;
}
.article-text h3 {
margin: 0 0 8px;
color: #2a2a2a;
font-size: 15px;
font-weight: 700;
line-height: 1.5;
}
.article-text p {
margin: 0 0 8px;
color: #6e7881;
font-size: 13px;
line-height: 1.6;
}
.article-text span {
color: #a3aab0;
font-size: 12px;
}
.article-row img {
width: 105px;
height: 72px;
object-fit: cover;
border-radius: 2px;
}
.experts-section {
margin-bottom: 28px;
}
.experts-heading {
justify-content: center;
margin-bottom: 18px;
min-height: 68px;
background-position: center;
background-repeat: no-repeat;
background-size: 100% 100%;
}
.experts-heading-title {
position: absolute;
left: 50%;
top: 50%;
width: 100%;
transform: translate(-50%, -50%);
}
.experts-tabs {
display: flex;
align-items: center;
justify-content: space-between;
padding-bottom: 14px;
border-bottom: 1px solid #e6eef5;
margin-bottom: 18px;
}
.experts-tabs-left {
display: flex;
align-items: center;
gap: 26px;
}
.experts-tab-btn {
padding: 0;
border: 0;
background: transparent;
color: #798895;
font-size: 15px;
cursor: pointer;
transition: color 0.2s ease;
}
.experts-tab-btn:hover {
color: #2c6eaa;
}
.experts-tab-btn.active {
color: #2c6eaa;
font-weight: 700;
}
.expert-apply-btn {
display: block;
width: 116px;
line-height: 0;
flex-shrink: 0;
}
.expert-apply-btn img {
width: 100%;
display: block;
}
.experts-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 18px;
}
.expert-card {
background: #fff;
border: 1px solid #edf2f5;
}
.expert-card img {
width: 100%;
height: 220px;
object-fit: cover;
display: block;
}
.expert-card-body {
padding: 10px 10px 12px;
}
.expert-card-body h3 {
margin: 0 0 6px;
color: #d54235;
font-size: 14px;
font-weight: 700;
}
.expert-card-body p {
margin: 0;
color: #8f989f;
font-size: 12px;
}
.logo-list-wrap {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 14px 10px;
}
.logo-card {
display: flex;
flex-direction: column;
align-items: center;
gap: 8px;
padding: 8px 0;
}
.logo-circle {
width: 70px;
height: 70px;
border-radius: 50%;
background: radial-gradient(circle at 50% 50%, #fff 0 24%, #1d2b4b 25% 36%, #7ea2d8 37% 44%, #0d1730 45% 100%);
color: #fff;
font-size: 10px;
display: flex;
align-items: center;
justify-content: center;
letter-spacing: 1px;
}
.logo-card span {
color: #3d4d5a;
font-size: 12px;
}
.action-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 16px;
margin-bottom: 32px;
}
.action-card {
display: flex;
align-items: center;
justify-content: center;
gap: 14px;
min-height: 78px;
background: #fff;
border: 2px solid #dceaf3;
color: #5c8aa5;
font-size: 28px;
font-weight: 700;
}
.action-card span:last-child {
font-size: 28px;
}
.action-icon {
font-size: 34px;
line-height: 1;
}
.action-card.cyan {
border-color: #cce9ef;
color: #55abc0;
}
.action-card.blue {
border-color: #d6e6f6;
color: #4e87c8;
}
.action-card.green {
border-color: #d9efe7;
color: #7db9aa;
}
.action-card.red {
border-color: #f4d8d6;
color: #db7f77;
}
.site-footer {
background: #fff;
}
.footer-nav {
background: #0f69b9;
}
.footer-nav-inner {
display: flex;
gap: 22px;
padding: 10px 0;
}
.footer-nav a {
color: #fff;
font-size: 12px;
}
@media (max-width: 1100px) {
.headline-grid,
.article-columns.two,
.experts-grid,
.action-grid {
grid-template-columns: 1fr;
}
.headline-center,
.headline-right,
.headline-left,
.experts-section {
padding-left: 0;
padding-right: 0;
}
.feature-title {
font-size: 26px;
}
.logo-list-wrap {
grid-template-columns: repeat(3, 1fr);
}
}
@media (max-width: 768px) {
.container {
width: min(100%, calc(100% - 24px));
}
.headline-grid {
gap: 12px;
}
.headline-center,
.headline-right,
.headline-left,
.article-panel,
.experts-section {
padding: 0;
}
.headline-center {
padding: 12px;
}
.headline-right {
padding: 12px;
}
.feature-title {
font-size: 22px;
}
.feature-image-wrap img {
height: 240px;
}
.section-heading {
justify-content: flex-start;
}
.section-heading-title {
padding: 0 0 0 2px;
text-align: left;
}
.section-heading-title::before,
.section-heading-title::after {
display: none;
}
.expert-apply-btn {
position: static;
transform: none;
margin-left: auto;
width: 100px;
}
.experts-grid {
grid-template-columns: repeat(2, 1fr);
}
.expert-card img {
height: 170px;
}
.logo-list-wrap {
grid-template-columns: repeat(2, 1fr);
}
.article-row {
grid-template-columns: 1fr;
}
.article-row img {
width: 100%;
height: 180px;
}
.action-card,
.action-card span:last-child {
font-size: 22px;
}
.action-icon {
font-size: 28px;
}
.footer-nav-inner {
flex-wrap: wrap;
gap: 10px 16px;
}
}
</style>