Files
jiapu/public/js/family-home-pages.js
T
2026-08-29 19:06:07 +08:00

286 lines
10 KiB
JavaScript

(function (root, factory) {
if (typeof module === 'object' && module.exports) {
module.exports = factory(root);
return;
}
root.FamilyHomePages = factory(root);
if (root.document) {
root.document.addEventListener('DOMContentLoaded', function () {
root.FamilyHomePages.init();
});
}
})(typeof globalThis !== 'undefined' ? globalThis : window, function (root) {
'use strict';
var MediaDisplay = root.MediaDisplay || (typeof require === 'function' ? require('./media-display.js') : null);
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 result;
if (typeof value === 'number' && !Number.isSafeInteger(value)) return '';
if (value === undefined || value === null) return '';
result = String(value).trim();
return /^[1-9][0-9]*$/.test(result) ? result : '';
}
function text(value) {
if (value === undefined || value === null) return '';
return String(value).trim();
}
function normalizeCount(value) {
var result = Number(value);
return Number.isSafeInteger(result) && result >= 0 ? result : null;
}
function normalizeFamilyOverview(item, expectedGenealogyId) {
var source = item || {};
var genealogyId = normalizeId(source.genealogyId);
var expectedId = normalizeId(expectedGenealogyId);
var memberCount = normalizeCount(source.memberCount);
var personCount = normalizeCount(source.personCount);
var coverFile = MediaDisplay && MediaDisplay.normalizeFileAccess(source.coverFile);
var overview;
if (!genealogyId || genealogyId !== expectedId ||
!text(source.genealogyName) || String(source.status) !== '0' ||
memberCount === null || personCount === null) {
return null;
}
overview = {
genealogyId: genealogyId,
genealogyNo: text(source.genealogyNo),
genealogyName: text(source.genealogyName),
surname: text(source.surname),
ancestralHall: text(source.ancestralHall),
originPlace: text(source.originPlace),
regionFullName: text(source.regionFullName),
memberCount: memberCount,
personCount: personCount,
canManage: source.canManage === true,
canEditContent: source.canEditContent === true
};
if (source.coverFile !== undefined && source.coverFile !== null && !coverFile) return null;
if (coverFile) overview.coverFile = coverFile;
return overview;
}
function renderFamilyOverview(overview) {
var source = overview || {};
var details = [
source.genealogyNo ? '家谱编号 ' + source.genealogyNo : '',
source.surname ? '姓氏 ' + source.surname : '',
source.ancestralHall ? '堂号 ' + source.ancestralHall : '',
source.originPlace ? '祖籍 ' + source.originPlace : '',
source.regionFullName ? '地区 ' + source.regionFullName : ''
].filter(Boolean).join(' · ');
return (MediaDisplay ? MediaDisplay.renderImage(source.coverFile, {
alt: source.genealogyName + '封面',
className: 'family-cover-media'
}) : '') + '<h3>' + escapeHtml(source.genealogyName) + '</h3><p>' +
escapeHtml(details) + '</p><p>成员 ' + escapeHtml(source.memberCount) +
' 人 · 世系人物 ' + escapeHtml(source.personCount) + ' 人</p>';
}
function shouldShowFamilyManagement(overview) {
return !!overview && overview.canManage === true;
}
function shouldRedirectToLogin(api, error) {
var status = error && (error.status || error.code);
return !api || !api.getToken || !api.getToken() || Number(status) === 401;
}
function isForbidden(error) {
return Number(error && (error.status || error.code)) === 403;
}
async function loadFamilyHome(api, genealogyId) {
var normalizedId = normalizeId(genealogyId);
var results;
var overview;
if (!normalizedId || !api || !api.genealogyOverview || !api.lineageTree) {
throw new Error('家谱主页接口初始化失败');
}
results = await Promise.all([
api.genealogyOverview(normalizedId),
api.lineageTree(normalizedId)
]);
overview = normalizeFamilyOverview(results[0], normalizedId);
if (!overview) throw new Error('家谱概览响应无效');
return {
overview: overview,
tree: results[1]
};
}
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 query(selector) {
return root.document && root.document.querySelector(selector);
}
function queryAll(selector) {
return root.document ? Array.prototype.slice.call(root.document.querySelectorAll(selector)) : [];
}
function setText(selector, value) {
var element = query(selector);
if (element) element.textContent = value;
}
function setHomeState(selector, type, message) {
var element = query(selector);
if (!element) return;
if (root.ProfileUI && root.ProfileUI.setApiState) {
root.ProfileUI.setApiState(element, type, message);
return;
}
element.textContent = message;
}
function setHomeStatus(message, type) {
var element = query('[data-family-home-status]');
if (!element) return;
element.hidden = !message;
if (!message) {
element.innerHTML = '';
return;
}
if (type && root.ProfileUI && root.ProfileUI.setApiState) {
root.ProfileUI.setApiState(element, type, message);
return;
}
element.textContent = message;
}
async function initFamilyHomePage() {
var page = query('[data-family-home-page]');
var api = root.GenealogyApi && root.GenealogyApi.defaultClient;
var genealogyId;
var result;
var treeHtml;
if (!page) return;
if (shouldRedirectToLogin(api)) {
redirectToLogin(api);
return;
}
genealogyId = root.ProfileUI && root.ProfileUI.getGenealogyId();
if (!genealogyId) {
if (root.location && typeof root.location.replace === 'function') {
root.location.replace('profile-families.html?next=profile-family-home.html');
}
return;
}
if (root.ProfileUI && root.ProfileUI.syncGenealogyContextLinks) {
root.ProfileUI.syncGenealogyContextLinks();
}
if (!root.LineagePages || !root.LineagePages.renderLineageTreeHtml) {
setHomeState('[data-family-home-overview]', 'error', '家谱主页初始化失败,请刷新后重试。');
setHomeState('[data-lineage-home-tree]', 'error', '世系预览初始化失败,请刷新后重试。');
setHomeStatus('世系预览初始化失败,请刷新后重试。', 'error');
return;
}
setHomeState('[data-family-home-overview]', 'loading', '正在加载家谱概览…');
setHomeState('[data-lineage-home-tree]', 'loading', '正在加载世系树…');
setHomeStatus('正在读取家谱概览…', 'loading');
try {
result = normalizeFamilyOverview(await api.genealogyOverview(genealogyId), genealogyId);
if (!result) throw new Error('家谱概览响应无效');
if (root.ProfileUI && root.ProfileUI.setCurrentGenealogyContext) {
root.ProfileUI.setCurrentGenealogyContext(result.genealogyId, result.genealogyName);
}
setText('[data-family-home-title]', result.genealogyName);
setText('[data-family-home-context]', result.genealogyName);
query('[data-family-home-overview]').innerHTML = renderFamilyOverview(result);
setText('[data-family-home-member-count]', String(result.memberCount));
setText('[data-family-home-person-count]', String(result.personCount));
queryAll('[data-family-home-management]').forEach(function (element) {
element.hidden = !shouldShowFamilyManagement(result);
});
} catch (error) {
if (shouldRedirectToLogin(api, error)) {
redirectToLogin(api);
return;
}
setHomeState(
'[data-family-home-overview]',
isForbidden(error) ? 'forbidden' : 'error',
isForbidden(error) ? '当前账号无权查看该家谱。' : '家谱概览读取失败,请稍后重试。'
);
setHomeState(
'[data-lineage-home-tree]',
isForbidden(error) ? 'forbidden' : 'error',
isForbidden(error) ? '当前账号无权查看该家谱。' : '世系树读取失败,请稍后重试。'
);
setHomeStatus(
isForbidden(error) ? '当前账号无权查看该家谱。' : (error.message || '家谱主页读取失败,请稍后重试。'),
isForbidden(error) ? 'forbidden' : 'error'
);
return;
}
try {
result = await api.lineageTree(genealogyId);
treeHtml = Array.isArray(result) ? root.LineagePages.renderLineageTreeHtml(result) : '';
if (!treeHtml) {
setHomeState('[data-lineage-home-tree]', 'empty', '暂无世系树');
} else {
query('[data-lineage-home-tree]').innerHTML = treeHtml;
}
setHomeStatus('');
} catch (error) {
if (shouldRedirectToLogin(api, error)) {
redirectToLogin(api);
return;
}
setHomeState(
'[data-lineage-home-tree]',
isForbidden(error) ? 'forbidden' : 'error',
isForbidden(error) ? '当前账号无权查看该家谱世系树。' : '世系树读取失败,请稍后重试。'
);
setHomeStatus(
isForbidden(error) ? '当前账号无权查看该家谱世系树。' : (error.message || '世系树读取失败,请稍后重试。'),
isForbidden(error) ? 'forbidden' : 'error'
);
}
}
function init() {
return initFamilyHomePage();
}
return {
normalizeFamilyOverview: normalizeFamilyOverview,
renderFamilyOverview: renderFamilyOverview,
shouldShowFamilyManagement: shouldShowFamilyManagement,
shouldRedirectToLogin: shouldRedirectToLogin,
isForbidden: isForbidden,
loadFamilyHome: loadFamilyHome,
initFamilyHomePage: initFamilyHomePage,
init: init
};
});