登录 / 注册
2026-02-04

博主 1.29日~2.4日 BUG修复清单

1) 首页异步分页 + 智能滚动(移动端“丝滑”修复)

改动点

前端改成走 GET /api/articles 拉数据,再 history.pushState() 更新地址栏(伪静态体验)。

Bug 现象

手机端点击侧边栏分类/分页后,页面滚动出现“跳动/不滚动/突然回顶部”。

触发位置

/mnt/data/index.ejsloadData()(AJAX 成功回调里)

关键代码:setTimeout(() => $('html, body').animate(...), delayTime)

触发原因(机制级)

移动端侧边栏收起动画期间,body 会短暂处于“滚动锁定/布局变动”状态;滚动指令($('html, body').animate)过早执行会被浏览器忽略或滚动到错误位置。

修复方案

window.innerWidth <= 736 判定移动端,设置 delayTime = 600ms,PC 端 150ms

移动端等侧边栏动画结束 + 解锁滚动后再执行 animate

PC只需要等待内容淡出/重绘即可


2) 首页“首页 5 篇 + 后续 6 篇”智能分页(避免重复/漏文章)

触发位置

/mnt/data/server.jsgetArticlesData(req, callback)

核心变量:limitPage1 = 5limitOther = 6

触发原因

如果首页与后续页 LIMIT 不一致,但仍用传统 offset=(page-1)*limit,会导致 分页重复跳过文章

修复方案(算法)

page=1:limit=limitPage1offset=0

page>=2:limit=limitOtheroffset=limitPage1 + (page-2)*limitOther

同时按 priority DESC, id DESC 排序,保证“置顶优先 + 新文优先”的稳定顺序。


3) 文章摘要“HTML 实体乱码”(  “ 等)修复

Bug 现象

首页摘要出现 &nbsp;&ldquo;&amp; 等“代码符号”,影响阅读。

触发位置

/mnt/data/server.jsfunction stripHtml(html)

摘要来源:processedArticles = articles.map(... preview: stripHtml(art.content))

触发原因

仅做了“去标签”(/<[^>]+>/g),但富文本内容里还有大量 HTML 实体(entities),不会自动变成正常字符。

修复方案

stripHtml() 内新增实体替换链:

&nbsp; -> 空格

&ldquo; &rdquo; -> 中文引号

&amp; -> &(放最后防二次替换)

再做 \s+ 合并空格并截断 150 字输出 ...


4) 评论“楼中楼断链”问题:软删除 + 留坑(is_deleted)

Bug 现象

删除一条主评论后,子回复(parent_id 指向它的评论)在页面结构里“消失/错乱”。

触发位置

数据表:comments

/mnt/data/server.js

启动迁移:ALTER TABLE comments ADD COLUMN is_deleted INTEGER DEFAULT 0

删除逻辑:UPDATE comments SET is_deleted = 1 WHERE id = ?

渲染时说明:即使 is_deleted=1 也查出来,再在前端/模板层替换显示

触发原因

物理删除(DELETE)会导致回复链 parent_id 悬空,树结构无法构建,表现成“子评论没了”。

修复方案

is_deleted 做软删除:

删除改 UPDATE 不改 DELETE

渲染时检测 is_deleted=1,把 content 替换为“🗑️ 该评论已删除”,保留楼层结构与审计能力


5) 回复“@某人”名字显示为空(回复指向不清晰)

Bug 现象

回复时 UI 中 “@xxx” 后面名字不显示,用户不知道在回复谁。

触发位置

评论渲染逻辑(在 post.ejs/后端组装评论树处)

触发原因

旧逻辑为了防“套娃/重复显示”,对某些父级节点做了隐藏昵称判断(类似 “如果 parent 是楼主就不显示”),结果误伤正常回复显示。

修复方案

去掉/放宽这类条件判断:只要是回复(parent_id!=0)就显示被回复者昵称,确保对话链清晰。


6) 个人中心:改昵称后历史评论仍显示旧名(comments.name 快照未同步)

Bug 现象

用户资料里昵称已更新,但历史评论依然显示旧昵称。

触发位置

/mnt/data/server.js/profile/update(资料更新接口)

关联字段:comments.namecomments.user_id

触发原因

评论表会存一个 name 快照;用户表 users.nickname 更新不会自动回写历史评论。

修复方案

在资料更新事务里追加同步 SQL:

