(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, '>') .replace(/"/g, '"') .replace(/'/g, '''); } 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' }) : '') + '
' + escapeHtml(details) + '
成员 ' + escapeHtml(source.memberCount) + ' 人 · 世系人物 ' + escapeHtml(source.personCount) + ' 人
'; } 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 }; });