修复文章所有的问题
This commit is contained in:
parent
ab83710eb6
commit
9ed938c946
@ -1,94 +0,0 @@
|
||||
---
|
||||
import type { CollectionEntry } from 'astro:content';
|
||||
|
||||
interface Props {
|
||||
title?: string;
|
||||
articles: CollectionEntry<'articles'>[];
|
||||
}
|
||||
|
||||
const {
|
||||
title = "文章时间线",
|
||||
articles = []
|
||||
} = Astro.props;
|
||||
|
||||
// 按日期排序文章
|
||||
const sortedArticles = articles.sort(
|
||||
(a, b) => b.data.date.getTime() - a.data.date.getTime()
|
||||
);
|
||||
---
|
||||
|
||||
<div class="container mx-auto px-4 py-8">
|
||||
{title && <h1 class="text-3xl font-bold mb-6 text-primary-900 dark:text-primary-100">{title}</h1>}
|
||||
|
||||
<div id="article-timeline" class="relative space-y-8 before:absolute before:inset-0 before:ml-5 before:h-full before:w-0.5 before:-translate-x-px before:bg-gradient-to-b before:from-transparent before:via-primary-300 before:to-transparent md:before:mx-auto md:before:translate-x-0">
|
||||
{sortedArticles.length > 0 ? (
|
||||
sortedArticles.map((article, index) => {
|
||||
const isEven = index % 2 === 0;
|
||||
return (
|
||||
<div class="relative group">
|
||||
{/* 时间线节点 */}
|
||||
<div class="absolute left-5 -translate-x-1/2 md:left-1/2 top-6 flex h-3 w-3 items-center justify-center">
|
||||
<div class="h-2 w-2 rounded-full bg-primary-500 dark:bg-primary-400 ring-2 ring-white dark:ring-gray-900 ring-offset-2 ring-offset-white dark:ring-offset-gray-900"></div>
|
||||
</div>
|
||||
|
||||
{/* 文章卡片 */}
|
||||
<a href={`/articles/${article.id}`}
|
||||
class={`group/card ml-10 md:ml-0 ${isEven ? 'md:mr-[50%] md:pr-8' : 'md:ml-[50%] md:pl-8'} block`}>
|
||||
<article class="relative flex flex-col gap-4 rounded-xl bg-white dark:bg-gray-800 p-6 shadow-lg hover:shadow-xl hover:-translate-y-1 transition-all duration-300 border border-gray-200 dark:border-gray-700">
|
||||
{/* 日期标签 */}
|
||||
<time datetime={article.data.date.toISOString()}
|
||||
class="absolute top-4 right-4 text-xs font-medium text-secondary-500 dark:text-secondary-400">
|
||||
{article.data.date.toLocaleDateString('zh-CN', {year: 'numeric', month: 'long', day: 'numeric'})}
|
||||
</time>
|
||||
|
||||
{/* 文章标题 */}
|
||||
<h3 class="pr-16 text-xl font-bold text-gray-900 dark:text-gray-100 group-hover/card:text-primary-600 dark:group-hover/card:text-primary-400 transition-colors">
|
||||
{article.data.title}
|
||||
</h3>
|
||||
|
||||
{/* 文章摘要 */}
|
||||
{article.data.summary && (
|
||||
<p class="text-secondary-600 dark:text-secondary-300 line-clamp-2">
|
||||
{article.data.summary}
|
||||
</p>
|
||||
)}
|
||||
|
||||
{/* 文章元信息 */}
|
||||
<div class="flex flex-wrap items-center gap-4 text-sm">
|
||||
{article.data.section && (
|
||||
<span class="flex items-center text-secondary-500 dark:text-secondary-400">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 mr-1" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z" />
|
||||
</svg>
|
||||
{article.data.section}
|
||||
</span>
|
||||
)}
|
||||
|
||||
{article.data.tags && article.data.tags.length > 0 && (
|
||||
<div class="flex flex-wrap gap-2">
|
||||
{article.data.tags.map(tag => (
|
||||
<span class="text-xs bg-primary-50 dark:bg-primary-900/30 text-primary-600 dark:text-primary-400 py-1 px-2 rounded-full">
|
||||
#{tag}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* 阅读更多指示器 */}
|
||||
<div class="flex items-center text-sm text-primary-600 dark:text-primary-400 group-hover/card:translate-x-1 transition-transform">
|
||||
<span class="font-medium">阅读全文</span>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 ml-1" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
</div>
|
||||
</article>
|
||||
</a>
|
||||
</div>
|
||||
);
|
||||
})
|
||||
) : (
|
||||
<div class="text-center py-4 text-secondary-600 dark:text-secondary-400">暂无文章数据</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
import { getCollection, render } from 'astro:content';
|
||||
import { contentStructure, getRelativePath, getBasename, getDirPath, getOriginalPath, getSpecialPath } from '@/content.config';
|
||||
import { contentStructure, getRelativePath, getBasename, getDirPath, getSpecialPath } from '@/content.config';
|
||||
import type { SectionStructure } from '@/content.config';
|
||||
import Layout from '@/components/Layout.astro';
|
||||
import Breadcrumb from '@/components/Breadcrumb.astro';
|
||||
@ -10,6 +10,7 @@ export const prerender = true;
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const articles = await getCollection('articles');
|
||||
const views = ['grid', 'timeline'];
|
||||
|
||||
// 为每篇文章添加section信息
|
||||
const articlesWithSections = articles.map(article => {
|
||||
@ -67,23 +68,41 @@ export async function getStaticPaths() {
|
||||
});
|
||||
|
||||
// 为每篇文章生成路由参数
|
||||
return articlesWithSections.map(article => {
|
||||
const paths = [];
|
||||
for (const article of articlesWithSections) {
|
||||
// 检查文章ID是否需要特殊处理
|
||||
const specialId = getSpecialPath(article.id);
|
||||
|
||||
return {
|
||||
// 添加基本路由
|
||||
paths.push({
|
||||
params: { id: specialId },
|
||||
props: {
|
||||
article,
|
||||
section: article.section,
|
||||
originalId: specialId !== article.id ? article.id : undefined
|
||||
originalId: specialId !== article.id ? article.id : undefined,
|
||||
view: undefined
|
||||
}
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
// 为每个视图添加路由
|
||||
for (const view of views) {
|
||||
paths.push({
|
||||
params: { id: `${specialId}/${view}` },
|
||||
props: {
|
||||
article,
|
||||
section: article.section,
|
||||
originalId: specialId !== article.id ? article.id : undefined,
|
||||
view
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return paths;
|
||||
}
|
||||
|
||||
// 获取文章内容
|
||||
const { article, section, originalId } = Astro.props;
|
||||
const { article, section, originalId, view } = Astro.props;
|
||||
|
||||
// 如果有原始ID,使用它来渲染内容
|
||||
const articleToRender = originalId ? { ...article, id: originalId } : article;
|
||||
@ -108,7 +127,7 @@ const description = article.data.summary || `${article.data.title} - 发布于 $
|
||||
|
||||
// 处理特殊ID的函数
|
||||
function getArticleUrl(articleId: string) {
|
||||
return `/articles/${getSpecialPath(articleId)}`;
|
||||
return `/articles/${getSpecialPath(articleId)}${view ? `/${view}` : ''}`;
|
||||
}
|
||||
---
|
||||
|
||||
@ -139,7 +158,7 @@ function getArticleUrl(articleId: string) {
|
||||
|
||||
<div class="flex items-center gap-3">
|
||||
{/* 返回按钮 */}
|
||||
<a href="/articles" class="text-secondary-500 dark:text-secondary-400 hover:text-primary-600 dark:hover:text-primary-400 transition-colors flex items-center text-sm">
|
||||
<a href={`/articles${view ? `/${view}` : ''}`} class="text-secondary-500 dark:text-secondary-400 hover:text-primary-600 dark:hover:text-primary-400 transition-colors flex items-center text-sm">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 mr-1" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18" />
|
||||
</svg>
|
||||
|
@ -4,7 +4,6 @@ import type { CollectionEntry } from 'astro:content';
|
||||
import { contentStructure } from '../../content.config';
|
||||
import Layout from '@/components/Layout.astro';
|
||||
import Breadcrumb from '@/components/Breadcrumb.astro';
|
||||
import ArticleTimeline from '@/components/ArticleTimeline.astro';
|
||||
|
||||
// 启用静态预渲染
|
||||
export const prerender = true;
|
||||
@ -194,7 +193,7 @@ interface Breadcrumb {
|
||||
|
||||
// 处理特殊ID的函数
|
||||
function getArticleUrl(articleId: string) {
|
||||
return `/articles/${articleId}`;
|
||||
return `/articles/${articleId}${view ? `/${view}` : ''}`;
|
||||
}
|
||||
|
||||
---
|
||||
@ -245,7 +244,7 @@ function getArticleUrl(articleId: string) {
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6 mb-12">
|
||||
{/* 上一级目录卡片 - 仅在浏览目录时显示 */}
|
||||
{!tagFilter && pathSegments.length > 0 && (
|
||||
<a href={`/articles/${pathSegments.length > 1 ? pathSegments.slice(0, -1).join('/') : ''}`}
|
||||
<a href={`/articles/${pathSegments.length > 1 ? pathSegments.slice(0, -1).join('/') : ''}/${view}`}
|
||||
class="group flex flex-col h-full p-5 border border-gray-200 dark:border-gray-700 rounded-xl bg-white dark:bg-gray-800 hover:shadow-xl hover:-translate-y-1 transition-all duration-300 shadow-lg">
|
||||
<div class="flex items-center">
|
||||
<div class="w-10 h-10 flex items-center justify-center rounded-lg bg-primary-100 text-primary-600 group-hover:bg-primary-200 transition-colors">
|
||||
@ -447,7 +446,80 @@ function getArticleUrl(articleId: string) {
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<ArticleTimeline title="" articles={sortedArticles} />
|
||||
<div class="container mx-auto px-4 py-8">
|
||||
{/* 时间线视图 */}
|
||||
<div id="article-timeline" class="relative space-y-8 before:absolute before:inset-0 before:ml-5 before:h-full before:w-0.5 before:-translate-x-px before:bg-gradient-to-b before:from-transparent before:via-primary-300 before:to-transparent md:before:mx-auto md:before:translate-x-0">
|
||||
{sortedArticles.length > 0 ? (
|
||||
sortedArticles.map((article, index) => {
|
||||
const isEven = index % 2 === 0;
|
||||
return (
|
||||
<div class="relative group">
|
||||
{/* 时间线节点 */}
|
||||
<div class="absolute left-5 -translate-x-1/2 md:left-1/2 top-6 flex h-3 w-3 items-center justify-center">
|
||||
<div class="h-2 w-2 rounded-full bg-primary-500 dark:bg-primary-400 ring-2 ring-white dark:ring-gray-900 ring-offset-2 ring-offset-white dark:ring-offset-gray-900"></div>
|
||||
</div>
|
||||
|
||||
{/* 文章卡片 */}
|
||||
<a href={`/articles/${article.id}${viewMode ? `/${viewMode}` : ''}`}
|
||||
class={`group/card ml-10 md:ml-0 ${isEven ? 'md:mr-[50%] md:pr-8' : 'md:ml-[50%] md:pl-8'} block`}>
|
||||
<article class="relative flex flex-col gap-4 rounded-xl bg-white dark:bg-gray-800 p-6 shadow-lg hover:shadow-xl hover:-translate-y-1 transition-all duration-300 border border-gray-200 dark:border-gray-700">
|
||||
{/* 日期标签 */}
|
||||
<time datetime={article.data.date.toISOString()}
|
||||
class="absolute top-4 right-4 text-xs font-medium text-secondary-500 dark:text-secondary-400">
|
||||
{article.data.date.toLocaleDateString('zh-CN', {year: 'numeric', month: 'long', day: 'numeric'})}
|
||||
</time>
|
||||
|
||||
{/* 文章标题 */}
|
||||
<h3 class="pr-16 text-xl font-bold text-gray-900 dark:text-gray-100 group-hover/card:text-primary-600 dark:group-hover/card:text-primary-400 transition-colors">
|
||||
{article.data.title}
|
||||
</h3>
|
||||
|
||||
{/* 文章摘要 */}
|
||||
{article.body && (
|
||||
<p class="text-secondary-600 dark:text-secondary-300 line-clamp-2">
|
||||
{extractSummary(article.body)}
|
||||
</p>
|
||||
)}
|
||||
|
||||
{/* 文章元信息 */}
|
||||
<div class="flex flex-wrap items-center gap-4 text-sm">
|
||||
{article.data.section && (
|
||||
<span class="flex items-center text-secondary-500 dark:text-secondary-400">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 mr-1" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z" />
|
||||
</svg>
|
||||
{article.data.section}
|
||||
</span>
|
||||
)}
|
||||
|
||||
{article.data.tags && article.data.tags.length > 0 && (
|
||||
<div class="flex flex-wrap gap-2">
|
||||
{article.data.tags.map(tag => (
|
||||
<span class="text-xs bg-primary-50 dark:bg-primary-900/30 text-primary-600 dark:text-primary-400 py-1 px-2 rounded-full">
|
||||
#{tag}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* 阅读更多指示器 */}
|
||||
<div class="flex items-center text-sm text-primary-600 dark:text-primary-400 group-hover/card:translate-x-1 transition-transform">
|
||||
<span class="font-medium">阅读全文</span>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 ml-1" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
</div>
|
||||
</article>
|
||||
</a>
|
||||
</div>
|
||||
);
|
||||
})
|
||||
) : (
|
||||
<div class="text-center py-4 text-secondary-600 dark:text-secondary-400">暂无文章数据</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</main>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user