cover

走马

陈粒

归档统计

661 字
3 分钟
归档统计
AI 摘要

获取归档列表#

文件路径:src/pages/archive.astro

---
import { getSortedPostsList } from "@/utils/content-utils"; // [!code --]
const sortedPostsList = await getSortedPostsList(); // [!code --]
<ArchivePanel sortedPosts={sortedPostsList} client:only="svelte" /> // [!code --]
import { getArchiveList } from "@/utils/content-utils";
// 获取归档列表(posts + moments + bangumi + life)
const archiveList = await getArchiveList();
// 计算各类型数量
const postsCount = archiveList.filter(item => item.type === "post").length;
const momentsCount = archiveList.filter(item => item.type === "moment").length;
const bangumiCount = archiveList.filter(item => item.type === "bangumi").length;
const lifeCount = archiveList.filter(item => item.type === "life").length;
const totalCount = postsCount + momentsCount + bangumiCount + lifeCount;
---
<MainGridLayout title={i18n(I18nKey.archive)}>
<!-- 统计信息 -->
<div class="card-base px-8 py-6 mb-6">
<div class="flex flex-wrap gap-6 justify-center text-center">
<div class="flex flex-col">
<span class="text-3xl font-bold text-amber-500">{postsCount}</span>
<span class="text-sm text-30 mt-1">{i18n(I18nKey.postList)}</span>
</div>
<div class="w-px bg-neutral-200 dark:bg-neutral-700"></div>
<div class="flex flex-col">
<span class="text-3xl font-bold text-(--primary)">{momentsCount}</span>
<span class="text-sm text-30 mt-1">{i18n(I18nKey.moments)}</span>
</div>
<div class="w-px bg-neutral-200 dark:bg-neutral-700"></div>
<div class="flex flex-col">
<span class="text-3xl font-bold text-red-500 dark:text-red-400">{bangumiCount}</span>
<span class="text-sm text-30 mt-1">{i18n(I18nKey.bangumi)}</span>
</div>
<div class="w-px bg-neutral-200 dark:bg-neutral-700"></div>
<div class="flex flex-col">
<span class="text-3xl font-bold text-emerald-600 dark:text-emerald-400">{lifeCount}</span>
<span class="text-sm text-30 mt-1">生活</span>
</div>
<div class="w-px bg-neutral-200 dark:bg-neutral-700"></div>
<div class="flex flex-col">
<span class="text-3xl font-bold text-(--primary)">{totalCount}</span>
<span class="text-sm text-30 mt-1">总计</span>
</div>
</div>
</div>
<ArchivePanel sortedPosts={archiveList} client:only="svelte" />
</MainGridLayout>

更新内容工具函数文件#

文件路径:src/utils/content-utils.ts

