多软件区分:邮件按软件换色+图标+软件名;补提交回执邮件

用户要求:多软件并存时,用「颜色 + 图标 + 名字」三重区分,
邮件也要跟着所属软件变,一眼能看出是哪款软件的来信。

1. software 表加 icon / download_url 字段(幂等迁移)
   - icon 存单个字符(emoji / 汉字 / 字母),不存图片路径:
     前端与邮件用同一个字符渲染,天然一致,不用再管一套上传与权限
   - 没配 icon 时取名首字兜底,任何地方都不出现空图标
   - 后台软件编辑加图标快选(12 个常用 emoji)

2. 邮件配色改为跟随软件(fb_mail_brand 取 fb_software_colors)
   - 头部色条、按钮、引用块色条、徽标全部跟着软件走
   - 邮件头部改为「图标色块 + 软件名」,下面再小字标站点名
   - 主题行统一加【软件名】前缀,不点开就能分辨

3. 新增 receipt 事件:提交后立即给提问人发「已收到、待审核、请耐心等待」
   - 独立开关 notify.receipt_enabled(与「回复通知」是两件事)
   - 新增 7 处调用前的静默 return 也一并写日志

4. reply 邮件补上下文:原提问摘要 + 本次回复,像博客评论通知
5. status=resolved 文案改为「已完成并上线」,配了下载地址时给下载按钮

验证:多软件配色/图标/前缀全部通过(含反向验证),XSS 转义通过,
空图标兜底通过;页面顶栏、页头、选择器图标渲染正确。
This commit is contained in:
2026-11-03 08:00:50 +08:00
parent e43f2ce67a
commit 738c6c09ff
12 changed files with 451 additions and 52 deletions
+12 -1
View File
@@ -119,6 +119,13 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$swRow = fb_software((int)$swId);
if ($swRow) { $swName = (string)$swRow['name']; }
}
/* ① 先给提交人发「已收到」回执 —— 让他知道东西送达了、正在等审核。
* 这一步是用户最在意的:提交完页面跳走了,没有回执就等于石沉大海。
* 放在管理员通知之前,是因为回执对人的价值更高,且失败互不影响。 */
fb_notify_event($pdo, 'receipt', $newThread, ['software_name' => $swName]);
/* ② 再通知管理员「有新反馈」 */
fb_notify_event($pdo, 'new', $newThread, ['software_name' => $swName]);
}
} catch (Throwable $e) {
@@ -137,6 +144,10 @@ fb_layout_head('我要反馈', ['robots' => 'noindex,follow', 'software' => $sw]
<section class="narrow">
<h1>我要反馈</h1>
<?php if ($sw): ?>
<div class="sw-context"><?php echo fb_software_badge($sw, 'md'); ?>
<span class="muted small">你正在为这个软件提交反馈</span></div>
<?php endif; ?>
<p class="muted">请描述你遇到的问题或想要的功能。提交后会先进入审核,确认为有效问题后才会公开显示;<b>若经确认不是应用的问题,我们会把结论与说明通过邮件发送给你</b>(请填写常用邮箱)。</p>
<?php fb_flash_box($err, 'error'); ?>
@@ -155,7 +166,7 @@ fb_layout_head('我要反馈', ['robots' => 'noindex,follow', 'software' => $sw]
<div class="chips">
<?php foreach ($swList as $one): ?>
<a class="chip <?php echo ((int)$one['id'] === $swId) ? 'on' : ''; ?>"
href="new.php?sw=<?php echo e(urlencode((string)$one['slug'])); ?>"><?php echo e((string)$one['name']); ?></a>
href="new.php?sw=<?php echo e(urlencode((string)$one['slug'])); ?>"><?php echo fb_software_badge($one, 'sm'); ?></a>
<?php endforeach; ?>
</div>
</div>