import type { Metadata } from 'next'; import { getSEOConfig } from '../../../../lib/seo-config'; import { Article } from '@/lib/types'; import NewsArticleServerComponent from '@/app/components/news/NewsArticleServerComponent'; import { notFound } from 'next/navigation'; // 服务端获取文章数据 async function getArticleData(slug: string, locale: string) { try { // 检查是否为静态导出模式 const isStaticMode = process.env.BUILD_MODE === 'static'; if (isStaticMode) { // 静态模式下直接从文件系统读取 const { getStaticArticleBySlug, getStaticArticles } = await import('../../../../lib/static-data'); const article = getStaticArticleBySlug(slug, locale as 'zh-CN' | 'zh-TW' | 'en'); if (!article) { return null; } // 获取相关文章 const allArticles = getStaticArticles(locale as 'zh-CN' | 'zh-TW' | 'en'); const relatedArticles = allArticles .filter(a => a.slug !== slug && a.metadata.category === article.metadata.category) .slice(0, 3); return { article, relatedArticles }; } else { // 开发模式下使用 API const baseUrl = process.env.NEXT_PUBLIC_BASE_URL || 'http://localhost:3000'; const response = await fetch(`${baseUrl}/api/articles/${slug}?locale=${locale}`, { // 使用 ISR 缓存策略,1小时后重新验证 next: { revalidate: 3600 } }); if (!response.ok) { if (response.status === 404) { return null; } throw new Error('Failed to fetch article'); } const data = await response.json(); return data; } } catch (error) { console.error('Error fetching article:', error); return null; } } // 生成静态参数 export async function generateStaticParams() { const { getStaticArticles } = await import('../../../../lib/static-data'); const locales = ['zh-CN', 'zh-TW', 'en']; const params = []; for (const locale of locales) { const articles = getStaticArticles(locale as 'zh-CN' | 'zh-TW' | 'en'); for (const article of articles) { // 为每个locale生成对应的路由参数 if (locale === 'zh-CN') { // 为简体中文生成两个路由:zh 和 zh-CN params.push({ locale: 'zh', id: article.slug, }); params.push({ locale: 'zh-CN', id: article.slug, }); } else { params.push({ locale: locale, id: article.slug, }); } } } return params; } // 生成动态元数据 export async function generateMetadata({ params: { locale, id }, }: { params: { locale: string; id: string }; }): Promise { const mappedLocale = locale === 'zh' ? 'zh-CN' : locale === 'zh-CN' ? 'zh-CN' : locale === 'zh-TW' ? 'zh-TW' : 'en'; const data = await getArticleData(id, mappedLocale); if (!data?.article) { return { title: '文章未找到 - AwsLinker', description: '您访问的文章不存在或已被移除。', }; } const article: Article = data.article; const language = mappedLocale; return { title: `${article.metadata.title} - AwsLinker`, description: article.metadata.description, keywords: article.metadata.tags, openGraph: { title: article.metadata.title, description: article.metadata.description, type: 'article', images: article.metadata.image ? [{ url: article.metadata.image }] : undefined, publishedTime: article.metadata.date, authors: article.metadata.author ? [article.metadata.author] : undefined, }, twitter: { card: 'summary_large_image', title: article.metadata.title, description: article.metadata.description, images: article.metadata.image ? [article.metadata.image] : undefined, }, alternates: { canonical: locale === 'zh' ? `/news/${id}` : `/${locale}/news/${id}`, languages: { 'zh-CN': `/news/${id}`, 'zh-TW': `/zh-TW/news/${id}`, en: `/en/news/${id}`, }, }, }; } // 服务器组件 - 预渲染数据 export default async function NewsArticlePage({ params: { locale, id }, }: { params: { locale: string; id: string }; }) { const mappedLocale = locale === 'zh' ? 'zh-CN' : locale === 'zh-CN' ? 'zh-CN' : locale === 'zh-TW' ? 'zh-TW' : 'en'; const data = await getArticleData(id, mappedLocale); if (!data?.article) { notFound(); } return ( ); }