Files
jiapu/public/js/join-review-pages.js
T
2026-08-03 16:49:38 +08:00

388 lines
14 KiB
JavaScript

(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, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#39;');
}
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
? '<div class="bottom-actions"><button class="btn primary" type="button" data-join-audit-id="' +
escapeHtml(item.applyId) + '" data-join-audit-status="1">通过</button>' +
'<button class="btn ghost" type="button" data-join-audit-id="' +
escapeHtml(item.applyId) + '" data-join-audit-status="2">拒绝</button></div>'
: '';
return '<article class="module-row"><div><h3>' + escapeHtml(item.applicantName) +
'申请加入' + escapeHtml(item.genealogyName || '当前家谱') + '</h3><p>' +
escapeHtml(details || '申请人未补充说明') + '</p></div>' + actions + '</article>';
}).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 = '<a class="module-row" href="profile-families.html?next=profile-join-review.html">选择家谱后继续</a>';
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
};
});