UNPKG

vitepress-theme-base-teek

Version:

查看 [使用说明](https://vp.xiaoying.org.cn/pages/9d746f)

166 lines (145 loc) 5.33 kB
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"] ); };