4.3 KiB
4.3 KiB
始祖标识功能说明(使用 isFounder 字段)
功能概述
系统使用专门的 isFounder 数据库字段来标识家族始祖,而不是使用 tags 标签。这样可以在业务逻辑中更准确地识别和处理始祖成员。
数据库Schema
FamilyMember 模型新增字段
model FamilyMember {
// ... 其他字段
isFounder Boolean @default(false) // 是否为始祖
// ... 其他字段
}
自动设置逻辑
第一个成员自动处理
当家族树中没有任何成员时,添加的第一个成员会自动:
- 设置 isFounder:
isFounder: true - 设置世代:
generation: 1 - 特殊提示:页面标题显示"添加家族始祖"
代码实现
// 检测是否是第一个成员
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(),
}
视觉标识
成员列表页
始祖成员具有特殊的视觉标识:
- 皇冠图标:名字前显示 👑
- 金色文字:
text-amber-600 - 特殊标签:显示"家族始祖"(
text-amber-700 font-semibold)
代码实现
// 检测始祖
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>
) : ...}
业务逻辑使用
成员分组
在按世代分组时,始祖成员会被优先识别:
const familyMembers = members.filter(m => {
const isFounder = m.isFounder === true
const hasFamilyParents = m.fatherId || m.motherId
if (hasFamilyParents || isFounder) return true
// ...
})
排序逻辑
始祖成员在同世代中排在最前面:
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 字段的优势
- 类型安全:Boolean 类型,不会有拼写错误
- 查询效率:数据库可以直接索引和查询
- 业务清晰:明确的语义,不会与其他标签混淆
- 逻辑简单:
member.isFounder === true比member.tags?.includes('始祖')更简洁
tags 的用途
tags 字段保留用于其他标签,如:
- 职业标签:教书先生、医生、商人
- 成就标签:进士、举人、秀才
- 其他自定义标签
数据迁移
已创建数据库迁移:
migrations/20251124005530_add_is_founder_field/migration.sql
迁移内容:
ALTER TABLE "FamilyMember" ADD COLUMN "isFounder" BOOLEAN NOT NULL DEFAULT false;
示例数据
王氏家族始祖
{
surname: '王',
givenName: '德厚',
fullName: '王德厚',
gender: 'MALE',
generation: 1,
isFounder: true, // 始祖标识
tags: ['教书先生'], // 其他标签
// ...
}
虞氏家族始祖
{
surname: '虞',
givenName: '文昌',
fullName: '虞文昌',
gender: 'MALE',
generation: 1,
isFounder: true, // 始祖标识
tags: ['商人'], // 其他标签
// ...
}
TypeScript 类型
export interface FamilyMember {
// ... 其他字段
isFounder?: boolean // 是否为始祖
// ... 其他字段
}
注意事项
- 唯一性:每个家族树通常只有一个始祖(
isFounder: true) - 不可自动撤销:一旦设置为始祖,需要手动编辑才能修改
- 世代关联:始祖通常是第1代
- 数据一致性:确保 isFounder 和 generation 的一致性
未来扩展
可能的功能扩展:
- 支持多个始祖(如夫妻双方都标记为始祖)
- 始祖成员在族谱图中的特殊显示样式
- 始祖成员的专属统计信息
- 从始祖开始的完整世系追溯功能
- 始祖成员的特殊权限或保护机制