(function (root, factory) { if (typeof module === 'object' && module.exports) { module.exports = factory(root); return; } root.JoinReviewPages = factory(root); if (root.document) { root.document.addEventListener('DOMContentLoaded', function () { root.JoinReviewPages.initJoinReviewPage(); }); } })(typeof globalThis !== 'undefined' ? globalThis : window, function (root) { 'use strict'; function escapeHtml(value) { return String(value === undefined || value === null ? '' : value) .replace(/&/g, '&') .replace(//g, '>') .replace(/"/g, '"') .replace(/'/g, '''); } function normalizeId(value) { var text; if (typeof value === 'number' && !Number.isSafeInteger(value)) return ''; if (value === undefined || value === null) return ''; text = String(value).trim(); return /^[1-9][0-9]*$/.test(text) ? text : ''; } function optionalText(value) { if (value === undefined || value === null) return ''; return String(value).trim(); } function getCurrentGenealogyId(search) { var contextId; var params; if (search === undefined && root.ProfileUI && root.ProfileUI.getGenealogyId) { contextId = root.ProfileUI.getGenealogyId(); return normalizeId(contextId); } params = new URLSearchParams(String(search || '').replace(/^\?/, '')); return normalizeId(params.get('genealogyId')); } function buildJoinAuditBody(values) { var source = values || {}; var body = { status: String(source.status === undefined || source.status === null ? '' : source.status).trim() }; var auditRemark = optionalText(source.auditRemark); if (auditRemark) body.auditRemark = auditRemark; return body; } function validateJoinAuditBody(body) { if (!body || ['1', '2'].indexOf(body.status) < 0) return '审核状态无效'; if (String(body.auditRemark || '').length > 500) return '审核说明不能超过 500 个字符'; return ''; } function normalizePendingApply(item) { var source = item || {}; var applyId = normalizeId(source.applyId); var genealogyId = normalizeId(source.genealogyId); if (!applyId || !genealogyId || String(source.status) !== '0') return null; return { applyId: applyId, genealogyId: genealogyId, genealogyName: optionalText(source.genealogyName), applicantName: optionalText(source.applicantName) || optionalText(source.appUserNickName) || '未填写姓名', phone: optionalText(source.phone), relationDesc: optionalText(source.relationDesc), applyReason: optionalText(source.applyReason) }; } function normalizePendingApplies(data) { var items; if (!Array.isArray(data)) return []; items = data.map(normalizePendingApply); return items.some(function (item) { return !item; }) ? [] : items; } function renderPendingJoinApplies(data, canManage) { var items = normalizePendingApplies(data); if (!items.length) return ''; return items.map(function (item) { var details = [ item.phone ? '申请联系电话:' + item.phone : '', item.relationDesc ? '关系:' + item.relationDesc : '', item.applyReason ? '理由:' + item.applyReason : '' ].filter(Boolean).join(' · '); var actions = canManage ? '
' + '
' : ''; return '

' + escapeHtml(item.applicantName) + '申请加入' + escapeHtml(item.genealogyName || '当前家谱') + '

' + escapeHtml(details || '申请人未补充说明') + '

' + actions + '
'; }).join(''); } function shouldRedirectToLogin(api, error) { var status = error && (error.status || error.code); return !api || !api.getToken || !api.getToken() || Number(status) === 401; } function redirectToLogin(api) { if (api && api.clearToken) api.clearToken(); if (!root.location) return; if (typeof root.location.replace === 'function') root.location.replace('login.html'); else root.location.href = 'login.html'; } function getApiStateType(error) { return Number(error && (error.status || error.code)) === 403 ? 'forbidden' : 'error'; } function setStatus(message, type) { var element = root.document && root.document.querySelector('[data-join-review-status]'); if (!element) return; if (!message) { element.innerHTML = ''; return; } if (root.ProfileUI && root.ProfileUI.setApiState) { root.ProfileUI.setApiState(element, type || 'error', message); return; } element.textContent = message; } function setReviewFormStatus(message, type) { var element = root.document && root.document.querySelector('[data-join-review-form-status]'); if (!element) return; if (!message) { element.innerHTML = ''; return; } if (root.ProfileUI && root.ProfileUI.setApiState) { root.ProfileUI.setApiState(element, type || 'error', message); return; } element.textContent = message; } function setPendingListState(message, type) { var element = root.document && root.document.querySelector('[data-join-apply-list="pending"]'); if (!element) return; if (root.ProfileUI && root.ProfileUI.setApiState) { root.ProfileUI.setApiState(element, type || 'error', message); return; } element.textContent = message; } function setReviewFormEnabled(enabled) { var form = root.document && root.document.querySelector('[data-join-review-form]'); if (!form) return; Array.prototype.slice.call(form.querySelectorAll('textarea, button')).forEach(function (field) { field.disabled = !enabled; }); } function setReviewSubmitPending(pending) { var button = root.document && root.document.querySelector('[data-join-review-submit]'); if (!button) return; if (!button.dataset.defaultLabel) button.dataset.defaultLabel = button.textContent; button.textContent = pending ? '正在提交…' : button.dataset.defaultLabel; button.setAttribute('aria-busy', pending ? 'true' : 'false'); } function openReviewForm(applyId, status) { var form = root.document && root.document.querySelector('[data-join-review-form]'); var panel = root.document && root.document.querySelector('[data-join-review-editor]'); var title = root.document && root.document.querySelector('[data-join-review-form-title]'); var submit = root.document && root.document.querySelector('[data-join-review-submit]'); if (!form || !panel || !applyId || ['1', '2'].indexOf(status) < 0) return; form.reset(); form.querySelector('[name="applyId"]').value = applyId; form.querySelector('[name="status"]').value = status; if (title) title.textContent = status === '1' ? '通过加入申请' : '拒绝加入申请'; if (submit) submit.textContent = status === '1' ? '确认通过' : '确认拒绝'; setReviewFormStatus(''); panel.hidden = false; if (root.location && root.location.hash !== '#join-review-form') root.location.hash = 'join-review-form'; if (form.querySelector('[name="auditRemark"]') && form.querySelector('[name="auditRemark"]').focus) { form.querySelector('[name="auditRemark"]').focus(); } } function closeReviewForm() { var form = root.document && root.document.querySelector('[data-join-review-form]'); var panel = root.document && root.document.querySelector('[data-join-review-editor]'); if (form) form.reset(); if (panel) panel.hidden = true; setReviewFormStatus(''); } async function initJoinReviewPage() { var page = root.document && root.document.querySelector('[data-join-review-page]'); var list = root.document && root.document.querySelector('[data-join-apply-list="pending"]'); var refresh = root.document && root.document.querySelector('[data-join-review-refresh]'); var form = root.document && root.document.querySelector('[data-join-review-form]'); var api = root.GenealogyApi && root.GenealogyApi.defaultClient; var genealogyId = getCurrentGenealogyId(); var canManage = false; var writePending = false; if (!page) return; if (!genealogyId) { setStatus('请先从“我的家谱”选择要管理的家谱', 'forbidden'); setReviewFormEnabled(false); list.innerHTML = '选择家谱后继续'; return; } if (root.ProfileUI && root.ProfileUI.syncGenealogyContextLinks) { root.ProfileUI.syncGenealogyContextLinks(); } if (shouldRedirectToLogin(api)) { redirectToLogin(api); return; } async function loadPending() { var data; setStatus('正在读取待审核申请…', 'loading'); try { data = await api.pendingGenealogyJoinApplies(genealogyId); if (!Array.isArray(data) || (data.length && !normalizePendingApplies(data).length)) { setPendingListState('待审核申请响应字段不完整,请联系后端核对。', 'error'); setStatus('待审核申请响应字段不完整,请联系后端核对。', 'error'); return []; } if (!data.length) { setPendingListState('当前没有待审核申请', 'empty'); setStatus(''); return []; } list.innerHTML = renderPendingJoinApplies(data, canManage); setStatus(canManage ? '' : '当前账号没有审核该家谱申请的权限', canManage ? undefined : 'forbidden'); return normalizePendingApplies(data); } catch (error) { if (shouldRedirectToLogin(api, error)) { redirectToLogin(api); return []; } setPendingListState( getApiStateType(error) === 'forbidden' ? '当前账号没有审核该家谱申请的权限。' : '读取待审核申请失败,请稍后重试。', getApiStateType(error) ); setStatus(error.message || '读取待审核申请失败,请稍后重试', getApiStateType(error)); return []; } } try { var detail = await api.genealogyDetail(genealogyId); canManage = detail && detail.canManage === true; if (!canManage) { setPendingListState('当前账号没有审核该家谱申请的权限。', 'forbidden'); setStatus('当前账号没有审核该家谱申请的权限', 'forbidden'); setReviewFormEnabled(false); return; } } catch (error) { if (shouldRedirectToLogin(api, error)) { redirectToLogin(api); return; } setStatus(error.message || '无法核验当前家谱管理权限', getApiStateType(error)); setPendingListState( getApiStateType(error) === 'forbidden' ? '当前账号没有审核该家谱申请的权限。' : '无法读取待审核申请,请稍后重试。', getApiStateType(error) ); setReviewFormEnabled(false); return; } setReviewFormEnabled(true); refresh.addEventListener('click', function () { loadPending(); }); list.addEventListener('click', function (event) { var button = event.target.closest('[data-join-audit-id]'); var applyId; var status; if (!button || !list.contains(button) || writePending || !canManage) return; applyId = normalizeId(button.getAttribute('data-join-audit-id')); status = button.getAttribute('data-join-audit-status'); if (!applyId || ['1', '2'].indexOf(status) < 0) return; openReviewForm(applyId, status); }); form.addEventListener('submit', async function (event) { var values; var applyId; var body; var validation; var refreshed; var forbidden = false; event.preventDefault(); if (writePending || !canManage) return; values = {}; Array.prototype.slice.call(form.querySelectorAll('[name]')).forEach(function (field) { values[field.name] = field.value; }); applyId = normalizeId(values.applyId); body = buildJoinAuditBody(values); if (!applyId) { setReviewFormStatus('申请编号无效,请返回列表重新操作。', 'error'); return; } validation = validateJoinAuditBody(body); if (validation) { setReviewFormStatus(validation, 'error'); return; } writePending = true; setReviewFormEnabled(false); setReviewSubmitPending(true); setReviewFormStatus('正在提交审核结果…', 'loading'); try { await api.auditGenealogyJoinApply(genealogyId, applyId, body); refreshed = await loadPending(); if (refreshed.some(function (item) { return item.applyId === applyId; })) { throw new Error('审核后申请仍在待审核列表'); } closeReviewForm(); } catch (error) { if (shouldRedirectToLogin(api, error)) { redirectToLogin(api); return; } forbidden = getApiStateType(error) === 'forbidden'; setReviewFormStatus( forbidden ? '当前账号无权审核该家谱申请。' : (error.message || '提交审核结果失败,请稍后重试。'), getApiStateType(error) ); if (forbidden) { canManage = false; setStatus('当前账号无权审核该家谱申请。', 'forbidden'); } } finally { writePending = false; setReviewSubmitPending(false); if (!forbidden) setReviewFormEnabled(true); } }); root.document.querySelector('[data-join-review-cancel]').addEventListener('click', function () { if (!writePending) closeReviewForm(); }); await loadPending(); } return { getCurrentGenealogyId: getCurrentGenealogyId, buildJoinAuditBody: buildJoinAuditBody, validateJoinAuditBody: validateJoinAuditBody, normalizePendingApply: normalizePendingApply, renderPendingJoinApplies: renderPendingJoinApplies, initJoinReviewPage: initJoinReviewPage }; });