diff --git a/blog.config.js b/blog.config.js index e9e4613b..37c12af0 100644 --- a/blog.config.js +++ b/blog.config.js @@ -38,7 +38,7 @@ const BLOG = { ...require('./conf/ad.config'), // 广告营收插件 // 高级用法 - ...require('./conf/layout-map.config'), // 路由与布局映射自定义 + ...require('./conf/layout-map.config'), // 路由与布局映射自定义,例如自定义特定路由的页面布局 ...require('./conf/notion.config'), // 读取notion数据库相关的扩展配置,例如自定义表头 ...require('./conf/dev.config'), // 开发、调试时需要关注的配置 diff --git a/conf/notion.config.js b/conf/notion.config.js index 0bc2c273..f402c8b3 100644 --- a/conf/notion.config.js +++ b/conf/notion.config.js @@ -1,5 +1,6 @@ /** * 读取Notion相关的配置 + * 如果需要在Notion中添加自定义字段,可以修改此文件 */ module.exports = { // 自定义配置notion数据库字段名 diff --git a/lib/db/getSiteData.js b/lib/db/getSiteData.js index f5e926c6..07e619f6 100755 --- a/lib/db/getSiteData.js +++ b/lib/db/getSiteData.js @@ -233,6 +233,15 @@ async function converNotionToSiteDate(pageId, from, pageRecordMap) { if (post?.type === 'Post' && post.status === 'Published') { postCount++ } + + // 新特性,判断文章的发布和下架时间,如果不在有效期内则进行下架处理 + const publish = isInRange(post.date) + if (!publish) { + console.log(post.title, '未处于发布时段 [', post.date, '] 内,将强制隐藏') + // 隐藏 + post.status = 'Invisible' + } + return ( post && post?.slug && @@ -555,12 +564,13 @@ function getCategoryOptions(schema) { * @returns {Promise<{title,description,pageCover,icon}>} */ function getSiteInfo({ collection, block, NOTION_CONFIG }) { - const defaultTitle = NOTION_CONFIG?.TITLE || BLOG.TITLE - const defaultDescription = NOTION_CONFIG?.DESCRIPTION || BLOG.DESCRIPTION - const defaultPageCover = - NOTION_CONFIG?.HOME_BANNER_IMAGE || BLOG.HOME_BANNER_IMAGE - const defaultIcon = NOTION_CONFIG?.AVATAR || BLOG.AVATAR + const defaultTitle = NOTION_CONFIG?.TITLE || 'NotionNext BLOG' + const defaultDescription = + 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 + // 空数据的情况返回默认值 if (!collection && !block) { return { title: defaultTitle, @@ -597,6 +607,78 @@ function getSiteInfo({ collection, block, NOTION_CONFIG }) { return { title, description, pageCover, icon, link } } +/** + * 判断文章是否在发布时间内 + * @param {*} param0 + * @returns + */ +function isInRange(date = {}) { + const { start_date, start_time, end_date, end_time, time_zone } = date + + // 如果没有传入时区,使用默认时区 'Asia/Shanghai' + const effectiveTimeZone = time_zone || 'Asia/Shanghai' + + // 辅助函数:根据时区和日期时间字符串创建 Date 对象 + function parseDateTime(date, time, timeZone) { + if (!date) return null // 如果没有传日期,返回 null + const dateTimeString = `${date}T${time}:00${getTimezoneOffset(timeZone)}` + return new Date(dateTimeString) // 返回一个 Date 对象 + } + + // 辅助函数:获取时区的偏移量 + function getTimezoneOffset(timeZone) { + const date = new Date() + const options = { timeZone, hour12: false, timeZoneName: 'short' } + const timeString = new Intl.DateTimeFormat('en-US', options).format(date) + const match = timeString.match(/([A-Za-z]+)([+\-]\d{1,2})(\d{2})/) // 捕获时区信息,确保偏移小时和分钟 + if (match) { + const offset = match[2] + match[3] // 组合偏移小时和分钟 + return offset // 返回格式:+08:00 或 -03:00 + } + return '' // 默认没有时区偏移 + } + + // 当前时间(转换为目标时区) + const currentDateTime = new Date() + const currentDateTimeInZone = parseDateTime( + currentDateTime.toISOString().slice(0, 10), + currentDateTime.toISOString().slice(11, 16), + effectiveTimeZone + ) + + // 判断开始时间范围 + let startDateTime = null + if (start_date) { + startDateTime = parseDateTime( + start_date, + start_time || '00:00', + effectiveTimeZone + ) // 如果没有 start_time 默认设置为 '00:00' + } + + // 判断结束时间范围 + let endDateTime = null + if (end_date) { + endDateTime = parseDateTime( + end_date, + end_time || '23:59', + effectiveTimeZone + ) // 如果没有 end_time 默认设置为 '23:59' + } + + // 如果有 start_date,当前时间必须大于等于 start_date 和 start_time + if (startDateTime && currentDateTimeInZone < startDateTime) { + return false + } + + // 如果有 end_date,当前时间必须小于等于 end_date 和 end_time + if (endDateTime && currentDateTimeInZone > endDateTime) { + return false + } + + return true // 如果都通过了判断,返回 true +} + /** * 获取导航用的精减文章列表 * gitbook主题用到,只保留文章的标题分类标签分类信息,精减掉摘要密码日期等数据