(function (root, factory) {
// 世系模块同时支持浏览器页面和 Node 单元测试。
if (typeof module === 'object' && module.exports) {
module.exports = factory(root);
return;
}
root.LineagePages = factory(root);
if (root.document) {
root.document.addEventListener('DOMContentLoaded', function () {
root.LineagePages.init();
});
}
})(typeof globalThis !== 'undefined' ? globalThis : window, function (root) {
'use strict';
var documentRef = root.document;
var selectedPersonId = '';
function normalizeList(data) {
// 通用列表响应可能是数组,也可能包在 rows、records、list、data 中。
if (Array.isArray(data)) return data;
if (!data || typeof data !== 'object') return [];
if (Array.isArray(data.rows)) return data.rows;
if (Array.isArray(data.records)) return data.records;
if (Array.isArray(data.list)) return data.list;
if (Array.isArray(data.data)) return data.data;
return [];
}
function pick(item, keys, fallback) {
var source = item || {};
var index;
var value;
for (index = 0; index < keys.length; index += 1) {
value = source[keys[index]];
if (value !== undefined && value !== null && value !== '') return value;
}
return fallback || '';
}
function escapeHtml(value) {
// 世系人物信息进入 innerHTML 前统一转义,避免姓名和简介污染页面结构。
return String(value === undefined || value === null ? '' : value)
.replace(/&/g, '&')
.replace(//g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''');
}
function getApi() {
return root.GenealogyApi && root.GenealogyApi.defaultClient;
}
function query(selector, rootNode) {
return (rootNode || documentRef).querySelector(selector);
}
function queryAll(selector, rootNode) {
return Array.prototype.slice.call((rootNode || documentRef).querySelectorAll(selector));
}
function showMessage(message) {
if (root.layui && root.layui.layer) {
root.layui.layer.msg(message);
return;
}
root.alert(message);
}
function getQueryParam(search, name) {
var params = new URLSearchParams(String(search || '').replace(/^\?/, ''));
return params.get(name) || '';
}
function getCurrentGenealogyId() {
var search = root.location && root.location.search;
var page = query('[data-lineage-page], [data-family-home-page]');
return getQueryParam(search, 'id') ||
getQueryParam(search, 'genealogyId') ||
(page && page.getAttribute('data-genealogy-id')) ||
'';
}
function toNumber(value) {
var text = String(value === undefined || value === null ? '' : value).trim();
var number = Number(text);
return text && Number.isFinite(number) ? number : undefined;
}
function trimOrUndefined(value) {
var text = String(value === undefined || value === null ? '' : value).trim();
return text || undefined;
}
function formatSex(value) {
var text = String(value === undefined || value === null ? '' : value);
if (text === '0' || text === '男') return '男';
if (text === '1' || text === '女') return '女';
return '未知';
}
function getPersonId(item) {
return pick(item, ['personId', 'lineagePersonId', 'id'], '');
}
function buildLineagePersonBody(values) {
// LineagePersonBody 来自 APP.openapi.json,空值统一转为 undefined,避免提交无意义空字符串。
var source = values || {};
return {
appUserId: toNumber(source.appUserId),
personNo: trimOrUndefined(source.personNo),
personName: String(source.personName || '').trim(),
aliasName: trimOrUndefined(source.aliasName),
sex: String(source.sex || '').trim() || '0',
generationNo: toNumber(source.generationNo),
generationName: trimOrUndefined(source.generationName),
avatarOssId: toNumber(source.avatarOssId),
birthDate: trimOrUndefined(source.birthDate),
deathDate: trimOrUndefined(source.deathDate),
introduction: trimOrUndefined(source.introduction)
};
}
function buildPersonRow(item) {
var personId = getPersonId(item);
var name = pick(item, ['personName', 'name', 'realName'], '未命名成员');
var generationNo = pick(item, ['generationNo', 'generation', 'generationIndex'], '-');
var generationName = pick(item, ['generationName', 'generationText'], '未设置');
var sex = formatSex(pick(item, ['sex', 'gender'], ''));
var bound = pick(item, ['boundAccount', 'bindAccount', 'hasAccount', 'appUserId'], '') ? '已绑定账号' : '未绑定账号';
return '';
}
function getChildren(item) {
var source = item || {};
return normalizeList(source.children || source.childList || source.descendants);
}
function buildTreeNode(item) {
var personId = getPersonId(item);
var name = pick(item, ['personName', 'name', 'realName'], '未命名成员');
var generationNo = pick(item, ['generationNo', 'generation', 'generationIndex'], '-');
var children = getChildren(item);
var html = '
';
if (children.length) {
html += '
' + children.map(buildTreeNode).join('') + '
';
}
return html + '
';
}
function buildHomeSummary(detail, rootCount) {
// 家谱主页摘要优先展示后端家谱信息,世系根节点数量来自树接口。
var source = detail || {};
var genealogyNo = pick(source, ['genealogyNo', 'genealogyCode', 'code'], '未设置编号');
var hallName = pick(source, ['hallName', 'ancestralHall', 'tanghao'], '未设置');
var memberCount = pick(source, ['memberCount', 'personCount', 'members'], '0');
return genealogyNo + ' · 堂号 ' + hallName + ' · 共 ' + memberCount + ' 人 · ' + rootCount + ' 个世系根节点';
}
function renderTree(items) {
var container = query('[data-lineage-tree], [data-lineage-home-tree]');
var list = normalizeList(items);
if (!container) return;
if (!list.length) {
container.innerHTML = '
暂无世系树数据
';
return;
}
container.innerHTML = '
' + list.map(buildTreeNode).join('') + '
';
}
function renderPersons(items) {
var container = query('[data-lineage-list]');
var list = normalizeList(items);
if (!container) return;
if (!list.length) {
container.innerHTML = '
暂无世系人物
';
return;
}
container.innerHTML = list.map(buildPersonRow).join('');
}
function renderHomeDetail(detail, rootCount) {
var title = query('[data-family-home-title]');
var summary = query('[data-family-home-summary]');
var source = detail || {};
if (title) title.textContent = pick(source, ['genealogyName', 'name'], title.textContent || '家谱主页');
if (summary) summary.textContent = buildHomeSummary(source, rootCount);
}
function renderDetail(item) {
var container = query('[data-lineage-detail]');
var source = item || {};
var name = pick(source, ['personName', 'name', 'realName'], '未命名成员');
var intro = pick(source, ['introduction', 'intro', 'remark'], '暂无简介');
if (!container) return;
container.innerHTML = '