0.0.1.2
This commit is contained in:
+68
-13
@@ -1,7 +1,7 @@
|
||||
"use client"
|
||||
|
||||
import type React from "react"
|
||||
import { createContext, useContext, useState, useCallback, useEffect } from "react"
|
||||
import { createContext, useContext, useState, useCallback, useEffect, useRef } from "react"
|
||||
import type { FamilyMember, FamilyTreeData } from "@/types/family"
|
||||
import { useSession } from "next-auth/react"
|
||||
import { useSearchParams } from "next/navigation"
|
||||
@@ -12,6 +12,7 @@ interface FamilyTreeInfo {
|
||||
description: string | null
|
||||
ownerId: string
|
||||
rootMemberId: string | null
|
||||
currentUserRole?: "OWNER" | "EDITOR" | "VIEWER"
|
||||
}
|
||||
|
||||
interface FamilyContextType {
|
||||
@@ -43,6 +44,7 @@ export function FamilyProvider({ children }: { children: React.ReactNode }) {
|
||||
members: {},
|
||||
})
|
||||
const [currentTree, setCurrentTree] = useState<FamilyTreeInfo | null>(null)
|
||||
const loadingTreeIdRef = useRef<string | null>(null)
|
||||
|
||||
// 监听 URL 和 Session 变化,加载家族树
|
||||
useEffect(() => {
|
||||
@@ -63,22 +65,28 @@ export function FamilyProvider({ children }: { children: React.ReactNode }) {
|
||||
setCurrentTree(null)
|
||||
setTreeData({ rootId: "", members: {} })
|
||||
setIsLoading(false)
|
||||
loadingTreeIdRef.current = null
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 需要加载的树 ID
|
||||
const targetTreeId = treeId || 'first'
|
||||
|
||||
// 如果正在加载相同的树,跳过
|
||||
if (loadingTreeIdRef.current === targetTreeId) {
|
||||
console.log('⏭️ 跳过重复加载:', targetTreeId)
|
||||
return
|
||||
}
|
||||
|
||||
// 如果 treeId 与当前树相同,跳过
|
||||
if (treeId && treeId === currentTree?.id) {
|
||||
console.log('⏭️ 已加载该树,跳过:', treeId)
|
||||
return
|
||||
}
|
||||
|
||||
// 如果没有 treeId 且已有树,跳过
|
||||
if (!treeId && currentTree) {
|
||||
return
|
||||
}
|
||||
|
||||
// 需要加载新树
|
||||
const targetTreeId = treeId || 'first'
|
||||
// 标记正在加载
|
||||
loadingTreeIdRef.current = targetTreeId
|
||||
|
||||
if (!signal.aborted) setIsLoading(true)
|
||||
|
||||
@@ -93,6 +101,15 @@ export function FamilyProvider({ children }: { children: React.ReactNode }) {
|
||||
}
|
||||
const data = await res.json()
|
||||
|
||||
console.log('🌳 获取家族树响应:', {
|
||||
fetchUrl,
|
||||
targetTreeId,
|
||||
responseData: data,
|
||||
treesCount: data.trees?.length,
|
||||
firstTree: data.trees?.[0],
|
||||
singleTree: data.tree
|
||||
})
|
||||
|
||||
if (signal.aborted) return
|
||||
|
||||
let tree = null
|
||||
@@ -102,16 +119,28 @@ export function FamilyProvider({ children }: { children: React.ReactNode }) {
|
||||
tree = data.tree
|
||||
}
|
||||
|
||||
console.log('🎯 选择的家族树:', tree)
|
||||
|
||||
if (tree) {
|
||||
setCurrentTree(tree)
|
||||
// 加载该树的成员数据
|
||||
console.log('🔄 开始加载成员数据:', { treeId: tree.id, treeName: tree.name })
|
||||
try {
|
||||
const memberRes = await fetch(`/api/trees/${tree.id}/members`, { signal })
|
||||
console.log('📡 成员数据响应状态:', memberRes.status, memberRes.ok)
|
||||
if (!memberRes.ok) {
|
||||
throw new Error(`Failed to load members: ${memberRes.status}`)
|
||||
}
|
||||
const memberData = await memberRes.json()
|
||||
|
||||
console.log('📊 获取到的成员数据:', {
|
||||
treeId: tree.id,
|
||||
treeName: tree.name,
|
||||
membersCount: memberData.members?.length || 0,
|
||||
members: memberData.members,
|
||||
rootId: memberData.rootId
|
||||
})
|
||||
|
||||
if (signal.aborted) return
|
||||
|
||||
if (memberData.members) {
|
||||
@@ -122,13 +151,21 @@ export function FamilyProvider({ children }: { children: React.ReactNode }) {
|
||||
},
|
||||
{}
|
||||
)
|
||||
console.log('✅ 设置 treeData:', {
|
||||
rootId: memberData.rootId || "",
|
||||
membersMapKeys: Object.keys(membersMap),
|
||||
membersMapCount: Object.keys(membersMap).length
|
||||
})
|
||||
setTreeData({
|
||||
rootId: memberData.rootId || "",
|
||||
members: membersMap,
|
||||
})
|
||||
}
|
||||
} catch (err: any) {
|
||||
if (err.name === 'AbortError') return
|
||||
if (err.name === 'AbortError') {
|
||||
console.log('❌ 成员数据加载被中断')
|
||||
return
|
||||
}
|
||||
console.error('加载成员数据失败:', err)
|
||||
// 即使成员加载失败,也保留树的信息
|
||||
setTreeData({ rootId: "", members: {} })
|
||||
@@ -138,9 +175,12 @@ export function FamilyProvider({ children }: { children: React.ReactNode }) {
|
||||
setTreeData({ rootId: "", members: {} })
|
||||
}
|
||||
} catch (err: any) {
|
||||
if (err.name === 'AbortError') return
|
||||
if (err.name === 'AbortError') {
|
||||
console.log('❌ 家族树加载被中断')
|
||||
return
|
||||
}
|
||||
|
||||
// 忽略 Failed to fetch 错误,通常发生在页面跳转或网络问题时
|
||||
// 忽略 Failed to fetch 错误
|
||||
if (err.message === 'Failed to fetch' || err.toString().includes('Failed to fetch')) {
|
||||
return
|
||||
}
|
||||
@@ -149,7 +189,11 @@ export function FamilyProvider({ children }: { children: React.ReactNode }) {
|
||||
setCurrentTree(null)
|
||||
setTreeData({ rootId: "", members: {} })
|
||||
} finally {
|
||||
if (!signal.aborted) setIsLoading(false)
|
||||
if (!signal.aborted) {
|
||||
setIsLoading(false)
|
||||
// 加载完成后清除标记
|
||||
loadingTreeIdRef.current = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,7 +202,7 @@ export function FamilyProvider({ children }: { children: React.ReactNode }) {
|
||||
return () => {
|
||||
controller.abort()
|
||||
}
|
||||
}, [searchParams, session?.user?.id, status, currentTree?.id])
|
||||
}, [searchParams, session?.user?.id, status])
|
||||
|
||||
const getMember = useCallback(
|
||||
(id: string) => {
|
||||
@@ -312,6 +356,17 @@ export function FamilyProvider({ children }: { children: React.ReactNode }) {
|
||||
return () => window.removeEventListener("family-data-import" as any, handleImport as any)
|
||||
}, [loadData])
|
||||
|
||||
// 监听 treeData 变化
|
||||
useEffect(() => {
|
||||
console.log('🔄 FamilyContext treeData 更新:', {
|
||||
rootId: treeData.rootId,
|
||||
membersCount: Object.keys(treeData.members).length,
|
||||
memberIds: Object.keys(treeData.members),
|
||||
currentTreeId: currentTree?.id,
|
||||
currentTreeName: currentTree?.name
|
||||
})
|
||||
}, [treeData, currentTree])
|
||||
|
||||
return (
|
||||
<FamilyContext.Provider
|
||||
value={{
|
||||
|
||||
Reference in New Issue
Block a user