Some checks failed
CI / Lint + Build (push) Has been cancelled
审计修复: - CSP: unsafe-inline移除, nonce替代; unsafe-eval保留供Vditor使用 - HSTS: 始终启用(不再依赖release模式) - Controller Exp: common.GetGinExp包装, 不再直接读context - UID解析: common.ParseUIDParam统一, follow/admin controller改用 重构: - router/api.go(198行)拆为7个域文件: auth/settings/posts/comments/reactions/social/studio - 管理后台站点设置: 单页拆为4个子页(brand/security/registration/content)+子菜单 - 前台用户设置页: 1201行拆为6个独立模板+6个独立JS文件 新增: - DB健康检测中间件(middleware/db_health.go): 5s ping+降级页面 - 时区配置: config.yaml server.timezone→time.Local初始化 - .gitea/workflows/ci.yml: strict模式CI流水线
91 lines
4.2 KiB
JavaScript
91 lines
4.2 KiB
JavaScript
(function(){'use strict';
|
|
<script nonce="{{.CSPNonce}}">
|
|
(function () {
|
|
'use strict';
|
|
|
|
var toastEl = document.getElementById('settingsToast');
|
|
var toastTimer = null;
|
|
|
|
function showSettingsToast(msg, isError) {
|
|
if (!toastEl) return;
|
|
clearTimeout(toastTimer);
|
|
toastEl.textContent = msg;
|
|
toastEl.className = 'settings-toast' + (isError ? ' error' : '');
|
|
void toastEl.offsetWidth;
|
|
toastEl.classList.add('show');
|
|
toastTimer = setTimeout(function () {
|
|
toastEl.classList.remove('show');
|
|
}, 5000);
|
|
}
|
|
// ===== 通知偏好 Tab =====
|
|
(function () {
|
|
var bodyEl = document.getElementById('notifyPrefsBody');
|
|
if (!bodyEl) return;
|
|
|
|
function loadPrefs() {
|
|
fetch('/api/settings/notify-prefs')
|
|
.then(function (r) { return r.json(); })
|
|
.then(function (d) {
|
|
if (!d.success || !d.data) {
|
|
bodyEl.innerHTML = '<div class="energy-log-empty">加载失败</div>';
|
|
return;
|
|
}
|
|
var prefs = d.data;
|
|
var items = [
|
|
{ key: 'comment', label: '评论通知', desc: '有人评论我的文章时通知我' },
|
|
{ key: 'comment_reply', label: '回复通知', desc: '有人回复我的评论时通知我' },
|
|
{ key: 'like_aggregated', label: '点赞通知', desc: '每日汇总的点赞通知' },
|
|
{ key: 'follow', label: '关注通知', desc: '有人关注我时通知我' }
|
|
];
|
|
var html = '';
|
|
items.forEach(function (item) {
|
|
var checked = prefs[item.key] ? 'checked' : '';
|
|
html += '<div class="notify-pref-row">'
|
|
+ '<div class="notify-pref-info">'
|
|
+ '<span class="notify-pref-label">' + item.label + '</span>'
|
|
+ '<span class="notify-pref-desc">' + item.desc + '</span>'
|
|
+ '</div>'
|
|
+ '<label class="notify-pref-toggle">'
|
|
+ '<input type="checkbox" class="notify-pref-cb" data-key="' + item.key + '" ' + checked + '>'
|
|
+ '<span class="notify-pref-slider"></span>'
|
|
+ '</label>'
|
|
+ '</div>';
|
|
});
|
|
bodyEl.innerHTML = html;
|
|
|
|
// 绑定切换事件
|
|
bodyEl.querySelectorAll('.notify-pref-cb').forEach(function (cb) {
|
|
cb.addEventListener('change', function () {
|
|
var key = cb.getAttribute('data-key');
|
|
var enabled = cb.checked;
|
|
var xhr = new XMLHttpRequest();
|
|
xhr.open('PUT', '/api/settings/notify-prefs', true);
|
|
xhr.setRequestHeader('Content-Type', 'application/json');
|
|
xhr.onreadystatechange = function () {
|
|
if (xhr.readyState !== 4) return;
|
|
try {
|
|
var r = JSON.parse(xhr.responseText);
|
|
if (r.success) {
|
|
showSettingsToast('通知偏好已更新');
|
|
} else {
|
|
showSettingsToast(r.message || '更新失败', true);
|
|
cb.checked = !enabled;
|
|
}
|
|
} catch (e) {
|
|
showSettingsToast('更新失败', true);
|
|
cb.checked = !enabled;
|
|
}
|
|
};
|
|
xhr.send(JSON.stringify({ key: key, enabled: enabled }));
|
|
});
|
|
});
|
|
})
|
|
.catch(function () {
|
|
bodyEl.innerHTML = '<div class="energy-log-empty">加载失败</div>';
|
|
});
|
|
}
|
|
|
|
loadPrefs();
|
|
})();
|
|
})();
|