一、问题现象
文章通过批量操作从「未审核」变为「已审核」后,其关联的 TAG 在 管理TAGS 列表中显示信息数为 0+1(0 条已审 + 1 条未审)。
同时,前台标签页 /e/tags/?tagname=xxx 显示为空。
二、涉及的数据表
| 表名 | 作用 |
|---|---|
enewstags |
TAG 主表,num = 已审计数,cnum = 未审计数 |
enewstagsdata |
已审文章与 TAG 的关联关系 |
enewstagsdata_check |
未审文章与 TAG 的关联关系 |
三、根本原因
正常流程(单条编辑)
通过后台 EditNews.php 修改文章时,EditNews() 函数会检测审核状态变化,调用 eInsertTags() → MoveCheckTagsData(),将 TAG 数据在 enewstagsdata 和 enewstagsdata_check 之间正确转移。
异常流程(批量审核)
通过 ListNews.php 勾选文章 → 点击「审核」按钮,走的是 CheckNews_all() 函数。该函数调用了 MoveCheckInfoData() 转移文章数据,但没有调用 MoveCheckTagsData() 转移 TAG 数据。
NoCheckNews_all()(批量取消审核)同理。
触发条件(核心路径:文章从未审核 → 已审核)
最容易踩坑的场景:文章先以未审核状态入库,之后通过批量操作审核通过。
- 文章以未审核状态提交(TAG 数据写入
enewstagsdata_check,cnum+1) - 管理员通过批量操作审核通过该文章(文章数据移到主表,但 TAG 数据仍留在
enewstagsdata_check) - 结果:文章已审核,TAG 计数却显示
0+1,前台标签页读不到数据
为什么容易碰到:很多站长习惯先批量采集/导入文章(默认未审),再批量审核发布。这个流程正好命中了 bug。
四、清理多余TAGS信息
如果已经出现了问题,可以使用后台 ClearTags.php 工具,**勾选「自动互转审核信息」**后执行。系统会自动检测 TAG 数据和文章审核状态是否匹配,并调用 MoveCheckTagsData() 将数据移到正确的表。
五、永久修复(代码层面)
在 e/class/userfun.php 新增通用函数:
/**
* 批量审核/取消审核时同步TAGS数据到对应表
* @param int $infoid 信息ID
* @param int $mid 模型ID(防止多模型下infoid重复)
* @param int $checked 目标审核状态:1=审核通过 0=取消审核
*/
function MoveCheckTagsDataByInfoId($infoid, $mid, $checked)
{
global $empire, $dbtbpre;
$infoid = (int)$infoid;
$mid = (int)$mid;
$checked = (int)$checked;
if ($checked == 1) {
// 审核通过:从 enewstagsdata_check 移到 enewstagsdata
$tagdatar = $empire->query("select tid,tagid,classid,newstime,mid from {$dbtbpre}enewstagsdata_check where id='$infoid' and mid='$mid'");
while ($tagr = $empire->fetch($tagdatar)) {
MoveCheckTagsData(0, $tagr['tid'], $tagr['tagid'], $tagr['classid'], $infoid, $tagr['newstime'], $tagr['mid']);
}
} else {
// 取消审核:从 enewstagsdata 移到 enewstagsdata_check
$tagdatar = $empire->query("select tid,tagid,classid,newstime,mid from {$dbtbpre}enewstagsdata where id='$infoid' and mid='$mid'");
while ($tagr = $empire->fetch($tagdatar)) {
MoveCheckTagsData(1, $tagr['tid'], $tagr['tagid'], $tagr['classid'], $infoid, $tagr['newstime'], $tagr['mid']);
}
}
}
在 e/class/hinfofun.php 中两处调用:
CheckNews_all()(line 1973 之后)— 批量审核通过,$checked=1:
在 MoveCheckInfoData($class_r[$classid]['tbname'],0,$infor['stb'],"id='$infoid'"); 之后添加:
//TAGS审核互转
MoveCheckTagsDataByInfoId($infoid, $class_r[$classid]['modid'], 1);
NoCheckNews_all()(line 2074 之后)— 批量取消审核,$checked=0:
在 MoveCheckInfoData($class_r[$classid]['tbname'],1,$r['stb'],"id='$infoid'"); 之后添加:
//TAGS审核互转
MoveCheckTagsDataByInfoId($infoid, $class_r[$classid]['modid'], 0);