---
import { getCategoryUrl, getPostUrlBySlug } from "@utils/url-utils";
import { getDiaryList } from "@/data/diary"
---
export interface ArchiveItem {
id: string;
type: "post" | "moment" | "bangumi" | "life";
link?: string;
data: {
title: string;
published: Date;
tags: string[];
category?: string | null;
};
}
export async function getArchiveList(): Promise<ArchiveItem[]> {
const posts = await getCollection("posts", ({ data }) => {
return import.meta.env.PROD ? data.draft !== true : true;
});
const diaryList = getDiaryList();
const postItems: ArchiveItem[] = posts.map((post) => ({
id: post.id,
type: "post",
link: getPostUrlBySlug(post.id),
data: {
title: post.data.title,
published: post.data.published,
tags: post.data.tags,
category: post.data.category || null,
},
}));
// 将日记数据转换为归档项
const momentItems: ArchiveItem[] = diaryList.map((diary) => {
let title = diary.content || "";
title = title.replace(/[#*`]/g, "").trim();
if (title.length > 50) title = `${title.substring(0, 50)}...`;
if (!title) title = i18n(I18nKey.moments) || "日常动态";
return {
id: String(diary.id),
type: "moment",
link: "/diary/",
data: {
title: title,
published: new Date(diary.date),
tags: diary.tags || [],
category: null,
},
};
});
// 空数组,用于保持接口兼容性
const bangumiItems: ArchiveItem[] = [];
const lifeItems: ArchiveItem[] = [];
return [...postItems, ...momentItems, ...bangumiItems, ...lifeItems].sort((a, b) => {
const timeA = a.data.published.getTime();
const timeB = b.data.published.getTime();
return timeB - timeA;
});
}

定义类型#

文件路径:src/components/controls/ArchivePanel.svelte

interface Post {
id: string;
type?: "post" | "moment" | "bangumi" | "life";
link?: string;
data: {
title: string;
tags: string[];
category?: string | null;
published: Date;
};
}
{@const postLink = post.link || getPostUrlBySlug(post.id)}
<a
href={getPostUrlBySlug(post.id)} // [!code --]
href={postLink} // [!code ++]
aria-label={post.data.title}
class="group btn-plain block! h-10 w-full rounded-lg hover:text-[initial]"
>
<div
class="w-[70%] md:max-w-[65%] md:w-[65%] text-left font-bold
group-hover:translate-x-1 transition-all group-hover:text-(--primary)
text-75 pr-8 whitespace-nowrap text-ellipsis overflow-hidden flex items-center gap-2"
>
{#if post.type === 'post'}
<span class="px-1.5 py-0.5 text-[10px] bg-amber-500 text-white rounded-md shrink-0 uppercase tracking-wider opacity-80 font-normal">
文章
</span>
{:else if post.type === 'moment'}
<span class="px-1.5 py-0.5 text-[10px] bg-(--primary) text-white rounded-md shrink-0 uppercase tracking-wider opacity-80 font-normal">
{i18n(I18nKey.moments) || 'Moment'}
</span>
{:else if post.type === 'bangumi'}
<span class="px-1.5 py-0.5 text-[10px] bg-red-500 text-white rounded-md shrink-0 uppercase tracking-wider opacity-80 font-normal">
{i18n(I18nKey.bangumi) || 'Record'}
</span>
{:else if post.type === 'life'}
<span class="px-1.5 py-0.5 text-[10px] bg-emerald-600 text-white rounded-md shrink-0 uppercase tracking-wider opacity-80 font-normal">
生活
</span>
{/if}
<span class="truncate">{post.data.title}</span>
</div>

语言配置#

  • 文件路径:src/i18n/i18nKey.ts
moments = "moments",
  • 文件路径:src/i18n/languages/en.ts
[Key.moments]: "Dynamic",
  • 文件路径:src/i18n/languages/ja.ts
[Key.moments]: "ダイナミック",
  • 文件路径:src/i18n/languages/ru.ts
[Key.moments]: "Динамика",
  • 文件路径:src/i18n/languages/zh_CN.ts
[Key.moments]: "动态",
  • 文件路径:src/i18n/languages/zh_TW.ts
[Key.moments]: "動態",

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或打赏支持!

打赏
归档统计
https://my-firefly-blog-dpzi92pofgva.edgeone.cool/blog/ArchiveStatistics/
作者
R1ng13
发布于
2026-06-02
许可协议
CC BY-NC-SA 4.0
相关文章 智能推荐
1
Umami 访问统计卡片
Firefly 最近给博客侧边栏加了个小彩蛋——Umami 访问统计卡片,不用后端、不破风格,数据实时还带点击跳转。整个过程就是在 Firefly 主题里新建一个组件,填入 Umami 的分享链接,系统自动解析 API 和 Token,再配个备用数据兜底。连统计周期都能按需调,比如改成最近 30 天,改个毫秒数就完事~现在每次打开博客,侧边栏都默默告诉我:“今天又被看了好多眼”。
2
集成朋友圈与笔记本功能
Firefly 本教程详细介绍如何将朋友圈(Moments)和笔记本(Notebooks)功能集成到项目中,数据存储在 GitHub Gist 中。
3
隐藏封面图
Firefly 最近在折腾博客的封面图显示逻辑,加了个「隐藏封面图」的开关功能——从类型定义、配置项、工具函数到 UI 控件和样式,一步步把整个流程补全了。代码分散在多个文件里,但核心就一件事:让用户能一键收起或展开文章封面,既保持页面简洁,又不丢失视觉层次。顺手还做了多语言支持,中文、英文切换也一起配上了。
4
给博客增加单个和全部分类页面
Firefly 最近给博客加了个小功能:点击分类名就能跳转到该分类下的所有文章,还能一键查看全部分类列表——整个过程其实挺顺的,从创建页面、写 URL 工具函数,到更新导航栏和多语言支持,一步步配下来,连分类链接都自动带上了本地化路径,现在逛自己博客像逛图书馆一样清爽 😄
5
恋爱计时组件
Firefly 最近给博客加了个小彩蛋——「恋爱计时组件」,从零撸了一个记录纪念日的小工具。写了组件代码、配了全局注册、还兼顾了桌面端侧边栏和移动端的显示逻辑,连 TypeScript 类型定义和双方昵称/日期的配置项都琢磨得挺细。虽然只是个轻量小功能,但每次看到倒计时跳动,心里都悄悄甜一下 😊
随机文章 随机推荐

评论区

Profile Image of the Author
R1ng13
Hello, I'm R1ng13.
📢 欢迎来访者
👋🏻 Hi,我是R1ng13,欢迎您!
分类
标签
站点统计
文章
11
分类
2
标签
5
总字数
4,867
运行时长
0
最后活动
0 天前
站点信息
构建平台
EdgeOne
博客版本
Firefly v6.12.3
文章许可
CC BY-NC-SA 4.0
音乐
封面

音乐

暂未播放

0:00 0:00
暂无歌词
我和宝宝在一起已经
---------TSH ❤️ CXY---------
---------TSH
❤️
CXY---------
0 0 0 0 0 00
✨ 今日一言
" 山重水复疑无路,柳暗花明又一村。 "
—— 陆游
天气预报
统计

文章目录

✨️ 复制成功,转载请标注本文地址