登录 / 注册
2026-02-04

博主 1.29日~2.4日新增功能清单

1) 用户注册 / 登录 / 退出(Session 登录态)

新增内容

完整账号体系:注册、登录、退出,所有互动功能(评论/关注/投稿)都以 req.session.user 为身份来源。

落点位置

/mnt/data/server.js

GET /registerPOST /register

GET /login-userPOST /login-user

GET /logout-user

关键变量/机制

Session:req.session.userreq.session.isAdmin

密码:bcrypt.hash() 存储、bcrypt.compare() 登录校验(Security 增强)

用户表:users(id, email, nickname, password, avatar, signature, is_banned, created_at...)


2) 邮箱验证码体系(注册验证码 + 找回密码验证码 + 改密验证码)

新增内容

发验证码接口拆分成多条:注册/找回/改密分别独立,避免混用。

增加验证码冷却(防刷):设置为 60 秒粒度。

落点位置

/mnt/data/server.js

POST /api/send-code(注册)

POST /api/send-reset-password-code(找回密码)

POST /api/send-change-password-code(登录后改密)

关键变量/工具名

邮件发送:nodemailertransporter.sendMail()

验证码缓存结构:常见是 Map/对象(例如 emailCodes[email] = { code, expireAt, cooldownAt } 这种模式)

风控字段:cooldown / expiresAt(防爆破、防频繁请求)


3) 忘记密码流程(/forgot-password)

新增内容

“忘记密码 → 邮箱验证码 → 重置密码”的完整闭环。

落点位置

/mnt/data/forgot-password.ejs(页面)

/mnt/data/server.js

GET /forgot-password

POST /forgot-password(校验验证码 + 更新密码)

 

关键机制

更新密码时仍走 bcrypt.hash()

典型处理是:验证成功后删除验证码缓存,避免复用。


4) 登录后修改密码(/profile/change-password)

新增内容

登录态下的改密入口:对当前用户邮箱发验证码,再更新密码。

落点位置

/mnt/data/server.js

POST /profile/change-password

关键变量

当前用户:req.session.user.id / req.session.user.email

成功后常用 res.redirect('/profile?pwd=...') 这种 query 参数做提示状态


5) 个人中心 Profile:资料展示、修改昵称/签名

新增内容

/profile 汇总展示:头像、昵称、签名、我的文章、我的评论、关注/粉丝数量等(“个人名片 + 数据面板”)。

/profile/update 支持更新 users.nicknameusers.signature

落点位置

/mnt/data/profile.ejs

/mnt/data/server.js

GET /profile

POST /profile/update

关键字段/变量

用户字段:users.nicknameusers.signature

渲染变量: currentUser / user
-昵称同步评论 name 的修复


6) 头像上传系统(sharp 压缩 + Session 同步)

新增内容

/profile/avatar 允许用户上传头像并落库,前端各处显示头像。

图片压缩保存:降低体积,降低服务器带宽占用。

落点位置

/mnt/data/server.js

POST /profile/avatar

图片处理函数:saveCompressedImage(...)(基于 sharp

前端:/mnt/data/profile.ejs/mnt/data/index.ejs 等页面显示头像区域

关键工具/实现

multer负责接收 multipart/form-data

sharpresize() + jpeg({ quality })png 输出

更新后同步:req.session.user.avatar = newAvatarPath


7) 关注系统(Follow / Followers / Following / 移除粉丝)

新增内容

关注关系表 + 完整链路:

关注:/follow/:id

取关:/unfollow/:id

粉丝列表:/profile/followers

关注列表:/profile/following

移除粉丝:/remove-follower/:id

落点位置

/mnt/data/server.js(路由 + SQL)

页面:/mnt/data/followers.ejs/mnt/data/following.ejs/mnt/data/user.ejs

关键表结构

follows(follower_id, followee_id, created_at)

索引:(follower_id, followee_id) 唯一约束/索引(避免重复关注 + 提升查询)


8) 用户主页(/user/:id)与访问策略雏形

新增内容

增加对外用户主页:展示对方基本信息 + 文章列表 + 关注按钮状态。

落点位置

/mnt/data/server.js

GET /user/:id

/mnt/data/user.ejs

关键变量

isFollowing(当前用户是否已关注对方,用于按钮显示)

userId / profileUser(模板渲染对方信息)


9) UGC 投稿:前台投稿 + 待审核状态(status)

新增内容

普通用户投稿进入“待审核”(articles.status=0),管理员通过后上线(status=1)。

博主/管理员投稿可直接发布(绕过审核)。

