Files
chinese-family-tree-2/FOUNDER_FEATURE_UPDATED.md
T
freedakgmail 3d075c6076 0.0.8.5
2025-11-24 14:02:34 +08:00

193 lines
4.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 始祖标识功能说明(使用 isFounder 字段)
## 功能概述
系统使用专门的 `isFounder` 数据库字段来标识家族始祖,而不是使用 tags 标签。这样可以在业务逻辑中更准确地识别和处理始祖成员。
## 数据库Schema
### FamilyMember 模型新增字段
```prisma
model FamilyMember {
// ... 其他字段
isFounder Boolean @default(false) // 是否为始祖
// ... 其他字段
}
```
## 自动设置逻辑
### 第一个成员自动处理
当家族树中没有任何成员时,添加的第一个成员会自动:
1. **设置 isFounder**`isFounder: true`
2. **设置世代**`generation: 1`
3. **特殊提示**:页面标题显示"添加家族始祖"
### 代码实现
```typescript
// 检测是否是第一个成员
const existingMembers = Object.values(treeData.members)
const isFirstMember = existingMembers.length === 0
// 保存时自动设置
const memberData = isFirstMember ? {
...newMember,
generation: 1,
isFounder: true,
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
} : {
...newMember,
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
}
```
## 视觉标识
### 成员列表页
始祖成员具有特殊的视觉标识:
1. **皇冠图标**:名字前显示 👑
2. **金色文字**`text-amber-600`
3. **特殊标签**:显示"家族始祖"`text-amber-700 font-semibold`
### 代码实现
```typescript
// 检测始祖
const isFounder = member.isFounder === true
// 显示皇冠图标
{isFounder && <span className="text-amber-600">👑</span>}
// 显示特殊标签
{isFounder ? (
<p className="text-xs text-amber-700 font-semibold mt-0.5 truncate">
</p>
) : ...}
```
## 业务逻辑使用
### 成员分组
在按世代分组时,始祖成员会被优先识别:
```typescript
const familyMembers = members.filter(m => {
const isFounder = m.isFounder === true
const hasFamilyParents = m.fatherId || m.motherId
if (hasFamilyParents || isFounder) return true
// ...
})
```
### 排序逻辑
始祖成员在同世代中排在最前面:
```typescript
const sortedFamilyMembers = familyMembers.sort((a, b) => {
const aIsFounder = a.isFounder === true
const bIsFounder = b.isFounder === true
if (aIsFounder && !bIsFounder) return -1
if (!aIsFounder && bIsFounder) return 1
// ... 其他排序逻辑
})
```
## 与 tags 的区别
### 使用 isFounder 字段的优势
1. **类型安全**:Boolean 类型,不会有拼写错误
2. **查询效率**:数据库可以直接索引和查询
3. **业务清晰**:明确的语义,不会与其他标签混淆
4. **逻辑简单**`member.isFounder === true``member.tags?.includes('始祖')` 更简洁
### tags 的用途
tags 字段保留用于其他标签,如:
- 职业标签:教书先生、医生、商人
- 成就标签:进士、举人、秀才
- 其他自定义标签
## 数据迁移
已创建数据库迁移:
```
migrations/20251124005530_add_is_founder_field/migration.sql
```
迁移内容:
```sql
ALTER TABLE "FamilyMember" ADD COLUMN "isFounder" BOOLEAN NOT NULL DEFAULT false;
```
## 示例数据
### 王氏家族始祖
```typescript
{
surname: '王',
givenName: '德厚',
fullName: '王德厚',
gender: 'MALE',
generation: 1,
isFounder: true, // 始祖标识
tags: ['教书先生'], // 其他标签
// ...
}
```
### 虞氏家族始祖
```typescript
{
surname: '虞',
givenName: '文昌',
fullName: '虞文昌',
gender: 'MALE',
generation: 1,
isFounder: true, // 始祖标识
tags: ['商人'], // 其他标签
// ...
}
```
## TypeScript 类型
```typescript
export interface FamilyMember {
// ... 其他字段
isFounder?: boolean // 是否为始祖
// ... 其他字段
}
```
## 注意事项
1. **唯一性**:每个家族树通常只有一个始祖(`isFounder: true`
2. **不可自动撤销**:一旦设置为始祖,需要手动编辑才能修改
3. **世代关联**:始祖通常是第1代
4. **数据一致性**:确保 isFounder 和 generation 的一致性
## 未来扩展
可能的功能扩展:
- [ ] 支持多个始祖(如夫妻双方都标记为始祖)
- [ ] 始祖成员在族谱图中的特殊显示样式
- [ ] 始祖成员的专属统计信息
- [ ] 从始祖开始的完整世系追溯功能
- [ ] 始祖成员的特殊权限或保护机制