mirror of
https://github.com/d0zingcat/NotionNext.git
synced 2026-05-13 15:09:13 +00:00
184 lines
5.0 KiB
JavaScript
184 lines
5.0 KiB
JavaScript
/**
|
|
* 文章相关工具
|
|
*/
|
|
import { isHttpLink } from '.'
|
|
import { getPostBlocks } from '@/lib/db/getSiteData'
|
|
import { getPageTableOfContents } from '@/lib/notion/getPageTableOfContents'
|
|
import { siteConfig } from '@/lib/config'
|
|
import { getDataFromCache, setDataToCache } from '@/lib/cache/cache_manager'
|
|
import { getAiSummary } from '@/lib/plugins/aiSummary'
|
|
import BLOG from '@/blog.config'
|
|
import { uploadDataToAlgolia } from '@/lib/plugins/algolia'
|
|
import { countWords } from '@/lib/plugins/wordCount'
|
|
import { getPageContentText } from '@/lib/notion/getPageContentText'
|
|
|
|
/**
|
|
* 获取文章的关联推荐文章列表,目前根据标签关联性筛选
|
|
* @param post
|
|
* @param {*} allPosts
|
|
* @param {*} count
|
|
* @returns
|
|
*/
|
|
export function getRecommendPost(post, allPosts, count = 6) {
|
|
let recommendPosts = []
|
|
const postIds = []
|
|
const currentTags = post?.tags || []
|
|
for (let i = 0; i < allPosts.length; i++) {
|
|
const p = allPosts[i]
|
|
if (p.id === post.id || p.type.indexOf('Post') < 0) {
|
|
continue
|
|
}
|
|
|
|
for (let j = 0; j < currentTags.length; j++) {
|
|
const t = currentTags[j]
|
|
if (postIds.indexOf(p.id) > -1) {
|
|
continue
|
|
}
|
|
if (p.tags && p.tags.indexOf(t) > -1) {
|
|
recommendPosts.push(p)
|
|
postIds.push(p.id)
|
|
}
|
|
}
|
|
}
|
|
|
|
if (recommendPosts.length > count) {
|
|
recommendPosts = recommendPosts.slice(0, count)
|
|
}
|
|
return recommendPosts
|
|
}
|
|
|
|
/**
|
|
* 确认slug中不包含 / 符号
|
|
* @param {*} row
|
|
* @returns
|
|
*/
|
|
export function checkSlugHasNoSlash(row) {
|
|
let slug = row.slug
|
|
if (slug.startsWith('/')) {
|
|
slug = slug.substring(1)
|
|
}
|
|
return (
|
|
(slug.match(/\//g) || []).length === 0 &&
|
|
!isHttpLink(slug) &&
|
|
row.type.indexOf('Menu') < 0
|
|
)
|
|
}
|
|
|
|
/**
|
|
* 检查url中包含一个 /
|
|
* @param {*} row
|
|
* @returns
|
|
*/
|
|
export function checkSlugHasOneSlash(row) {
|
|
let slug = row.slug
|
|
if (slug.startsWith('/')) {
|
|
slug = slug.substring(1)
|
|
}
|
|
return (
|
|
(slug.match(/\//g) || []).length === 1 &&
|
|
!isHttpLink(slug) &&
|
|
row.type.indexOf('Menu') < 0
|
|
)
|
|
}
|
|
|
|
/**
|
|
* 检查url中包含两个及以上的 /
|
|
* @param {*} row
|
|
* @returns
|
|
*/
|
|
export function checkSlugHasMorThanTwoSlash(row) {
|
|
let slug = row.slug
|
|
if (slug.startsWith('/')) {
|
|
slug = slug.substring(1)
|
|
}
|
|
return (
|
|
(slug.match(/\//g) || []).length >= 2 &&
|
|
row.type.indexOf('Menu') < 0 &&
|
|
!isHttpLink(slug)
|
|
)
|
|
}
|
|
|
|
/**
|
|
* 获取文章摘要
|
|
* @param props
|
|
* @param pageContentText
|
|
* @returns {Promise<void>}
|
|
*/
|
|
async function getPageAISummary(props, pageContentText) {
|
|
const aiSummaryAPI = siteConfig('AI_SUMMARY_API')
|
|
if (aiSummaryAPI) {
|
|
const post = props.post
|
|
const cacheKey = `ai_summary_${post.id}`
|
|
let aiSummary = await getDataFromCache(cacheKey)
|
|
if (aiSummary) {
|
|
props.post.aiSummary = aiSummary
|
|
} else {
|
|
const aiSummaryKey = siteConfig('AI_SUMMARY_KEY')
|
|
const aiSummaryCacheTime = siteConfig('AI_SUMMARY_CACHE_TIME')
|
|
const wordLimit = siteConfig('AI_SUMMARY_WORD_LIMIT', '1000')
|
|
let content = ''
|
|
for (let heading of post.toc) {
|
|
content += heading.text + ' '
|
|
}
|
|
content += pageContentText
|
|
const combinedText = post.title + ' ' + content
|
|
const truncatedText = combinedText.slice(0, wordLimit)
|
|
aiSummary = await getAiSummary(aiSummaryAPI, aiSummaryKey, truncatedText)
|
|
await setDataToCache(cacheKey, aiSummary, aiSummaryCacheTime)
|
|
props.post.aiSummary = aiSummary
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 处理文章数据
|
|
* @param props
|
|
* @param from
|
|
* @returns {Promise<void>}
|
|
*/
|
|
export async function processPostData(props, from) {
|
|
// 文章内容加载
|
|
if (!props?.post?.blockMap) {
|
|
props.post.blockMap = await getPostBlocks(props.post.id, from)
|
|
}
|
|
|
|
if (props.post?.blockMap?.block) {
|
|
// 目录默认加载
|
|
props.post.content = Object.keys(props.post.blockMap.block).filter(
|
|
key => props.post.blockMap.block[key]?.value?.parent_id === props.post.id
|
|
)
|
|
props.post.toc = getPageTableOfContents(props.post, props.post.blockMap)
|
|
const pageContentText = getPageContentText(props.post, props.post.blockMap)
|
|
const { wordCount, readTime } = countWords(pageContentText)
|
|
props.post.wordCount = wordCount
|
|
props.post.readTime = readTime
|
|
await getPageAISummary(props, pageContentText)
|
|
}
|
|
|
|
// 生成全文索引 && JSON.parse(BLOG.ALGOLIA_RECREATE_DATA)
|
|
if (BLOG.ALGOLIA_APP_ID) {
|
|
uploadDataToAlgolia(props?.post)
|
|
}
|
|
|
|
// 推荐关联文章处理
|
|
const allPosts = props.allPages?.filter(
|
|
page => page.type === 'Post' && page.status === 'Published'
|
|
)
|
|
if (allPosts && allPosts.length > 0) {
|
|
const index = allPosts.indexOf(props.post)
|
|
props.prev = allPosts.slice(index - 1, index)[0] ?? allPosts.slice(-1)[0]
|
|
props.next = allPosts.slice(index + 1, index + 2)[0] ?? allPosts[0]
|
|
props.recommendPosts = getRecommendPost(
|
|
props.post,
|
|
allPosts,
|
|
siteConfig('POST_RECOMMEND_COUNT')
|
|
)
|
|
} else {
|
|
props.prev = null
|
|
props.next = null
|
|
props.recommendPosts = []
|
|
}
|
|
|
|
delete props.allPages
|
|
}
|