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
+265
View File
@@ -0,0 +1,265 @@
# 🔐 权限控制实施状态
## ✅ 已完成
### 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
**当前状态**: 🚧 进行中
**预计完成**: 今天晚上