Merge pull request #3472 from qixing-jk/feat/expiry-reminder

feat(ArticleExpirationNotice): implement ArticleExpirationNotice comp…
This commit is contained in:
tangly1024
2025-07-07 15:11:53 +08:00
committed by GitHub
3 changed files with 86 additions and 1 deletions

View File

@@ -0,0 +1,73 @@
import { siteConfig } from '@/lib/config'
/**
* 文章过期提醒组件
* 当文章超过指定天数时显示提醒
* @param {Object} props - 组件属性
* @param {Object} props.post - 文章数据
* @param {number} [props.daysThreshold=90] - 过期阈值(天)
* @returns {JSX.Element|null}
*/
export default function ArticleExpirationNotice({
post,
daysThreshold = siteConfig('ARTICLE_EXPIRATION_DAYS', 90)
}) {
const articleExpirationEnabled = siteConfig(
'ARTICLE_EXPIRATION_ENABLED',
false
)
if (!articleExpirationEnabled || !post?.lastEditedDay) {
return null
}
const postDate = new Date(post.lastEditedDay)
const today = new Date()
const diffTime = Math.abs(today - postDate)
const daysOld = Math.ceil(diffTime / (1000 * 60 * 60 * 24))
const isVisible = daysOld >= daysThreshold
if (!isVisible) {
return null
}
// 使用 %%DAYS%% 作为占位符
const articleExpirationMessage = siteConfig(
'ARTICLE_EXPIRATION_MESSAGE',
'这篇文章发布于 %%DAYS%% 天前,内容可能已过时,请谨慎参考。'
)
const articleExpirationMessageParts =
articleExpirationMessage.split('%%DAYS%%')
// 直接返回 JSX 内容
return (
<div
className={
'p-4 rounded-lg border border-blue-300 bg-blue-50 dark:bg-blue-900/20 text-gray-800 dark:text-gray-200 shadow-sm'
}>
<div className='flex items-start'>
<i className='fas fa-exclamation-triangle text-blue-500 dark:text-blue-400 mt-0.5 mr-2 flex-shrink-0' />
<div className='ml-1'>
<div className='text-blue-600 dark:text-blue-400 font-medium'>
{siteConfig('ARTICLE_EXPIRATION_TITLE', '温馨提醒')}
</div>
<div className='flex items-center mt-1 text-sm text-gray-700 dark:text-gray-300'>
<i className='far fa-clock text-red-500 dark:text-red-400 mr-1' />
<span>
{(() => {
return (
<>
{articleExpirationMessageParts[0]}
<span className='text-red-500 dark:text-red-400 font-bold'>
{daysOld}
</span>
{articleExpirationMessageParts[1]}
</>
)
})()}
</span>
</div>
</div>
</div>
</div>
)
}

View File

@@ -28,6 +28,16 @@ module.exports = {
POST_RECOMMEND_COUNT: process.env.NEXT_PUBLIC_POST_RECOMMEND_COUNT || 6, // 推荐文章数量
POSTS_PER_PAGE: process.env.NEXT_PUBLIC_POST_PER_PAGE || 12, // post counts per page
POSTS_SORT_BY: process.env.NEXT_PUBLIC_POST_SORT_BY || 'notion', // 排序方式 'date'按时间,'notion'由notion控制
// 文章过期提醒配置 p.s. 目前此功能暂时只适用于heo主题
ARTICLE_EXPIRATION_DAYS:
process.env.NEXT_PUBLIC_ARTICLE_EXPIRATION_DAYS || 90, // 文章过期提醒阈值(天)
ARTICLE_EXPIRATION_MESSAGE:
process.env.NEXT_PUBLIC_ARTICLE_EXPIRATION_MESSAGE ||
'这篇文章发布于 %%DAYS%% 天前,内容可能已过时,请谨慎参考。', // 过期提示信息,使用 %%DAYS%% 作为天数占位符
ARTICLE_EXPIRATION_ENABLED:
process.env.NEXT_PUBLIC_ARTICLE_EXPIRATION_ENABLED || 'false', // 是否启用文章过期提醒
POST_WAITING_TIME_FOR_404:
process.env.NEXT_PUBLIC_POST_WAITING_TIME_FOR_404 || '8', // 文章加载超时时间单位秒超时后跳转到404页面

View File

@@ -43,6 +43,7 @@ import SideRight from './components/SideRight'
import CONFIG from './config'
import { Style } from './style'
import AISummary from '@/components/AISummary'
import ArticleExpirationNotice from '@/components/ArticleExpirationNotice'
/**
* 基础布局 采用上中下布局,移动端使用顶部侧边导航栏
@@ -307,7 +308,8 @@ const LayoutSlug = props => {
<section
className='wow fadeInUp p-5 justify-center mx-auto'
data-wow-delay='.2s'>
<AISummary aiSummary={post.aiSummary}/>
<ArticleExpirationNotice post={post} />
<AISummary aiSummary={post.aiSummary} />
<WWAds orientation='horizontal' className='w-full' />
{post && <NotionPage post={post} />}
<WWAds orientation='horizontal' className='w-full' />