ow
This commit is contained in:
1 parent
be6d24e096
commit
f6157578de
2 files changed
+54
-4
No files matched your search
@@ -69,10 +69,12 @@ const data = ref<FamilyTreeData | null>(null);
|
||||
const hasPerson = computed(() => !!data.value?.CurrentPerson?.FamilyPerson?.PersonId);
|
||||
const rootPersonId = computed(() => data.value?.CurrentPerson?.FamilyPerson?.PersonId ?? "");
|
||||
|
||||
/** 全族索引:人员信息 / 夫妻关系(双向)/ 亲子关系 */
|
||||
/** 全族索引:人员信息 / 夫妻关系(双向)/ 亲子关系 / 亲子反向索引 */
|
||||
let personMap = new Map<string, any>();
|
||||
let spousesOf = new Map<string, any[]>();
|
||||
let childrenOf = new Map<string, any[]>();
|
||||
/** 孩子 -> 父母记录列表(一个孩子可能同时挂在生父、过继父等多个父节点下) */
|
||||
let parentsOf = new Map<string, { parentId: string; relation?: string }[]>();
|
||||
|
||||
/** 已展开(显示孩子)的节点 personId 集合 */
|
||||
const expandedIds = ref<Set<string>>(new Set());
|
||||
@@ -155,6 +157,7 @@ const buildIndex = (resp: FamilyTreeData) => {
|
||||
personMap = new Map();
|
||||
spousesOf = new Map();
|
||||
childrenOf = new Map();
|
||||
parentsOf = new Map();
|
||||
|
||||
// 1) 所有人员信息(含性别),优先作为人员卡片数据源
|
||||
const persons = resp?.CurrentPerson?.FamilyTreePersons ?? [];
|
||||
@@ -238,10 +241,29 @@ const buildIndex = (resp: FamilyTreeData) => {
|
||||
orderby: c.Orderby,
|
||||
});
|
||||
childrenOf.set(c.PersonId, list);
|
||||
// 反向记录:同一孩子可能有多条父记录(生父 / 过继父),保留以判断由谁承担后代
|
||||
const parentList = parentsOf.get(c.ChildrenId) ?? [];
|
||||
parentList.push({ parentId: c.PersonId, relation: c.RelationType });
|
||||
parentsOf.set(c.ChildrenId, parentList);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/** 承祧 / 入嗣 / 收养类关系:孩子被过继到该父名下,由其承担其后代世系 */
|
||||
const ADOPTIVE_RELATIONS = new Set(["C", "E", "F", "G", "H", "I", "J", "K", "L"]);
|
||||
|
||||
/**
|
||||
* 同一孩子挂在多个父节点下时,选定“承担后代”的父节点:
|
||||
* 优先取承祧 / 过继关系的一方(如“继子”“承嗣”),否则取记录顺序中的第一个。
|
||||
* 其余父节点仅显示该孩子的引用卡片,不再展开其后代,避免后代被重复展示。
|
||||
*/
|
||||
const primaryParentOf = (personId: string): string => {
|
||||
const parents = parentsOf.get(personId) ?? [];
|
||||
if (parents.length === 0) return "";
|
||||
const adopted = parents.find((p) => ADOPTIVE_RELATIONS.has(p.relation ?? ""));
|
||||
return (adopted ?? parents[0]).parentId;
|
||||
};
|
||||
|
||||
/** 构建图数据:递归一次性展示所有人员,祖先为根,配偶同行右侧,孩子列在配偶正下方 */
|
||||
const buildGraphData = () => {
|
||||
const nodes: any[] = [];
|
||||
@@ -320,8 +342,36 @@ const buildGraphData = () => {
|
||||
// 孩子列与本人第一行的配偶列对齐(x + 260),即孩子位于配偶正下方,竖直跟第一行对齐
|
||||
const childBaseX = x + 260;
|
||||
children.forEach((c: any) => {
|
||||
walk(c.id, depth + 1, childBaseX);
|
||||
edges.push({ source: "n-" + personId, target: "n-" + c.id, data: { kind: "parent" } });
|
||||
// 一个孩子可能同时是多方之子(生父 / 过继父):每个父节点下各显示一张卡片。
|
||||
// 由“承祧 / 过继”的一方承担其后代,其余父节点只显示一张引用卡片(不展开其后代)。
|
||||
const isPrimary = primaryParentOf(c.id) === personId;
|
||||
if (isPrimary) {
|
||||
if (!visited.has(c.id)) {
|
||||
walk(c.id, depth + 1, childBaseX);
|
||||
}
|
||||
edges.push({ source: "n-" + personId, target: "n-" + c.id, data: { kind: "parent" } });
|
||||
} else {
|
||||
const childInfo = personMap.get(c.id) ?? {};
|
||||
const refId = "r-" + personId + "-" + c.id;
|
||||
nodes.push({
|
||||
id: refId,
|
||||
style: { x: childBaseX, y: cursor },
|
||||
data: {
|
||||
kind: "member",
|
||||
personId: c.id,
|
||||
tag: "族员",
|
||||
name: (childInfo.Surname ?? c.ChildrenSurname ?? "") + (childInfo.GenealogyName ?? c.ChildrenGenealogyName ?? ""),
|
||||
commonName: childInfo.CommonName ?? c.ChildrenCommonName,
|
||||
gender: childInfo.Gender ?? c.gender,
|
||||
avatarUrl: childInfo.AvatarUrl ?? "",
|
||||
hasChildren: false,
|
||||
expanded: false,
|
||||
loaded: true,
|
||||
},
|
||||
});
|
||||
cursor += Y_STEP;
|
||||
edges.push({ source: "n-" + personId, target: refId, data: { kind: "parent" } });
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user