活力39282
在线时间13640 小时
阅读权限200
管理员
自由的灵魂
- 积分
- 107434
- 主题
- 5630
- 回帖
- 26661
- 注册时间
- 2003-4-10
- 最后登录
- 2026-10-2
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
一、需求背景
论坛用户在对帖子进行评分(加分/扣分)后,被评分者无法及时获知,不利于用户互动和回流。需要增加邮件通知功能,在用户帖子被评分时自动发送邮件提醒。
功能目标:
- 覆盖主题帖评分和回帖评分
- 包含评分分值、评分理由、评分人、帖子链接
- 实时发送,无需等待队列
二、技术方案
2.1 核心逻辑位置
在 source/module/forum/forum_misc.php 的 action=rate 分支中,评分成功并写入日志后,增加邮件发送逻辑。
代码位置:forum_misc.php 第 600-700 行(评分成功块内,showmessage 之前)
2.2 邮件内容设计
| 字段 | 来源 | 说明 | | 收件人 | $post['authorid'] → 用户邮箱 | 帖子作者 | | 帖子类型 | $post['first'] | 主题/回帖 | | 帖子标题 | $thread['subject'] 或从数据库获取 | 主题标题 | | 评分分值 | $creditsarray | 各积分项变动 | | 评分理由 | $sqlreason | 用户填写的理由 | | 评分人 | $_G['member']['username'] | 执行评分的用户 | | 帖子链接 | 根据 pid/tid 构建 | 可直达被评帖子 |
2.3 邮件模板(简洁版)
- 您在 『版块名称』 的帖子被评分
- 尊敬的 {username},您好:
- 您在论坛发布的{主题/回帖}《{subject}》获得了评分:
- {积分项}: {分值}
- 评分理由:{reason}
- 评分人:{from_user}
- 查看详情:{post_url}
- 操作时间:{dateline}
- 期待您继续参与社区讨论。
复制代码
2.4 发送方式
采用实时发送(直接调用 sendmail()),不使用邮件队列。原因:
- Discuz! 默认最多 8 个积分项,不存在批量评分的场景
- 评分操作本身对实时性要求较高
- 避免用户等待 5 分钟队列周期
三、涉及文件
| 文件 | 绝对路径 | 修改内容 | | forum_misc.php | /source/module/forum/forum_misc.php | 在评分成功块中新增邮件发送代码 |
四、关键代码片段
- // ========= 新增:评分后发送邮件通知 =========
- $author = C::t('common_member')->fetch($post['authorid']);
- if($author && !empty($author['email']) && $post['authorid'] != $_G['uid']) {
- // 构建分值显示
- $score_parts = array();
- foreach($creditsarray as $id => $addcredits) {
- if(isset($_G['setting']['extcredits'][$id])) {
- $score_parts[] = $_G['setting']['extcredits'][$id]['title'] . ': ' .
- ($addcredits > 0 ? '+' . $addcredits : $addcredits);
- }
- }
- $score_display = implode(' | ', $score_parts);
-
- // 判断帖子类型并获取标题、链接
- $post_type = $post['first'] ? '主题' : '回帖';
- if($post['first']) {
- $thread_info = C::t('forum_thread')->fetch_thread($post['tid']);
- $subject_title = $thread_info ? $thread_info['subject'] : '主题';
- $post_url = $_G['siteurl'] . 'forum.php?mod=viewthread&tid=' . $post['tid'];
- } else {
- $thread_info = C::t('forum_thread')->fetch_thread($post['tid']);
- $subject_title = $thread_info ? $thread_info['subject'] : '帖子';
- $post_url = $_G['siteurl'] . 'forum.php?mod=redirect&goto=findpost&ptid=' .
- $post['tid'] . '&pid=' . $post['pid'];
- }
-
- // 发送邮件
- include_once libfile('function/mail');
- sendmail($author['email'], $subject, $message);
- }
- // ========= 评分邮件通知结束 =========
复制代码
五、技术难点与解决
| 难点 | 解决方案 | | 主题评分时标题获取 | 主题评分时 $thread['subject'] 可能为空,改为从数据库查询 forum_thread 表 | | 回帖评分时标题获取 | 从数据库查询主题标题,回帖本身无标题 | | 自己评分不通知 | 添加 $post['authorid'] != $_G['uid'] 判断 | | 评分理由可能为空 | 设置默认值 '无',避免空字段 | | 邮件标题重复问题 | 从「站点名称」改为「版块名称」,如 您在 『版块名』 的帖子被评分 |
六、测试验证
| 测试场景 | 预期结果 | 状态 | | 对主题帖评分 | 主题作者收到邮件,含正确标题和链接 | ✅ | | 对回帖评分 | 回帖作者收到邮件,含主题标题和回帖链接 | ✅ | | 自己评自己 | 不发邮件 | ✅ | | 带理由评分 | 邮件中包含评分理由 | ✅ | | 多积分项评分 | 邮件中显示所有积分变动 | ✅ |
七、技术沉淀
| 项目 | 经验总结 | | 数据来源判断 | 评分代码中 $post['first'] 可区分主题/回帖,但 $thread 变量不可靠,需主动查询数据库 | | 邮件标题优化 | 使用版块名称比站点名称更精准,避免重复 | | 无需队列 | 评分场景不存在批量操作(最多8个积分项),直接实时发送即可 | | HTML 转义 | 帖子标题可能含特殊字符,使用 htmlspecialchars() 防护 |
八、env-base 分支更新
已在第九节(目录结构与关键路径) 中标注:
- source/module/forum/forum_misc.php — 评分处理(含评分邮件通知)
九、相关配置依赖
| 配置项 | 说明 | 状态 | | $_G['setting']['sitename'] | 站点名称,备用 | ✅ | | $_G['forum']['name'] | 版块名称,用于邮件标题 | ✅ | | $_G['siteurl'] | 站点 URL,用于构建完整链接 | ✅ | | $creditsarray | 评分积分数据 | ✅ | | $sqlreason | 评分理由 | ✅ |
十、未来展望
- 如需增加其他通知场景(如 @ 提及),可复用相同的 sendmail() 模式
- 如论坛规模扩大(日均评分 > 1000),可考虑改用队列发送
|
|