更改字段

This commit is contained in:
Blackberry009
2025-06-18 11:16:58 +08:00
parent 088ae612be
commit b2714fa4a5
11 changed files with 50 additions and 219 deletions

View File

@@ -19,7 +19,7 @@ export { getPost } from '../notion/getNotionPost'
export { getPage as getPostBlocks } from '../notion/getPostBlocks'
/**
* 获取博客数据; 基于Notion实现
* 获取博客数据; 基于 Notion 实现
* @param {*} pageId
* @param {*} from
* @param {*} locale 语言 zh|en|jp 等等
@@ -31,7 +31,7 @@ export async function getGlobalData({
from,
locale
}) {
// 获取站点数据 如果pageId有逗号隔开则分次取数据
// 获取站点数据如果 pageId 有逗号隔开则分次取数据
const siteIds = pageId?.split(',') || []
let data = EmptyData(pageId)
@@ -65,7 +65,7 @@ export async function getGlobalData({
* @returns {Promise<JSX.Element|*|*[]>}
*/
export async function getSiteDataByPageId({ pageId, from }) {
// 获取NOTION原始数据此接支持mem缓存。
// 获取 NOTION 原始数据,此接支持 mem 缓存。
return await getOrSetDataWithCache(
`site_data_${pageId}`,
async (pageId, from) => {
@@ -101,7 +101,7 @@ const EmptyData = pageId => {
allPages: [
{
id: 1,
title: `无法获取Notion数据请检查Notion_ID \n 当前 ${pageId}`,
title: `无法获取 Notion 数据,请检查 Notion_ID \n 当前 ${pageId}`,
summary:
'访问文档获取帮助 → https://docs.tangly1024.com/article/vercel-deploy-notion-next',
status: 'Published',
@@ -137,7 +137,7 @@ const EmptyData = pageId => {
}
/**
* 将Notion数据转站点数据
* 将 Notion 数据转站点数据
* 这里统一对数据格式化
* @returns {Promise<JSX.Element|null|*>}
*/
@@ -149,7 +149,7 @@ async function convertNotionToSiteData(pageId, from, pageRecordMap) {
pageId = idToUuid(pageId)
let block = pageRecordMap.block || {}
const rawMetadata = block[pageId]?.value
// Check Type Page-DatabaseInline-Database
// Check Type Page-DatabaseInline-Database
if (
rawMetadata?.type !== 'collection_view_page' &&
rawMetadata?.type !== 'collection_view'
@@ -175,7 +175,7 @@ async function convertNotionToSiteData(pageId, from, pageRecordMap) {
if (pageIds?.length === 0) {
console.error(
'获取到的文章列表为空请检查notion模板',
'获取到的文章列表为空,请检查 notion 模板',
collectionQuery,
collection,
collectionView,
@@ -183,10 +183,10 @@ async function convertNotionToSiteData(pageId, from, pageRecordMap) {
pageRecordMap
)
} else {
// console.log('有效Page数量', pageIds?.length)
// console.log('有效 Page 数量', pageIds?.length)
}
// 抓取主数据库最多抓取1000blocks溢出的数block这里统一抓取一遍
// 抓取主数据库最多抓取 1000blocks溢出的数 block 这里统一抓取一遍
const blockIdsNeedFetch = []
for (let i = 0; i < pageIds.length; i++) {
const id = pageIds[i]
@@ -369,21 +369,21 @@ function handleDataBeforeReturn(db) {
p.date.time_zone
)
console.log(
'[定时发布] 隐藏--> 文章:',
'[定时发布] 隐藏--> 文章',
p.title,
'当前时间戳:',
'当前时间戳',
currentTimestamp,
'目标时间戳:',
'目标时间戳',
startTimestamp,
'-',
endTimestamp
)
console.log(
'[定时发布] 隐藏--> 文章:',
'[定时发布] 隐藏--> 文章',
p.title,
'当前时间:',
'当前时间',
new Date(),
'目标时间:',
'目标时间',
p.date
)
// 隐藏
@@ -431,7 +431,7 @@ function cleanPages(allPages, tagOptions) {
}
/**
* 清理一组数据的id
* 清理一组数据的 id
* @param {*} items
* @returns
*/
@@ -449,7 +449,7 @@ function shortenIds(items) {
}
/**
* 清理一组数据的id
* 清理一组数据的 id
* @param {*} items
* @returns
*/
@@ -466,7 +466,7 @@ function cleanIds(items) {
}
/**
* 清理和过滤tagOptions
* 清理和过滤 tagOptions
* @param {*} tagOptions
* @returns
*/
@@ -482,7 +482,7 @@ function cleanTagOptions(tagOptions) {
}
/**
* 清理block数据
* 清理 block 数据
*/
function cleanBlock(item) {
const post = deepClone(item)
@@ -537,7 +537,7 @@ function getLatestPosts({ allPages, from, latestPostCount }) {
/**
* 获取用户自定义单页菜单
* 旧版本不读取Menu菜单而是读取type=Page生成菜单
* 旧版本,不读取 Menu 菜单,而是读取 type=Page 生成菜单
* @param notionPageData
* @returns {Promise<[]|*[]>}
*/
@@ -625,7 +625,7 @@ function getCategoryOptions(schema) {
function getSiteInfo({ collection, block, NOTION_CONFIG }) {
const defaultTitle = NOTION_CONFIG?.TITLE || 'NotionNext BLOG'
const defaultDescription =
NOTION_CONFIG?.DESCRIPTION || '这是一个由NotionNext生成的站点'
NOTION_CONFIG?.DESCRIPTION || '这是一个由 NotionNext 生成的站点'
const defaultPageCover = NOTION_CONFIG?.HOME_BANNER_IMAGE || '/bg_image.jpg'
const defaultIcon = NOTION_CONFIG?.AVATAR || '/avatar.svg'
const defaultLink = NOTION_CONFIG?.LINK || BLOG.LINK
@@ -658,7 +658,7 @@ function getSiteInfo({ collection, block, NOTION_CONFIG }) {
// 站点网址
const link = NOTION_CONFIG?.LINK || defaultLink
// 站点图标不能是emoji
// 站点图标不能是 emoji
const emojiPattern = /\uD83C[\uDF00-\uDFFF]|\uD83D[\uDC00-\uDE4F]/g
if (!icon || emojiPattern.test(icon)) {
icon = defaultIcon
@@ -674,7 +674,7 @@ function getSiteInfo({ collection, block, NOTION_CONFIG }) {
* @param {string} date.start_time - 开始时间可选格式HH:mm
* @param {string} date.end_date - 结束日期格式YYYY-MM-DD
* @param {string} date.end_time - 结束时间可选格式HH:mm
* @param {string} date.time_zone - 时区IANA格式如 "Asia/Shanghai"
* @param {string} date.time_zone - 时区IANA 格式,如 "Asia/Shanghai"
* @returns {boolean} 是否在范围内
*/
function isInRange(title, date = {}) {
@@ -812,8 +812,8 @@ function getTimestamp(date, time = '00:00', time_zone) {
/**
* 获取导航用的精减文章列表
* gitbook主题用到只保留文章的标题分类标签分类信息精减掉摘要密码日期等数据
* 导航页面的条件必须是Posts
* gitbook 主题用到,只保留文章的标题分类标签分类信息,精减掉摘要密码日期等数据
* 导航页面的条件,必须是 Posts
* @param {*} param0
*/
export function getNavPages({ allPages }) {

View File

@@ -1,13 +0,0 @@
import dynamic from 'next/dynamic'
const NotionPage = dynamic(() => import('@/components/NotionPage'))
const Announcement = ({ post, className }) => {
if (!post) {
return <></>
}
return <>{post && (<div id="announcement-content" className='px-3'>
<NotionPage post={post} />
</div>)} </>
}
export default Announcement

View File

@@ -11,7 +11,7 @@ import CONFIG from '../config'
export const BlogItem = props => {
const { post } = props
const { NOTION_CONFIG } = useGlobal()
const showPageCover = siteConfig('SIMPLE_POST_COVER_ENABLE', false, CONFIG)
const showPageCover = siteConfig('TYPOGRAPHY_POST_COVER_ENABLE', false, CONFIG)
const showPreview =
siteConfig('POST_LIST_PREVIEW', false, NOTION_CONFIG) && post.blockMap
return (
@@ -81,11 +81,10 @@ export const BlogItem = props => {
</div>
</header>
<main className='text-[var(--primary-color)] dark:text-gray-300 leading-normal mb-6'>
<main className='text-[var(--primary-color)] dark:text-gray-300 mb-6 line-clamp-4 overflow-hidden text-ellipsis relative leading-[1.7]'>
{!showPreview && (
<>
{post.summary}
{post.summary && <span>...</span>}
</>
)}
{showPreview && post?.blockMap && (

View File

@@ -20,8 +20,8 @@ export default function BlogListPage(props) {
const currentPage = +page
// 博客列表嵌入广告
const SIMPLE_POST_AD_ENABLE = siteConfig(
'SIMPLE_POST_AD_ENABLE',
const TYPOGRAPHY_POST_AD_ENABLE = siteConfig(
'TYPOGRAPHY_POST_AD_ENABLE',
false,
CONFIG
)
@@ -39,10 +39,10 @@ export default function BlogListPage(props) {
<div id='posts-wrapper'>
{posts?.map((p, index) => (
<div key={p.id}>
{SIMPLE_POST_AD_ENABLE && (index + 1) % 3 === 0 && (
{TYPOGRAPHY_POST_AD_ENABLE && (index + 1) % 3 === 0 && (
<AdSlot type='in-article' />
)}
{SIMPLE_POST_AD_ENABLE && index + 1 === 4 && <AdSlot type='flow' />}
{TYPOGRAPHY_POST_AD_ENABLE && index + 1 === 4 && <AdSlot type='flow' />}
<BlogItem post={p} />
</div>
))}

View File

@@ -1,54 +0,0 @@
import LazyImage from '@/components/LazyImage'
import { siteConfig } from '@/lib/config'
import Link from 'next/link'
import CONFIG from '../config'
import SocialButton from './SocialButton'
/**
* 网站顶部
* @returns
*/
export default function Header(props) {
const { siteInfo } = props
return (
<header className='text-center justify-between items-center px-6 bg-white h-80 dark:bg-black relative z-10'>
<div className='float-none inline-block py-12'>
<Link href='/'>
{/* 可使用一张单图作为logo */}
<div className='flex space-x-6 justify-center'>
<div className='hover:rotate-45 hover:scale-125 transform duration-200 cursor-pointer justify-center items-center flex'>
<LazyImage
priority={true}
src={siteInfo?.icon}
className='rounded-full'
width={100}
height={100}
alt={siteConfig('AUTHOR')}
/>
</div>
<div className='flex-col flex justify-center'>
<div className='text-2xl font-serif dark:text-white py-2 hover:scale-105 transform duration-200'>
{siteConfig('AUTHOR')}
</div>
<div
className='font-light dark:text-white py-2 hover:scale-105 transform duration-200 text-center'
dangerouslySetInnerHTML={{
__html: siteConfig('SIMPLE_LOGO_DESCRIPTION', null, CONFIG)
}}
/>
</div>
</div>
</Link>
<div className='flex justify-center'>
<SocialButton />
</div>
<div className='text-xs mt-4 text-gray-500 dark:text-gray-300'>
{siteConfig('DESCRIPTION')}
</div>
</div>
</header>
)
}

View File

@@ -29,24 +29,23 @@ export const MenuList = ({ customNav, customMenu }) => {
})
let links = [
{
icon: 'fas fa-archive',
name: locale.NAV.ARCHIVE,
href: '/archive',
show: siteConfig('SIMPLE_MENU_ARCHIVE', null, CONFIG)
show: siteConfig('TYPOGRAPHY_MENU_ARCHIVE', null, CONFIG)
},
{
icon: 'fas fa-folder',
name: locale.COMMON.CATEGORY,
href: '/category',
show: siteConfig('SIMPLE_MENU_CATEGORY', null, CONFIG)
show: siteConfig('TYPOGRAPHY_MENU_CATEGORY', null, CONFIG)
},
{
icon: 'fas fa-tag',
name: locale.COMMON.TAGS,
href: '/tag',
show: siteConfig('SIMPLE_MENU_TAG', null, CONFIG)
show: siteConfig('TYPOGRAPHY_MENU_TAG', null, CONFIG)
}
]

View File

@@ -18,11 +18,11 @@ export default function NavBar(props) {
<Link href='/'>
<div className='flex flex-col-reverse md:flex-col items-center md:items-start'>
<div className='font-bold text-4xl text-center' id='blog-name'>
山野
{siteConfig('TYPOGRAPHY_BLOG_NAME')}
</div>
<div className='font-bold text-xl text-center' id='blog-name-en'>
{siteConfig('TYPOGRAPHY_BLOG_NAME_EN')}
</div>
{/* <div className='font-bold text-xl text-center' id='blog-name-en'>
Blog
</div> */}
</div>
</Link>
</header>

View File

@@ -8,7 +8,7 @@ import { siteConfig } from '@/lib/config'
*/
const RecommendPosts = ({ recommendPosts }) => {
const { locale } = useGlobal()
if (!siteConfig('SIMPLE_ARTICLE_RECOMMEND_POSTS', null, CONFIG) || !recommendPosts || recommendPosts.length < 1) {
if (!siteConfig('TYPOGRAPHY_ARTICLE_RECOMMEND_POSTS', null, CONFIG) || !recommendPosts || recommendPosts.length < 1) {
return <></>
}

View File

@@ -1,86 +0,0 @@
import { useRouter } from 'next/router'
import { useImperativeHandle, useRef, useState } from 'react'
let lock = false
const SearchInput = ({ keyword, cRef, className }) => {
const [onLoading, setLoadingState] = useState(false)
const router = useRouter()
const searchInputRef = useRef()
useImperativeHandle(cRef, () => {
return {
focus: () => {
searchInputRef?.current?.focus()
}
}
})
const handleSearch = () => {
const key = searchInputRef.current.value
if (key && key !== '') {
setLoadingState(true)
location.href = '/search/' + key
} else {
router.push({ pathname: '/' }).then(r => {
})
}
}
const handleKeyUp = (e) => {
if (e.keyCode === 13) { // 回车
handleSearch(searchInputRef.current.value)
} else if (e.keyCode === 27) { // ESC
cleanSearch()
}
}
const cleanSearch = () => {
searchInputRef.current.value = ''
}
const [showClean, setShowClean] = useState(false)
const updateSearchKey = (val) => {
if (lock) {
return
}
searchInputRef.current.value = val
if (val) {
setShowClean(true)
} else {
setShowClean(false)
}
}
function lockSearchInput() {
lock = true
}
function unLockSearchInput() {
lock = false
}
return <div className={'flex w-full bg-gray-100 ' + className}>
<input
ref={searchInputRef}
type='text'
className={'outline-none w-full text-sm pl-2 transition focus:shadow-lg font-light leading-10 text-black bg-gray-100 dark:bg-gray-900 dark:text-white'}
onKeyUp={handleKeyUp}
onCompositionStart={lockSearchInput}
onCompositionUpdate={lockSearchInput}
onCompositionEnd={unLockSearchInput}
onChange={e => updateSearchKey(e.target.value)}
defaultValue={keyword}
/>
<div className='-ml-8 cursor-pointer float-right items-center justify-center py-2'
onClick={handleSearch}>
<i className={`hover:text-black transform duration-200 text-gray-500 dark:hover:text-gray-300 cursor-pointer fas ${onLoading ? 'fa-spinner animate-spin' : 'fa-search'} `} />
</div>
{(showClean &&
<div className='-ml-12 cursor-pointer float-right items-center justify-center py-2'>
<i className='fas fa-times hover:text-black transform duration-200 text-gray-400 cursor-pointer dark:hover:text-gray-300' onClick={cleanSearch} />
</div>
)}
</div>
}
export default SearchInput

View File

@@ -1,22 +1,15 @@
const CONFIG = {
SIMPLE_LOGO_IMG: '/Logo.webp',
SIMPLE_TOP_BAR: true, // 显示顶栏
SIMPLE_TOP_BAR_CONTENT: process.env.NEXT_PUBLIC_THEME_SIMPLE_TOP_TIPS || '',
SIMPLE_LOGO_DESCRIPTION: process.env.NEXT_PUBLIC_THEME_SIMPLE_LOGO_DESCRIPTION || '<div>编程爱好者<br/>/互联网从业者<br/>/知识分享博主</div>',
TYPOGRAPHY_POST_AD_ENABLE: process.env.NEXT_PUBLIC_TYPOGRAPHY_POST_AD_ENABLE || false, // 文章列表是否插入广告
SIMPLE_AUTHOR_LINK: process.env.NEXT_PUBLIC_AUTHOR_LINK || '#',
SIMPLE_POST_AD_ENABLE: process.env.NEXT_PUBLIC_SIMPLE_POST_AD_ENABLE || false, // 文章列表是否插入广告
SIMPLE_POST_COVER_ENABLE: process.env.NEXT_PUBLIC_SIMPLE_POST_COVER_ENABLE || false, // 是否展示博客封面
SIMPLE_ARTICLE_RECOMMEND_POSTS: process.env.NEXT_PUBLIC_SIMPLE_ARTICLE_RECOMMEND_POSTS || true, // 文章详情底部显示推荐
TYPOGRAPHY_POST_COVER_ENABLE: process.env.NEXT_PUBLIC_TYPOGRAPHY_POST_COVER_ENABLE || false, // 是否展示博客封面
TYPOGRAPHY_ARTICLE_RECOMMEND_POSTS: process.env.NEXT_PUBLIC_TYPOGRAPHY_ARTICLE_RECOMMEND_POSTS || true, // 文章详情底部显示推荐
TYPOGRAPHY_BLOG_NAME: process.env.NEXT_PUBLIC_TYPOGRAPHY_BLOG_NAME || '活字印刷',
TYPOGRAPHY_BLOG_NAME_EN: process.env.NEXT_PUBLIC_TYPOGRAPHY_BLOG_NAME || 'Typography',
// 菜单配置
SIMPLE_MENU_CATEGORY: true, // 显示分类
SIMPLE_MENU_TAG: true, // 显示标签
SIMPLE_MENU_ARCHIVE: true, // 显示归档
SIMPLE_MENU_SEARCH: true // 显示搜索
TYPOGRAPHY_MENU_CATEGORY: true, // 显示分类
TYPOGRAPHY_MENU_TAG: true, // 显示标签
TYPOGRAPHY_MENU_ARCHIVE: true, // 显示归档
}
export default CONFIG

View File

@@ -4,7 +4,6 @@ import NotionPage from '@/components/NotionPage'
import { siteConfig } from '@/lib/config'
import { useGlobal } from '@/lib/global'
import { isBrowser } from '@/lib/utils'
import { Transition } from '@headlessui/react'
import dynamic from 'next/dynamic'
import Link from 'next/link'
import { useRouter } from 'next/router'
@@ -40,9 +39,6 @@ const JumpToTopButton = dynamic(() => import('./components/JumpToTopButton'), {
ssr: false
})
const Footer = dynamic(() => import('./components/Footer'), { ssr: false })
const SearchInput = dynamic(() => import('./components/SearchInput'), {
ssr: false
})
const WWAds = dynamic(() => import('@/components/WWAds'), { ssr: false })
const BlogListPage = dynamic(() => import('./components/BlogListPage'), {
ssr: false
@@ -96,7 +92,7 @@ const LayoutBase = props => {
{onLoading ? (
// loading 时显示 spinner
<div className='flex items-center justify-center min-h-[500px] w-full'>
<div className='animate-spin rounded-full h-12 w-12 border-t-2 border-b-2 border-gray-900'></div>
<div className='animate-spin rounded-full h-12 w-12 border-t-2 border-b-2 border-gray-900 dark:border-white'></div>
</div>
) : (
<>
@@ -106,7 +102,7 @@ const LayoutBase = props => {
)}
<AdSlot type='native' />
{/* 移动端页脚 - 显示在底部 */}
<div className='md:hidden z-30 dark:bg-black'>
<div className='md:hidden z-30 '>
<Footer {...props} />
</div>
</div>
@@ -175,9 +171,6 @@ const LayoutSearch = props => {
}
}, [])
const slotTop = siteConfig('ALGOLIA_APP_ID') ? null : (
<SearchInput {...props} />
)
return <LayoutPostList {...props} slotTop={slotTop} />
}
@@ -219,7 +212,7 @@ const LayoutSlug = props => {
{!lock && post && (
<div
className={`px-2 pt-3 ${fullWidth ? '' : 'xl:max-w-4xl 2xl:max-w-6xl'}`}>
className={`px-5 pt-3 ${fullWidth ? '' : 'xl:max-w-4xl 2xl:max-w-6xl'}`}>
{/* 文章信息 */}
<ArticleInfo post={post} />