From 71701fa314b88f443f632a892c082a6ba9d3432e Mon Sep 17 00:00:00 2001 From: "tangly1024.com" Date: Thu, 16 May 2024 11:04:35 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E5=87=8F=E5=B0=8FNEXT=5FDATA=E4=BD=93?= =?UTF-8?q?=E7=A7=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/ExternalPlugins.js | 4 +- lib/db/getSiteData.js | 127 +++++++++++++----- .../{mapPageUrl.js => convertInnerUrl.js} | 12 +- lib/notion/getNotionConfig.js | 6 +- lib/notion/getNotionPost.js | 4 +- lib/notion/getPostBlocks.js | 31 +---- package.json | 3 +- 7 files changed, 120 insertions(+), 67 deletions(-) rename lib/notion/{mapPageUrl.js => convertInnerUrl.js} (77%) diff --git a/components/ExternalPlugins.js b/components/ExternalPlugins.js index 89c18688845..616792e84d6 100644 --- a/components/ExternalPlugins.js +++ b/components/ExternalPlugins.js @@ -6,7 +6,7 @@ import TianLiGPT from './TianliGPT' import WebWhiz from './Webwhiz' import { CUSTOM_EXTERNAL_CSS, CUSTOM_EXTERNAL_JS } from '@/blog.config' -import { mapPageUrl } from '@/lib/notion/mapPageUrl' +import { convertInnerUrl } from '@/lib/notion/convertInnerUrl' import { isBrowser, loadExternalResource } from '@/lib/utils' import { useRouter } from 'next/router' import { useEffect } from 'react' @@ -106,7 +106,7 @@ const ExternalPlugin = props => { } // 映射url - mapPageUrl(props?.allNavPages) + convertInnerUrl(props?.allNavPages) }, [router]) useEffect(() => { diff --git a/lib/db/getSiteData.js b/lib/db/getSiteData.js index 272c17f15cc..a4f042bd549 100755 --- a/lib/db/getSiteData.js +++ b/lib/db/getSiteData.js @@ -5,9 +5,9 @@ import getAllPageIds from '@/lib/notion/getAllPageIds' import { getAllTags } from '@/lib/notion/getAllTags' import { getConfigMapFromConfigPage } from '@/lib/notion/getNotionConfig' import getPageProperties, { - adjustPageProperties + adjustPageProperties } from '@/lib/notion/getPageProperties' -import { fetchInBatches, getPostBlocks } from '@/lib/notion/getPostBlocks' +import { fetchInBatches, getPage } from '@/lib/notion/getPostBlocks' import { compressImage, mapImgUrl } from '@/lib/notion/mapImage' import { deepClone } from '@/lib/utils' import { idToUuid } from 'notion-utils' @@ -16,7 +16,7 @@ import { extractLangId, extractLangPrefix } from '../utils/pageId' export { getAllTags } from '../notion/getAllTags' export { getPost } from '../notion/getNotionPost' -export { getPostBlocks } from '../notion/getPostBlocks' +export { getPage as getPostBlocks } from '../notion/getPostBlocks' /** * 获取博客数据; 基于Notion实现 @@ -77,7 +77,16 @@ export async function getNotionPageData({ pageId, from }) { } // 返回给前端的数据做处理 - const db = deepClone(data) + return compressData(deepClone(data)) +} + +/** + * 减少返回给前端的数据 + * 并脱敏 + * @param {*} db + */ +function compressData(db) { + // 清理多余数据 delete db.block delete db.schema delete db.rawMetadata @@ -95,38 +104,96 @@ export async function getNotionPageData({ pageId, from }) { if (db?.post) { db.post = cleanBlock(db?.post) } + + db.tagOptions = cleanIds(db?.tagOptions) + db.categoryOptions = cleanIds(db?.categoryOptions) + db.customMenu = cleanIds(db?.customMenu) + + db.latestPosts = cleanIds(db?.latestPosts) + db.allNavPages = shortenIds(db?.allNavPages) + // db.allPages = cleanBlocks(db?.allPages) + return db } /** - * 清理block数据 + * 清理一组数据的id + * @param {*} items + * @returns */ -function cleanBlock(post) { - const pageBlock = post?.blockMap?.block - for (const i in pageBlock) { - pageBlock[i] = cleanBlock(pageBlock[i]) - delete pageBlock[i]?.role - delete pageBlock[i]?.value?.version - delete pageBlock[i]?.value?.created_by_table - delete pageBlock[i]?.value?.created_by_id - delete pageBlock[i]?.value?.last_edited_by_table - delete pageBlock[i]?.value?.last_edited_by_id - delete pageBlock[i]?.value?.space_id - delete pageBlock[i]?.value?.version - delete pageBlock[i]?.value?.format?.copied_from_pointer - delete pageBlock[i]?.value?.format?.block_locked_by - delete pageBlock[i]?.value?.parent_table - delete pageBlock[i]?.value?.copied_from_pointer - delete pageBlock[i]?.value?.copied_from - delete pageBlock[i]?.value?.created_by_table - delete pageBlock[i]?.value?.created_by_id - delete pageBlock[i]?.value?.last_edited_by_table - delete pageBlock[i]?.value?.last_edited_by_id - delete pageBlock[i]?.value?.permissions - delete pageBlock[i]?.value?.alive +function shortenIds(items) { + if (items && Array.isArray(items)) { + return deepClone( + items.map(item => { + item.short_id = getFirstPart(item.id) + delete item.id + return item + }) + ) } + return items +} + +function getFirstPart(uuid) { + if (!uuid || uuid.indexOf('-') < 0) { + return uuid + } + // 找到第一个 '-' 的位置 + const index = uuid.indexOf('-') + // 截取从开始到第一个 '-' 之前的部分 + return uuid.substring(0, index) +} +/** + * 清理一组数据的id + * @param {*} items + * @returns + */ +function cleanIds(items) { + if (items && Array.isArray(items)) { + return deepClone( + items.map(item => { + delete item.id + return item + }) + ) + } + return items +} + +/** + * 清理block数据 + */ +function cleanBlock(item) { + const post = deepClone(item) + const pageBlock = post?.blockMap?.block + delete post?.id // delete post?.blockMap?.collection + + if (pageBlock) { + for (const i in pageBlock) { + pageBlock[i] = cleanBlock(pageBlock[i]) + delete pageBlock[i]?.role + delete pageBlock[i]?.value?.version + delete pageBlock[i]?.value?.created_by_table + delete pageBlock[i]?.value?.created_by_id + delete pageBlock[i]?.value?.last_edited_by_table + delete pageBlock[i]?.value?.last_edited_by_id + delete pageBlock[i]?.value?.space_id + delete pageBlock[i]?.value?.version + delete pageBlock[i]?.value?.format?.copied_from_pointer + delete pageBlock[i]?.value?.format?.block_locked_by + delete pageBlock[i]?.value?.parent_table + delete pageBlock[i]?.value?.copied_from_pointer + delete pageBlock[i]?.value?.copied_from + delete pageBlock[i]?.value?.created_by_table + delete pageBlock[i]?.value?.created_by_id + delete pageBlock[i]?.value?.last_edited_by_table + delete pageBlock[i]?.value?.last_edited_by_id + delete pageBlock[i]?.value?.permissions + delete pageBlock[i]?.value?.alive + } + } return post } @@ -320,7 +387,7 @@ async function getNotice(post) { return null } - post.blockMap = await getPostBlocks(post.id, 'data-notice') + post.blockMap = await getPage(post.id, 'data-notice') return post } @@ -372,7 +439,7 @@ const EmptyData = pageId => { */ async function getDataBaseInfoByNotionAPI({ pageId, from }) { console.log('[Fetching Data]', pageId, from) - const pageRecordMap = await getPostBlocks(pageId, from) + const pageRecordMap = await getPage(pageId, from) if (!pageRecordMap) { console.error('can`t get Notion Data ; Which id is: ', pageId) return {} diff --git a/lib/notion/mapPageUrl.js b/lib/notion/convertInnerUrl.js similarity index 77% rename from lib/notion/mapPageUrl.js rename to lib/notion/convertInnerUrl.js index 80fe70d8e2b..f4539fb4835 100644 --- a/lib/notion/mapPageUrl.js +++ b/lib/notion/convertInnerUrl.js @@ -1,12 +1,12 @@ -import { uuidToId } from 'notion-utils' +import { idToUuid } from 'notion-utils' import { checkStrIsNotionId, getLastPartOfUrl, isBrowser } from '../utils' /** * 处理页面内连接跳转: - * 1. 若是本站域名,则在当前窗口打开、不开新窗口 - * 2. 若是Notion笔记中的内链,尝试转换成博客中现有的文章地址 + * 1.若是本站域名,则在当前窗口打开、不开新窗口 + * 2.url是notion-id,转成站内文章链接 */ -export const mapPageUrl = allPages => { +export const convertInnerUrl = allPages => { if (isBrowser) { const currentURL = window.location.origin + window.location.pathname const allAnchorTags = document.getElementsByTagName('a') // 或者使用 document.querySelectorAll('a') 获取 NodeList @@ -16,7 +16,9 @@ export const mapPageUrl = allPages => { // 如果url是一个Notion_id,尝试匹配成博客的文章内链 const slug = getLastPartOfUrl(anchorTag.href) if (checkStrIsNotionId(slug)) { - const slugPage = allPages?.find(page => uuidToId(page.id) === slug) + const slugPage = allPages?.find(page => { + return idToUuid(slug).indexOf(page.short_id) === 0 + }) if (slugPage) { anchorTag.href = slugPage?.href } diff --git a/lib/notion/getNotionConfig.js b/lib/notion/getNotionConfig.js index 889005f2a22..c0ef7c29a5f 100644 --- a/lib/notion/getNotionConfig.js +++ b/lib/notion/getNotionConfig.js @@ -9,7 +9,7 @@ import { getDateValue, getTextContent } from 'notion-utils' import { deepClone } from '../utils' import getAllPageIds from './getAllPageIds' -import { getPostBlocks } from './getPostBlocks' +import { getPage } from './getPostBlocks' /** * 从Notion中读取Config配置表 @@ -41,12 +41,12 @@ export async function getConfigMapFromConfigPage(allPages) { } const configPageId = configPage.id // console.log('[Notion配置]请求配置数据 ', configPage.id) - let pageRecordMap = await getPostBlocks(configPageId, 'config-table') + let pageRecordMap = await getPage(configPageId, 'config-table') // console.log('配置中心Page', configPageId, pageRecordMap) let content = pageRecordMap.block[configPageId].value.content for (const table of ['Config-Table', 'CONFIG-TABLE']) { if (content) break - pageRecordMap = await getPostBlocks(configPageId, table) + pageRecordMap = await getPage(configPageId, table) content = pageRecordMap.block[configPageId].value.content } diff --git a/lib/notion/getNotionPost.js b/lib/notion/getNotionPost.js index 3e096a1148b..f5aabb2a15a 100644 --- a/lib/notion/getNotionPost.js +++ b/lib/notion/getNotionPost.js @@ -2,7 +2,7 @@ import BLOG from '@/blog.config' import { idToUuid } from 'notion-utils' import { defaultMapImageUrl } from 'react-notion-x' import formatDate from '../utils/formatDate' -import { getPostBlocks } from './getPostBlocks' +import { getPage } from './getPostBlocks' /** * 根据页面ID获取内容 @@ -10,7 +10,7 @@ import { getPostBlocks } from './getPostBlocks' * @returns */ export async function getPost(pageId) { - const blockMap = await getPostBlocks(pageId, 'slug') + const blockMap = await getPage(pageId, 'slug') if (!blockMap) { return null } diff --git a/lib/notion/getPostBlocks.js b/lib/notion/getPostBlocks.js index 0b151f17be9..8bac9e2ad3f 100644 --- a/lib/notion/getPostBlocks.js +++ b/lib/notion/getPostBlocks.js @@ -10,7 +10,7 @@ import { deepClone, delay } from '../utils' * @param {*} slice * @returns */ -export async function getPostBlocks(id, from, slice) { +export async function getPage(id, from, slice) { const cacheKey = 'page_block_' + id let pageBlock = await getDataFromCache(cacheKey) if (pageBlock) { @@ -27,28 +27,6 @@ export async function getPostBlocks(id, from, slice) { return pageBlock } -/** - * 针对在getDataBaseInfoByNotionAPI=>getPostBlocks中获取不到的溢出的block-id,用此方法另外抓取 - * @param {*} id - * @param {*} from - * @returns - */ -export async function getSingleBlock(id, from) { - const cacheKey = 'single_block_' + id - let pageBlock = await getDataFromCache(cacheKey) - if (pageBlock) { - // console.log('[API<<--缓存]', `from:${from}`, cacheKey) - return pageBlock - } - - pageBlock = await getPageWithRetry(id, 'single_' + from) - - if (pageBlock) { - await setDataToCache(cacheKey, pageBlock) - } - return pageBlock -} - /** * 调用接口,失败会重试 * @param {*} id @@ -162,6 +140,11 @@ function filterPostBlocks(id, blockMap, slice) { * @returns */ export const fetchInBatches = async (ids, batchSize = 100) => { + // 如果 ids 不是数组,则将其转换为数组 + if (!Array.isArray(ids)) { + ids = [ids] + } + const authToken = BLOG.NOTION_ACCESS_TOKEN || null const api = new NotionAPI({ authToken, @@ -171,7 +154,7 @@ export const fetchInBatches = async (ids, batchSize = 100) => { let fetchedBlocks = {} for (let i = 0; i < ids.length; i += batchSize) { const batch = ids.slice(i, i + batchSize) - console.log('[API-->>请求] Fetching missing blocks', ids.length) + console.log('[API-->>请求] Fetching missing blocks', batch, ids.length) const start = new Date().getTime() const pageChunk = await api.getBlocks(batch) const end = new Date().getTime() diff --git a/package.json b/package.json index 5e7761c7e06..9d6259b0cdb 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,8 @@ "start": "next start", "post-build": "next-sitemap --config next-sitemap.config.js", "export": "next build && next-sitemap --config next-sitemap.config.js && next export", - "bundle-report": "cross-env ANALYZE=true yarn build" + "bundle-report": "cross-env ANALYZE=true next build", + "build-all-in-dev": "cross-env VERCEL_ENV=production next build" }, "dependencies": { "@headlessui/react": "^1.7.15", From 59025e801847aebc643613dbbfe4a9d1fac0de6a Mon Sep 17 00:00:00 2001 From: "tangly1024.com" Date: Thu, 16 May 2024 15:29:02 +0800 Subject: [PATCH 2/2] =?UTF-8?q?gitbook=20=E4=B8=BB=E9=A2=98fix=E6=9C=80?= =?UTF-8?q?=E8=BF=91=E9=98=85=E8=AF=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/db/getSiteData.js | 24 ++++++------------------ lib/utils/pageId.js | 16 +++++++++++++++- pages/[prefix]/[slug]/[...suffix].js | 2 +- pages/[prefix]/[slug]/index.js | 2 +- pages/[prefix]/index.js | 2 +- themes/gitbook/index.js | 19 +++++++++---------- 6 files changed, 33 insertions(+), 32 deletions(-) diff --git a/lib/db/getSiteData.js b/lib/db/getSiteData.js index a4f042bd549..f113eb20593 100755 --- a/lib/db/getSiteData.js +++ b/lib/db/getSiteData.js @@ -5,14 +5,14 @@ import getAllPageIds from '@/lib/notion/getAllPageIds' import { getAllTags } from '@/lib/notion/getAllTags' import { getConfigMapFromConfigPage } from '@/lib/notion/getNotionConfig' import getPageProperties, { - adjustPageProperties + adjustPageProperties } from '@/lib/notion/getPageProperties' import { fetchInBatches, getPage } from '@/lib/notion/getPostBlocks' import { compressImage, mapImgUrl } from '@/lib/notion/mapImage' import { deepClone } from '@/lib/utils' import { idToUuid } from 'notion-utils' import { siteConfig } from '../config' -import { extractLangId, extractLangPrefix } from '../utils/pageId' +import { extractLangId, extractLangPrefix, getShortId } from '../utils/pageId' export { getAllTags } from '../notion/getAllTags' export { getPost } from '../notion/getNotionPost' @@ -100,16 +100,14 @@ function compressData(db) { // 清理多余的块 if (db?.notice) { db.notice = cleanBlock(db?.notice) - } - if (db?.post) { - db.post = cleanBlock(db?.post) + delete db.notice?.id } db.tagOptions = cleanIds(db?.tagOptions) db.categoryOptions = cleanIds(db?.categoryOptions) db.customMenu = cleanIds(db?.customMenu) - db.latestPosts = cleanIds(db?.latestPosts) + db.latestPosts = shortenIds(db?.latestPosts) db.allNavPages = shortenIds(db?.allNavPages) // db.allPages = cleanBlocks(db?.allPages) @@ -125,7 +123,7 @@ function shortenIds(items) { if (items && Array.isArray(items)) { return deepClone( items.map(item => { - item.short_id = getFirstPart(item.id) + item.short_id = getShortId(item.id) delete item.id return item }) @@ -134,16 +132,6 @@ function shortenIds(items) { return items } -function getFirstPart(uuid) { - if (!uuid || uuid.indexOf('-') < 0) { - return uuid - } - // 找到第一个 '-' 的位置 - const index = uuid.indexOf('-') - // 截取从开始到第一个 '-' 之前的部分 - return uuid.substring(0, index) -} - /** * 清理一组数据的id * @param {*} items @@ -167,7 +155,7 @@ function cleanIds(items) { function cleanBlock(item) { const post = deepClone(item) const pageBlock = post?.blockMap?.block - delete post?.id + // delete post?.id // delete post?.blockMap?.collection if (pageBlock) { diff --git a/lib/utils/pageId.js b/lib/utils/pageId.js index e3c648e1649..c963df28b62 100644 --- a/lib/utils/pageId.js +++ b/lib/utils/pageId.js @@ -30,4 +30,18 @@ function extractLangId(str) { } } -module.exports = { extractLangPrefix, extractLangId } +/** + * 列表中用过来区分page只需要端的id足够 + */ + +function getShortId(uuid) { + if (!uuid || uuid.indexOf('-') < 0) { + return uuid + } + // 找到第一个 '-' 的位置 + const index = uuid.indexOf('-') + // 截取从开始到第一个 '-' 之前的部分 + return uuid.substring(0, index) +} + +module.exports = { extractLangPrefix, extractLangId, getShortId } diff --git a/pages/[prefix]/[slug]/[...suffix].js b/pages/[prefix]/[slug]/[...suffix].js index 2050e81d8d0..475372666ca 100644 --- a/pages/[prefix]/[slug]/[...suffix].js +++ b/pages/[prefix]/[slug]/[...suffix].js @@ -92,7 +92,7 @@ export async function getStaticProps({ } // 文章内容加载 - if (!props?.posts?.blockMap) { + if (!props?.post?.blockMap) { props.post.blockMap = await getPostBlocks(props.post.id, from) } // 生成全文索引 && JSON.parse(BLOG.ALGOLIA_RECREATE_DATA) diff --git a/pages/[prefix]/[slug]/index.js b/pages/[prefix]/[slug]/index.js index 2c844ebabe5..2b414ce4e49 100644 --- a/pages/[prefix]/[slug]/index.js +++ b/pages/[prefix]/[slug]/index.js @@ -81,7 +81,7 @@ export async function getStaticProps({ params: { prefix, slug }, locale }) { } // 文章内容加载 - if (!props?.posts?.blockMap) { + if (!props?.post?.blockMap) { props.post.blockMap = await getPostBlocks(props.post.id, from) } // 生成全文索引 && JSON.parse(BLOG.ALGOLIA_RECREATE_DATA) diff --git a/pages/[prefix]/index.js b/pages/[prefix]/index.js index 469ca617cdd..973ce32153c 100644 --- a/pages/[prefix]/index.js +++ b/pages/[prefix]/index.js @@ -145,7 +145,7 @@ export async function getStaticProps({ params: { prefix }, locale }) { } // 文章内容加载 - if (!props?.posts?.blockMap) { + if (!props?.post?.blockMap) { props.post.blockMap = await getPostBlocks(props.post.id, from) } diff --git a/themes/gitbook/index.js b/themes/gitbook/index.js index d70e152e003..c81110b0ce7 100644 --- a/themes/gitbook/index.js +++ b/themes/gitbook/index.js @@ -9,6 +9,7 @@ import ShareBar from '@/components/ShareBar' import { siteConfig } from '@/lib/config' import { useGlobal } from '@/lib/global' import { isBrowser } from '@/lib/utils' +import { getShortId } from '@/lib/utils/pageId' import { Transition } from '@headlessui/react' import dynamic from 'next/dynamic' import Link from 'next/link' @@ -54,14 +55,14 @@ function getNavPagesWithLatest(allNavPages, latestPosts, post) { localStorage.getItem('post_read_time') || '{}' ) if (post) { - postReadTime[post.id] = new Date().getTime() + postReadTime[getShortId(post.id)] = new Date().getTime() } // 更新 localStorage.setItem('post_read_time', JSON.stringify(postReadTime)) return allNavPages?.map(item => { const res = { - id: item.id, + short_id: item.short_id, title: item.title || '', pageCoverThumbnail: item.pageCoverThumbnail || '', category: item.category || null, @@ -74,9 +75,9 @@ function getNavPagesWithLatest(allNavPages, latestPosts, post) { } // 属于最新文章通常6篇 && (无阅读记录 || 最近更新时间大于上次阅读时间) if ( - latestPosts.some(post => post.id === item.id) && - (!postReadTime[item.id] || - postReadTime[item.id] < new Date(item.lastEditedDate).getTime()) + latestPosts.some(post => item?.short_id === post?.short_id) && + (!postReadTime[item.short_id] || + postReadTime[item.short_id] < new Date(item.lastEditedDate).getTime()) ) { return { ...res, isLatest: true } } else { @@ -412,11 +413,9 @@ const LayoutArchive = props => { */ const Layout404 = props => { return ( - <> -
- 404 Not found. -
- +
+ 404 Not found. +
) }