This commit is contained in:
freedakgmail
2025-11-23 18:03:04 +08:00
parent 9cdd751a56
commit e44dd0bd95
489 changed files with 264491 additions and 4157 deletions
+1 -1
View File
@@ -42,7 +42,7 @@ export async function generateBio(member: Partial<FamilyMember>): Promise<string
const prompt = `请根据以下信息生成一段简洁的人物简介(100字以内):
姓名:${member.fullName || "未知"}
性别:${member.gender === "male" ? "男" : member.gender === "female" ? "女" : "未知"}
性别:${member.gender === "MALE" ? "男" : member.gender === "FEMALE" ? "女" : "未知"}
出生日期:${member.birthDate || "未知"}
${member.deathDate ? `逝世日期:${member.deathDate}` : ""}
籍贯:${member.ancestralHome || "未知"}
+6 -6
View File
@@ -32,9 +32,9 @@ export function exportToGedcom(treeData: FamilyTreeData): string {
lines.push(`2 _AKA ${member.courtesyName}`)
}
if (member.gender === 'male') {
if (member.gender === 'MALE') {
lines.push("1 SEX M")
} else if (member.gender === 'female') {
} else if (member.gender === 'FEMALE') {
lines.push("1 SEX F")
}
@@ -113,14 +113,14 @@ export function exportToGedcom(treeData: FamilyTreeData): string {
// 创建配偶家庭
if (member.spouseIds.length > 0) {
member.spouseIds.forEach(spouseId => {
const famId = member.gender === 'male'
const famId = member.gender === 'MALE'
? `F${member.id}_${spouseId}`
: `F${spouseId}_${member.id}`
if (!processedFamilies.has(famId)) {
lines.push(`0 @${famId}@ FAM`)
if (member.gender === 'male') {
if (member.gender === 'MALE') {
lines.push(`1 HUSB @I${member.id}@`)
lines.push(`1 WIFE @I${spouseId}@`)
} else {
@@ -163,7 +163,7 @@ export function importFromGedcom(gedcomText: string): FamilyTreeData {
let givenName = ''
let surname = ''
let courtesyName: string | undefined
let gender: 'male' | 'female' | 'other' = 'other'
let gender: 'MALE' | 'FEMALE' | 'OTHER' = 'OTHER'
let birthDate: string | undefined
let deathDate: string | undefined
let birthPlace: string | undefined
@@ -181,7 +181,7 @@ export function importFromGedcom(gedcomText: string): FamilyTreeData {
})
}
if (field.tag === 'SEX') {
gender = field.data === 'M' ? 'male' : field.data === 'F' ? 'female' : 'other'
gender = field.data === 'M' ? 'MALE' : field.data === 'F' ? 'FEMALE' : 'OTHER'
}
if (field.tag === 'BIRT') {
field.tree?.forEach((subField: any) => {
+25 -25
View File
@@ -4,7 +4,7 @@ import type { FamilyMember, FamilyTreeData } from "@/types/family"
const createMember = (
id: string,
name: string,
gender: "male" | "female",
gender: "MALE" | "FEMALE",
generation: number,
props: Partial<FamilyMember> = {},
): FamilyMember => {
@@ -26,7 +26,7 @@ const createMember = (
const members: Record<string, FamilyMember> = {
// ========== 第一代 (曾祖父母辈,1920年代出生) ==========
"1": createMember("1", "国强", "male", 1, {
"1": createMember("1", "国强", "MALE", 1, {
ancestralHome: "广东省广州市",
bio: "李氏家族第一代,抗战时期参加革命工作,新中国成立后在政府部门工作,为人正直,深受敬重。",
tags: ["革命干部", "始祖"],
@@ -35,7 +35,7 @@ const members: Record<string, FamilyMember> = {
spouseIds: ["2"],
childrenIds: ["3", "4", "5"],
}),
"2": createMember("2", "秀芳", "female", 1, {
"2": createMember("2", "秀芳", "FEMALE", 1, {
fullName: "王秀芳",
surname: "王",
givenName: "秀芳",
@@ -48,7 +48,7 @@ const members: Record<string, FamilyMember> = {
}),
// ========== 第二代 (祖父母辈,1950年代出生) ==========
"3": createMember("3", "建华", "male", 2, {
"3": createMember("3", "建华", "MALE", 2, {
fatherId: "1",
motherId: "2",
ancestralHome: "广东省深圳市",
@@ -60,7 +60,7 @@ const members: Record<string, FamilyMember> = {
spouseIds: ["6"],
childrenIds: ["9", "10"],
}),
"4": createMember("4", "建国", "male", 2, {
"4": createMember("4", "建国", "MALE", 2, {
fatherId: "1",
motherId: "2",
generationName: "建",
@@ -73,7 +73,7 @@ const members: Record<string, FamilyMember> = {
spouseIds: ["7"],
childrenIds: ["11", "12", "13"],
}),
"5": createMember("5", "建军", "male", 2, {
"5": createMember("5", "建军", "MALE", 2, {
fatherId: "1",
motherId: "2",
generationName: "建",
@@ -88,7 +88,7 @@ const members: Record<string, FamilyMember> = {
}),
// 第二代配偶
"6": createMember("6", "丽华", "female", 2, {
"6": createMember("6", "丽华", "FEMALE", 2, {
fullName: "陈丽华",
surname: "陈",
givenName: "丽华",
@@ -99,7 +99,7 @@ const members: Record<string, FamilyMember> = {
spouseIds: ["3"],
childrenIds: ["9", "10"],
}),
"7": createMember("7", "美玲", "female", 2, {
"7": createMember("7", "美玲", "FEMALE", 2, {
fullName: "张美玲",
surname: "张",
givenName: "美玲",
@@ -109,7 +109,7 @@ const members: Record<string, FamilyMember> = {
spouseIds: ["4"],
childrenIds: ["11", "12", "13"],
}),
"8": createMember("8", "雅琴", "female", 2, {
"8": createMember("8", "雅琴", "FEMALE", 2, {
fullName: "林雅琴",
surname: "林",
givenName: "雅琴",
@@ -121,7 +121,7 @@ const members: Record<string, FamilyMember> = {
}),
// ========== 第三代 (父母辈,1980年代出生) ==========
"9": createMember("9", "志远", "male", 3, {
"9": createMember("9", "志远", "MALE", 3, {
fatherId: "3",
motherId: "6",
generationName: "志",
@@ -137,7 +137,7 @@ const members: Record<string, FamilyMember> = {
spouseIds: ["15"],
childrenIds: ["17", "18"],
}),
"10": createMember("10", "志强", "male", 3, {
"10": createMember("10", "志强", "MALE", 3, {
fatherId: "3",
motherId: "6",
generationName: "志",
@@ -153,7 +153,7 @@ const members: Record<string, FamilyMember> = {
spouseIds: ["16"],
childrenIds: ["19"],
}),
"11": createMember("11", "志明", "male", 3, {
"11": createMember("11", "志明", "MALE", 3, {
fatherId: "4",
motherId: "7",
generationName: "志",
@@ -170,7 +170,7 @@ const members: Record<string, FamilyMember> = {
spouseIds: ["20"],
childrenIds: ["21", "22"],
}),
"12": createMember("12", "志文", "male", 3, {
"12": createMember("12", "志文", "MALE", 3, {
fatherId: "4",
motherId: "7",
generationName: "志",
@@ -183,7 +183,7 @@ const members: Record<string, FamilyMember> = {
phone: "13600136004",
email: "zhiwen.li@writer.com",
}),
"13": createMember("13", "志勇", "male", 3, {
"13": createMember("13", "志勇", "MALE", 3, {
fatherId: "4",
motherId: "7",
generationName: "志",
@@ -197,7 +197,7 @@ const members: Record<string, FamilyMember> = {
email: "zhiyong.li@lawfirm.com",
address: "上海市浦东新区陆家嘴金融中心",
}),
"14": createMember("14", "志诚", "male", 3, {
"14": createMember("14", "志诚", "MALE", 3, {
fatherId: "5",
motherId: "8",
generationName: "志",
@@ -216,7 +216,7 @@ const members: Record<string, FamilyMember> = {
}),
// 第三代配偶
"15": createMember("15", "晓雯", "female", 3, {
"15": createMember("15", "晓雯", "FEMALE", 3, {
fullName: "赵晓雯",
surname: "赵",
givenName: "晓雯",
@@ -226,7 +226,7 @@ const members: Record<string, FamilyMember> = {
spouseIds: ["9"],
childrenIds: ["17", "18"],
}),
"16": createMember("16", "诗涵", "female", 3, {
"16": createMember("16", "诗涵", "FEMALE", 3, {
fullName: "刘诗涵",
surname: "刘",
givenName: "诗涵",
@@ -236,7 +236,7 @@ const members: Record<string, FamilyMember> = {
spouseIds: ["10"],
childrenIds: ["19"],
}),
"20": createMember("20", "雨欣", "female", 3, {
"20": createMember("20", "雨欣", "FEMALE", 3, {
fullName: "周雨欣",
surname: "周",
givenName: "雨欣",
@@ -246,7 +246,7 @@ const members: Record<string, FamilyMember> = {
spouseIds: ["11"],
childrenIds: ["21", "22"],
}),
"23": createMember("23", "婉婷", "female", 3, {
"23": createMember("23", "婉婷", "FEMALE", 3, {
fullName: "郑婉婷",
surname: "郑",
givenName: "婉婷",
@@ -258,7 +258,7 @@ const members: Record<string, FamilyMember> = {
}),
// ========== 第四代 (子女辈,2010年代出生) ==========
"17": createMember("17", "浩然", "male", 4, {
"17": createMember("17", "浩然", "MALE", 4, {
fatherId: "9",
motherId: "15",
generationName: "浩",
@@ -267,7 +267,7 @@ const members: Record<string, FamilyMember> = {
tags: ["学生"],
birthDate: "2010-05-10",
}),
"18": createMember("18", "思琪", "female", 4, {
"18": createMember("18", "思琪", "FEMALE", 4, {
fatherId: "9",
motherId: "15",
generationName: "思",
@@ -276,7 +276,7 @@ const members: Record<string, FamilyMember> = {
tags: ["学生"],
birthDate: "2013-08-22",
}),
"19": createMember("19", "宇轩", "male", 4, {
"19": createMember("19", "宇轩", "MALE", 4, {
fatherId: "10",
motherId: "16",
generationName: "宇",
@@ -285,7 +285,7 @@ const members: Record<string, FamilyMember> = {
tags: ["学生"],
birthDate: "2015-11-18",
}),
"21": createMember("21", "梓涵", "female", 4, {
"21": createMember("21", "梓涵", "FEMALE", 4, {
fatherId: "11",
motherId: "20",
generationName: "梓",
@@ -294,7 +294,7 @@ const members: Record<string, FamilyMember> = {
tags: ["大学生"],
birthDate: "2007-03-05",
}),
"22": createMember("22", "子轩", "male", 4, {
"22": createMember("22", "子轩", "MALE", 4, {
fatherId: "11",
motherId: "20",
generationName: "子",
@@ -303,7 +303,7 @@ const members: Record<string, FamilyMember> = {
tags: ["学生"],
birthDate: "2010-07-14",
}),
"24": createMember("24", "欣怡", "female", 4, {
"24": createMember("24", "欣怡", "FEMALE", 4, {
fatherId: "14",
motherId: "23",
generationName: "欣",
+240 -7
View File
@@ -1,10 +1,13 @@
import { prisma } from "./prisma"
import { Role } from "@prisma/client"
import { Role as PrismaRole } from "@prisma/client"
// 导出 Role 类型供前端使用
export type Role = "OWNER" | "EDITOR" | "VIEWER"
export async function checkPermission(
userId: string,
treeId: string,
requiredRole: Role = Role.VIEWER
requiredRole: PrismaRole = PrismaRole.VIEWER
) {
// 检查是否是所有者
const tree = await prisma.familyTree.findFirst({
@@ -15,7 +18,7 @@ export async function checkPermission(
})
if (tree) {
return { hasPermission: true, role: Role.OWNER }
return { hasPermission: true, role: PrismaRole.OWNER as Role }
}
// 检查协作者权限
@@ -31,14 +34,14 @@ export async function checkPermission(
}
const roleHierarchy = {
[Role.OWNER]: 3,
[Role.EDITOR]: 2,
[Role.VIEWER]: 1
[PrismaRole.OWNER]: 3,
[PrismaRole.EDITOR]: 2,
[PrismaRole.VIEWER]: 1
}
const hasPermission = roleHierarchy[collaborator.role] >= roleHierarchy[requiredRole]
return { hasPermission, role: collaborator.role }
return { hasPermission, role: collaborator.role as Role }
}
export async function requireAuth(userId: string | undefined) {
@@ -47,3 +50,233 @@ export async function requireAuth(userId: string | undefined) {
}
return userId
}
/**
* 权限控制工具函数
* 用于基于角色的访问控制 (RBAC)
*/
/**
* 权限检查函数集合
*/
export const permissions = {
// ==================== 增加权限 ====================
/**
* 是否可以创建/添加成员
* OWNER | EDITOR | VIEWER
*/
canCreate: (role?: Role): boolean => {
return role === "OWNER" || role === "EDITOR"
},
/**
* 是否可以创建家族树
* 所有登录用户都可以创建自己的家族树
*/
canCreateTree: (role?: Role): boolean => {
return true // 所有人都可以创建新家族树
},
// ==================== 修改权限 ====================
/**
* 是否可以编辑/更新成员信息
* OWNER | EDITOR | VIEWER
*/
canUpdate: (role?: Role): boolean => {
return role === "OWNER" || role === "EDITOR"
},
/**
* 是否可以导入数据
* OWNER | EDITOR | VIEWER
*/
canImport: (role?: Role): boolean => {
return role === "OWNER" || role === "EDITOR"
},
// ==================== 删除权限 ====================
/**
* 是否可以删除成员
* OWNER | EDITOR | VIEWER
*/
canDeleteMember: (role?: Role): boolean => {
return role === "OWNER" || role === "EDITOR"
},
/**
* 是否可以删除家族树
* OWNER | EDITOR | VIEWER
*/
canDeleteTree: (role?: Role): boolean => {
return role === "OWNER"
},
/**
* 是否可以清空数据
* OWNER | EDITOR | VIEWER
*/
canClearData: (role?: Role): boolean => {
return role === "OWNER"
},
// ==================== 协作者管理权限 ====================
/**
* 是否可以邀请协作者
* OWNER | EDITOR | VIEWER
*/
canInviteCollaborators: (role?: Role): boolean => {
return role === "OWNER"
},
/**
* 是否可以移除协作者
* OWNER | EDITOR | VIEWER
*/
canRemoveCollaborators: (role?: Role): boolean => {
return role === "OWNER"
},
/**
* 是否可以管理协作者(邀请和移除)
* OWNER | EDITOR | VIEWER
*/
canManageCollaborators: (role?: Role): boolean => {
return role === "OWNER"
},
// ==================== 查看权限 ====================
/**
* 是否可以查看信息
* OWNER | EDITOR | VIEWER
*/
canView: (role?: Role): boolean => {
return true //
},
/**
* 是否可以搜索和查询
* OWNER | EDITOR | VIEWER
*/
canSearch: (role?: Role): boolean => {
return true //
},
/**
* 是否可以导出数据
* OWNER | EDITOR | VIEWER
*/
canExport: (role?: Role): boolean => {
return true //
},
/**
* 是否可以打印
* OWNER | EDITOR | VIEWER
*/
canPrint: (role?: Role): boolean => {
return true //
},
}
// ==================== 兼容旧代码的函数 ====================
/**
* @deprecated
*/
export function canEditTree(role?: Role): boolean {
return permissions.canUpdate(role)
}
/**
* @deprecated
*/
export function canDeleteTree(role?: Role): boolean {
return permissions.canDeleteTree(role)
}
/**
* @deprecated
*/
export function canInviteCollaborators(role?: Role): boolean {
return permissions.canInviteCollaborators(role)
}
// ==================== 权限验证辅助函数 ====================
/**
*
*/
export function requirePermission(
role: Role | undefined,
permissionCheck: (role?: Role) => boolean,
errorMessage: string = "您没有权限执行此操作"
): void {
if (!permissionCheck(role)) {
throw new Error(errorMessage)
}
}
/**
*
*/
export function getRoleDisplayName(role: Role): string {
const roleNames: Record<Role, string> = {
OWNER: "所有者",
EDITOR: "编辑者",
VIEWER: "查看者",
}
return roleNames[role] || role
}
/**
*
*/
export function getRoleDescription(role: Role): string {
const descriptions: Record<Role, string> = {
OWNER: "拥有全部权限,可以管理家族树和协作者",
EDITOR: "可以添加、编辑和删除成员,但不能删除家族树或管理协作者",
VIEWER: "只能查看、搜索和导出数据,不能进行任何修改操作",
}
return descriptions[role] || ""
}
/**
*
*/
export function getRolePermissions(role: Role): string[] {
const allPermissions = {
OWNER: [
"查看所有信息",
"搜索和筛选",
"导出和打印",
"添加成员",
"编辑成员",
"删除成员",
"导入数据",
"邀请协作者",
"移除协作者",
"删除家族树",
"清空数据",
],
EDITOR: [
"查看所有信息",
"搜索和筛选",
"导出和打印",
"添加成员",
"编辑成员",
"删除成员",
"导入数据",
],
VIEWER: [
"查看所有信息",
"搜索和筛选",
"导出和打印",
],
}
return allPermissions[role] || []
}