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

4.3 KiB
Raw Blame History

始祖标识功能说明(使用 isFounder 字段)

功能概述

系统使用专门的 isFounder 数据库字段来标识家族始祖,而不是使用 tags 标签。这样可以在业务逻辑中更准确地识别和处理始祖成员。

数据库Schema

FamilyMember 模型新增字段

model FamilyMember {
  // ... 其他字段
  isFounder  Boolean  @default(false)  // 是否为始祖
  // ... 其他字段
}

自动设置逻辑

第一个成员自动处理

当家族树中没有任何成员时,添加的第一个成员会自动:

  1. 设置 isFounderisFounder: true
  2. 设置世代generation: 1
  3. 特殊提示:页面标题显示"添加家族始祖"

代码实现

// 检测是否是第一个成员
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

代码实现

// 检测始祖
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 字段的优势

  1. 类型安全Boolean 类型,不会有拼写错误
  2. 查询效率:数据库可以直接索引和查询
  3. 业务清晰:明确的语义,不会与其他标签混淆
  4. 逻辑简单member.isFounder === truemember.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 // 是否为始祖
  // ... 其他字段
}

注意事项

  1. 唯一性:每个家族树通常只有一个始祖(isFounder: true
  2. 不可自动撤销:一旦设置为始祖,需要手动编辑才能修改
  3. 世代关联:始祖通常是第1代
  4. 数据一致性:确保 isFounder 和 generation 的一致性

未来扩展

可能的功能扩展:

  • 支持多个始祖(如夫妻双方都标记为始祖)
  • 始祖成员在族谱图中的特殊显示样式
  • 始祖成员的专属统计信息
  • 从始祖开始的完整世系追溯功能
  • 始祖成员的特殊权限或保护机制