官方通知插件编写思路
BBS1 官方通知插件基础需求说明 v1.0
文档版本: v1.0
文档类型: 基础产品需求 / 插件开发需求
适用对象: BBS1 产品维护者、PHP/MySQL 开发人员、前端开发人员
状态: 第一版需求1. 需求背景
BBS1 现有论坛具备帖子置顶功能,但「置顶」主要用于提高帖子曝光度,并不能很好地解决以下场景:
- 管理员需要向全体用户发布重要公告;
- 某些公告只要求每个用户至少看到一次;
- 公告不适合长期置顶;
- 新用户不应该看到论坛建站以来所有历史公告;
- 管理员需要控制公告的生效时间和失效时间;
- 用户需要能够方便地查看尚未处理的官方公告。
因此,需要开发一个独立的「官方通知」插件。
该插件用于向论坛用户提供官方公告通知,并记录用户是否已经处理对应通知。
2. 产品目标
本插件的核心目标:
- 管理员可以创建官方通知。
- 每条通知对应一个已有论坛帖子。
- 用户可以通过论坛右上角的铃铛入口查看官方通知。
- 系统能够判断用户是否已经处理某条通知。
- 用户可以查看通知对应的帖子。
- 用户可以标记单条通知为已读。
- 用户可以一键忽略当前全部通知。
- 通知支持生效时间和失效时间。
- 没有失效时间的通知可以长期有效,并对之后注册的新用户生效。
- 通知采用服务器端数据库保存用户状态。
- 已发布通知不可编辑,只允许软删除。
3. 非目标
第一版暂不实现以下功能:
- 通知修改;
- 通知草稿;
- 通知撤回/重新启用;
- 通知优先级;
- 通知分类;
- 多语言通知;
- 通知推送邮件;
- 短信通知;
- 浏览器 Push;
- 强制用户阅读完整帖子;
- 阅读时长统计;
- 阅读百分比统计;
- 通知阅读数据报表;
- 与论坛现有个人通知系统联动。
4. 核心概念
4.1 官方通知
由管理员/维护者发布,用于向论坛用户传达重要官方信息。
例如:
论坛今晚 23:00 进行服务器维护。
官方通知对应一个论坛帖子,用户点击通知后进入该帖子。
4.2 已处理通知
用户已经明确表示不需要继续处理的通知。
第一版中以下行为会产生「已处理」状态:
A 模式
用户点击通知后立即视为已处理。
C 模式
用户在通知列表中主动点击「标记已读」。
4.3 忽略
用户可以使用「一键忽略全部」功能,将当前所有有效且未处理的通知标记为已处理。
第一版不单独保存「忽略」和「已读」两种状态。
统一保存为:
用户已经处理该通知。
5. 用户端功能
5.1 通知入口
论坛现有右上角存在搜索区域。
官方通知入口放置在搜索区域左侧
当存在至少一条当前有效且未处理的通知时,在铃铛上显示小红点:
🔔 ●没有需要处理的通知时:
🔔第一版不要求在铃铛上显示具体未读数量。
5.2 登录要求
官方通知功能仅面向已登录用户。
未登录用户
- 不显示官方通知未读状态;
- 不保存通知处理状态。
已登录用户
- 可以查看官方通知;
- 可以查看通知对应帖子;
- 可以标记通知已读;
- 可以一键忽略全部;
- 服务端保存用户处理记录。
6. 通知列表
用户点击铃铛后,显示官方通知列表。
通知按照时间倒序排列:
最新通知显示在最上方。
默认按照通知生效时间倒序排列;如果产品实现需要,也可以使用发布时间倒序,但必须保证最新通知优先。
示例:
官方通知 ──────────────────────── ● 论坛今晚进行服务器维护 2026-08-12 ● 社区规则更新 2026-08-10 ○ 新版论坛使用说明 2026-08-01 ──────────────────────── [ 一键忽略全部 ]其中:
●:当前未处理;○:已处理/历史状态,可根据最终 UI 设计隐藏;- 第一版可以只显示当前需要处理的通知,具体是否展示已处理通知由前端实现决定。
7. 通知点击行为
用户点击某条通知后:
通知列表 ↓ 点击通知 ↓ 根据 notification.tid 获取帖子 ↓ 跳转论坛帖子页面通知数据库只保存帖子
TID,不保存完整 URL。帖子 URL 使用 BBS1 现有帖子 URL 规则生成。
这样可以避免数据库中的 TID 与 URL 不一致。
8. 通知处理模式
管理员创建通知时,可以选择通知的处理模式。
8.1 A 模式:点击即处理
适用于普通公告。
用户:
点击通知 ↓ 立即写入用户处理记录 ↓ 跳转对应帖子即使用户随后没有完整阅读帖子,该通知也不会再次作为未处理通知出现。
8.2 C 模式:用户手动标记已读
适用于管理员希望用户主动确认的通知。
用户:
点击通知 ↓ 跳转对应帖子此时通知是否已经处理,不由点击行为决定。
用户需要回到通知列表,并点击:
[ 标记已读 ]系统才写入用户处理记录。
第一版不要求检测用户是否实际阅读了帖子内容。
9. 一键忽略全部
通知列表提供:
[ 一键忽略全部 ]点击后,将当前用户所有:
- 当前有效;
- 未处理;
- 未被删除;
的官方通知全部标记为已处理。
示例:
当前未处理: 通知 A 通知 B 通知 C 点击「一键忽略全部」 ↓ A 已处理 B 已处理 C 已处理处理后:
- 铃铛小红点消失;
- 当前通知不再作为未处理通知提示。
该操作不影响通知本身,也不删除通知。
10. 通知有效期
每条通知具有:
- 生效时间;
- 失效时间。
10.1 生效时间
通知只有在当前时间达到生效时间后,才进入用户的有效通知集合。
例如:
生效时间:2026-08-15 12:00在 2026-08-15 12:00 之前:
用户不应该看到该通知。
10.2 失效时间
通知达到失效时间后,不再作为当前有效通知显示。
例如:
生效时间:2026-08-01 00:00 失效时间:2026-08-10 00:00在 8 月 10 日之后:
该通知不再作为当前官方通知提示。
但数据库记录仍然保留。
10.3 永久有效
expired_at = NULL表示没有失效时间。这种通知从生效时间开始永久有效。
例如:
生效时间:2026-08-01 失效时间:NULL8 月 12 日注册的新用户仍然可以看到该通知。
11. 新用户通知规则
新用户不能收到论坛历史上所有官方通知。
系统只向用户提供:
当前时间已经达到生效时间,并且尚未达到失效时间的通知。
因此:
已过期通知
新用户不会收到。
当前有效且永久有效通知
新用户可以收到。
当前有效但用户已经处理的通知
不再提示。
12. 通知删除规则
已发布通知不可修改。
管理员只能执行:
删除。
删除采用软删除。
删除后:
- 普通用户不能再看到该通知;
- 不再产生新的未读提示;
- 原有通知数据仍保留在数据库;
- 原有用户处理记录原则上也保留,具体清理方式由数据库实现决定。
通知表使用:
deleted_at判断通知是否被删除。
如果需要记录删除操作人员,则保存:
deleted_by13. 管理员功能
13.1 创建官方通知
管理员后台提供创建功能。
字段:
TID
类型:
INT由管理员输入。
提交时后端必须验证对应帖子是否存在。
如果 TID 不存在:
创建失败并提示管理员。
通知标题
管理员手动输入。
通知标题可以与帖子标题不同。
例如:
帖子标题: 关于服务器迁移的一些说明 通知标题: 重要:论坛今晚将进行服务器迁移生效时间
管理员指定。
失效时间
管理员可以指定,也可以设置为:
永久有效对应数据库:
expired_at = NULL处理方式
提供:
○ 点击通知即处理 ○ 用户手动标记已读13.2 发布用户
发布通知时,系统自动记录当前登录管理员的用户 ID。
管理员不能通过前端输入或修改该字段。
字段:
created_by13.3 创建时间
系统自动记录通知创建时间:
created_at不允许管理员手动修改。
13.4 已发布通知不可编辑
通知发布成功后:
不允许修改通知内容。
如果管理员发现通知存在错误:
- 删除错误通知;
- 创建新的通知。
这样可以避免已经产生的用户处理记录与修改后的通知内容产生歧义。
14. 管理员通知列表
后台建议提供:
字段 说明 ID 通知 ID 标题 通知标题 TID 对应帖子 ID 生效时间 通知生效时间 失效时间 通知失效时间 处理模式 A / C 发布人 created_by对应用户创建时间 created_at删除状态 正常 / 已删除 操作 删除 第一版可以不实现复杂的搜索、筛选和统计。
15. 数据库设计
建议建立两张核心数据表。
15.1 官方通知表
建议表名:
bbs_notification字段:
字段 类型 NULL 说明 idINT/BIGINT NO 主键 tidINT NO 对应论坛帖子 ID titleVARCHAR NO 通知标题 effective_atDATETIME NO 生效时间 expired_atDATETIME YES 失效时间,NULL=永久有效 read_modeTINYINT NO 处理模式 created_byINT NO 发布用户 ID created_atDATETIME NO 创建时间 deleted_atDATETIME YES 删除时间 deleted_byINT YES 删除用户 ID read_mode建议:
1 = 点击通知即处理 2 = 用户手动标记已读16. 用户通知处理表
建议表名:
bbs_notification_user字段:
字段 类型 NULL 说明 useridINT NO 用户 ID notification_idINT/BIGINT NO 通知 ID processed_atDATETIME NO 处理时间 建议建立唯一约束:
UNIQUE(userid, notification_id)保证同一用户不会重复产生同一通知的处理记录。
17. 数据库索引建议
通知表建议至少考虑:
INDEX(effective_at, expired_at) INDEX(deleted_at) INDEX(created_by)用户处理表建议:
UNIQUE(userid, notification_id) INDEX(userid) INDEX(notification_id)最终索引设计应结合 BBS1 实际数据量和 MySQL 版本进行调整。
18. 核心业务查询
获取某个用户当前有效且未处理的通知,逻辑等价于:
SELECT n.* FROM bbs_notification n LEFT JOIN bbs_notification_user nu ON nu.notification_id = n.id AND nu.userid = ? WHERE n.deleted_at IS NULL AND n.effective_at <= NOW() AND (n.expired_at IS NULL OR n.expired_at > NOW()) AND nu.notification_id IS NULL ORDER BY n.effective_at DESC;实际开发时应根据 BBS1 数据库规范、字段类型和索引情况进行优化。
19. 铃铛红点判断
只需要判断:
当前用户是否存在至少一条有效、未删除、未处理通知。
无需首先加载所有通知。
逻辑:
存在符合条件的通知 ↓ 显示红点 不存在 ↓ 不显示红点可以使用:
SELECT 1 FROM ... LIMIT 1;以减少不必要的数据读取。
20. 已处理通知的处理
第一版不要求用户端展示完整的「已处理历史通知」。
用户端的核心目标是:
快速发现自己目前需要处理的官方通知。
因此前端可以只请求:
当前有效 + 未处理的通知。
未来如果需要增加「通知历史」功能,可以直接基于现有通知表扩展。
21. 与论坛现有个人通知系统的关系
本插件第一版不接入论坛现有个人通知系统。
原因:
- 官方通知和个人通知的业务语义不同;
- 避免用户收到重复通知;
- 避免出现两个通知系统的已读状态不一致;
- 官方通知已经拥有独立的铃铛入口;
- 降低第一版插件与现有论坛代码的耦合。
未来如果确实存在用户容易忽略官方通知的问题,可以单独增加:
「是否同时产生一条论坛个人通知」
作为可选功能。
第一版不实现。
22. 权限控制
只有具备相应管理员/维护者权限的用户可以:
- 创建官方通知;
- 查看后台官方通知列表;
- 删除官方通知。
普通用户:
- 只能查看自己的官方通知;
- 只能修改自己的通知处理状态;
- 不能创建、修改或删除通知。
created_by、created_at、deleted_by、deleted_at等字段必须由服务端生成或控制。不能信任前端提交的管理员 ID 或用户 ID。
23. 安全要求
23.1 TID 校验
创建通知时必须确认:
TID 是合法整数并且对应帖子存在。
23.2 权限校验
所有管理员接口必须进行服务端权限检查。
不能仅依靠前端隐藏按钮实现权限控制。
23.3 SQL 安全
所有涉及用户 ID、通知 ID、TID 等参数的数据库查询,应使用参数化查询,避免 SQL 注入。
23.4 标题输出
通知标题必须进行适当的 HTML 转义,避免管理员输入恶意 HTML/脚本造成 XSS。
23.5 CSRF
管理员创建、删除通知以及用户修改通知处理状态的 POST/状态修改接口,应按照 BBS1 现有安全机制进行 CSRF 防护。
24. 前端交互要求
第一版尽量复用 BBS1 现有 UI 风格。
铃铛
位置:
搜索区域左侧。
状态:
无未处理通知: 🔔 存在未处理通知: 🔔 ●通知列表
要求:
- 最新通知在最上方;
- 显示通知标题;
- 可以点击通知;
- C 模式提供「标记已读」;
- 提供「一键忽略全部」。
示例:
┌──────────────────────────┐ │ 官方通知 │ ├──────────────────────────┤ │ ● 论坛今晚进行服务器维护 │ │ 2026-08-12 │ │ │ │ ● 社区规则更新 │ │ 2026-08-10 │ │ │ │ [ 一键忽略全部 ] │ └──────────────────────────┘具体 UI 尺寸、颜色、动画等以 BBS1 现有设计规范为准。
25. 异常情况
25.1 通知对应帖子被删除
如果管理员创建通知后,对应帖子被其他系统功能删除:
用户点击通知时可能无法正常进入帖子。
插件应避免因此导致页面错误。
建议:
帖子不存在 ↓ 提示「该通知对应的帖子已不存在」同时该通知是否继续显示,由产品后续规则决定。
第一版建议仍允许管理员在后台删除该通知。
25.2 TID 不存在
创建通知时直接阻止发布。
25.3 通知已软删除
已软删除通知:
- 不出现在用户通知列表;
- 不产生红点;
- 不允许通过普通用户接口读取。
25.4 通知已过期
已过期通知:
- 不产生红点;
- 不作为当前通知展示;
- 数据库中保留。
26. 性能要求
本插件不应在每次页面加载时扫描全部历史通知并逐条判断用户状态。
查询必须优先利用:
生效时间 失效时间 删除状态 用户 ID 通知 ID等字段进行过滤。
重点保证:
随着历史通知数量增加,不应导致所有用户每次页面访问都加载全部历史通知。
数据库应通过合理索引保证查询效率。
27. 安装与数据库迁移
由于插件需要新增数据库表,插件安装/启用时应执行数据库初始化。
至少创建:
bbs_notification bbs_notification_user如果 BBS1 插件系统已有标准的:
- install;
- migration;
- upgrade;
机制,应优先使用现有机制。
如果插件系统不允许自动建表,则需要在插件安装文档中提供对应 SQL。
28. MVP 功能范围
第一版必须实现:
用户端
- [ ] 登录用户显示官方通知入口
- [ ] 铃铛图标
- [ ] 未处理通知小红点
- [ ] 官方通知列表
- [ ] 按时间倒序显示
- [ ] 点击通知跳转帖子
- [ ] A 模式
- [ ] C 模式
- [ ] 单条标记已读
- [ ] 一键忽略全部
- [ ] 服务端保存用户处理状态
- [ ] 生效时间
- [ ] 失效时间
- [ ] 永久有效通知
- [ ] 新用户只接收当前有效通知
管理端
- [ ] 创建通知
- [ ] 输入 TID
- [ ] TID 存在性检查
- [ ] 输入通知标题
- [ ] 设置生效时间
- [ ] 设置失效时间
- [ ] 设置永久有效
- [ ] 选择 A/C 处理模式
- [ ] 自动记录发布用户 ID
- [ ] 自动记录发布时间
- [ ] 通知发布后不可编辑
- [ ] 通知软删除
- [ ] 自动记录删除时间
- [ ] 自动记录删除用户 ID
数据库
- [ ] 官方通知表
- [ ] 用户通知处理表
- [ ] 唯一约束
- [ ] 必要索引
- [ ] 软删除字段
29. 暂不实现
以下内容明确排除在 v1.0 范围之外:
通知编辑 通知草稿 通知撤回 通知重新启用 通知分类 通知优先级 邮件推送 短信推送 浏览器 Push 个人通知系统联动 阅读时长统计 阅读完成度统计 阅读率报表 通知数量角标 多语言30. 验收标准
场景 1:创建通知
管理员输入有效 TID 并创建通知。
预期:
- 通知创建成功;
- 自动记录发布用户 ID;
- 自动记录创建时间;
- 用户可以在生效后看到通知。
场景 2:TID 不存在
管理员输入不存在的 TID。
预期:
系统拒绝创建通知。
场景 3:未来生效
通知:
生效时间:明天当前时间:
今天预期:
用户看不到该通知。
场景 4:通知过期
通知:
失效时间:昨天预期:
用户看不到该通知,也不会产生红点。
但数据库记录仍然存在。
场景 5:永久通知
通知:
expired_at = NULL预期:
在生效后持续有效。
新注册用户也可以看到。
场景 6:A 模式
用户点击通知。
预期:
- 通知立即写入用户处理记录;
- 跳转对应帖子;
- 用户再次打开通知列表时,该通知不再属于未处理通知;
- 如果没有其他未处理通知,铃铛红点消失。
场景 7:C 模式
用户点击通知。
预期:
- 跳转对应帖子;
- 不立即写入处理记录;
- 用户返回通知列表后,可以手动标记已读;
- 点击标记已读后,通知不再作为未处理通知。
场景 8:一键忽略
用户存在 3 条有效未处理通知。
点击:
一键忽略全部预期:
- 3 条通知全部产生用户处理记录;
- 通知红点消失;
- 通知本身没有被删除。
场景 9:新用户
论坛历史存在大量通知,其中:
10 条已经过期 3 条当前有效新用户注册后。
预期:
只看到 3 条当前有效通知。
场景 10:多设备
用户在设备 A 处理通知。
然后使用设备 B 登录同一个账号。
预期:
设备 B 不再提示该通知。
这是服务器端存储相对于 LocalStorage 的重要功能。
场景 11:管理员删除
管理员软删除通知。
预期:
- 用户无法继续看到该通知;
- 不再显示未读红点;
- 数据库记录仍然存在;
- 可以查询到删除时间;
- 可以查询到删除用户 ID。
31. 推荐的核心业务模型
最终第一版可以简化成下面这个模型:
┌──────────────────┐ │ 管理员发布通知 │ └────────┬─────────┘ │ ▼ ┌──────────────────┐ │ bbs_notification │ │ │ │ TID │ │ 标题 │ │ 生效时间 │ │ 失效时间 │ │ A/C模式 │ │ 发布人 │ │ 软删除 │ └────────┬─────────┘ │ ▼ 当前是否处于有效期? │ │ 否 是 │ │ ▼ ▼ 不显示 检查用户处理记录 │ ┌──────┴──────┐ │ │ 已处理 未处理 │ │ ▼ ▼ 不显示 🔔 小红点 │ ▼ 通知列表 │ ┌────────────┼────────────┐ ▼ ▼ ▼ 查看帖子 标记已读 一键忽略 │ │ │ └────────────┴────────────┘ │ ▼ bbs_notification_user32. 第一版设计原则总结
本插件第一版遵循以下原则:
- 官方通知与论坛置顶帖分离。
- 官方通知与论坛现有个人通知系统分离。
- 通知以 TID 作为目标对象,而不是保存 URL。
- 通知发布后不可编辑,只能软删除。
- 通知有效期决定它是否属于当前通知集合。
- 用户处理记录决定某个用户是否还需要看到该通知。
- 永久有效通知通过
expired_at = NULL表示。 - 新用户不会获得历史过期通知。
- 用户处理状态存储在服务器端,实现跨设备同步。
- A/C 两种处理模式由发布者针对单条通知选择。
- 一键忽略全部只影响当前用户,不影响其他用户。
- 第一版保持功能简单,不引入复杂的推送、统计和通知分类系统。
33. 后续版本可扩展方向
在 v1.0 基础上,未来可以考虑:
- 通知阅读率统计;
- 通知阅读人数;
- 「强制阅读」通知;
- 通知分类;
- 通知优先级;
- 通知数量角标;
- 历史通知页面;
- 管理员搜索通知;
- 通知搜索;
- 个人通知系统联动;
- 邮件/Push 通知;
- 通知模板;
- 通知定时发布;
- 管理员操作日志。
这些功能不应影响 v1.0 的基础数据模型设计。
34. 版本结论
BBS1 官方通知插件 v1.0 的核心实现可以归纳为:
一个官方通知表 + 一个用户通知处理关系表 + 一个论坛铃铛入口。
通知通过
TID关联论坛帖子,通过effective_at / expired_at控制生命周期,通过userid + notification_id判断用户是否已经处理。该设计能够同时满足:
- 官方公告;
- 用户至少处理一次;
- 新用户过滤历史通知;
- 通知时效;
- 永久公告;
- 一键忽略;
- A/C 两种处理策略;
- 多设备同步;
- 软删除;
- 发布者追踪;
并且与现有 BBS1 的帖子、用户、个人通知体系保持较低耦合,适合作为第一期 MVP 实现。
主楼@jesen 已按这份 v1.0 文档完成并发布
official_notifications1.0.0,市场 topic/403。已实现两张插件表、服务器端跨设备处理状态、搜索区左侧铃铛红点、当前有效通知列表、A 模式点击即处理、C 模式手动确认、一键忽略全部、生效时间、失效时间、永久有效、新用户仅看到当前有效通知、TID 存在校验、发布人/发布时间自动记录、发布后不可编辑、软删除及删除人/删除时间。查询用有效期+删除状态+用户处理关系和 LIMIT 1 判断红点,不扫描全部历史。
本地已创建 C 模式通知验证:铃铛红点出现、列表显示未读、标记已读按钮正常;后台字段和不可编辑/软删除流程正常。