import fs from 'fs'; import path from 'path'; import matter from 'gray-matter'; import { Locale } from './i18n'; export interface NewsArticle { id: string; title: string; category: string; date: string; excerpt: string; author: string; readTime: string; tags: string[]; featured: boolean; content: string; locale: Locale; } const DOCS_PATH = path.join(process.cwd(), 'docs', 'news'); export async function getNewsArticle(id: string, locale: Locale): Promise { try { const filePath = path.join(DOCS_PATH, locale, `${id}.md`); if (!fs.existsSync(filePath)) { return null; } const fileContents = fs.readFileSync(filePath, 'utf8'); const { data, content } = matter(fileContents); return { id, title: data.title, category: data.category, date: data.date, excerpt: data.excerpt, author: data.author, readTime: data.readTime, tags: data.tags || [], featured: data.featured || false, content, locale, }; } catch (error) { console.error(`Error reading article ${id} for locale ${locale}:`, error); return null; } } export async function getAllNewsArticles(locale: Locale): Promise { try { const articlesDir = path.join(DOCS_PATH, locale); if (!fs.existsSync(articlesDir)) { return []; } const filenames = fs.readdirSync(articlesDir); const articles: NewsArticle[] = []; for (const filename of filenames) { if (filename.endsWith('.md')) { const id = filename.replace(/\.md$/, ''); const article = await getNewsArticle(id, locale); if (article) { articles.push(article); } } } // Sort by date (newest first) // Handle Chinese date format (e.g., "2024年1月15日") const parseChineseDate = (dateStr: string): Date => { // Try to parse Chinese date format first const chineseDateMatch = dateStr.match(/(\d{4})年(\d{1,2})月(\d{1,2})日/); if (chineseDateMatch) { const [, year, month, day] = chineseDateMatch; return new Date(parseInt(year), parseInt(month) - 1, parseInt(day)); } // Fallback to regular Date parsing return new Date(dateStr); }; return articles.sort((a, b) => { const dateA = parseChineseDate(a.date); const dateB = parseChineseDate(b.date); return dateB.getTime() - dateA.getTime(); }); } catch (error) { console.error(`Error reading articles for locale ${locale}:`, error); return []; } } export async function getAvailableLocalesForArticle(id: string): Promise { const availableLocales: Locale[] = []; const locales: Locale[] = ['zh-CN', 'zh-TW', 'en']; for (const locale of locales) { const filePath = path.join(DOCS_PATH, locale, `${id}.md`); if (fs.existsSync(filePath)) { availableLocales.push(locale); } } return availableLocales; } export function checkArticleExists(id: string, locale: Locale): boolean { const filePath = path.join(DOCS_PATH, locale, `${id}.md`); return fs.existsSync(filePath); } /** * 获取最新的新闻文章(用于首页显示) * @param locale 语言 * @param limit 限制文章数量,默认为3 * @returns 最新的新闻文章数组 */ export async function getLatestNewsArticles(locale: Locale, limit: number = 3): Promise { const allArticles = await getAllNewsArticles(locale); return allArticles.slice(0, limit); }