library-picturebook-activity/frontend/PERMISSION_USAGE.md
aid 418aa57ea8 Day4: 超管端设计优化 + UGC绘本创作社区P0实现
一、超管端设计优化
- 文档管理SOP体系建立,docs目录重组
- 统一用户管理:跨租户全局视角,合并用户管理+公众用户
- 活动监管全模块重构:全部活动(统计卡片+阶段筛选+SuperDetail详情页)、报名数据/作品数据/评审进度(两层合一扁平列表)、成果发布(去Tab+统计+隐藏写操作)
- 菜单精简:移除评委管理/评审规则/通知管理
- Bug修复:租户编辑丢失隐藏菜单、pageSize限制、主色统一

二、UGC绘本创作社区P0
- 数据库:10张新表(user_works/user_work_pages/work_tags等)
- 子女账号独立化:Child升级为独立User,家长切换+独立登录
- 用户作品库:CRUD+发布审核,8个API
- AI创作流程:提交→生成→保存到作品库,4个API
- 作品广场:首页改造为推荐流,标签+搜索+排序
- 内容审核(超管端):作品审核+作品管理+标签管理
- 活动联动:WorkSelector作品选择器
- 布局改造:底部5Tab(发现/创作/活动/作品库/我的)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 22:20:25 +08:00

