vitepress-theme-base-teek
Version:
查看 [使用说明](https://vp.xiaoying.org.cn/pages/9d746f)
166 lines (145 loc) • 5.33 kB
text/typescript
import type { GroupCardItem, TkContentData, Post } from "./types";
/**
* Post 空数据,方便定义空对象
*/
export const emptyPost: Post = {
originPosts: [],
sortPostsByDateAndSticky: [],
sortPostsByDate: [],
groupPostsByYear: {},
groupPostsByYearMonth: {},
groupPosts: { categories: {}, tags: {} },
groupCards: { categories: [], tags: [] },
locales: {},
};
/**
* 过滤非文章页
* @param posts 所有文章数据
*/
export const filterPosts = (posts: TkContentData[]): TkContentData[] => {
return posts.filter(
({ frontmatter: { catalogue, article, layout } }) => article !== false && layout !== "home"
);
};
/**
* 按置顶和时间排序
* @param posts 过滤非文章页之后的文章数据
*/
export const getSortPostsByDateAndSticky = (posts: TkContentData[]): TkContentData[] => {
// sort 会改变原数组,因此确保参数不被修改,复杂一份
const p = [...posts];
return p.sort((prev, next) => {
// 先根据 sticky 排序,sticky 值越小越靠前,如果 sticky 相同,则按时间排序
const prevSticky = prev.frontmatter.sticky;
const nextSticky = next.frontmatter.sticky;
if (prevSticky && nextSticky) return prevSticky === nextSticky ? compareDate(prev, next) : prevSticky - nextSticky;
if (prevSticky) return -1;
if (nextSticky) return 1;
return compareDate(prev, next);
});
};
/**
* 按时间排序
* @param posts 过滤非文章页之后的文章数据
*/
export const getSortPostsByDate = (posts: TkContentData[]): TkContentData[] => {
// sort 会改变原数组,因此确保参数不被修改,复杂一份
const p = [...posts];
return p.sort((prev, next) => compareDate(prev, next));
};
/**
* 按分类和标签分组
* @param posts 按时间排序之后的文章数据
*/
export const getGroupPosts = (posts: TkContentData[]): Post["groupPosts"] => {
const categoriesObj: Record<string, TkContentData[]> = {};
const tagsObj: Record<string, TkContentData[]> = {};
posts.forEach(post => {
const { categories, tags } = post.frontmatter as { categories: string[]; tags: string[]; [key: string]: any };
[categories || []].flat().forEach(category => {
if (category) {
if (!categoriesObj[category]) categoriesObj[category] = [];
categoriesObj[category].push(post);
}
});
[tags || []].flat().forEach(tag => {
if (tag) {
if (!tagsObj[tag]) tagsObj[tag] = [];
tagsObj[tag].push(post);
}
});
});
return {
categories: categoriesObj,
tags: tagsObj,
};
};
/**
* 获取所有分类和标签
* @param groupPosts 按分类和标签分组之后的文章数据
*/
export const getGroupCards = (groupPosts: Post["groupPosts"]): Post["groupCards"] => {
const categoriesArr: GroupCardItem[] = [];
const tagsArr: GroupCardItem[] = [];
for (let key in groupPosts.categories) categoriesArr.push({ name: key, length: groupPosts.categories[key].length });
for (let key in groupPosts.tags) tagsArr.push({ name: key, length: groupPosts.tags[key].length });
return {
categories: categoriesArr,
tags: tagsArr,
};
};
/**
* 获取文章时间戳
* @param post 文章数据
*/
export const getPostsTime = (post: TkContentData): number => {
const dateStr = post.date;
let date = dateStr ? new Date(dateStr) : new Date();
if ((date as unknown as string) === "Invalid Date" && dateStr) {
return new Date(dateStr.replace(/-/g, "/")).getTime();
}
return date.getTime();
};
/**
* 文章时间排序
* @param prev 文章 1
* @param next 文章 2
*/
export const compareDate = (prev: TkContentData, next: TkContentData) => {
return getPostsTime(next) - getPostsTime(prev);
};
/**
* 根据年份分组,key 为年份,value 为该年份的文章列表,如 { 2025: [{}, {}], 2024: [{}, {}] }
* @param posts 文章列表
*/
export const groupByYear = (posts: TkContentData[]) => {
return posts.reduce(
(pre, cur) => {
// 加个空格转为字符串,避免生产的对象自动根据数字排序(字符串数字也会自定义排序,因此加个空格)
const year = new Date(cur.date || cur.frontmatter.date).getFullYear() + " ";
if (!pre[year]) pre[year] = [];
pre[year].push(cur);
return pre;
},
{} as Post["groupPostsByYear"]
);
};
/**
* 根据年份和月份分组,key 为年份,value 为该年份的月份分组,如:{ 2025: { 01: [{}, {}], 02: [{}, {}] }, 2024: { 01: [], 02: [{}, {}] } }
* @param posts 文章列表
*/
export const groupByYearMonth = (posts: TkContentData[]) => {
return posts.reduce(
(pre, cur) => {
const date = new Date(cur.date || cur.frontmatter.date);
// 加个空格转字符串,避免生成的对象自动根据数字排序(字符串数字也会自定义排序,因此加个空格)
const year = date.getFullYear() + " ";
const month = String(date.getMonth() + 1).padStart(2, "0");
if (!pre[year]) pre[year] = {};
if (!pre[year][month]) pre[year][month] = [];
pre[year][month].push(cur);
return pre;
},
{} as Post["groupPostsByYearMonth"]
);
};