From 8b3e49e09106ed6a88eaa377c1ba4b37e1cd2d90 Mon Sep 17 00:00:00 2001 From: laoyang Date: Tue, 3 Nov 2026 10:08:49 +0800 Subject: [PATCH] =?UTF-8?q?=E9=82=AE=E4=BB=B6=EF=BC=9A=E5=B8=A6=E7=A7=81?= =?UTF-8?q?=E4=BA=BA=E9=93=BE=E6=8E=A5=E6=97=B6=E7=BB=9F=E4=B8=80=E5=8A=A0?= =?UTF-8?q?=E3=80=8C=E8=BF=99=E4=B8=AA=E9=93=BE=E6=8E=A5=E5=8F=AA=E6=9C=89?= =?UTF-8?q?=E6=82=A8=E8=83=BD=E6=89=93=E5=BC=80=EF=BC=8C=E8=AF=B7=E4=B8=8D?= =?UTF-8?q?=E8=A6=81=E8=BD=AC=E5=8F=91=E3=80=8D=E6=8F=90=E9=86=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 用户要求:每次发这种链接,都要在链接上/下给他一个提示 —— 这个链接是独有的,不要转给别人、不要让别人看到,是跟踪反馈的唯一凭证。 实现:在 fb_mail_layout() 里加 $privNoteHtml, layout 传 personal=true 才渲染,位置在「按钮之后、纯文本链接之前」。 这样只要新增邮件是发给提交人的,标一下就自动带上,不会漏。 覆盖 7 处(全部发给提交人的): 回复通知 / 状态变更 / 审核通过 / 转为不公开 / 关闭说明 / 提交回执 / 兜底 不覆盖 1 处(管理员通知,按钮指向后台,不是私人凭证) 提醒文案(斟酌过,讲清缘由而不只是禁止): 标题:这个链接只有您能打开,请不要转发 正文:它等同于您在这条反馈上的身份凭证 —— 谁拿到这个链接, 谁就能查看和处理这条反馈。请只自己使用,不要发给别人, 也不要发到公开的地方。如果不需要继续跟踪,删掉这封邮件即可。 → 说清「是什么」而不是只喊「别外传」,用户才会真的照做; 补一句退路(删掉邮件即可),避免像是免责声明。 验证:7 类邮件全部含提醒且都在页脚之前;管理员通知不含; 像素级检查确认视觉顺序为「蓝色按钮 y=719 → 黄色提醒块 y=874..982」, 即提醒在按钮下方、正文区内,不是埋在邮件底部。 --- lib/mailer.php | 46 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/lib/mailer.php b/lib/mailer.php index b6eca0b..b2867fa 100644 --- a/lib/mailer.php +++ b/lib/mailer.php @@ -367,6 +367,36 @@ if (!function_exists('fb_mail_layout')) { . fb_mail_esc($link) . '

'; } + /* ---- 私人链接安全提醒 ---- + * + * 用户 2026-11-03:「每次给他发这种链接的时候,都要在链接下面或上面 + * 给他一个提示:这个链接是你独有的,不要转给别人。」 + * + * 为什么必须提醒:这个链接里带 track_token,它就是**唯一凭证**—— + * 谁拿到这串东西,谁就能看(甚至回复)这条反馈。而本站不做登录, + * 我们没法事后判断"是本人还是捡到链接的人"。 + * 只要邮件里带了私人链接(personal=true),这条提醒就必须出现。 + * + * 措辞取舍: + * - 说清"是什么"(只有你能看的入口),而不只是"别外传"——只讲禁止, + * 用户会觉得是免责声明;讲清缘由他才会真的照做。 + * - 不让用户恐慌:补一句"不需要的话可以删掉这封邮件",给出退路。 + * - 管理员后台通知里的链接不是私人凭证,不加这段(personal=false)。 */ + $privNoteHtml = ''; + if (!empty($o['personal'])) { + $privNoteHtml = '' + . '
' + . '

' + . '这个链接只有您能打开,请不要转发

' + . '

' + . '它等同于您在这条反馈上的身份凭证 —— 谁拿到这个链接,谁就能查看和处理这条反馈。' + . '请只自己使用,不要发给别人,也不要发到公开的地方。' + . '如果不需要继续跟踪,删掉这封邮件即可。

' + . '
'; + } + // ---- 收件人问候 ---- $introHtml = ''; if ($intro !== '') { @@ -420,8 +450,10 @@ if (!function_exists('fb_mail_layout')) { . 'color:#1b2430">' . fb_mail_esc($title) . '' // 正文 + // 顺序:按钮 → 私人链接提醒 → 纯文本兜底链接。 + // 提醒要贴在按钮旁边(同一屏可见),不能埋到邮件最底部。 . '' - . $introHtml . $body . $btnHtml . $linkHtml + . $introHtml . $body . $btnHtml . $privNoteHtml . $linkHtml . '' // 页脚 @@ -914,6 +946,7 @@ if (!function_exists('fb_notify_render')) { 'blocks' => $blocks, 'button' => ['text' => '查看并回复', 'url' => $url], 'link' => $url, + 'personal' => true, // 发给提交人:带 token 的私人链接,需提醒勿外传 'recipient' => $to, ]; } @@ -972,6 +1005,7 @@ if (!function_exists('fb_notify_render')) { // 下载按钮之外,始终保留「查看这条反馈」的原文链接 'link' => ($btnUrl === $url) ? $url : ('下载地址:' . $dlUrl . "\n" . '查看反馈:' . $url), + 'personal' => true, // 发给提交人 'recipient' => $to, ]; } @@ -994,6 +1028,7 @@ if (!function_exists('fb_notify_render')) { ], 'button' => ['text' => '查看并跟踪这条反馈', 'url' => $url], 'link' => $url, + 'personal' => true, // 发给提交人 'recipient' => $to, ]; } @@ -1022,6 +1057,7 @@ if (!function_exists('fb_notify_render')) { 'blocks' => $blocks, 'button' => ['text' => '查看这条反馈', 'url' => $url], 'link' => $url, + 'personal' => true, // 发给提交人(转为不公开) 'recipient' => $to, ]; } @@ -1050,6 +1086,10 @@ if (!function_exists('fb_notify_render')) { ? '如果上面的说明没能解决您的疑问,直接回复本邮件即可,我们继续跟进;也可以发到 ' . $mail . '。' : '如果上面的说明没能解决您的疑问,直接回复本邮件即可,我们继续跟进。'), ]; + /* 这条已经「已关闭 + 不公开」,不带 token 的链接打不开 —— + * 必须给带 token 的私人链接,用户才能回来看上下文、继续补充。 + * 注意:button 是 layout 层属性,不是 block 类型。 */ + $closeBtnUrl = fb_thread_link($thread, true); $layout = [ 'software' => $sw, @@ -1058,6 +1098,8 @@ if (!function_exists('fb_notify_render')) { 'title' => '关于您反馈的问题,我们的说明', 'intro' => ($name !== '' ? $name . ',您好:' : '您好:'), 'blocks' => $blocks, + 'button' => ['text' => '查看这条反馈', 'url' => $closeBtnUrl], + 'personal' => true, // 发给提交人(关闭说明) 'recipient' => $to, ]; } @@ -1131,6 +1173,7 @@ if (!function_exists('fb_notify_render')) { 'blocks' => $blocks, 'button' => ['text' => '查看这条反馈', 'url' => $url], 'link' => $url, + 'personal' => true, // 发给提交人(回执) 'recipient' => $to, ]; } @@ -1146,6 +1189,7 @@ if (!function_exists('fb_notify_render')) { 'blocks' => [['type' => 'text', 'text' => '您关注的反馈有更新。']], 'button' => ['text' => '查看详情', 'url' => $url], 'link' => $url, + 'personal' => true, // 兜底同样是发给提交人的 'recipient' => $to, ]; }