落点位置

/mnt/data/submit.ejs(投稿页)

/mnt/data/server.js

GET /article/submit

POST /article/submit

关键字段/变量

文章表:articles(status, author_id, author_name, title, content, category, cover, reject_reason, reviewed_by, reviewed_at...)

权限判断:req.session.isAdminisBlogger(req) 之类的 helper

分类过滤:普通用户只见 categories.allow_submit=1(这是功能设计 + 防滥用)


10) 审核后台:通过/驳回 + 驳回原因 + 邮件通知

新增内容

管理员审核页预览:/admin/review/:id

审核通过:/admin/review/:id/approve

审核驳回:/admin/review/:id/reject(写入 reject_reason

邮件通知投稿者审核结果

落点位置

/mnt/data/review.ejs(审核页)

/mnt/data/server.js(审核路由 + 更新 SQL + nodemailer)

关键变量/工具

nodemailer transporter.sendMail()

articles.statusarticles.reject_reason


11) 驳回后可编辑再提交(状态回滚到待审核)

新增内容

被驳回的文章允许作者修改并重新提交,重新进入待审核队列。

落点位置

页面:/mnt/data/submit_edit.ejs 

路由:GET /article/edit/:idPOST /article/edit/:id

关键字段

重新提交时会:

status = 0

reject_reason = NULL/''

reviewed_by/reviewed_at = NULL

并邮件提醒管理员“有新稿待审”


12) 评论系统:登录评论 + 回复(parent_id)+ 邮件提醒

新增内容

评论发布:POST /post/:id/comment

楼中楼回复:comments.parent_id

评论提醒逻辑:评论/回复触发 nodemailer 通知(博主或被回复者)

落点位置

/mnt/data/post.ejs(评论区 UI)

/mnt/data/server.js(评论写入 + 通知逻辑)

关键表字段

comments(id, article_id, user_id, name, email, content, parent_id, created_at, is_deleted...)

关键机制

身份来源:req.session.userisBlogger(req)

通知过滤:避免给自己发( if (targetEmail !== currentEmail)


13) 文章分享系统:链接 + 二维码 + 海报(share_cache 缓存)

新增内容

分享接口:GET /api/share/:id 输出:

url(文章链接)

qr(二维码资源地址)

poster(海报资源地址)

资源路由:

/share/qr/:id.png

/share/poster/:id.jpg

缓存目录:share_cache(减少重复生成)

落点位置

/mnt/data/server.js

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

常量:SHARE_QR_SIZESHARE_POSTER_W/HSHARE_JPEG_QUALITY

前端按钮:/mnt/data/post.ejs

关键工具

二维码:QRCode(npm 包)

海报合成:sharp(拼图/合成/压缩)

缓存控制:Cache-Control,并支持 ?refresh=1 强制刷新


14) 后台运营面板(/admin):文章/评论/用户的分页、搜索、筛选

新增内容

后台入口 /admin 做成“多面板”:

文章列表:分页 + title 搜索 + 分类筛选 + 状态筛选(待审/已发)

评论列表:分页 + 关键字搜索 + 按 user_id/article_id 筛

用户列表:搜索(nickname/email)+ 封禁/解封 + 删除 + 重置密码

落点位置

/mnt/data/admin.ejs

/mnt/data/server.js(大量 SQL:COUNT + LIMIT/OFFSET)

关键变量

pagepageSizeoffset

q(search query)

status / category filters

封禁字段:users.is_banned


15) 后台分类管理:allow_submit 可配置(用于“开放投稿”的栏目)

新增内容

分类新增/编辑时可以设置 allow_submit,用于控制普通用户能投稿到哪些栏目。

落点位置

/mnt/data/admin.ejs 分类表格(checkbox + form 绑定)

/mnt/data/server.js

POST /admin/categories/add

POST /admin/categories/update/:id

 

关键字段

categories(value, label, allow_submit, sort_order...)

后续与投稿页联动:GET /article/submit 只展示 allow_submit=1


16) 内容一致性:视频 iframe 自动包裹(autoWrapVideo)

新增内容

对富文本里的 B 站/视频 iframe 做统一结构包裹(例如 .video-container),保证 CSS 样式一致。

落点位置

/mnt/data/server.jsfunction autoWrapVideo(content)

写入文章内容的入口(投稿/后台新增/后台编辑/驳回重提)统一调用它

关键作用

避免“同样的视频,在不同文章/不同入口保存后样式不一致”的维护成本

💬 留言板 (0)

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

登录后参与评论

加入讨论,与博主互动

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

快捷分享