This commit is contained in:
freedakgmail
2025-11-30 09:16:43 +08:00
parent b436ae0680
commit fd9c064749
227 changed files with 1251 additions and 912 deletions
+33 -25
View File
@@ -2,7 +2,7 @@
import type { FamilyMember } from "@/types/family"
import { FamilyNode } from "./family-node"
import { useFamily } from "@/context/family-context"
import { useEffect, useRef, useState, useCallback } from "react"
import { useEffect, useRef, useState, useCallback, useMemo, memo } from "react"
import { useRouter } from "next/navigation"
interface TreeLayoutProps {
@@ -131,10 +131,33 @@ export function TreeLayout({
}
}, [calculateConnections, treeData])
// 预计算排序后的子节点映射,避免每次渲染时重复计算
const sortedChildrenMap = useMemo(() => {
const map = new Map<string, string[]>()
Object.values(treeData.members).forEach(member => {
if (member.childrenIds && member.childrenIds.length > 0) {
const sorted = [...member.childrenIds].sort((aId, bId) => {
const a = treeData.members[aId]
const b = treeData.members[bId]
if (!a || !b) return 0
const aIsFounder = a.tags?.includes('始祖') || a.generation === 1
const bIsFounder = b.tags?.includes('始祖') || b.generation === 1
if (aIsFounder && !bIsFounder) return -1
if (!aIsFounder && bIsFounder) return 1
return (a.birthDate || "").localeCompare(b.birthDate || "")
})
map.set(member.id, sorted)
}
})
return map
}, [treeData.members])
if (!root) return null
// 递归渲染树节点
const TreeNode = ({ memberId, isRoot = false }: { memberId: string; isRoot?: boolean }) => {
// 递归渲染树节点 - 使用 memo 优化
const TreeNode = memo(function TreeNode({ memberId, isRoot = false }: { memberId: string; isRoot?: boolean }) {
const member = getMember(memberId)
if (!member) return null
@@ -145,6 +168,9 @@ export function TreeLayout({
? member.spouseIds.map(id => getMember(id)).filter(Boolean) as FamilyMember[]
: []
// 使用预计算的排序结果
const sortedChildren = sortedChildrenMap.get(memberId) || []
return (
<div className="flex flex-col items-center">
{/* 节点本身 */}
@@ -178,32 +204,14 @@ export function TreeLayout({
gap: `${HORIZONTAL_GAP}px`
}}
>
{(() => {
// 对子节点进行排序:始祖排最左边,其他按出生日期排序
const sortedChildren = [...member.childrenIds].sort((aId, bId) => {
const a = getMember(aId)
const b = getMember(bId)
if (!a || !b) return 0
// 始祖永远排最左边
const aIsFounder = a.tags?.includes('始祖') || a.generation === 1
const bIsFounder = b.tags?.includes('始祖') || b.generation === 1
if (aIsFounder && !bIsFounder) return -1
if (!aIsFounder && bIsFounder) return 1
// 其他按出生日期排序
return (a.birthDate || "").localeCompare(b.birthDate || "")
})
return sortedChildren.map((childId) => (
<TreeNode key={childId} memberId={childId} />
))
})()}
{sortedChildren.map((childId) => (
<TreeNode key={childId} memberId={childId} />
))}
</div>
)}
</div>
)
}
})
return (
<div className="relative">