多软件区分:邮件按软件换色+图标+软件名;补提交回执邮件
用户要求:多软件并存时,用「颜色 + 图标 + 名字」三重区分,
邮件也要跟着所属软件变,一眼能看出是哪款软件的来信。
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:
@@ -772,12 +772,42 @@
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------- 图标快选(后台软件编辑) ---------- */
|
||||
function bindIconPicker() {
|
||||
var boxes = document.querySelectorAll('.icon-presets');
|
||||
for (var i = 0; i < boxes.length; i++) {
|
||||
(function (box) {
|
||||
// 图标输入框是「图标快选」的前一个兄弟里的 input[name=icon]
|
||||
var field = box.parentNode;
|
||||
var input = field ? field.querySelector('input[name=icon]') : null;
|
||||
if (!input) { return; }
|
||||
var btns = box.querySelectorAll('.icon-preset');
|
||||
|
||||
function syncOn(v) {
|
||||
for (var k = 0; k < btns.length; k++) {
|
||||
var same = (btns[k].getAttribute('data-icon') || '') === v;
|
||||
if (same) { btns[k].classList.add('on'); } else { btns[k].classList.remove('on'); }
|
||||
}
|
||||
}
|
||||
for (var j = 0; j < btns.length; j++) {
|
||||
btns[j].addEventListener('click', function () {
|
||||
input.value = this.getAttribute('data-icon') || '';
|
||||
syncOn(input.value);
|
||||
});
|
||||
}
|
||||
input.addEventListener('input', function () { syncOn(this.value); });
|
||||
syncOn(input.value);
|
||||
})(boxes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------- 邮件测试发送(后台设置页) ---------- */
|
||||
function bindMailTest() {
|
||||
var btn = document.getElementById('mailTestBtn');
|
||||
if (!btn) { return; }
|
||||
var out = document.getElementById('mailTestOut');
|
||||
var to = document.getElementById('mailTestTo');
|
||||
var swSel = document.getElementById('mailTestSw');
|
||||
btn.addEventListener('click', function () {
|
||||
var addr = to ? (to.value || '').trim() : '';
|
||||
if (!addr) {
|
||||
@@ -793,6 +823,7 @@
|
||||
fd.append('csrf', btn.getAttribute('data-csrf') || '');
|
||||
fd.append('act', 'mail_test');
|
||||
fd.append('to', addr);
|
||||
if (swSel && swSel.value) { fd.append('sw', swSel.value); }
|
||||
|
||||
fetch('admin.php', { method: 'POST', body: fd, credentials: 'same-origin' })
|
||||
.then(function (r) { return r.text(); })
|
||||
@@ -821,6 +852,7 @@
|
||||
bindAdminToggle();
|
||||
bindWontfixPanel();
|
||||
bindColorPicker();
|
||||
bindIconPicker();
|
||||
bindMailTest();
|
||||
bindInlineValidate(); // ★ 必须在 bindNoDoubleSubmit 之前
|
||||
bindNoDoubleSubmit();
|
||||
|
||||
Reference in New Issue
Block a user