336 lines
14 KiB
Plaintext
336 lines
14 KiB
Plaintext
---
|
|
import { getCollection, type CollectionEntry } from "astro:content";
|
|
import MainLayout from "../../components/MainLayout.astro";
|
|
|
|
// 定义Props类型
|
|
export interface Props {
|
|
entry: CollectionEntry<"culture">;
|
|
}
|
|
|
|
// 生成静态路径
|
|
export async function getStaticPaths() {
|
|
const cultures = await getCollection("culture");
|
|
return cultures.map((entry) => ({
|
|
params: { slug: entry.slug },
|
|
props: { entry },
|
|
}));
|
|
}
|
|
|
|
// 获取当前文化数据
|
|
const { entry } = Astro.props;
|
|
const { Content } = await entry.render();
|
|
|
|
// 获取相关文化
|
|
const allCultures = await getCollection("culture");
|
|
const relatedCultures = allCultures
|
|
.filter(
|
|
(item) =>
|
|
item.slug !== entry.slug &&
|
|
item.data.tags.some((tag) => entry.data.tags.includes(tag))
|
|
)
|
|
.slice(0, 3);
|
|
---
|
|
|
|
<MainLayout title={`${entry.data.title} - 河北游礼`}>
|
|
<!-- 移动端浮动返回按钮 -->
|
|
<div class="md:hidden fixed bottom-6 left-1/2 transform -translate-x-1/2 z-50">
|
|
<a
|
|
href="/culture"
|
|
class="flex items-center space-x-2 px-5 py-3 bg-ancient-accent dark:bg-ancient-accent-dark text-ancient-white rounded-full shadow-lg hover:bg-ancient-accent/90 dark:hover:bg-ancient-accent-dark/90 transition-colors border border-ancient-accent/30 dark:border-ancient-accent-dark/30 backdrop-blur-sm"
|
|
aria-label="返回所有文化"
|
|
>
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 17l-5-5m0 0l5-5m-5 5h12" />
|
|
</svg>
|
|
<span>返回文化列表</span>
|
|
</a>
|
|
</div>
|
|
|
|
<!-- 页面标题区域 - 古籍风格 -->
|
|
<div class="relative py-16 bg-ancient-paper dark:bg-ancient-paper-dark overflow-hidden">
|
|
<div class="absolute inset-0 bg-opacity-20 bg-amber-100 dark:bg-opacity-20 dark:bg-amber-900"></div>
|
|
|
|
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10">
|
|
<div class="flex flex-wrap items-center gap-2 mb-4">
|
|
<a href="/" class="text-ancient-black/80 dark:text-ancient-white/80 hover:text-ancient-accent dark:hover:text-ancient-accent-dark transition-colors font-ancient-small">首页</a>
|
|
<span class="text-ancient-black/60 dark:text-ancient-white/60 font-ancient-small">/</span>
|
|
<a href="/culture" class="text-ancient-black/80 dark:text-ancient-white/80 hover:text-ancient-accent dark:hover:text-ancient-accent-dark transition-colors font-ancient-small">文化</a>
|
|
<span class="text-ancient-black/60 dark:text-ancient-white/60 font-ancient-small">/</span>
|
|
<span class="text-ancient-black/60 dark:text-ancient-white/60 font-ancient-small">{entry.data.title}</span>
|
|
</div>
|
|
|
|
<!-- 典籍风格标题 -->
|
|
<div class="official-title">
|
|
<h1 class="text-4xl md:text-5xl font-ancient text-ancient-black dark:text-ancient-white mb-4 leading-snug">{entry.data.title}</h1>
|
|
<div class="w-40 h-0.5 my-6 bg-ancient-accent dark:bg-ancient-accent-dark"></div>
|
|
</div>
|
|
|
|
<div class="flex flex-wrap items-center gap-4 mb-4">
|
|
{entry.data.city && entry.data.city.length > 0 && (
|
|
<div class="flex items-center text-ancient-black/90 dark:text-ancient-white/90 font-ancient-body">
|
|
<span class="mr-1">📍</span>
|
|
{entry.data.city.map((cityName, index) => (
|
|
<>
|
|
<span>{cityName}</span>
|
|
{index < entry.data.city.length - 1 && <span>, </span>}
|
|
</>
|
|
))}
|
|
</div>
|
|
)}
|
|
|
|
{entry.data.pubDate && (
|
|
<div class="flex items-center text-ancient-black/90 dark:text-ancient-white/90 font-ancient-body">
|
|
<span class="mr-1">📅</span> {new Date(entry.data.pubDate).toLocaleDateString('zh-CN')}
|
|
</div>
|
|
)}
|
|
|
|
<div class="flex items-center text-ancient-black/90 dark:text-ancient-white/90 font-ancient-body">
|
|
<span class="mr-1">🏷️</span> {entry.data.category}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="flex flex-wrap gap-2 mb-6">
|
|
{entry.data.tags.map((tag) => (
|
|
<span class="px-3 py-1 bg-ancient-paper/70 dark:bg-ancient-paper-dark/70 text-ancient-black dark:text-ancient-white text-sm font-ancient-small border border-ancient-accent/30 dark:border-ancient-accent-dark/30 hover:border-ancient-accent/50 dark:hover:border-ancient-accent-dark/50 rounded-full">
|
|
{tag}
|
|
</span>
|
|
))}
|
|
</div>
|
|
|
|
<p class="text-xl text-ancient-black/90 dark:text-ancient-white/90 max-w-3xl font-ancient-body">{entry.data.description}</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 主要内容区域 - 古籍风格 -->
|
|
<div class="py-12 bg-ancient-paper dark:bg-ancient-paper-dark">
|
|
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
<div class="grid grid-cols-1 lg:grid-cols-12 gap-6">
|
|
<!-- 左侧内容 - 古籍风格 -->
|
|
<div class="lg:col-span-8">
|
|
<div class="prose prose-lg dark:prose-invert max-w-none font-ancient-body bg-ancient-paper-light/30 dark:bg-ancient-paper-dark/30 p-0 relative">
|
|
<Content />
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 右侧边栏 - 古籍风格 -->
|
|
<div class="lg:col-span-4 space-y-6">
|
|
<!-- 文化图片 - 古籍风格 -->
|
|
<div class="border border-ancient-accent/40 dark:border-ancient-accent-dark/40 overflow-hidden shadow-md">
|
|
<div class="h-64 bg-ancient-paper-light/70 dark:bg-ancient-paper-dark/70 flex items-center justify-center relative">
|
|
{entry.data.image ? (
|
|
<img
|
|
src={entry.data.image}
|
|
alt={entry.data.title}
|
|
class="w-full h-full object-cover"
|
|
/>
|
|
) : (
|
|
<span class="text-ancient-black/40 dark:text-ancient-white/40 font-ancient">{entry.data.title} 图片</span>
|
|
)}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 文化信息卡片 - 古籍风格 -->
|
|
<div class="bg-ancient-paper-light dark:bg-ancient-paper-dark-light p-5 border border-ancient-accent/30 dark:border-ancient-accent-dark/30 shadow-md">
|
|
<h3 class="text-xl font-ancient-heading text-ancient-black dark:text-ancient-white mb-4 flex items-center">
|
|
<svg class="w-5 h-5 mr-2 text-ancient-accent dark:text-ancient-accent-dark" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
</svg>
|
|
文化信息
|
|
</h3>
|
|
|
|
<div class="space-y-3 font-ancient-body">
|
|
{entry.data.city && entry.data.city.length > 0 && (
|
|
<div class="flex">
|
|
<span class="w-24 flex-shrink-0 text-ancient-black/60 dark:text-ancient-white/60">分布地区:</span>
|
|
<div class="text-ancient-black dark:text-ancient-white">
|
|
{entry.data.city.map((cityName, index) => (
|
|
<>
|
|
<span>{cityName}</span>
|
|
{index < entry.data.city.length - 1 && <span>, </span>}
|
|
</>
|
|
))}
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
<div class="flex">
|
|
<span class="w-24 flex-shrink-0 text-ancient-black/60 dark:text-ancient-white/60">文化类型:</span>
|
|
<span class="text-ancient-black dark:text-ancient-white">{entry.data.category}</span>
|
|
</div>
|
|
|
|
<div class="flex">
|
|
<span class="w-24 flex-shrink-0 text-ancient-black/60 dark:text-ancient-white/60">特色标签:</span>
|
|
<div class="flex flex-wrap gap-1">
|
|
{entry.data.tags.map((tag) => (
|
|
<span class="px-2 py-0.5 bg-ancient-paper/70 dark:bg-ancient-paper-dark/70 text-sm font-ancient-small border border-ancient-accent/30 dark:border-ancient-accent-dark/30 text-ancient-black dark:text-ancient-white text-xs rounded-full">
|
|
{tag}
|
|
</span>
|
|
))}
|
|
</div>
|
|
</div>
|
|
|
|
{entry.data.pubDate && (
|
|
<div class="flex">
|
|
<span class="w-24 flex-shrink-0 text-ancient-black/60 dark:text-ancient-white/60">发布时间:</span>
|
|
<span class="text-ancient-black dark:text-ancient-white">{new Date(entry.data.pubDate).toLocaleDateString('zh-CN')}</span>
|
|
</div>
|
|
)}
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 相关文化 - 古籍风格 -->
|
|
{relatedCultures.length > 0 && (
|
|
<div class="bg-ancient-paper-light dark:bg-ancient-paper-dark-light p-5 border border-ancient-accent/30 dark:border-ancient-accent-dark/30 shadow-md">
|
|
<h3 class="text-xl font-ancient-heading text-ancient-black dark:text-ancient-white mb-4 flex items-center">
|
|
<svg class="w-5 h-5 mr-2 text-ancient-accent dark:text-ancient-accent-dark" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" />
|
|
</svg>
|
|
相关文化
|
|
</h3>
|
|
|
|
<div class="space-y-4">
|
|
{relatedCultures.map((culture) => (
|
|
<a
|
|
href={`/culture/${culture.slug}`}
|
|
class="block group"
|
|
>
|
|
<div class="flex items-start space-x-3">
|
|
<div class="w-16 h-16 flex-shrink-0 bg-ancient-paper/70 dark:bg-ancient-paper-dark/70 border border-ancient-accent/20 dark:border-ancient-accent-dark/20 rounded flex items-center justify-center overflow-hidden">
|
|
{culture.data.image ? (
|
|
<img
|
|
src={culture.data.image}
|
|
alt={culture.data.title}
|
|
class="w-full h-full object-cover"
|
|
/>
|
|
) : (
|
|
<span class="text-xs text-ancient-black/40 dark:text-ancient-white/40">图片</span>
|
|
)}
|
|
</div>
|
|
<div>
|
|
<h4 class="text-base font-ancient-heading text-ancient-black dark:text-ancient-white group-hover:text-ancient-accent dark:group-hover:text-ancient-accent-dark transition-colors">
|
|
{culture.data.title}
|
|
</h4>
|
|
<p class="text-sm text-ancient-black/70 dark:text-ancient-white/70 line-clamp-2 font-ancient-body">
|
|
{culture.data.description.substring(0, 60)}...
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</a>
|
|
))}
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
<!-- 返回按钮 - 仅在非移动端显示 - 古籍风格 -->
|
|
<div class="hidden md:block">
|
|
<a
|
|
href="/culture"
|
|
class="block w-full py-4 mt-8 mb-4 text-center bg-ancient-accent dark:bg-ancient-accent-dark text-ancient-white rounded-md hover:bg-ancient-accent/90 dark:hover:bg-ancient-accent-dark/90 transition-colors font-ancient shadow-lg border border-ancient-accent/50 dark:border-ancient-accent-dark/50 text-lg backdrop-blur-sm"
|
|
>
|
|
返回所有文化
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</MainLayout>
|
|
|
|
<style>
|
|
/* 确保这些CSS类对此页面有效 */
|
|
.prose {
|
|
color: var(--ancient-black) !important;
|
|
}
|
|
|
|
.dark .prose {
|
|
color: var(--ancient-white) !important;
|
|
}
|
|
|
|
.prose h1, .prose h2, .prose h3, .prose h4 {
|
|
color: var(--ancient-black) !important;
|
|
font-family: var(--font-ancient-heading);
|
|
}
|
|
|
|
.dark .prose h1, .dark .prose h2, .dark .prose h3, .dark .prose h4 {
|
|
color: var(--ancient-white) !important;
|
|
}
|
|
|
|
.prose p, .prose ul, .prose ol {
|
|
font-family: var(--font-ancient-body);
|
|
}
|
|
|
|
.prose a {
|
|
color: var(--ancient-accent) !important;
|
|
text-decoration: none;
|
|
border-bottom: 1px dashed var(--ancient-accent);
|
|
transition: all 0.2s ease;
|
|
}
|
|
|
|
.dark .prose a {
|
|
color: var(--ancient-accent-dark) !important;
|
|
border-bottom-color: var(--ancient-accent-dark);
|
|
}
|
|
|
|
.prose a:hover {
|
|
border-bottom-style: solid;
|
|
color: var(--ancient-red) !important;
|
|
}
|
|
|
|
.dark .prose a:hover {
|
|
color: var(--ancient-red-dark) !important;
|
|
}
|
|
|
|
.prose blockquote {
|
|
border-left-color: var(--ancient-accent) !important;
|
|
background-color: rgba(var(--ancient-paper-light-rgb), 0.3) !important;
|
|
font-style: italic;
|
|
}
|
|
|
|
.dark .prose blockquote {
|
|
border-left-color: var(--ancient-accent-dark) !important;
|
|
background-color: rgba(var(--ancient-paper-dark-rgb), 0.3) !important;
|
|
}
|
|
|
|
.prose code {
|
|
background-color: rgba(var(--ancient-paper-light-rgb), 0.5) !important;
|
|
color: var(--ancient-black) !important;
|
|
padding: 0.2em 0.4em;
|
|
border-radius: 0.25em;
|
|
font-size: 0.875em;
|
|
}
|
|
|
|
.dark .prose code {
|
|
background-color: rgba(var(--ancient-paper-dark-rgb), 0.5) !important;
|
|
color: var(--ancient-white) !important;
|
|
}
|
|
|
|
.prose pre {
|
|
background-color: rgba(var(--ancient-paper-light-rgb), 0.8) !important;
|
|
border: 1px solid rgba(var(--ancient-accent-rgb), 0.2) !important;
|
|
}
|
|
|
|
.dark .prose pre {
|
|
background-color: rgba(var(--ancient-paper-dark-rgb), 0.8) !important;
|
|
border-color: rgba(var(--ancient-accent-dark-rgb), 0.2) !important;
|
|
}
|
|
|
|
.prose img {
|
|
border: 1px solid rgba(var(--ancient-accent-rgb), 0.2);
|
|
border-radius: 0.25rem;
|
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
|
}
|
|
|
|
.dark .prose img {
|
|
border-color: rgba(var(--ancient-accent-dark-rgb), 0.2);
|
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
|
|
}
|
|
|
|
.prose hr {
|
|
border-color: rgba(var(--ancient-accent-rgb), 0.2) !important;
|
|
}
|
|
|
|
.dark .prose hr {
|
|
border-color: rgba(var(--ancient-accent-dark-rgb), 0.2) !important;
|
|
}
|
|
</style> |