feat(home): 更新首页新闻栏目数据获取逻辑

- 将硬编码的新闻栏目数据替换为从CMS动态获取
- 添加了新闻栏目数据类型定义和解析函数
- 实现了新闻文章链接生成和标题解析功能
- 更新了页面参数传递,将navigationId改为categoryId
- 添加了加载状态和空数据状态的UI显示
- 集成了文章详情页的动态路由跳转功能
This commit is contained in:
2026-01-29 17:29:21 +08:00
parent 0f5f70522a
commit 322bf2466f

View File

@@ -19,71 +19,61 @@
</div> </div>
<div v-if="showBrandbar" class="brandbar"> <div v-if="showBrandbar" class="brandbar">
<div class="mx-auto grid max-w-screen-xl grid-cols-12 items-center gap-6 px-4 py-4"> <div class="brandbar-inner mx-auto grid max-w-screen-xl grid-cols-12 items-center gap-6 px-4 py-4">
<NuxtLink to="/" class="col-span-12 flex items-center gap-4 md:col-span-6"> <NuxtLink to="/" class="col-span-12 flex items-center gap-4 md:col-span-6">
<img class="brand-logo" :src="`https://oss.wsdns.cn/20260127/989e5cf82b0847ed9168023baf68f4a9.png`" :alt="siteName" /> <img class="brand-logo" :src="`https://oss.wsdns.cn/20260127/989e5cf82b0847ed9168023baf68f4a9.png`" :alt="siteName" />
</NuxtLink> </NuxtLink>
<div class="col-span-12 text-right md:col-span-6"> <div class="col-span-12 hidden text-right md:col-span-6 md:block">
<div class="brand-mission">{{ missionText }}</div> <div class="brand-mission">{{ missionText }}</div>
<div class="brand-values">{{ valuesText }}</div> <div class="brand-values">{{ valuesText }}</div>
</div> </div>
</div> </div>
</div> </div>
<a-affix :offset-top="0" @change="onAffixChange"> <div class="hidden md:block">
<div class="navbar"> <a-affix :offset-top="0" @change="onAffixChange">
<div class="mx-auto flex max-w-screen-xl items-center justify-between gap-20 px-"> <div class="navbar">
<NuxtLink v-if="isAffixed" to="/" class="navbar-brand" :class="{ 'navbar-brand-hidden': !isAffixed }"> <div class="mx-auto flex max-w-screen-xl items-center justify-between gap-3 px-4">
<img class="navbar-logo" :src="logoUrl" :alt="siteName" /> <NuxtLink v-if="isAffixed" to="/" class="navbar-brand">
<span class="navbar-brand-name"> <img class="navbar-logo" :src="logoUrl" :alt="siteName" />
{{ siteName }} <span class="navbar-brand-name">
</span> {{ siteName }}
</NuxtLink> </span>
<nav class="nav hidden md:flex"> </NuxtLink>
<template v-for="item in navItems" :key="item.key"> <nav class="nav hidden md:flex">
<a-dropdown v-if="item.children?.length" :trigger="['hover']"> <template v-for="item in navItems" :key="item.key">
<a class="nav-link" :class="{ active: isActive(item) }" @click.prevent> <a-dropdown v-if="item.children?.length" :trigger="['hover', 'click']">
<a class="nav-link" :class="{ active: isActive(item) }" @click.prevent>
{{ item.label }}
</a>
<template #overlay>
<a-menu>
<a-menu-item
v-for="child in item.children"
:key="child.key"
@click="onNavClick(child)"
>
{{ child.label }}
</a-menu-item>
</a-menu>
</template>
</a-dropdown>
<NuxtLink
v-else-if="item.to"
class="nav-link"
:class="{ active: isActive(item) }"
:to="item.to"
>
{{ item.label }} {{ item.label }}
</a> </NuxtLink>
<template #overlay> </template>
<a-menu> </nav>
<a-menu-item </div>
v-for="child in item.children"
:key="child.key"
@click="onNavClick(child)"
>
{{ child.label }}
</a-menu-item>
</a-menu>
</template>
</a-dropdown>
<NuxtLink
v-else-if="item.to"
class="nav-link"
:class="{ active: isActive(item) }"
:to="item.to"
>
{{ item.label }}
</NuxtLink>
<a
v-else
class="nav-link"
:class="{ active: isActive(item) }"
:href="item.href"
:target="item.target || undefined"
rel="noopener noreferrer"
>
{{ item.label }}
</a>
</template>
</nav>
<div class="nav-spacer md:hidden" />
</div> </div>
</div> </a-affix>
</a-affix> </div>
</header> </header>
<a-drawer v-model:open="open" title="导航" placement="right"> <a-drawer v-model:open="open" title="导航" placement="right">
@@ -397,13 +387,6 @@ onBeforeUnmount(() => {
transition: opacity 0.18s ease, transform 0.18s ease; transition: opacity 0.18s ease, transform 0.18s ease;
} }
.navbar-brand-hidden {
opacity: 0;
visibility: hidden;
pointer-events: none;
transform: translateY(-4px);
}
.navbar-logo { .navbar-logo {
width: 28px; width: 28px;
height: 28px; height: 28px;
@@ -453,4 +436,12 @@ onBeforeUnmount(() => {
.nav-spacer { .nav-spacer {
height: 48px; height: 48px;
} }
@media (max-width: 640px) {
.brandbar-inner {
height: 160px;
padding-top: 0;
padding-bottom: 0;
}
}
</style> </style>