mirror of
https://github.com/d0zingcat/NotionNext.git
synced 2026-05-14 07:26:52 +00:00
重构优化NotionData
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
export { getAllPosts } from './notion/getAllPosts'
|
||||
export { getAllTags } from './notion/getAllTags'
|
||||
export { getPostBlocks } from './notion/getPostBlocks'
|
||||
export { getAllCategories } from './notion/getAllCategories'
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
import { isIterable } from '../utils'
|
||||
|
||||
/**
|
||||
* 获取所有文章的分类
|
||||
* @param allPosts
|
||||
* @returns {Promise<{}|*[]>}
|
||||
*/
|
||||
export async function getAllCategories({ allPosts, categoryOptions, sliceCount = 0 }) {
|
||||
if (!allPosts || !categoryOptions) {
|
||||
return []
|
||||
}
|
||||
// 计数
|
||||
let categories = allPosts.map(p => p.category)
|
||||
categories = [...categories.flat()]
|
||||
const categoryObj = {}
|
||||
categories.forEach(category => {
|
||||
if (category in categoryObj) {
|
||||
categoryObj[category]++
|
||||
} else {
|
||||
categoryObj[category] = 1
|
||||
}
|
||||
})
|
||||
const list = []
|
||||
if (isIterable(categoryOptions)) {
|
||||
for (const c of categoryOptions) {
|
||||
const count = categoryObj[c.value]
|
||||
if (count) {
|
||||
list.push({ id: c.id, name: c.value, color: c.color, count })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 按照数量排序
|
||||
// list.sort((a, b) => b.count - a.count)
|
||||
if (sliceCount && sliceCount > 0) {
|
||||
return list.slice(0, sliceCount)
|
||||
} else {
|
||||
return list
|
||||
}
|
||||
}
|
||||
@@ -73,19 +73,3 @@ function getPostCover(id, block) {
|
||||
if (pageCover.startsWith('http')) return defaultMapImageUrl(pageCover, block[id].value)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取博文总数
|
||||
* @param {*} param0
|
||||
* @returns
|
||||
*/
|
||||
export async function getAllPostCount({ notionPageData, from }) {
|
||||
if (!notionPageData) {
|
||||
notionPageData = await getNotionPageData({ from })
|
||||
}
|
||||
if (!notionPageData) {
|
||||
return []
|
||||
}
|
||||
const allPosts = await getAllPosts({ notionPageData, from, pageType: ['Post'] })
|
||||
return allPosts?.length || 0
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import { isIterable } from '../utils'
|
||||
* @param tagOptions tags的下拉选项
|
||||
* @returns {Promise<{}|*[]>}
|
||||
*/
|
||||
export async function getAllTags({ allPosts, sliceCount = 0, tagOptions }) {
|
||||
export function getAllTags({ allPosts, sliceCount = 0, tagOptions }) {
|
||||
if (!allPosts || !tagOptions) {
|
||||
return []
|
||||
}
|
||||
|
||||
@@ -3,9 +3,11 @@ import { getDataFromCache, setDataToCache } from '@/lib/cache/cache_manager'
|
||||
import { getPostBlocks } from '@/lib/notion/getPostBlocks'
|
||||
import { idToUuid } from 'notion-utils'
|
||||
import { defaultMapImageUrl } from 'react-notion-x'
|
||||
import { getAllCategories } from './getAllCategories'
|
||||
import { getAllPosts, getAllPostCount } from './getAllPosts'
|
||||
import { isIterable } from '../utils'
|
||||
import getAllPageIds from './getAllPageIds'
|
||||
import { getAllPosts } from './getAllPosts'
|
||||
import { getAllTags } from './getAllTags'
|
||||
import getPageProperties from './getPageProperties'
|
||||
|
||||
/**
|
||||
* 获取博客数据
|
||||
@@ -15,40 +17,18 @@ import { getAllTags } from './getAllTags'
|
||||
* @param categoryCount
|
||||
* @param tagsCount 截取标签数量
|
||||
* @param pageType 过滤的文章类型,数组格式 ['Page','Post']
|
||||
* @returns {
|
||||
allPosts, 所有博客
|
||||
latestPosts,
|
||||
categories, 所有分类
|
||||
postCount,
|
||||
customNav, 自定义导航菜单
|
||||
tags, 所有标签
|
||||
siteInfo:{
|
||||
title,
|
||||
description,
|
||||
pageCover
|
||||
}
|
||||
}
|
||||
* @returns
|
||||
*
|
||||
*/
|
||||
export async function getGlobalNotionData({
|
||||
pageId = BLOG.NOTION_PAGE_ID,
|
||||
from,
|
||||
latestPostCount = 5,
|
||||
categoryCount = BLOG.PREVIEW_CATEGORY_COUNT,
|
||||
tagsCount = BLOG.PREVIEW_TAG_COUNT,
|
||||
pageType = ['Post']
|
||||
}) {
|
||||
const notionPageData = await getNotionPageData({ pageId, from })
|
||||
const siteInfo = await getBlogInfo({ notionPageData, from })
|
||||
const tagOptions = notionPageData.tagOptions
|
||||
const categoryOptions = notionPageData.categoryOptions
|
||||
const customNav = await getCustomNav({ notionPageData })
|
||||
const allPosts = await getAllPosts({ notionPageData, from, pageType })
|
||||
const postCount = await getAllPostCount({ notionPageData, from })
|
||||
const categories = await getAllCategories({ allPosts, categoryOptions, sliceCount: categoryCount })
|
||||
const tags = await getAllTags({ allPosts, tagOptions, sliceCount: tagsCount })
|
||||
const latestPosts = await getLatestPosts({ notionPageData, from, latestPostCount })
|
||||
return { allPosts, latestPosts, categories, postCount, customNav, tags, siteInfo }
|
||||
notionPageData.allPosts = allPosts
|
||||
return notionPageData
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -56,8 +36,7 @@ export async function getGlobalNotionData({
|
||||
* @param {*}} param0
|
||||
* @returns
|
||||
*/
|
||||
async function getLatestPosts({ notionPageData, from, latestPostCount }) {
|
||||
const allPosts = await getAllPosts({ notionPageData, from, pageType: ['Post'] })
|
||||
function getLatestPosts({ allPosts, from, latestPostCount }) {
|
||||
const latestPosts = Object.create(allPosts).sort((a, b) => {
|
||||
const dateA = new Date(a?.lastEditedTime || a?.createdTime || a?.date?.start_date)
|
||||
const dateB = new Date(b?.lastEditedTime || b?.createdTime || b?.date?.start_date)
|
||||
@@ -79,7 +58,7 @@ export async function getNotionPageData({ pageId, from }) {
|
||||
// 尝试从缓存获取
|
||||
const cacheKey = 'page_block_' + pageId
|
||||
const data = await getDataFromCache(cacheKey)
|
||||
if (data) {
|
||||
if (data && data.pageIds?.length > 0) {
|
||||
console.log('[请求缓存]:', `from:${from}`, `root-page-id:${pageId}`)
|
||||
return data
|
||||
}
|
||||
@@ -96,14 +75,7 @@ export async function getNotionPageData({ pageId, from }) {
|
||||
* @param notionPageData
|
||||
* @returns {Promise<[]|*[]>}
|
||||
*/
|
||||
async function getCustomNav({ notionPageData }) {
|
||||
if (!notionPageData) {
|
||||
notionPageData = await getNotionPageData({ from: 'custom-nav' })
|
||||
}
|
||||
if (!notionPageData) {
|
||||
return []
|
||||
}
|
||||
const allPage = await getAllPosts({ notionPageData, from: 'custom-nav', pageType: ['Page'] })
|
||||
function getCustomNav({ allPage }) {
|
||||
const customNav = []
|
||||
if (allPage && allPage.length > 0) {
|
||||
allPage.forEach(p => {
|
||||
@@ -139,23 +111,55 @@ function getCategoryOptions(schema) {
|
||||
return categorySchema?.options || []
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有文章的分类
|
||||
* @param allPosts
|
||||
* @returns {Promise<{}|*[]>}
|
||||
*/
|
||||
function getAllCategories({ allPosts, categoryOptions, sliceCount = 0 }) {
|
||||
if (!allPosts || !categoryOptions) {
|
||||
return []
|
||||
}
|
||||
// 计数
|
||||
let categories = allPosts.map(p => p.category)
|
||||
categories = [...categories.flat()]
|
||||
const categoryObj = {}
|
||||
categories.forEach(category => {
|
||||
if (category in categoryObj) {
|
||||
categoryObj[category]++
|
||||
} else {
|
||||
categoryObj[category] = 1
|
||||
}
|
||||
})
|
||||
const list = []
|
||||
if (isIterable(categoryOptions)) {
|
||||
for (const c of categoryOptions) {
|
||||
const count = categoryObj[c.value]
|
||||
if (count) {
|
||||
list.push({ id: c.id, name: c.value, color: c.color, count })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 按照数量排序
|
||||
// list.sort((a, b) => b.count - a.count)
|
||||
if (sliceCount && sliceCount > 0) {
|
||||
return list.slice(0, sliceCount)
|
||||
} else {
|
||||
return list
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 站点信息
|
||||
* @param notionPageData
|
||||
* @param from
|
||||
* @returns {Promise<{title,description,pageCover}>}
|
||||
*/
|
||||
async function getBlogInfo({ notionPageData, from }) {
|
||||
if (!notionPageData) {
|
||||
notionPageData = await getNotionPageData({ from })
|
||||
}
|
||||
if (!notionPageData) {
|
||||
return null
|
||||
}
|
||||
const collection = notionPageData?.collection
|
||||
function getBlogInfo(collection, block) {
|
||||
const title = collection?.name?.[0][0] || BLOG.TITLE
|
||||
const description = collection?.description?.[0][0] || BLOG.DESCRIPTION
|
||||
const pageCover = mapCoverUrl(collection?.cover, notionPageData.block)
|
||||
const pageCover = mapCoverUrl(collection?.cover, block)
|
||||
return { title, description, pageCover }
|
||||
}
|
||||
|
||||
@@ -183,24 +187,48 @@ async function getPageRecordMapByNotionAPI({ pageId, from }) {
|
||||
if (!pageRecordMap) {
|
||||
return []
|
||||
}
|
||||
pageId = idToUuid(pageId)
|
||||
const collection = Object.values(pageRecordMap.collection)[0]?.value
|
||||
const collectionQuery = pageRecordMap.collection_query
|
||||
const block = pageRecordMap.block
|
||||
const schema = collection?.schema
|
||||
const rawMetadata = block[pageId].value
|
||||
const tagOptions = getTagOptions(schema)
|
||||
const categoryOptions = getCategoryOptions(schema)
|
||||
|
||||
// Check Type Page-Database和Inline-Database
|
||||
if (
|
||||
rawMetadata?.type !== 'collection_view_page' &&
|
||||
rawMetadata?.type !== 'collection_view'
|
||||
rawMetadata?.type !== 'collection_view'
|
||||
) {
|
||||
console.warn(`pageId "${pageId}" is not a database`)
|
||||
return null
|
||||
}
|
||||
|
||||
pageId = idToUuid(pageId)
|
||||
const collection = Object.values(pageRecordMap.collection)[0]?.value
|
||||
const collectionQuery = pageRecordMap.collection_query
|
||||
const schema = collection?.schema
|
||||
const tagOptions = getTagOptions(schema)
|
||||
const categoryOptions = getCategoryOptions(schema)
|
||||
|
||||
const data = []
|
||||
const pageIds = getAllPageIds(collectionQuery)
|
||||
for (let i = 0; i < pageIds.length; i++) {
|
||||
const id = pageIds[i]
|
||||
const properties = (await getPageProperties(id, block, schema)) || null
|
||||
properties.slug = properties.slug ?? properties.id
|
||||
delete properties.content
|
||||
data.push(properties)
|
||||
}
|
||||
|
||||
const allPage = data.filter(post => {
|
||||
return post.title && post?.status?.[0] === 'Published' && ['Page'].indexOf(post?.type?.[0]) > -1
|
||||
})
|
||||
const allPosts = data.filter(post => {
|
||||
return post.title && post?.status?.[0] === 'Published' && ['Post'].indexOf(post?.type?.[0]) > -1
|
||||
})
|
||||
|
||||
const customNav = getCustomNav({ allPage })
|
||||
const postCount = allPosts?.length || 0
|
||||
const categories = getAllCategories({ allPosts, categoryOptions, sliceCount: BLOG.PREVIEW_CATEGORY_COUNT })
|
||||
const tags = getAllTags({ allPosts, tagOptions, sliceCount: BLOG.PREVIEW_TAG_COUNT })
|
||||
const latestPosts = getLatestPosts({ allPosts, from, latestPostCount: 5 })
|
||||
const siteInfo = getBlogInfo({ collection, block })
|
||||
|
||||
return {
|
||||
collection,
|
||||
collectionQuery,
|
||||
@@ -208,6 +236,13 @@ async function getPageRecordMapByNotionAPI({ pageId, from }) {
|
||||
schema,
|
||||
tagOptions,
|
||||
categoryOptions,
|
||||
rawMetadata
|
||||
rawMetadata,
|
||||
siteInfo,
|
||||
customNav,
|
||||
postCount,
|
||||
pageIds,
|
||||
categories,
|
||||
tags,
|
||||
latestPosts
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import { getGlobalNotionData } from '@/lib/notion/getNotionData'
|
||||
export async function getServerSideProps ({ res }) {
|
||||
res.setHeader('Content-Type', 'text/xml')
|
||||
// 获取最新文章
|
||||
const globalNotionData = await getGlobalNotionData({ from: 'rss', latestPostCount: 5 })
|
||||
const globalNotionData = await getGlobalNotionData({ from: 'rss' })
|
||||
const xmlFeed = await generateRss(globalNotionData?.latestPosts || [])
|
||||
res.write(xmlFeed)
|
||||
res.end()
|
||||
|
||||
@@ -16,7 +16,7 @@ export async function getStaticProps() {
|
||||
const meta = {
|
||||
title: `${siteInfo?.title} | ${siteInfo?.description}`,
|
||||
description: siteInfo?.description,
|
||||
image: siteInfo.pageCover,
|
||||
image: siteInfo?.pageCover,
|
||||
slug: '',
|
||||
type: 'website'
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ function getTagNames(tags) {
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const from = 'tag-static-path'
|
||||
const { tags } = await getGlobalNotionData({ from, tagsCount: 0 })
|
||||
const { tags } = await getGlobalNotionData({ from })
|
||||
const tagNames = getTagNames(tags)
|
||||
|
||||
return {
|
||||
|
||||
@@ -19,7 +19,7 @@ const TagIndex = props => {
|
||||
|
||||
export async function getStaticProps() {
|
||||
const from = 'tag-index-props'
|
||||
const props = await getGlobalNotionData({ from, tagsCount: 0 })
|
||||
const props = await getGlobalNotionData({ from })
|
||||
return {
|
||||
props,
|
||||
revalidate: 1
|
||||
|
||||
@@ -103,7 +103,7 @@ const Header = props => {
|
||||
className="duration-500 md:bg-fixed w-full bg-cover bg-center h-screen bg-black text-white"
|
||||
style={{
|
||||
backgroundImage:
|
||||
`linear-gradient(rgba(0, 0, 0, 0.8), rgba(0,0,0,0.2), rgba(0, 0, 0, 0.8) ),url("${siteInfo.pageCover}")`
|
||||
`linear-gradient(rgba(0, 0, 0, 0.8), rgba(0,0,0,0.2), rgba(0, 0, 0, 0.8) ),url("${siteInfo?.pageCover}")`
|
||||
}}
|
||||
>
|
||||
<div className="absolute flex flex-col h-full items-center justify-center w-full font-sans">
|
||||
|
||||
@@ -98,7 +98,7 @@ export default function Header(props) {
|
||||
className="duration-500 md:bg-fixed w-full bg-cover bg-center h-screen bg-black"
|
||||
style={{
|
||||
backgroundImage:
|
||||
`linear-gradient(rgba(0, 0, 0, 0.8), rgba(0,0,0,0.2), rgba(0, 0, 0, 0.8) ),url("${siteInfo.pageCover}")`
|
||||
`linear-gradient(rgba(0, 0, 0, 0.8), rgba(0,0,0,0.2), rgba(0, 0, 0, 0.8) ),url("${siteInfo?.pageCover}")`
|
||||
}}
|
||||
>
|
||||
<div className="absolute flex h-full items-center lg:-mt-14 justify-center w-full text-4xl md:text-7xl text-white">
|
||||
|
||||
Reference in New Issue
Block a user