# treeId 参数传递修复总结
## 问题描述
切换家族后,某些操作会丢失 `treeId` 参数,导致系统切换回默认家族或第一个家族。
## 根本原因
部分链接和路由跳转没有携带 `treeId` 查询参数,导致家族上下文丢失。
## 修复的位置
### 1. 首页 (`app/page.tsx`)
**修复的链接**:
- ✅ "添加成员"按钮
- ✅ "查看全部"按钮(成员列表)
- ✅ 纪念日成员链接
- ✅ 近期事件成员链接
- ✅ 迁徙记录成员链接
**修复方式**:
```tsx
// 修复前
// 修复后
```
### 2. 成员列表页 (`app/members/page.tsx`)
**修复的链接**:
- ✅ "新增成员"按钮
- ✅ 成员卡片链接
**修复方式**:
```tsx
// 使用当前URL的查询参数
```
### 3. 成员详情页 (`app/members/[id]/page.tsx`)
**修复的功能**:
- ✅ 添加子女
- ✅ 添加配偶
- ✅ 添加父亲
- ✅ 添加母亲
**修复方式**:
```tsx
// 修复前
const params = new URLSearchParams()
// 修复后
const params = new URLSearchParams(window.location.search)
```
### 4. 网站头部 (`components/site-header.tsx`)
**修复的链接**:
- ✅ Logo 链接(返回首页)
- ✅ 家族树切换(跳转到首页)
**修复方式**:
```tsx
// Logo
// 家族切换
router.push(`/?treeId=${tree.id}`)
```
## 技术方案
### 方案一:使用 currentTree.id
适用于服务端组件或有 currentTree 状态的组件:
```tsx
href={currentTree?.id ? `/path?treeId=${currentTree.id}` : '/path'}
```
### 方案二:保留当前 URL 参数
适用于客户端组件:
```tsx
href={`/path${typeof window !== 'undefined' ? window.location.search : ''}`}
```
### 方案三:使用 URLSearchParams
适用于需要添加额外参数的场景:
```tsx
const params = new URLSearchParams(window.location.search)
params.set('newParam', 'value')
router.push(`/path?${params.toString()}`)
```
### 方案四:使用辅助函数
已有的 `getUrlWithTreeId` 函数:
```tsx
const getUrlWithTreeId = (path: string) => {
if (!currentTree?.id) return path
return `${path}?treeId=${currentTree.id}`
}
```
## 数据流
```
用户操作
↓
切换家族 (setCurrentTree + router.push with treeId)
↓
URL 更新 (/?treeId=xxx)
↓
所有链接携带 treeId
↓
页面跳转保持家族上下文
↓
操作应用到正确的家族
```
## 验证清单
### 基本操作
- [x] 切换家族后停留在正确家族
- [x] 添加成员到正确家族
- [x] 查看成员详情显示正确数据
- [x] 编辑成员更新正确家族
### 导航链接
- [x] Logo 返回首页保持家族
- [x] 导航菜单保持家族
- [x] 统计卡片跳转保持家族
- [x] 成员卡片跳转保持家族
### 快速操作
- [x] 添加子女到正确家族
- [x] 添加配偶到正确家族
- [x] 添加父母到正确家族
- [x] 查看纪念日成员正确
## 未来改进
### 1. 使用 Context 统一管理
```tsx
const { getUrlWithTreeId } = useFamily()
```
### 2. 创建自定义 Link 组件
```tsx
成员列表
// 自动添加 treeId
```
### 3. 路由中间件
在 Next.js 中间件中自动处理 treeId:
```tsx
export function middleware(request: NextRequest) {
const treeId = request.cookies.get('currentTreeId')
// 自动添加到 URL
}
```
## 注意事项
1. **服务端 vs 客户端**
- 服务端组件:使用 `currentTree.id`
- 客户端组件:使用 `window.location.search`
2. **SSR 兼容性**
- 使用 `typeof window !== 'undefined'` 检查
- 避免在服务端访问 `window`
3. **参数优先级**
- URL 参数 > Cookie > 默认值
- 确保参数正确传递
4. **边界情况**
- 未登录用户
- 没有家族树
- 家族树被删除
## 测试场景
### 场景 1:切换家族
1. 登录系统
2. 选择家族 A
3. 切换到家族 B
4. 点击"添加成员"
5. ✅ 成员应添加到家族 B
### 场景 2:成员详情
1. 在家族 A 查看成员
2. 切换到家族 B
3. 点击成员卡片
4. ✅ 应显示家族 B 的成员
### 场景 3:快速添加
1. 在家族 A 的成员详情页
2. 点击"添加子女"
3. ✅ 子女应添加到家族 A
### 场景 4:导航
1. 在家族 A 的任意页面
2. 点击 Logo
3. ✅ 应返回家族 A 的首页
## 总结
通过系统性地检查和修复所有链接和路由跳转,确保了:
1. ✅ 家族切换后所有操作都应用到正确的家族
2. ✅ URL 参数正确传递
3. ✅ 用户体验流畅一致
4. ✅ 数据隔离完整
所有修复已完成并测试通过!