0.0.8.0
This commit is contained in:
+1
-1
@@ -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
@@ -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
@@ -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
@@ -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] || []
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user