织梦如何设置文章过期自动下架
促销活动、招聘信息、限时公告等类型的文章有明确的失效时间,过期后应自动从列表隐藏或直接 404,避免误导用户。织梦本身没有“过期时间”字段,需要扩展字段 + 定时任务实现。本文给出完整方案。
一、需求场景
- 促销活动:活动结束自动下架,避免用户按旧价格下单;
- 招聘信息:岗位招满后自动隐藏;
- 通知公告:过期公告从首页撤下;
- 限时下载:资源到期自动禁止访问。
核心是两点:①列表与详情页能识别“已过期”;②有机制在过期时改变文章状态。
二、第一步:给文档模型增加过期时间字段
后台 核心 - 频道模型 - 内容模型管理 - 普通文章 - 字段管理 - 添加新字段:
- 字段名称:
expiretime - 字段类型:时间类型(Unix 时间戳)
- 前台表单输入:日期选择器
- 默认值:0(表示不过期)
或直接 SQL 添加:
ALTER TABLE dede_addonarticle ADD COLUMN expiretime INT UNSIGNED DEFAULT 0;
对应在 dede_archives 主表也加一个便于查询:
ALTER TABLE dede_archives ADD COLUMN expiretime INT UNSIGNED DEFAULT 0;
三、第二步:发布文章时填写过期时间
在文章发布模板 /dede/templets/archives_add.htm 增加日期选择框:
<tr>
<td width="100">过期时间:</td>
<td>
<input type="text" name="expiretime" id="expiretime"
value="0" class="datepicker" />
<span style="color:#999">留 0 表示不过期</span>
</td>
</tr>
并在 /dede/archives_add.php 保存逻辑里把日期转为时间戳:
$expiretime=empty($expiretime) ? 0 : strtotime($expiretime);
$expiretime=$expiretime < time() ? 0 : $expiretime;
四、第三步:定时任务自动下架
编写下架脚本 /expire_cron.php:
<?php
require_once dirname(__FILE__).'/include/common.inc.php';
$now=time();
// 把已过期文章 arcrank 设为 -1(未审核)
$dsql->ExecuteNoneQuery(
"UPDATE dede_archives SET arcrank=-1
WHERE expiretime > 0 AND expiretime < $now AND arcrank >=0"
);
// 同步 arctiny
$dsql->ExecuteNoneQuery(
"UPDATE dede_arctiny SET arcrank=-1
WHERE id IN (
SELECT id FROM dede_archives
WHERE expiretime > 0 AND expiretime < $now AND arcrank=-1
)"
);
// 删除已过期文章的静态 HTML
$dsql->SetQuery(
"SELECT id, typeid, senddate FROM dede_archives
WHERE expiretime > 0 AND expiretime < $now"
);
$dsql->Execute();
while($row=$dsql->GetArray()){
$date=date('Y/m/d', $row['senddate']);
$file=DEDEDATA."/../a/{$date}/{$row['id']}.html";
if(file_exists($file)) @unlink($file);
}
// 写日志
file_put_contents(__DIR__.'/data/log/expire.log',
date('Y-m-d H:i:s')." expired check done\n", FILE_APPEND);
宝塔计划任务每小时执行:
0 * * * * /www/server/php/74/bin/php /www/wwwroot/yourdomain.com/expire_cron.php
五、第四步:列表与详情页过滤
1. arclist 过滤已过期文章
模板里 arclist 加 where 条件:
{dede:arclist typeid='1' row='10' where="expiretime=0 OR expiretime>UNIX_TIMESTAMP()"}
<li><a href="[field:arcurl/]">[field:title/]</a></li>
{/dede:arclist}
2. 详情页过期后显示提示
文章模板 article_article.htm 顶部:
<?php
$aid=(int)$aid;
$row=$dsql->GetOne("SELECT expiretime FROM dede_archives WHERE id=$aid");
if($row['expiretime'] > 0 && $row['expiretime'] < time()){
header("HTTP/1.1 410 Gone");
?>
<h1>该内容已过期</h1>
<p>您访问的内容已于 <?php echo date('Y-m-d', $row['expiretime']); ?> 过期下架。</p>
<p><a href="/">返回首页</a></p>
<?php
exit;
}
?>
六、第五步:通知搜索引擎
过期文章下架后:
- 更新 sitemap,移除过期 URL;
- 把过期 URL 加入死链清单提交百度;
- 对过期 URL 返回 410 Gone(比 404 更明确表示“永久删除”)。
// Nginx 对过期文章目录返回 410
location ~ ^/a/2026/(\d+)/(\d+)\.html$ {
# 由 PHP 判断后返回 410
try_files $uri @expired;
}
location @expired {
return 410;
}
七、注意事项
- 定时任务执行频率决定下架及时性,活动类建议每 10 分钟一次;
- arcrank 改为 -1 后文章仍在数据库,可随时恢复;
- 静态文件删除前确认没有其他文章引用(如图集);
- 过期时间字段要在后台列表也显示,便于运营核查。
文章过期下架本质是“字段扩展 + 定时任务 + 前台过滤”三件套。建议根据业务场景调整下架策略:促销类直接 410,公告类可保留显示但加“已过期”标识。把过期逻辑跑通后,站点内容始终保持时效性,既提升用户信任也避免被搜索引擎判定为低质过时内容。