- rehydrate.js 新增 boot()/aksrt:ready 事件,支持 boot 后晚注册立即以 init 触发 - aksrt-runtime.js 初始加载改走 AksrtFrontend.boot,tooltip/倒计时注册为组件 - 约 30 个前端脚本(首页、评论、支付、路由、页面叶子、widgets) 从直接 DOMContentLoaded 迁移为 AksrtFrontend.register,并加幂等标记 - section-navs 依赖改为 aksrt-runtime,保证注册时序 - 清理死代码:删除孤儿 loader.js/main.js 及 runtime/page-navs 遗留副本 - loader.js 移除已迁移模块的 tbquire 路径映射,main.js 相应瘦身 - build-public-assets.mjs 增加 runtime/main.min.js 自动压缩步骤 - 新增 4 个契约测试(homepage-dom/rehydrate-runtime/global-dom-init/ public-bundle-parity),3 个既有 harness 适配注册表初始化方式
166 lines
5.8 KiB
JavaScript
166 lines
5.8 KiB
JavaScript
/**
|
|
* AKSRT Report — 前台举报提交
|
|
*
|
|
* 监听 [data-aksrt-report] 按钮点击,弹出举报表单并提交。
|
|
*
|
|
* @package AKSRT
|
|
*/
|
|
|
|
(function () {
|
|
'use strict';
|
|
|
|
var API_ROOT = (function () {
|
|
var d = window.aksrtData || {};
|
|
var raw = d.apiUrl || d.restUrl || d.rest_url || '/index.php?rest_route=/aksrt/v1';
|
|
return String(raw).replace(/\/$/, '');
|
|
})();
|
|
var NONCE = (window.aksrtData && window.aksrtData.restNonce) || '';
|
|
|
|
function getReportCategories() {
|
|
// Default categories; can be overridden by server-rendered config
|
|
if (window.aksrtReportCategories && Array.isArray(window.aksrtReportCategories)) {
|
|
return window.aksrtReportCategories;
|
|
}
|
|
return [
|
|
{ value: 'spam', label: '垃圾信息' },
|
|
{ value: 'abuse', label: '人身攻击' },
|
|
{ value: 'copyright', label: '版权投诉' },
|
|
{ value: 'other', label: '其他' },
|
|
];
|
|
}
|
|
|
|
function createReportModal(data) {
|
|
// Remove existing modal if any
|
|
var existing = document.getElementById('aksrt-report-modal');
|
|
if (existing) existing.remove();
|
|
|
|
var categories = getReportCategories();
|
|
|
|
var overlay = document.createElement('div');
|
|
overlay.id = 'aksrt-report-modal';
|
|
overlay.style.cssText = 'position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.5);z-index:9999;display:flex;align-items:center;justify-content:center;';
|
|
|
|
var modal = document.createElement('div');
|
|
modal.style.cssText = 'background:#fff;border-radius:8px;padding:24px;max-width:420px;width:90%;box-shadow:0 4px 20px rgba(0,0,0,0.15);';
|
|
|
|
var title = document.createElement('h3');
|
|
title.textContent = '提交举报';
|
|
title.style.cssText = 'margin:0 0 16px;font-size:16px;font-weight:600;';
|
|
modal.appendChild(title);
|
|
|
|
// Category select
|
|
var catLabel = document.createElement('label');
|
|
catLabel.textContent = '举报分类';
|
|
catLabel.style.cssText = 'display:block;margin-bottom:4px;font-size:13px;color:#555;';
|
|
modal.appendChild(catLabel);
|
|
|
|
var catSelect = document.createElement('select');
|
|
catSelect.style.cssText = 'width:100%;padding:8px;border:1px solid #ddd;border-radius:4px;margin-bottom:12px;';
|
|
categories.forEach(function (cat) {
|
|
var opt = document.createElement('option');
|
|
opt.value = cat.value;
|
|
opt.textContent = cat.label;
|
|
catSelect.appendChild(opt);
|
|
});
|
|
modal.appendChild(catSelect);
|
|
|
|
// Reason textarea
|
|
var reasonLabel = document.createElement('label');
|
|
reasonLabel.textContent = '举报原因';
|
|
reasonLabel.style.cssText = 'display:block;margin-bottom:4px;font-size:13px;color:#555;';
|
|
modal.appendChild(reasonLabel);
|
|
|
|
var reasonInput = document.createElement('textarea');
|
|
reasonInput.placeholder = '请详细描述举报原因…';
|
|
reasonInput.style.cssText = 'width:100%;height:80px;padding:8px;border:1px solid #ddd;border-radius:4px;resize:vertical;margin-bottom:16px;box-sizing:border-box;';
|
|
modal.appendChild(reasonInput);
|
|
|
|
// Buttons
|
|
var btnRow = document.createElement('div');
|
|
btnRow.style.cssText = 'display:flex;gap:8px;justify-content:flex-end;';
|
|
|
|
var cancelBtn = document.createElement('button');
|
|
cancelBtn.type = 'button';
|
|
cancelBtn.textContent = '取消';
|
|
cancelBtn.style.cssText = 'padding:8px 16px;border:1px solid #ddd;border-radius:4px;background:#fff;cursor:pointer;';
|
|
cancelBtn.onclick = function () { overlay.remove(); };
|
|
btnRow.appendChild(cancelBtn);
|
|
|
|
var submitBtn = document.createElement('button');
|
|
submitBtn.type = 'button';
|
|
submitBtn.textContent = '提交举报';
|
|
submitBtn.style.cssText = 'padding:8px 16px;border:none;border-radius:4px;background:#e74c3c;color:#fff;cursor:pointer;';
|
|
submitBtn.onclick = function () {
|
|
var reason = reasonInput.value.trim();
|
|
if (!reason) {
|
|
reasonInput.style.borderColor = '#e74c3c';
|
|
reasonInput.focus();
|
|
return;
|
|
}
|
|
submitBtn.disabled = true;
|
|
submitBtn.textContent = '提交中…';
|
|
|
|
fetch(API_ROOT + '/report/submit', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'X-WP-Nonce': NONCE,
|
|
},
|
|
body: JSON.stringify({
|
|
target_type: data.target_type,
|
|
target_id: data.target_id,
|
|
category: catSelect.value,
|
|
reason: reason,
|
|
}),
|
|
})
|
|
.then(function (res) { return res.json(); })
|
|
.then(function (result) {
|
|
overlay.remove();
|
|
if (result.success) {
|
|
notyf(result.message || '举报已提交');
|
|
} else {
|
|
notyf(result.message || '提交失败', 'danger');
|
|
}
|
|
})
|
|
.catch(function () {
|
|
submitBtn.disabled = false;
|
|
submitBtn.textContent = '提交举报';
|
|
notyf('网络错误,请重试', 'danger');
|
|
});
|
|
};
|
|
btnRow.appendChild(submitBtn);
|
|
modal.appendChild(btnRow);
|
|
|
|
overlay.appendChild(modal);
|
|
overlay.addEventListener('click', function (e) {
|
|
if (e.target === overlay) overlay.remove();
|
|
});
|
|
|
|
document.body.appendChild(overlay);
|
|
reasonInput.focus();
|
|
}
|
|
|
|
function initReportButtons() {
|
|
if (document.documentElement.dataset.aksrtReportInitialized === '1') return;
|
|
document.documentElement.dataset.aksrtReportInitialized = '1';
|
|
document.addEventListener('click', function (e) {
|
|
var btn = e.target.closest('[data-aksrt-report]');
|
|
if (!btn) return;
|
|
e.preventDefault();
|
|
|
|
try {
|
|
var data = JSON.parse(btn.getAttribute('data-aksrt-report'));
|
|
if (data && data.target_type && data.target_id) {
|
|
createReportModal(data);
|
|
}
|
|
} catch {
|
|
// invalid data attribute
|
|
}
|
|
});
|
|
}
|
|
|
|
if (window.AksrtFrontend && typeof window.AksrtFrontend.register === 'function') {
|
|
window.AksrtFrontend.register('aksrt-report', initReportButtons);
|
|
}
|
|
})();
|