/** * AKSRT User Ban — 前台“禁封/解封用户”弹窗 * * 1:1 复刻参考主题 Zibll 前台禁封能力: * - zib_get_edit_user_ban_link → [data-aksrt-ban] 委托入口(三点菜单内) * - zib_get_set_user_ban_modal → REST /user-ban/modal 拉取弹窗内容 * - zib_ajax_set_user_ban → REST /user-ban/set 提交 * * 弹窗经 AksrtModalRuntime.openRemote 打开(与参考主题 refresh_modal 每次刷新 * 同语义):桌面 600px 宽(参考主题未传 data-class → Bootstrap .modal-dialog * 默认宽 600px)/ min-height 360px(data-height=360 → .modal-content 初始高度), * 移动端底部抽屉(mobileBottom)。提交成功语义与参考主题 zib_ajax_set_user_ban * 返回值一致:禁封 → reload:true(整页刷新),解封 → hide_modal:true(仅关闭弹窗)。 * * @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) || ''; var MODAL_HEIGHT = 360; function openBanModal(userId) { if (!window.AksrtModalRuntime || typeof window.AksrtModalRuntime.openRemote !== 'function') { notyf('禁封组件加载失败,请刷新页面后重试', 'danger'); return; } window.AksrtModalRuntime.openRemote({ url: API_ROOT + '/user-ban/modal', method: 'GET', query: { user_id: userId }, cache: false, height: MODAL_HEIGHT, mobileBottom: true, kind: 'user-ban', className: 'aksrt-user-ban-modal', onContent: function (html, session) { if (session && session.shell) bindBanModal(session.shell); }, }); } function collectPayload(shell, userId, unban) { var payload = { user_id: userId, ban: unban ? 0 : 1 }; if (unban) { var descInput = shell.querySelector('[data-aksrt-ban-form] [name="desc"]'); payload.desc = (descInput && descInput.value || '').trim(); return payload; } var form = shell.querySelector('[data-aksrt-ban-form]'); if (!form) return payload; var banInput = form.querySelector('input[name="ban"]:checked'); payload.ban = banInput ? parseInt(banInput.value, 10) : 1; var timeInput = form.querySelector('input[name="time_day"]:checked'); payload.time_day = timeInput ? parseInt(timeInput.value, 10) : 7; var reasonInput = form.querySelector('input[name="reason"]:checked'); payload.reason = reasonInput ? reasonInput.value : ''; var otherInput = form.querySelector('[name="reason_other"]'); payload.reason_other = (otherInput && otherInput.value || '').trim(); var desc = form.querySelector('[name="desc"]'); payload.desc = (desc && desc.value || '').trim(); payload.delete_content = !!(form.querySelector('[name="delete_content"]') || {}).checked; payload.no_appeal = !!(form.querySelector('[name="no_appeal"]') || {}).checked; var noAppealDesc = form.querySelector('[name="no_appeal_desc"]'); payload.no_appeal_desc = (noAppealDesc && noAppealDesc.value || '').trim(); return payload; } function submitBan(shell, userId, unban) { var payload = collectPayload(shell, userId, unban); if (!unban) { var reason = payload.reason === 'other' || !payload.reason ? payload.reason_other : payload.reason; if (!reason) { notyf('请选择或输入禁封原因', 'danger'); return; } if (payload.no_appeal && !payload.no_appeal_desc) { notyf('请输入禁止用户申诉的说明或原因', 'danger'); return; } } var submitBtn = shell.querySelector(unban ? '[data-aksrt-unban-submit]' : '[data-aksrt-ban-submit]'); if (submitBtn) submitBtn.disabled = true; notyf(unban ? '正在解封…' : '正在提交禁封…', 'load', 3000, 'aksrt-ban-submit'); window .fetch(API_ROOT + '/user-ban/set', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-WP-Nonce': NONCE }, body: JSON.stringify(payload), }) .then(function (res) { return res.json(); }) .then(function (result) { if (result && result.success) { notyf(result.message || '操作成功', 'success'); // 参考主题 zib_ajax_set_user_ban 返回值语义: // 禁封 → reload:true(整页刷新,入口按钮状态随页面重渲染); // 解封 → hide_modal:true(仅关闭弹窗)。 if (window.AksrtModalRuntime && typeof window.AksrtModalRuntime.close === 'function') { window.AksrtModalRuntime.close('submit'); } if (!unban) window.location.reload(); } else { if (submitBtn) submitBtn.disabled = false; notyf((result && result.message) || '操作失败', 'danger'); } }) .catch(function () { if (submitBtn) submitBtn.disabled = false; notyf('网络错误,请重试', 'danger'); }) .then(function () { var toast = document.getElementById('aksrt-ban-submit'); if (toast) toast.remove(); }); } function bindAutoHeight(textarea) { // 1:1 复刻参考主题 textarea[autoHeight] 行为(input/focus 触发): // 高度 = scrollHeight + 上下边框;超过 maxHeight 属性则锁定 maxHeight 并 // 打开自身滚动条(参考主题 main.js autoHeight 同语义)。 if (!textarea || textarea.dataset.aksrtAutoHeight === '1') return; textarea.dataset.aksrtAutoHeight = '1'; var grow = function () { var style = getComputedStyle(textarea); var border = (parseInt(style.getPropertyValue('border-top-width'), 10) || 0) + (parseInt(style.getPropertyValue('border-bottom-width'), 10) || 0); var max = parseInt(textarea.getAttribute('maxHeight'), 10) || 0; textarea.style.height = 'auto'; if (max > textarea.scrollHeight) { textarea.style.height = textarea.scrollHeight + border + 'px'; textarea.style.overflow = 'hidden'; } else { textarea.style.height = max + 'px'; textarea.style.overflow = 'auto'; } }; textarea.addEventListener('input', grow); textarea.addEventListener('focus', grow); if (textarea.offsetHeight > 0) grow(); } function syncBanForm(shell) { var form = shell.querySelector('[data-aksrt-ban-form]'); if (!form || form.getAttribute('data-aksrt-ban-mode') !== 'ban') return; var banInput = form.querySelector('input[name="ban"]:checked'); var ban = banInput ? banInput.value : '1'; Array.prototype.forEach.call(form.querySelectorAll('[data-aksrt-ban-desc]'), function (el) { el.style.display = el.getAttribute('data-aksrt-ban-desc') === ban ? '' : 'none'; }); var reasonInput = form.querySelector('input[name="reason"]:checked'); var otherBox = form.querySelector('[data-aksrt-ban-reason-other]'); if (otherBox) otherBox.style.display = reasonInput && reasonInput.value === 'other' ? '' : 'none'; var noAppealBox = form.querySelector('[data-aksrt-ban-noappeal-desc]'); var noAppealInput = form.querySelector('[name="no_appeal"]'); if (noAppealBox) noAppealBox.style.display = noAppealInput && noAppealInput.checked ? '' : 'none'; } function bindBanModal(shell) { Array.prototype.forEach.call(shell.querySelectorAll('textarea.form-control'), bindAutoHeight); syncBanForm(shell); } /** * 收起封面三点菜单面板(参考主题 author_header_drop_lists 菜单项点击后 * 不自动收起,需手动关闭;评论区与文章作者下拉由各自脚本点击项后自动收起)。 */ function closeCoverMenu(trigger) { var menu = trigger && trigger.closest ? trigger.closest('[data-aksrt-menu]') : null; if (!menu) return; var panel = menu.querySelector('.aksrt-cover-menu__panel'); if (panel) panel.hidden = true; var menuTrigger = menu.querySelector('.aksrt-cover-menu__trigger'); if (menuTrigger) menuTrigger.setAttribute('aria-expanded', 'false'); } function initBanBindings() { if (document.documentElement.dataset.aksrtBanInitialized === '1') return; document.documentElement.dataset.aksrtBanInitialized = '1'; document.addEventListener('click', function (event) { if (!event.target || !event.target.closest) return; // 禁封 / 解封入口(封面菜单按钮 / 评论区菜单项 / 文章作者菜单项)。 var banBtn = event.target.closest('[data-aksrt-ban]'); if (banBtn) { event.preventDefault(); var userId = parseInt(banBtn.getAttribute('data-aksrt-ban'), 10); if (userId > 0) { closeCoverMenu(banBtn); openBanModal(userId); } return; } // 弹窗内交互(事件委托到 document,弹窗壳由 runtime portal 到 body)。 var active = window.AksrtModalRuntime && window.AksrtModalRuntime.getActive ? window.AksrtModalRuntime.getActive() : null; if (!active || !active.contains(event.target)) return; var shell = active; var form = shell.querySelector('[data-aksrt-ban-form]'); var modalUser = form ? parseInt(form.getAttribute('data-aksrt-ban-user'), 10) : 0; var submitBtn = event.target.closest('[data-aksrt-ban-submit]'); if (submitBtn) { event.preventDefault(); submitBtn.disabled = true; submitBan(shell, modalUser, false); return; } var unbanBtn = event.target.closest('[data-aksrt-unban-submit]'); if (unbanBtn) { event.preventDefault(); unbanBtn.disabled = true; submitBan(shell, modalUser, true); return; } }); document.addEventListener('change', function (event) { var active = window.AksrtModalRuntime && window.AksrtModalRuntime.getActive ? window.AksrtModalRuntime.getActive() : null; if (!active || !event.target || !active.contains(event.target)) return; syncBanForm(active); }); // 弹窗内容注入后由 onContent 绑定;bs.modal 展示契约下对 user-ban 弹窗做同步。 jQuery(document).on('loaded.bs.modal show.bs.modal', function (event) { var shell = event.target && event.target.classList && event.target.classList.contains('aksrt-user-ban-modal') ? event.target : null; if (shell) syncBanForm(shell); }); } jQuery(document) .off('auto_fun.aksrt-ban') .on('auto_fun.aksrt-ban', initBanBindings); })();