全流程邮件通知:任何对反馈的变动都要通知提交人,模板重做
用户要求:「只要是对这个反馈进行变动的,别人回复他、编辑他,或者处理他、改变他的状态,都需要通知到这个人。」
new.php:45
filter_var
:128
required
threads.author_email NOT NULL
thread.php:132
admin.php:172
fb_notify_reply()
admin.php:115
fb_notify_closed()
status
admin.php:128-140
admin.php:100
:123
admin.php:177
cron.php
notify_log.ok=0
cron.php:83-104
fb_smtp_send
lib/mailer.php
fb_notify_html()
notify_log
reply_id
admin.php
状态变更的文案要按状态区分(用户原话):
⇒ 实现上建议:状态表里给每个状态配一句「给用户看的话」,不要写死在代码里。
现在 fb_notify_html() 和 fb_notify_closed_html() 是两套土法 div。 重做成一套统一的 HTML 邮件模板,要求:
fb_notify_closed_html()
#0057B8
assets/
用户原话是「如果有人给我提一个反馈,就要给我发一封邮件」。 ⇒ 新反馈提交时,给管理员发一封通知(现在是完全没有的)。 管理员收件地址在后台设置页可配。
邮件通知与软件/模块归属是两件互不依赖的事:#1 改数据结构与前后台界面,#2 改 mailer 与通知触发点;#2 可以独立验收(触发六个事件看邮件),不依赖 #1 完成。
原需求里「删除」这条保留,且文案要明确告知:「你的反馈已被删除」。 不要吞掉不发,用户有权知道。
用户明确:「短时间之内多次修改的可能性不是特别大。只要状态发生变化、有修改,这一次就发一封信就行。」
⇒ 撤回原需求里的「同一事件不重复轰炸 / 考虑合并或限流」那条。 不做时间窗合并,一次变动 = 一封信。实现简单,也符合预期。
用户明确:「管理员通知邮箱放在用户的,也就是管理后台的配置就可以了。」
⇒ 放进现有后台「站点设置」页,走 settings 表。
🔴 实现时必须同步改四处,否则填了不生效(这是本项目已知的坑):
lib/util.php
fb_setting_keys()
fb_admin_save_settings()
config.example.php
注意本项目设置体系是 fb_cfg() = config.php + settings 表叠加,且留空提交走 fb_unset_setting() 删除行回落出厂值 —— 空字符串会覆盖成空,不能直接写空。
fb_cfg()
config.php
settings
fb_unset_setting()
状态表现有四项(config.example.php:63-68):open 待处理 / doing 处理中 / resolved 已解决 / closed 已关闭。
config.example.php:63-68
open
doing
resolved
closed
用户口头说的是「不予考虑 / 正在处理 / 已上架」,与现有四项不完全对应。 实现时建议:在状态配置里给每个状态配一句「给用户看的话」, 后台可改,不要写死在代码里。若现有四项不够用,允许后台增删状态。
前几轮改代码时未按「没工单不许动代码」执行,此处补录已完成部分与验证证据。
55d2dfa
9b822d2
7a578fa
FB_ASSET_V
1c2e8d5
b835afc
1434a6d
c19e475
step
min
f1a81cb
e408dc7
software
categories
threads.software_id
category_id
th_move
?sw=
software.color
--brand
smtp.*
notify.*
PHP 8.5 全入口弃用日志 0 条。
已部署到 https://feedlite.yangyq.net/,41 文件 md5 全一致, 资源版本 v13,/data/ /config.php 均 403。
https://feedlite.yangyq.net/
/data/
/config.php
/tmp/reset-feedlite-for-reinstall.sh
用户原话:
站点设置现在太长了,应该把邮箱设置单独拿出来,做一个标签页。
「站点设置」这一个 tab 里塞了:站点信息、页脚、邮件通知、附件存储、审核、 存储体检。邮件那一段有 10 多个字段加测试按钮,占了大半屏,往下翻很累。
那就有问题了,我之前已经配置过了。你重置过数据库吗?或者说,你部署的时候把这个配置给我重置了?这个配置是写在数据库里,还是写在配置文件里的?
installed_at
oss.bucket
systemuploadstatic
oss.endpoint
oss-cn-qingdao-internal.aliyuncs.com
oss.instance_role
SystemUploadStaticOSSRole
oss.prefix
feedlite
site_name
老杨个人开源项目反馈系…
admin.username
laoyang
admin.password_hash
如果重置过,这些全都会消失(会是 config.php 的出厂默认)。所以数据层完好。
admin.php:231 只有一个 act === 'settings' 分支,而两个表单都提交 act=settings:
admin.php:231
act === 'settings'
act=settings
admin.php:888
admin.php:985
<input type="hidden" name="act" value="settings">
这就是我上一轮做「邮件拆成独立 tab」时埋的坑。我在提交说明里还写:
保存逻辑没动:新 tab 的表单仍提交 act=settings,走的还是原来那段处理代码, 所以 SMTP / notify 的写入行为完全不变。
"完全不变"恰恰是 bug:那段处理代码会无条件把表单里的 smtp 字段写进数据库。 你在站点设置页保存任何其他设置(比如附件那几项)时,该页表单里没有 smtp 字段, $post('smtp.host', '') 就取到空串,于是 fb_set_setting('smtp.host', '') 把已有配置覆盖成空。
$post('smtp.host', '')
fb_set_setting('smtp.host', '')
$smtpText = ['smtp.host', 'smtp.user', 'smtp.from', 'smtp.from_name']; foreach ($smtpText as $k) { fb_set_setting($k, trim((string)$post($k, ''))); // ← 不区分"没提交"和"提交了空" }
smtp.pass 之所以还留着 18 字节,是因为代码对它单独处理了「留空=不修改」:
smtp.pass
$sp = ... $_POST['smtp_pass'] ...; if (trim($sp) !== '') { fb_set_setting('smtp.pass', $sp); } // 留空不写
所以现状是 pass 有值、其余全空 —— 这个组合本身就是 bug 的指纹。
pass
典型的「部分表单提交导致未提交字段被清空」。 正确做法只有一条:保存前先判断该表单是否真的提交了这个字段。
修法两种,本次采用第 2 种 + 第 1 种兜底:
tab
$post
notify.enabled / notify.on_every_reply / notify.admin_new_thread 是 checkbox。 站点设置页里也没有它们,所以:
notify.enabled
notify.on_every_reply
notify.admin_new_thread
所以 notify.enabled 现在是 0,很可能也是被这样冲掉的。
这个设置项:
lib/util.php:414
admin.php:1070
grep -rn "admin_new_thread" 只命中这三处,没有任何地方在"有新反馈"时发信。 用户说的「我提交了一个反馈…它怎么不给我发邮件呢」正是这个 —— 功能压根没写, 不是配置问题。属于 #2 范围内的功能缺失。
grep -rn "admin_new_thread"
No dependencies set.
The note is not visible to the blocked user.
全流程邮件通知:任何对反馈的变动都要通知提交人,模板重做
背景
用户要求:「只要是对这个反馈进行变动的,别人回复他、编辑他,或者处理他、改变他的状态,都需要通知到这个人。」
现状摸底(已核实代码,不是猜)
new.php:45filter_var校验;:128表单required;threads.author_email NOT NULLthread.php:132、admin.php:172调fb_notify_reply()admin.php:115调fb_notify_closed()status分支只 UPDATE 数据库,不发信admin.php:128-140admin.php:100(approve)、:123(hide)admin.php:177cron.php扫notify_log.ok=0最多重试 5 次cron.php:83-104fb_smtp_send,256 行)lib/mailer.php所以真正的缺口是
fb_notify_html(),是 div 堆砌,粗陋;关单是另一个模板,两套风格不统一notify_log只有reply_id,无法区分「因为什么发的信」需求
1. 覆盖全部变动事件
admin.phpreplyadmin.phpstatusadmin.phpapproveadmin.phphideadmin.phpcloseadmin.phpdelete状态变更的文案要按状态区分(用户原话):
⇒ 实现上建议:状态表里给每个状态配一句「给用户看的话」,不要写死在代码里。
2. 统一邮件模板(要漂亮)
现在
fb_notify_html()和fb_notify_closed_html()是两套土法 div。重做成一套统一的 HTML 邮件模板,要求:
#0057B8,现有图标在assets/)3. 通知可靠性
notify_log,并记录事件类型(需要给表加列,注意老库迁移)cron.php重试(最多 5 次)4. 管理员自己也收一封?
用户原话是「如果有人给我提一个反馈,就要给我发一封邮件」。
⇒ 新反馈提交时,给管理员发一封通知(现在是完全没有的)。
管理员收件地址在后台设置页可配。
验收标准
为什么单独建单
邮件通知与软件/模块归属是两件互不依赖的事:#1 改数据结构与前后台界面,#2 改 mailer 与通知触发点;#2 可以独立验收(触发六个事件看邮件),不依赖 #1 完成。
补充(2026-11-01 用户确认三条)
1. 删除反馈必须发信
原需求里「删除」这条保留,且文案要明确告知:「你的反馈已被删除」。
不要吞掉不发,用户有权知道。
2. 不做合并限流 —— 每次变动发一封
用户明确:「短时间之内多次修改的可能性不是特别大。只要状态发生变化、有修改,这一次就发一封信就行。」
⇒ 撤回原需求里的「同一事件不重复轰炸 / 考虑合并或限流」那条。
不做时间窗合并,一次变动 = 一封信。实现简单,也符合预期。
3. 管理员通知邮箱放后台设置页
用户明确:「管理员通知邮箱放在用户的,也就是管理后台的配置就可以了。」
⇒ 放进现有后台「站点设置」页,走 settings 表。
🔴 实现时必须同步改四处,否则填了不生效(这是本项目已知的坑):
lib/util.php的fb_setting_keys()白名单fb_admin_save_settings()保存逻辑admin.php设置页表单字段config.example.php)注意本项目设置体系是
fb_cfg()=config.php+settings表叠加,且留空提交走fb_unset_setting()删除行回落出厂值 —— 空字符串会覆盖成空,不能直接写空。文案要求汇总(状态变更)
状态表现有四项(
config.example.php:63-68):open待处理 /doing处理中 /resolved已解决 /closed已关闭。用户口头说的是「不予考虑 / 正在处理 / 已上架」,与现有四项不完全对应。
实现时建议:在状态配置里给每个状态配一句「给用户看的话」,
后台可改,不要写死在代码里。若现有四项不够用,允许后台增删状态。
实现进度汇总(补记)
前几轮改代码时未按「没工单不许动代码」执行,此处补录已完成部分与验证证据。
已完成
55d2dfa9b822d27a578faFB_ASSET_V常量1c2e8d5b835afc1434a6dc19e475step与min冲突f1a81cbe408dc7本单(#1)覆盖的部分
software/categories表 +threads.software_id/category_id)th_move)?sw=进入对应软件software.color+ 覆写--brand三变量config.example.php移除 categories/statuses,改由数据库管理本单(#2)覆盖的部分
fb_setting_keys()白名单补 15 个smtp.*/notify.*键(原先完全没有,所以就算有表单也存不进去)
验证证据
PHP 8.5 全入口弃用日志 0 条。
线上状态
已部署到
https://feedlite.yangyq.net/,41 文件 md5 全一致,资源版本 v13,
/data//config.php均 403。遗留
(重置脚本
/tmp/reset-feedlite-for-reinstall.sh,已交给用户)未单独建表 —— 若确实需要三级,需另行确认
补充需求:站点设置太长,邮件设置拆成独立标签页
用户原话:
现状
「站点设置」这一个 tab 里塞了:站点信息、页脚、邮件通知、附件存储、审核、
存储体检。邮件那一段有 10 多个字段加测试按钮,占了大半屏,往下翻很累。
要做
验收
用户质疑:是不是你把我的 SMTP 配置重置了?
结论:没有重置数据库,但我有一个 bug 把它清空了。
证据:库没被重置
installed_atoss.bucketsystemuploadstaticoss.endpointoss-cn-qingdao-internal.aliyuncs.comoss.instance_roleSystemUploadStaticOSSRoleoss.prefixfeedlitesite_name老杨个人开源项目反馈系…admin.usernamelaoyangadmin.password_hash如果重置过,这些全都会消失(会是 config.php 的出厂默认)。所以数据层完好。
真因:两个 tab 共用同一个保存处理
admin.php:231只有一个act === 'settings'分支,而两个表单都提交act=settings:admin.php:888的「保存设置」按钮)admin.php:985的<input type="hidden" name="act" value="settings">)这就是我上一轮做「邮件拆成独立 tab」时埋的坑。我在提交说明里还写:
"完全不变"恰恰是 bug:那段处理代码会无条件把表单里的 smtp 字段写进数据库。
你在站点设置页保存任何其他设置(比如附件那几项)时,该页表单里没有 smtp 字段,
$post('smtp.host', '')就取到空串,于是fb_set_setting('smtp.host', '')把已有配置覆盖成空。smtp.pass之所以还留着 18 字节,是因为代码对它单独处理了「留空=不修改」:所以现状是
pass有值、其余全空 —— 这个组合本身就是 bug 的指纹。属于哪一类错误
典型的「部分表单提交导致未提交字段被清空」。
正确做法只有一条:保存前先判断该表单是否真的提交了这个字段。
修法两种,本次采用第 2 种 + 第 1 种兜底:
tab分流)$post的"键是否存在"判断,不存在就跳过,不写成空顺带发现的同类问题
notify.enabled/notify.on_every_reply/notify.admin_new_thread是 checkbox。站点设置页里也没有它们,所以:
所以
notify.enabled现在是 0,很可能也是被这样冲掉的。另一件事:
notify.admin_new_thread是假的这个设置项:
lib/util.php:414)admin.php:1070)grep -rn "admin_new_thread"只命中这三处,没有任何地方在"有新反馈"时发信。用户说的「我提交了一个反馈…它怎么不给我发邮件呢」正是这个 —— 功能压根没写,
不是配置问题。属于 #2 范围内的功能缺失。
用户的其他诉求(同属 #2)
fb_notify_html()和fb_notify_closed_html()两套风格不统一,都是 div 堆砌点一下生效;只有「不予考虑」弹出说明框(会随邮件发出)