Files
chinese-family-tree-2/PERMISSION_IMPLEMENTATION_STATUS.md
T
freedakgmail e44dd0bd95 0.0.8.0
2025-11-23 18:03:04 +08:00

266 lines
6.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 🔐 权限控制实施状态
## ✅ 已完成
### 1. 核心权限系统
-**权限工具函数** (`lib/permissions.ts`)
- 创建 `permissions` 对象,包含所有权限检查函数
- 添加辅助函数:`getRoleDisplayName``getRoleDescription``getRolePermissions`
- 修复类型冲突,使用 `PrismaRole` 和导出的 `Role` 类型
- 添加完整的中文注释和文档
### 2. 页面权限控制
-**首页** (`app/page.tsx`)
- 导入 `permissions`
- "添加成员"按钮使用 `permissions.canCreate(role)`
-**成员列表页** (`app/members/page.tsx`)
- 导入 `permissions``currentTree`
- "新增成员"按钮使用 `permissions.canCreate(role)`
- 筛选和搜索功能对所有人可见
---
## 🚧 待实施
### 高优先级(今天完成)
#### 1. 成员详情页 (`app/members/[id]/page.tsx`)
需要更新的按钮:
```tsx
// 快速添加按钮
{permissions.canCreate(role) && (
<>
{!member.fatherId && <Button onClick={handleAddFather}></Button>}
{!member.motherId && <Button onClick={handleAddMother}></Button>}
<Button onClick={handleAddChild}></Button>
<Button onClick={handleAddSpouse}></Button>
</>
)}
// 编辑删除按钮
{permissions.canUpdate(role) && (
<Button onClick={() => setIsEditing(true)}></Button>
)}
{permissions.canDeleteMember(role) && (
<Button variant="destructive" onClick={handleDelete}></Button>
)}
```
#### 2. 系统设置页 (`app/settings/page.tsx`)
需要更新的按钮:
```tsx
// 导入导出
{permissions.canImport(role) && (
<>
<Button onClick={handleImportData}></Button>
<Button onClick={handleImportGEDCOM}>GEDCOM</Button>
</>
)}
{permissions.canExport(role) && (
<>
<Button onClick={handleExportData}></Button>
<Button onClick={handleExportGEDCOM}>GEDCOM</Button>
</>
)}
// 清空操作(仅 OWNER
{permissions.canClearData(role) && (
<>
<Button variant="destructive" onClick={handleClearData}></Button>
<Button variant="destructive" onClick={handleClearLogs}></Button>
</>
)}
```
#### 3. 全局导航 (`components/site-header.tsx`)
需要更新的按钮:
```tsx
// 删除家族树(仅 OWNER
{permissions.canDeleteTree(role) && (
<DropdownMenuItem onClick={handleDeleteTree}>
<Trash2 className="mr-2 h-4 w-4" />
</DropdownMenuItem>
)}
// 创建家族树
{permissions.canCreateTree(role) && (
<DropdownMenuItem onClick={() => router.push('/trees/new')}>
<Plus className="mr-2 h-4 w-4" />
</DropdownMenuItem>
)}
```
### 中优先级(本周完成)
#### 4. 新增成员页 (`app/members/new/page.tsx`)
需要添加页面级权限检查:
```tsx
export default function NewMemberPage() {
const { currentTree } = useFamily()
const router = useRouter()
// 权限检查
useEffect(() => {
if (!permissions.canCreate(currentTree?.currentUserRole)) {
router.push('/members')
toast.error('您没有权限添加成员')
}
}, [currentTree?.currentUserRole])
// ... 其他代码
}
```
#### 5. 族谱图页 (`app/tree/page.tsx`)
所有按钮都是查看功能,无需特殊权限控制。
#### 6. 关系计算页 (`app/relationship/page.tsx`)
所有按钮都是查询功能,无需特殊权限控制。
#### 7. 大事记页 (`app/timeline/page.tsx`)
所有按钮都是查看功能,无需特殊权限控制。
### 低优先级(下周完成)
#### 8. API 层面权限验证
需要在以下 API 路由中添加权限检查:
```typescript
// app/api/trees/[treeId]/members/route.ts
export async function POST(request: Request, { params }: { params: Promise<{ treeId: string }> }) {
const session = await getServerSession(authOptions)
const { treeId } = await params
// 权限检查
const { hasPermission } = await checkPermission(
session.user.id,
treeId,
PrismaRole.EDITOR
)
if (!hasPermission) {
return NextResponse.json({ error: "权限不足" }, { status: 403 })
}
// ... 执行操作
}
```
需要添加权限检查的 API
-`/api/trees/[treeId]/members` POST - EDITOR
-`/api/trees/[treeId]/members/[memberId]` PATCH - EDITOR
-`/api/trees/[treeId]/members/[memberId]` DELETE - EDITOR
-`/api/trees/[treeId]` DELETE - OWNER
-`/api/trees/[treeId]/invite` POST - OWNER
-`/api/trees/[treeId]/collaborators/[collaboratorId]` DELETE - OWNER
-`/api/trees/[treeId]/import` POST - EDITOR
---
## 📊 进度统计
### 页面进度
- ✅ 完成: 2/11 (18%)
- 🚧 进行中: 0/11 (0%)
- ⏳ 待开始: 9/11 (82%)
### 按钮进度
- ✅ 完成: 3/80+ (4%)
- ⏳ 待更新: 77/80+ (96%)
### API 进度
- ⏳ 待开始: 0/7 (0%)
---
## 🎯 下一步行动
### 立即执行(接下来 30 分钟)
1. 更新成员详情页的所有按钮
2. 更新系统设置页的所有按钮
3. 测试 OWNER 和 EDITOR 的按钮显示
### 今天完成
4. 更新全局导航的按钮
5. 添加新增成员页的权限检查
6. 测试 VIEWER 的按钮显示
### 本周完成
7. 添加所有 API 的权限验证
8. 完整测试三种角色
9. 添加错误提示和处理
---
## 💻 代码示例
### 标准实施模式
```tsx
// 1. 导入权限函数
import { permissions } from "@/lib/permissions"
// 2. 获取当前角色
const { currentTree } = useFamily()
const role = currentTree?.currentUserRole
// 3. 条件渲染按钮
{permissions.canCreate(role) && (
<Button onClick={handleAdd}></Button>
)}
{permissions.canUpdate(role) && (
<Button onClick={handleEdit}></Button>
)}
{permissions.canDeleteMember(role) && (
<Button variant="destructive" onClick={handleDelete}></Button>
)}
{permissions.canDeleteTree(role) && (
<Button variant="destructive" onClick={handleDeleteTree}></Button>
)}
{permissions.canManageCollaborators(role) && (
<Button onClick={handleInvite}></Button>
)}
```
---
## 📝 注意事项
### 实施时注意
1. ✅ 所有页面都要导入 `permissions`
2. ✅ 所有页面都要获取 `currentTree``role`
3. ✅ 使用条件渲染而不是禁用状态(更好的用户体验)
4. ⚠️ 不要忘记 API 层面的权限验证
5. ⚠️ 测试所有三种角色的显示效果
### 测试检查清单
- [ ] OWNER 可以看到所有按钮
- [ ] EDITOR 看不到管理类按钮
- [ ] VIEWER 只能看到查看类按钮
- [ ] 无权限操作时有友好提示
- [ ] API 返回正确的错误码
---
## 🔗 相关文档
- [权限分类清单](./docs/BUTTON_PERMISSIONS.md)
- [快速参考](./PERMISSIONS_QUICK_REFERENCE.md)
- [实施计划](./PERMISSION_IMPLEMENTATION_PLAN.md)
- [按钮梳理](./BUTTONS_SUMMARY.md)
---
**最后更新**: 2025-11-23 17:35
**当前状态**: 🚧 进行中
**预计完成**: 今天晚上