Local WP has empty permalink_structure so /wp-json/* 404s on Apache. modal-auth fell back to /wp-json/aksrt/v1; prefer aksrtData.restUrl (index.php?rest_route=/aksrt/v1) and join paths correctly.
179 lines
6.3 KiB
JavaScript
179 lines
6.3 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) {
|
|
showToast(result.message || '举报已提交');
|
|
} else {
|
|
showToast(result.message || '提交失败', 'error');
|
|
}
|
|
})
|
|
.catch(function () {
|
|
submitBtn.disabled = false;
|
|
submitBtn.textContent = '提交举报';
|
|
showToast('网络错误,请重试', 'error');
|
|
});
|
|
};
|
|
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 showToast(msg, type) {
|
|
var toast = document.createElement('div');
|
|
toast.textContent = msg;
|
|
toast.style.cssText = 'position:fixed;top:20px;left:50%;transform:translateX(-50%);padding:12px 24px;border-radius:6px;color:#fff;font-size:14px;z-index:10000;transition:opacity 0.3s;';
|
|
toast.style.background = type === 'error' ? '#e74c3c' : '#27ae60';
|
|
document.body.appendChild(toast);
|
|
setTimeout(function () {
|
|
toast.style.opacity = '0';
|
|
setTimeout(function () { toast.remove(); }, 300);
|
|
}, 3000);
|
|
}
|
|
|
|
function initReportButtons() {
|
|
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
|
|
}
|
|
});
|
|
}
|
|
|
|
// Auto-init on DOMContentLoaded
|
|
if (document.readyState === 'loading') {
|
|
document.addEventListener('DOMContentLoaded', initReportButtons);
|
|
} else {
|
|
initReportButtons();
|
|
}
|
|
})();
|