194 lines
6.0 KiB
TypeScript
194 lines
6.0 KiB
TypeScript
// import fs from 'fs';
|
||
// import path from 'path';
|
||
// import matter from 'gray-matter';
|
||
|
||
// export interface ArticleMetadata {
|
||
// title: string;
|
||
// description: string;
|
||
// excerpt: string;
|
||
// category: string;
|
||
// tags: string[];
|
||
// author: string;
|
||
// date: string;
|
||
// image: string;
|
||
// locale: 'zh-CN' | 'zh-TW' | 'en';
|
||
// slug: string;
|
||
// featured: boolean;
|
||
// }
|
||
|
||
// export interface Article {
|
||
// metadata: ArticleMetadata;
|
||
// content: string;
|
||
// id: string;
|
||
// }
|
||
|
||
// const docsDirectory = path.join(process.cwd(), 'docs');
|
||
|
||
// // 获取所有文章
|
||
// export function getAllArticles(): Article[] {
|
||
// if (!fs.existsSync(docsDirectory)) {
|
||
// return [];
|
||
// }
|
||
|
||
// const fileNames = fs.readdirSync(docsDirectory);
|
||
// const articles: Article[] = [];
|
||
|
||
// fileNames.forEach((fileName) => {
|
||
// if (fileName.endsWith('.md')) {
|
||
// const fullPath = path.join(docsDirectory, fileName);
|
||
// const fileContents = fs.readFileSync(fullPath, 'utf8');
|
||
// const { data, content } = matter(fileContents);
|
||
|
||
// // 从文件名提取 ID(去掉语言后缀)
|
||
// const id = fileName.replace(/\.(zh-CN|zh-TW|en)\.md$/, '');
|
||
|
||
// articles.push({
|
||
// id,
|
||
// metadata: data as ArticleMetadata,
|
||
// content,
|
||
// });
|
||
// }
|
||
// });
|
||
|
||
// return articles;
|
||
// }
|
||
|
||
// // 根据语言获取文章
|
||
// export function getArticlesByLocale(locale: 'zh-CN' | 'zh-TW' | 'en'): Article[] {
|
||
// const allArticles = getAllArticles();
|
||
// return allArticles.filter((article) => article.metadata.locale === locale);
|
||
// }
|
||
|
||
// // 根据分类获取文章
|
||
// export function getArticlesByCategory(
|
||
// category: string,
|
||
// locale?: 'zh-CN' | 'zh-TW' | 'en',
|
||
// ): Article[] {
|
||
// let articles = getAllArticles();
|
||
|
||
// if (locale) {
|
||
// articles = articles.filter((article) => article.metadata.locale === locale);
|
||
// }
|
||
|
||
// return articles.filter((article) => article.metadata.category === category);
|
||
// }
|
||
|
||
// // 获取特色文章
|
||
// export function getFeaturedArticles(locale?: 'zh-CN' | 'zh-TW' | 'en'): Article[] {
|
||
// let articles = getAllArticles();
|
||
|
||
// if (locale) {
|
||
// articles = articles.filter((article) => article.metadata.locale === locale);
|
||
// }
|
||
|
||
// return articles.filter((article) => article.metadata.featured);
|
||
// }
|
||
|
||
// // 根据 slug 和语言获取单篇文章
|
||
// export function getArticleBySlug(slug: string, locale: 'zh-CN' | 'zh-TW' | 'en'): Article | null {
|
||
// const fileName = `${slug}.${locale}.md`;
|
||
// const fullPath = path.join(docsDirectory, fileName);
|
||
|
||
// if (!fs.existsSync(fullPath)) {
|
||
// return null;
|
||
// }
|
||
|
||
// const fileContents = fs.readFileSync(fullPath, 'utf8');
|
||
// const { data, content } = matter(fileContents);
|
||
|
||
// return {
|
||
// id: slug,
|
||
// metadata: data as ArticleMetadata,
|
||
// content,
|
||
// };
|
||
// }
|
||
|
||
// // 获取所有可用的分类
|
||
// export function getAllCategories(locale?: 'zh-CN' | 'zh-TW' | 'en'): string[] {
|
||
// let articles = getAllArticles();
|
||
|
||
// if (locale) {
|
||
// articles = articles.filter((article) => article.metadata.locale === locale);
|
||
// }
|
||
|
||
// const categories = articles.map((article) => article.metadata.category);
|
||
// return [...new Set(categories)];
|
||
// }
|
||
|
||
// // 获取所有可用的标签
|
||
// export function getAllTags(locale?: 'zh-CN' | 'zh-TW' | 'en'): string[] {
|
||
// let articles = getAllArticles();
|
||
|
||
// if (locale) {
|
||
// articles = articles.filter((article) => article.metadata.locale === locale);
|
||
// }
|
||
|
||
// const tags = articles.flatMap((article) => article.metadata.tags);
|
||
// return [...new Set(tags)];
|
||
// }
|
||
|
||
// // 搜索文章
|
||
// export function searchArticles(query: string, locale?: 'zh-CN' | 'zh-TW' | 'en'): Article[] {
|
||
// let articles = getAllArticles();
|
||
|
||
// if (locale) {
|
||
// articles = articles.filter((article) => article.metadata.locale === locale);
|
||
// }
|
||
|
||
// const lowercaseQuery = query.toLowerCase();
|
||
|
||
// return articles.filter((article) => {
|
||
// const { title, description, excerpt, tags } = article.metadata;
|
||
// return (
|
||
// title.toLowerCase().includes(lowercaseQuery) ||
|
||
// description.toLowerCase().includes(lowercaseQuery) ||
|
||
// excerpt.toLowerCase().includes(lowercaseQuery) ||
|
||
// tags.some((tag) => tag.toLowerCase().includes(lowercaseQuery)) ||
|
||
// article.content.toLowerCase().includes(lowercaseQuery)
|
||
// );
|
||
// });
|
||
// }
|
||
|
||
// // 获取相关文章
|
||
// export function getRelatedArticles(article: Article, limit: number = 3): Article[] {
|
||
// const allArticles = getAllArticles();
|
||
// const sameLocaleArticles = allArticles.filter(
|
||
// (a) => a.metadata.locale === article.metadata.locale && a.id !== article.id,
|
||
// );
|
||
|
||
// // 按分类和标签相似度排序
|
||
// const scored = sameLocaleArticles.map((a) => {
|
||
// let score = 0;
|
||
|
||
// // 同分类加分
|
||
// if (a.metadata.category === article.metadata.category) {
|
||
// score += 3;
|
||
// }
|
||
|
||
// // 共同标签加分
|
||
// const commonTags = a.metadata.tags.filter((tag) => article.metadata.tags.includes(tag));
|
||
// score += commonTags.length;
|
||
|
||
// return { article: a, score };
|
||
// });
|
||
|
||
// return scored
|
||
// .sort((a, b) => b.score - a.score)
|
||
// .slice(0, limit)
|
||
// .map((item) => item.article);
|
||
// }
|
||
|
||
// // 按日期排序文章
|
||
// export function sortArticlesByDate(articles: Article[], order: 'asc' | 'desc' = 'desc'): Article[] {
|
||
// return articles.sort((a, b) => {
|
||
// const dateA = new Date(a.metadata.date);
|
||
// const dateB = new Date(b.metadata.date);
|
||
|
||
// if (order === 'desc') {
|
||
// return dateB.getTime() - dateA.getTime();
|
||
// } else {
|
||
// return dateA.getTime() - dateB.getTime();
|
||
// }
|
||
// });
|
||
// }
|