找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 18|回复: 0

[维护日志] [2026-04-28] [功能] 后台用户管理操作自动邮件通知系统

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

9336

威望

7293

金钱

1万

贡献

管理员

自由的灵魂

积分
107261
主题
5618
回帖
26658
注册时间
2003-4-10
最后登录
2026-9-15
发表于 2026-4-28 17:35:59 | 显示全部楼层 |阅读模式

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

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

×
1、需求缘起及目标

需求背景:
管理员在对用户执行“禁止发言/访问”、“锁定账号”、“解禁”、“删除用户”等操作后,被操作用户无法及时获知账号状态变更,导致:
  • 用户误以为账号被盗或被误封,产生误解
  • 申诉时缺少操作时间和操作类型的明确记录
  • 管理员需额外通过其他渠道告知用户,增加沟通成本

目标设定:
  • 管理员执行特定管理操作时,系统自动向用户注册邮箱发送通知邮件
  • 邮件标题直接显示操作结果和账号名称,无需打开即可获知关键信息
  • 正文简洁:临时封禁显示时长,其他操作仅显示时间和联系方式
  • 不影响 Discuz! 原有功能和性能

2、方案设计

2.1 技术选型

项目选择理由
邮件发送函数Discuz! 内置 sendmail()复用现有邮件配置,无需额外开发
修改位置后台管理操作分支仅在管理员操作时触发,不影响前台
邮件格式HTML确保换行和分段在各种邮箱客户端正常显示


2.2 涉及操作及修改文件

操作类型修改文件触发条件
禁止发言/访问、锁定、解禁source/admincp/admincp_members.php后台 operation == 'ban' 分支
删除用户source/function/function_delete.phpdeletemember() 函数执行时


2.3 邮件格式设计

原则:标题直击结果,正文精简不重复

场景标题格式正文内容
临时禁止您在 {论坛名} 的账户 {用户名} 已被 禁止发言限制时长:X 天<br>操作时间:...<br>如有疑问,请联系网站管理员。
永久禁止您在 {论坛名} 的账户 {用户名} 已被 永久禁止发言操作时间:...<br>如有疑问,请联系网站管理员。
锁定您在 {论坛名} 的账户 {用户名} 已被 锁定操作时间:...<br>如有疑问,请联系网站管理员。
解禁您在 {论坛名} 的账户 {用户名} 已被 解禁操作时间:...<br>如有疑问,请联系网站管理员。
删除用户您在 {论坛名} 的账户 {用户名} 已被删除操作时间:...<br>如有疑问,请联系网站管理员。


设计亮点:
  • 账号纳入标题:用户在邮箱列表中即可直接看到是哪个账号被操作,无需打开邮件
  • 临时封禁额外显示时长:提供明确的限制期限信息
  • 正文不重复标题内容:避免冗余,保持简洁

3、核心代码实现

3.1 禁言/解禁/锁定邮件代码(admincp_members.php)

插入位置:C::t('common_member'.$tableext)->update($member['uid'], $setarr); 之后

  1. // --- 自动发送邮件通知 (新增代码开始) ---
  2. $user = C::t('common_member')->fetch($member['uid']);
  3. if($user && !empty($user['email'])) {
  4.     $toemail = $user['email'];
  5.    
  6.     // 计算实际天数
  7.     $expiry_timestamp = intval($_GET['banexpirynew']);
  8.     if($expiry_timestamp > 0) {
  9.         $expiry_days = ceil(($expiry_timestamp - TIMESTAMP) / 86400);
  10.     } else {
  11.         $expiry_days = 0;
  12.     }
  13.    
  14.     // 判断操作类型,标题直接包含账号
  15.     if($_GET['bannew'] == 'post') {
  16.         if($expiry_days > 0) {
  17.             $subject = '您在 ' . $_G['setting']['sitename'] . ' 的账户 ' . $user['username'] . ' 已被 禁止发言';
  18.             $detail = '限制时长:' . $expiry_days . ' 天';
  19.         } else {
  20.             $subject = '您在 ' . $_G['setting']['sitename'] . ' 的账户 ' . $user['username'] . ' 已被 永久禁止发言';
  21.             $detail = '';
  22.         }
  23.     } elseif($_GET['bannew'] == 'visit') {
  24.         if($expiry_days > 0) {
  25.             $subject = '您在 ' . $_G['setting']['sitename'] . ' 的账户 ' . $user['username'] . ' 已被 禁止访问';
  26.             $detail = '限制时长:' . $expiry_days . ' 天';
  27.         } else {
  28.             $subject = '您在 ' . $_G['setting']['sitename'] . ' 的账户 ' . $user['username'] . ' 已被 永久禁止访问';
  29.             $detail = '';
  30.         }
  31.     } elseif($_GET['bannew'] == 'status') {
  32.         $subject = '您在 ' . $_G['setting']['sitename'] . ' 的账户 ' . $user['username'] . ' 已被 锁定';
  33.         $detail = '';
  34.     } else {
  35.         // 解禁操作
  36.         $subject = '您在 ' . $_G['setting']['sitename'] . ' 的账户 ' . $user['username'] . ' 已被 解禁';
  37.         $detail = '';
  38.     }
  39.    
  40.     $message = "<html><body>";
  41.     if(!empty($detail)) {
  42.         $message .= "<p>" . $detail . "<br><br>";
  43.     } else {
  44.         $message .= "<p>";
  45.     }
  46.     $message .= "操作时间:" . date('Y-m-d H:i:s') . "<br><br>";
  47.     $message .= "如有疑问,请联系网站管理员。</p>";
  48.     $message .= "</body></html>";

  49.     loaducenter();
  50.     include_once libfile('function/mail');
  51.     sendmail($toemail, $subject, $message);
  52. }
  53. // --- 自动发送邮件通知 (新增代码结束) ---
