0.8.0.0
This commit is contained in:
+121
-78
@@ -1,5 +1,6 @@
|
||||
"use client"
|
||||
|
||||
import { useState } from "react"
|
||||
import type { FamilyMember } from "@/types/family"
|
||||
import { cn } from "@/lib/utils"
|
||||
import { useAvatarCache } from "@/hooks/use-avatar-cache"
|
||||
@@ -15,6 +16,8 @@ import {
|
||||
ContextMenuLabel,
|
||||
ContextMenuTrigger,
|
||||
} from "@/components/ui/context-menu"
|
||||
import { GenerationWarningDialog } from "@/components/tree/generation-warning-dialog"
|
||||
import { shouldShowGenerationWarning } from "@/lib/generation-utils"
|
||||
|
||||
interface FamilyNodeProps {
|
||||
member: FamilyMember
|
||||
@@ -90,6 +93,10 @@ function PersonCard({
|
||||
const router = useRouter()
|
||||
const { currentTree } = useFamily()
|
||||
|
||||
// 代数重新计算警告对话框状态
|
||||
const [showWarningDialog, setShowWarningDialog] = useState(false)
|
||||
const [pendingRelationType, setPendingRelationType] = useState<'father' | 'mother' | null>(null)
|
||||
|
||||
const birthYear = formatYear(member.birthDate)
|
||||
const deathYear = formatYear(member.deathDate)
|
||||
const age = calculateAge(member.birthDate, member.deathDate)
|
||||
@@ -123,7 +130,8 @@ function PersonCard({
|
||||
case 'father':
|
||||
params.set('childId', member.id)
|
||||
params.set('gender', 'MALE')
|
||||
params.set('generation', (member.generation - 1).toString())
|
||||
// 如果是第1代成员,新父母的世代也设为1(后端会重新计算所有成员世代)
|
||||
params.set('generation', member.generation === 1 ? '1' : (member.generation - 1).toString())
|
||||
// 如果已有母亲,设为配偶
|
||||
if (member.motherId) {
|
||||
params.set('spouseId', member.motherId)
|
||||
@@ -132,7 +140,8 @@ function PersonCard({
|
||||
case 'mother':
|
||||
params.set('childId', member.id)
|
||||
params.set('gender', 'FEMALE')
|
||||
params.set('generation', (member.generation - 1).toString())
|
||||
// 如果是第1代成员,新父母的世代也设为1(后端会重新计算所有成员世代)
|
||||
params.set('generation', member.generation === 1 ? '1' : (member.generation - 1).toString())
|
||||
// 如果已有父亲,设为配偶
|
||||
if (member.fatherId) {
|
||||
params.set('spouseId', member.fatherId)
|
||||
@@ -175,6 +184,13 @@ function PersonCard({
|
||||
}
|
||||
|
||||
const handleAddMember = (type: 'father' | 'mother' | 'spouse' | 'child') => {
|
||||
// 检查是否需要显示代数重新计算警告
|
||||
if ((type === 'father' || type === 'mother') && shouldShowGenerationWarning(member, type)) {
|
||||
setPendingRelationType(type)
|
||||
setShowWarningDialog(true)
|
||||
return
|
||||
}
|
||||
|
||||
const url = buildAddUrl(type)
|
||||
console.log('handleAddMember called:', type, url)
|
||||
// 使用 setTimeout 延迟跳转,确保菜单关闭后再执行
|
||||
@@ -183,6 +199,18 @@ function PersonCard({
|
||||
window.location.href = url
|
||||
}, 100)
|
||||
}
|
||||
|
||||
// 确认添加父母后的处理
|
||||
const handleConfirmAddParent = () => {
|
||||
if (pendingRelationType) {
|
||||
const url = buildAddUrl(pendingRelationType)
|
||||
console.log('Confirmed add parent, navigating to:', url)
|
||||
setTimeout(() => {
|
||||
window.location.href = url
|
||||
}, 100)
|
||||
setPendingRelationType(null)
|
||||
}
|
||||
}
|
||||
|
||||
// 是否显示右键菜单(有可添加的选项时才显示)
|
||||
const hasAddOptions = canEdit && (canAddFather || canAddMother || canAddSpouse || canAddChild)
|
||||
@@ -193,7 +221,8 @@ function PersonCard({
|
||||
// 庄严正式的中国风配色
|
||||
const isDead = !!member.deathDate
|
||||
const isMale = member.gender === 'MALE'
|
||||
const isFounder = member.isFounder === true
|
||||
// 使用 isRoot prop 而不是 isFounder 字段
|
||||
const isFounder = isRoot === true
|
||||
|
||||
const cardContent = (
|
||||
<div
|
||||
@@ -378,81 +407,94 @@ function PersonCard({
|
||||
|
||||
// 有可添加选项时,包裹右键菜单
|
||||
return (
|
||||
<ContextMenu>
|
||||
<ContextMenuTrigger>
|
||||
{cardContent}
|
||||
</ContextMenuTrigger>
|
||||
<ContextMenuContent className="w-48">
|
||||
<ContextMenuLabel className="text-xs text-muted-foreground">
|
||||
为 {member.fullName} 添加
|
||||
</ContextMenuLabel>
|
||||
<ContextMenuSeparator />
|
||||
|
||||
{canAddFather && (
|
||||
<ContextMenuItem
|
||||
className="gap-2 cursor-pointer"
|
||||
onPointerDown={(e) => {
|
||||
e.preventDefault()
|
||||
handleAddMember('father')
|
||||
}}
|
||||
>
|
||||
<UserPlus className="h-4 w-4 text-blue-500" />
|
||||
添加父亲
|
||||
</ContextMenuItem>
|
||||
)}
|
||||
|
||||
{canAddMother && (
|
||||
<ContextMenuItem
|
||||
className="gap-2 cursor-pointer"
|
||||
onPointerDown={(e) => {
|
||||
e.preventDefault()
|
||||
handleAddMember('mother')
|
||||
}}
|
||||
>
|
||||
<UserPlus className="h-4 w-4 text-pink-500" />
|
||||
添加母亲
|
||||
</ContextMenuItem>
|
||||
)}
|
||||
|
||||
{(canAddFather || canAddMother) && (canAddSpouse || canAddChild) && (
|
||||
<>
|
||||
<ContextMenu>
|
||||
<ContextMenuTrigger>
|
||||
{cardContent}
|
||||
</ContextMenuTrigger>
|
||||
<ContextMenuContent className="w-48">
|
||||
<ContextMenuLabel className="text-xs text-muted-foreground">
|
||||
为 {member.fullName} 添加
|
||||
</ContextMenuLabel>
|
||||
<ContextMenuSeparator />
|
||||
)}
|
||||
|
||||
{canAddSpouse && (
|
||||
<ContextMenuItem
|
||||
className="gap-2 cursor-pointer"
|
||||
onPointerDown={(e) => {
|
||||
e.preventDefault()
|
||||
if (onAddRelation) {
|
||||
onAddRelation('spouse')
|
||||
} else {
|
||||
handleAddMember('spouse')
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Users className="h-4 w-4 text-red-500" />
|
||||
添加配偶
|
||||
</ContextMenuItem>
|
||||
)}
|
||||
|
||||
{canAddChild && (
|
||||
<ContextMenuItem
|
||||
className="gap-2 cursor-pointer"
|
||||
onPointerDown={(e) => {
|
||||
e.preventDefault()
|
||||
if (onAddRelation) {
|
||||
onAddRelation('child')
|
||||
} else {
|
||||
handleAddMember('child')
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Baby className="h-4 w-4 text-green-500" />
|
||||
添加子女
|
||||
</ContextMenuItem>
|
||||
)}
|
||||
</ContextMenuContent>
|
||||
</ContextMenu>
|
||||
|
||||
{canAddFather && (
|
||||
<ContextMenuItem
|
||||
className="gap-2 cursor-pointer"
|
||||
onPointerDown={(e) => {
|
||||
e.preventDefault()
|
||||
handleAddMember('father')
|
||||
}}
|
||||
>
|
||||
<UserPlus className="h-4 w-4 text-blue-500" />
|
||||
添加父亲
|
||||
</ContextMenuItem>
|
||||
)}
|
||||
|
||||
{canAddMother && (
|
||||
<ContextMenuItem
|
||||
className="gap-2 cursor-pointer"
|
||||
onPointerDown={(e) => {
|
||||
e.preventDefault()
|
||||
handleAddMember('mother')
|
||||
}}
|
||||
>
|
||||
<UserPlus className="h-4 w-4 text-pink-500" />
|
||||
添加母亲
|
||||
</ContextMenuItem>
|
||||
)}
|
||||
|
||||
{(canAddFather || canAddMother) && (canAddSpouse || canAddChild) && (
|
||||
<ContextMenuSeparator />
|
||||
)}
|
||||
|
||||
{canAddSpouse && (
|
||||
<ContextMenuItem
|
||||
className="gap-2 cursor-pointer"
|
||||
onPointerDown={(e) => {
|
||||
e.preventDefault()
|
||||
if (onAddRelation) {
|
||||
onAddRelation('spouse')
|
||||
} else {
|
||||
handleAddMember('spouse')
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Users className="h-4 w-4 text-red-500" />
|
||||
添加配偶
|
||||
</ContextMenuItem>
|
||||
)}
|
||||
|
||||
{canAddChild && (
|
||||
<ContextMenuItem
|
||||
className="gap-2 cursor-pointer"
|
||||
onPointerDown={(e) => {
|
||||
e.preventDefault()
|
||||
if (onAddRelation) {
|
||||
onAddRelation('child')
|
||||
} else {
|
||||
handleAddMember('child')
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Baby className="h-4 w-4 text-green-500" />
|
||||
添加子女
|
||||
</ContextMenuItem>
|
||||
)}
|
||||
</ContextMenuContent>
|
||||
</ContextMenu>
|
||||
|
||||
{/* 代数重新计算警告对话框 */}
|
||||
{pendingRelationType && (
|
||||
<GenerationWarningDialog
|
||||
open={showWarningDialog}
|
||||
onOpenChange={setShowWarningDialog}
|
||||
memberName={member.fullName}
|
||||
relationType={pendingRelationType}
|
||||
onConfirm={handleConfirmAddParent}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -496,7 +538,8 @@ export function FamilyNode({
|
||||
// 有配偶时,合并到一个卡片中显示(类似D3布局)
|
||||
const isMale = member.gender === 'MALE'
|
||||
const isDead = !!member.deathDate
|
||||
const isFounder = member.isFounder === true
|
||||
// 使用 isRoot prop 而不是 isFounder 字段
|
||||
const isFounder = isRoot === true
|
||||
const avatarUrl = member.avatarUrl
|
||||
|
||||
// 计算生卒年份
|
||||
|
||||
Reference in New Issue
Block a user