379 lines
8.3 KiB
Markdown
Raw Permalink 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. **认证状态判断**
- **之前**: `isAuthenticated = !!token && !!user`(刷新页面时 user 为 null 导致判断失败)
- **现在**: `isAuthenticated = !!token`(只要有 token 就认为已认证)
### 2. **自动获取用户信息**
- **之前**: 刷新页面后用户信息丢失
- **现在**:
- 应用启动时自动获取(`main.ts`
- 路由守卫中自动获取(如果 token 存在但 user 不存在)
### 3. **权限检查**
- **之前**: 只检查 `requiresAuth`,没有角色和权限检查
- **现在**: 支持角色和权限检查
## 🎯 使用方法
### 1. 在路由中配置权限
#### 使用角色控制
```typescript
{
path: "users",
name: "SystemUsers",
component: () => import("@/views/system/users/Index.vue"),
meta: {
title: "用户管理",
requiresAuth: true,
roles: ["super_admin", "admin"], // 需要 super_admin 或 admin 角色
},
}
```
#### 使用权限控制
```typescript
{
path: "users",
name: "SystemUsers",
component: () => import("@/views/system/users/Index.vue"),
meta: {
title: "用户管理",
requiresAuth: true,
permissions: ["user:read"], // 需要 user:read 权限
},
}
```
#### 同时使用角色和权限
```typescript
{
path: "users",
name: "SystemUsers",
component: () => import("@/views/system/users/Index.vue"),
meta: {
title: "用户管理",
requiresAuth: true,
roles: ["admin"], // 需要 admin 角色
permissions: ["user:read"], // 并且需要 user:read 权限
},
}
```
**注意**: 如果同时设置了 `roles``permissions`,需要**同时满足**两者。
### 2. 在组件中使用权限
```vue
<template>
<div>
<!-- 根据角色显示 -->
<a-button v-if="authStore.hasRole('super_admin')" @click="deleteAll">
删除所有
</a-button>
<!-- 根据权限显示 -->
<a-button v-if="authStore.hasPermission('user:create')" @click="createUser">
创建用户
</a-button>
<!-- 检查多个角色 -->
<a-button
v-if="authStore.hasAnyRole(['admin', 'editor'])"
@click="editUser"
>
编辑用户
</a-button>
<!-- 检查多个权限 -->
<a-button
v-if="authStore.hasAnyPermission(['user:update', 'user:delete'])"
@click="manageUser"
>
管理用户
</a-button>
</div>
</template>
<script setup lang="ts">
import { useAuthStore } from "@/stores/auth";
const authStore = useAuthStore();
</script>
```
### 3. Store 方法说明
#### `hasRole(role: string): boolean`
检查用户是否有指定角色
```typescript
if (authStore.hasRole("super_admin")) {
// 用户是超级管理员
}
```
#### `hasPermission(permission: string): boolean`
检查用户是否有指定权限
```typescript
if (authStore.hasPermission("user:create")) {
// 用户可以创建用户
}
```
#### `hasAnyRole(roles: string[]): boolean`
检查用户是否有任一指定角色
```typescript
if (authStore.hasAnyRole(["admin", "editor"])) {
// 用户是 admin 或 editor
}
```
#### `hasAnyPermission(permissions: string[]): boolean`
检查用户是否有任一指定权限
```typescript
if (authStore.hasAnyPermission(["user:create", "user:update"])) {
// 用户可以创建或更新用户
}
```
## 🔄 工作流程
### 1. 应用启动流程
```
应用启动
检查 localStorage 中是否有 token
如果有 token调用 fetchUserInfo() 获取用户信息
用户信息包含 roles 和 permissions
应用挂载完成
```
### 2. 路由导航流程
```
用户访问路由
路由守卫 beforeEach
检查 token 是否存在
如果 token 存在但 user 不存在 → 自动获取用户信息
检查 requiresAuth → 是否需要登录
检查 roles → 是否有指定角色
检查 permissions → 是否有指定权限
允许/拒绝访问
```
### 3. 登录流程
```
用户登录
调用 authApi.login()
返回 token 和 user 信息(包含 roles 和 permissions
保存 token 到 localStorage
保存 user 到 store
跳转到目标页面
```
## 📝 路由配置示例
### 完整的路由配置示例
```typescript
const routes: RouteRecordRaw[] = [
{
path: "/login",
name: "Login",
component: () => import("@/views/auth/Login.vue"),
meta: { requiresAuth: false },
},
{
path: "/",
component: () => import("@/layouts/BasicLayout.vue"),
redirect: "/workbench",
meta: { requiresAuth: true },
children: [
{
path: "workbench",
name: "workbench",
component: () => import("@/views/workbench/Index.vue"),
meta: {
title: "仪表盘",
requiresAuth: true,
},
},
{
path: "system/users",
name: "SystemUsers",
component: () => import("@/views/system/users/Index.vue"),
meta: {
title: "用户管理",
requiresAuth: true,
permissions: ["user:read"], // 需要查看用户权限
},
},
{
path: "system/roles",
name: "SystemRoles",
component: () => import("@/views/system/roles/Index.vue"),
meta: {
title: "角色管理",
requiresAuth: true,
roles: ["super_admin", "admin"], // 需要管理员角色
},
},
],
},
];
```
## 🎨 实际应用场景
### 场景 1: 根据权限显示菜单
```vue
<template>
<a-menu>
<a-menu-item v-if="authStore.hasPermission('user:read')">
<router-link to="/system/users">用户管理</router-link>
</a-menu-item>
<a-menu-item v-if="authStore.hasRole('admin')">
<router-link to="/system/roles">角色管理</router-link>
</a-menu-item>
</a-menu>
</template>
```
### 场景 2: 根据权限显示按钮
```vue
<template>
<a-table>
<template #action="{ record }">
<a-space>
<a-button
v-if="authStore.hasPermission('user:update')"
@click="edit(record)"
>
编辑
</a-button>
<a-button
v-if="authStore.hasPermission('user:delete')"
danger
@click="remove(record)"
>
删除
</a-button>
</a-space>
</template>
</a-table>
</template>
```
### 场景 3: 组合权限检查
```vue
<template>
<!-- 需要同时满足角色和权限 -->
<a-button
v-if="authStore.hasRole('admin') && authStore.hasPermission('user:delete')"
@click="deleteAll"
>
批量删除
</a-button>
</template>
```
## ⚠️ 注意事项
### 1. 路由守卫是异步的
路由守卫使用了 `async/await`,确保在检查权限前用户信息已加载。
### 2. 权限检查顺序
1. 认证检查(`requiresAuth`
2. 角色检查(`roles`
3. 权限检查(`permissions`
### 3. 403 页面
如果没有权限,会跳转到 `/403` 页面。你可以自定义这个页面。
### 4. 权限更新
如果用户权限发生变化,需要:
- 重新登录,或
- 调用 `authStore.fetchUserInfo()` 刷新用户信息
## 🔍 调试技巧
### 1. 查看当前用户信息
```typescript
import { useAuthStore } from "@/stores/auth";
const authStore = useAuthStore();
console.log("用户信息:", authStore.user);
console.log("角色:", authStore.user?.roles);
console.log("权限:", authStore.user?.permissions);
```
### 2. 检查权限
```typescript
console.log("是否有 admin 角色:", authStore.hasRole("admin"));
console.log("是否有 user:create 权限:", authStore.hasPermission("user:create"));
```
## 📚 总结
现在权限控制系统已经完善:
1.**自动获取用户信息** - 刷新页面不会丢失
2.**路由权限检查** - 支持角色和权限控制
3.**组件权限检查** - 可以在组件中使用权限方法
4.**类型安全** - TypeScript 类型定义完善
可以开始使用权限控制功能了!