复制代码


3.2 删除用户邮件代码(function_delete.php)

插入位置:C::t('common_member')->delete($arruids, 1, 1); 之前

  1. // --- 自动发送邮件通知 (新增代码开始) ---
  2. $deleted_count = 0;
  3. foreach($arruids as $uid) {
  4.     $user = C::t('common_member')->fetch($uid);
  5.     if($user && !empty($user['email'])) {
  6.         $toemail = $user['email'];
  7.         
  8.         $subject = '您在 ' . $_G['setting']['sitename'] . ' 的账户 ' . $user['username'] . ' 已被删除';
  9.         
  10.         $message = "<html><body>";
  11.         $message .= "<p>操作时间:" . date('Y-m-d H:i:s') . "<br><br>";
  12.         $message .= "如有疑问,请联系网站管理员。</p>";
  13.         $message .= "</body></html>";

  14.         loaducenter();
  15.         include_once libfile('function/mail');
  16.         sendmail($toemail, $subject, $message);
  17.         $deleted_count++;
  18.     }
  19. }
  20. if($deleted_count) {
  21.     runlog('cron', "Sent deletion notification email to {$deleted_count} users.");
  22. }
  23. // --- 自动发送邮件通知 (新增代码结束) ---
复制代码


4、实施效果对比

指标实施前实施后变化
用户获知状态变更❌ 无通知,需主动询问✅ 自动邮件通知体验大幅提升
信息可见性仅管理员后台可见邮件标题直接显示账号和操作用户一目了然
申诉依据用户无操作记录邮件包含操作时间有效支撑申诉
管理员沟通成本需额外通知用户系统自动完成工作效率提升
临时封禁信息无时长说明明确显示限制天数用户清楚规则


5、实施注意事项

5.1 风险控制

风险项评估应对措施
PHP语法错误中风险修改前备份文件,修改后 php -l 检查语法
数据库更新失败低风险建议增加 DB::affected_rows() 判断
邮件发送失败低风险依赖后台邮件配置,可查看 /data/log/ 日志
性能影响极低仅管理员操作时触发,同步发送
升级覆盖长期风险升级前备份修改文件,升级后重新应用


5.2 测试验证

建议测试以下场景:
  • 临时禁止发言(设置天数)
  • 永久禁止发言
  • 永久禁止访问
  • 账号锁定
  • 解禁操作
  • 删除用户

每个场景确认邮件标题和正文格式正确。

6、技术沉淀点

  • 管理操作的通知闭环:重要操作应配套通知机制,提升用户体验和信息透明度
  • 标题即信息:将核心信息(账号、操作结果)前置到邮件标题,用户无需打开即可获取关键内容
  • HTML 邮件的必要性:纯文本邮件的换行符在不同客户端表现不一致,HTML 格式确保格式统一
  • 时间戳的正确处理banexpirynew 返回的是到期时间戳,需减去当前时间戳再计算天数
  • 代码插入位置的重要性:必须在数据库更新成功后、流程中断(如 cpmsg)之前插入,确保邮件发送
  • 测试驱动的功能开发:每个场景逐一测试验证,确保覆盖所有分支逻辑

7、后续扩展建议

  • 增加数据库状态判断:在邮件代码外层增加 if(DB::affected_rows()) 判断,避免“操作失败但通知成功”的误报
  • 扩展至其他管理操作
    • 禁止IP
    • 修改用户组
    • 积分变更
  • 邮件模板化:将邮件标题和正文模板存入数据库,支持后台自定义修改
  • 异步发送:将邮件发送改为队列异步处理,避免操作页面卡顿(适用于批量操作场景)
  • 邮件发送记录:在后台增加“邮件发送记录”功能,方便追溯和排查问题

总结:
通过本次功能开发,为论坛管理操作建立了完整的邮件通知闭环。在设计上遵循“标题直击结果、正文简洁不重复”的原则,显著提升了用户体验和管理效率。同时积累了 Discuz! 后台功能扩展的实践经验,为后续类似需求提供了可复用的技术方案。
不懂就搜!点此搜点拨论坛。如果本坛没有,请尝试点此问AI,或跟帖提问。
发帖前注意看置顶帖
不定期借助AI对点拨论坛陈年老帖进行挖坟回复,打扰勿怪!
您的提问是对点拨论坛的最大贡献!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-9-15 17:03 , Processed in 0.054981 second(s), 9 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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