找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 37|回复: 0

[维护日志] [2026-07-09] [修复] [前台标签重复追加问题] - 修复编辑帖子时标签重复递增的Bug

[复制链接]
  • 打卡等级:本地老炮

9336

威望

6876

金钱

1万

贡献

管理员

自由的灵魂

积分
106811
主题
5597
回帖
26608
注册时间
2003-4-10
最后登录
2026-8-11
发表于 2026-7-9 10:46:28 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
[2026-07-09] [修复] [前台标签重复追加问题] - 修复编辑帖子时标签重复递增的Bug

1、问题缘起

论坛用户反馈,编辑帖子标签时,每次保存都会在标签列表中重复追加已有的标签。例如:

  • 原标签:Editplus,查找,代码
  • 第一次编辑后:EditPlus,查找,代码,EmEditor
  • 第二次编辑后:EditPlus,查找,代码,EmEditor,EditPlus
  • 第三次编辑后:EditPlus,查找,代码,EmEditor,EditPlus,EditPlus

每编辑一次,EditPlus 就多一个,导致标签列表越来越长。

受影响的帖子示例tid=95930,其 dx_forum_post.tags 字段中出现了 5 次 6258,EditPlus

2、排查过程

步骤操作结果
1搜索标签保存相关文件定位到 forum_tag.phpclass_tag.php
2查看 forum_tag.php发现 $op == 'set' 分支调用 $class_tag->update_field()
3查看 class_tag.phpupdate_field()发现逻辑是追加而非覆盖


关键代码定位class_tag.php 第 55-79 行):

  1. public function update_field($tags, $itemid, $idtype = 'tid', $typeinfo = array()) {
  2. // ... 获取当前帖子已有标签 $tagstr ...
  3. foreach($tags as $tagid => $tagname) {
  4. if(empty($tagarray[$tagid])) {
  5. $tagstr = $tagstr.$tagid.','.$tagname."\t";  // 追加新标签
  6. }
  7. }
  8. // ... 删除不再使用的标签 ...
  9. return $tagstr;
  10. }
复制代码


3、解决方案

(1)简要技术分析

Discuz! 的 update_field() 方法在更新标签时,采用了“保留旧标签 + 追加新标签”的策略,导致每次编辑都会重复写入已有标签。修复方案改为“先清空所有旧标签关联,再写入新标签列表”,实现标签的完整覆盖更新。

(2)修改文件列表

操作文件路径
修改/source/class/class_tag.php


(3)关键代码段

修改前update_field 方法):
  1. public function update_field($tags, $itemid, $idtype = 'tid', $typeinfo = array()) {
  2. // ... 获取已有标签 $tagstr ...
  3. foreach($tags as $tagid => $tagname) {
  4. if(empty($tagarray[$tagid])) {
  5. $tagstr = $tagstr.$tagid.','.$tagname."\t";
  6. }
  7. }
  8. foreach($tagarray as $tagid => $tagname) {
  9. if(!in_array($tagname, $tagarraynew)) {
  10. C::t('common_tagitem')->delete_tagitem($tagid, $itemid, $idtype);
  11. $tagstr = str_replace("$tagid,$tagname\t", '', $tagstr);
  12. }
  13. }
  14. return $tagstr;
  15. }
复制代码


修改后(完整覆盖逻辑):
  1. public function update_field($tags, $itemid, $idtype = 'tid', $typeinfo = array()) {

  2. if($idtype == 'tid') {
  3. $tagstr = C::t('forum_post')->fetch_threadpost_by_tid_invisible($itemid);
  4. $tagstr = $tagstr['tags'];
  5. } elseif($idtype == 'blogid') {
  6. $tagstr = C::t('home_blogfield')->fetch_tag_by_blogid($itemid);
  7. } else {
  8. return '';
  9. }

  10. // 删除该帖子的所有旧标签关联
  11. C::t('common_tagitem')->delete_tagitem(0, $itemid, $idtype);

  12. // 重新添加新标签
  13. $new_tags = $this->add_tag($tags, $itemid, $idtype, 1);
  14. $tagstr_new = '';
  15. foreach($new_tags as $tagid => $tagname) {
  16. $tagstr_new .= $tagid.','.$tagname."\t";
  17. }

  18. return $tagstr_new;
  19. }
复制代码


4、最终实现效果

场景修改前修改后
编辑标签每次在末尾追加已有标签✅ 完整覆盖,无重复
dx_forum_post.tags 字段不断增长✅ 始终为最新标签列表
dx_common_tagitem存在重复关联记录✅ 无重复关联
前台标签显示显示重复标签✅ 显示干净的唯一标签列表


5、重要技术沉淀

需更新到固化摘要

  1. 二十六、标签重复追加修复(2026-07-09)

  2. 问题:编辑帖子标签时,已有标签被重复追加,导致标签列表膨胀
  3. 原因:update_field() 方法采用“追加”而非“覆盖”逻辑
  4. 解决:修改 source/class/class_tag.php 中的 update_field() 方法,先清空旧标签再写入新标签
  5. 涉及文件:source/class/class_tag.php
复制代码


踩坑点

踩坑正确做法
误以为 Discuz! 标签保存是覆盖逻辑实际是追加逻辑,需要修改代码
delete_tagitem(0, $itemid, $idtype) 参数顺序需确认调用前需确认 delete_tagitem 方法的参数顺序
标签字段 $tagstr 格式为 tagid,tagname\t重新构建时需保持相同格式,否则前台无法正确解析


6、进一步优化可能性

  • 批量清理:编写 SQL 脚本批量清理已存在的重复标签数据
  • 后台管理:在后台增加“标签去重”工具,一键清理全站重复标签
  • 前端防重复:在标签输入框增加重复检测,提交前拦截重复标签

不懂就搜!点此搜点拨论坛。如果本坛没有,请尝试点此问AI,或跟帖提问。
发帖前注意看置顶帖
不定期借助AI对点拨论坛陈年老帖进行挖坟回复,打扰勿怪!
有任何论坛使用问题,请看论坛帮助
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|点拨论坛 |网站地图|网站地图

GMT+8, 2026-8-11 22:42 , Processed in 0.045307 second(s), 5 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表