UPDATE comments SET name = ? WHERE user_id = ?

这样即使某些页面仍用 comments.name 渲染,也不会出现旧昵称残留。


7) 历史评论“无主数据”导致个人中心查不到(user_id=0/NULL)

Bug 现象

早期评论没有绑定账号,个人中心按 user_id 查询时无法展示“老评论”。

触发位置

/mnt/data/server.js 启动期“自动迁移/关联修复” SQL

关键条件:WHERE (user_id = 0 OR user_id IS NULL) AND email IN (SELECT email FROM users)

触发原因

早期只记录了 comments.email,没有写 comments.user_id,导致后续“按用户维度聚合/展示”缺少主键关联。

修复方案

迁移脚本用 email 反查 users.id,批量补齐 comments.user_id

SET user_id = (SELECT id FROM users WHERE users.email = comments.email)

迁移后个人中心能完整展示历史互动记录。


8) 投稿分类“前端限制可绕过”——后端二次校验 allow_submit

Bug 现象

普通用户可能通过改 POST 参数把文章投到“不允许投稿”的分类里(前端下拉框限制不够)。

触发位置

/mnt/data/server.jsPOST /article/submit

校验点:SELECT allow_submit FROM categories WHERE value = ?

触发原因

仅靠前端 select 做限制无法防篡改;用户可直接构造请求。

修复方案

后端强校验 allow_submit === 1 才允许继续写入;否则 alert + history.back() 拦截。

同时 GET /article/submit 对普通用户只查询 allow_submit=1 的分类列表,减少误操作入口。


9) 后台分类管理:allow_submit 无法编辑(纯文本展示)

Bug 现象

后台分类表只能看,不能修改“允许投稿”状态。

触发位置

/mnt/data/admin.ejs 分类表格

/mnt/data/server.jsPOST /admin/categories/addPOST /admin/categories/update/:id

关键字段:allow_submit(checkbox → req.body.allow_submit === 'on' ? 1 : 0

触发原因

原分类表格缺少 <input type="checkbox"> + 缺少 form 绑定,提交不到后端。

修复方案

前端表格嵌入 checkbox,并用 HTML5 form="xxx" 把表格控件绑定到操作按钮

后端把 allow_submit 入库与更新逻辑补齐。


10) 后台文章编辑报错:缺路由/缺 categories(模板渲染缺参)

Bug 现象

点击“编辑”报错、打不开、或渲染分类下拉时报错。

触发位置

/mnt/data/server.jsGET /admin/edit/:idPOST /admin/edit/:id

/mnt/data/edit.ejs:需要 categories 来渲染下拉

触发原因

常见是只查 articles 没查 categories,模板引用变量时报错;或路由缺失导致跳转/404。

修复方案

补齐 REST 风格编辑路由,并确保 res.render('edit', { article, categories }) 两个都传。


11) 严重崩溃:ReferenceError: saveCompressedImage is not defined

Bug 现象

发文章/上传封面时,Node 进程直接崩(ReferenceError)。

触发位置

/mnt/data/server.js 多处调用:例如投稿/后台编辑的 await saveCompressedImage(req.file.buffer, req.file.originalname)

函数定义:async function saveCompressedImage(fileBuffer, originalName)

触发原因

在多次合并修改过程中,函数定义被误删/移动,但调用点还在,导致运行时找不到符号。

修复方案

saveCompressedImage() 统一放回 server.js(可被所有路由复用)

采用 sharpresize({width:1920}) + jpeg压缩,输出到 public/uploads


12) 分享系统:/api/share + share_cache(低带宽优化)

新增点

/api/share/:id 输出文章分享信息;/share/qr/:id.png/share/poster/:id.jpg 生成二维码/海报

触发位置

/mnt/data/server.js

shareDir = path.join(__dirname, 'share_cache')

常量:SHARE_POSTER_W/HSHARE_QR_SIZESHARE_JPEG_QUALITY

设计原因(性能/安全)

分享素材生成成本高,所以落地到 share_cache 做缓存;并且不放 public 下,避免静态资源绕过后续鉴权设计。

海报采用较低 SHARE_JPEG_QUALITY,降低服务器带宽占用。

💬 留言板 (0)

还没有人留言,快来抢沙发吧~

登录后参与评论

加入讨论,与博主互动

去登录 / 注册
返回上一页
留言提交成功!

快捷分享