Files
cattleTransportation/权限管理功能使用说明.md

569 lines
16 KiB
Markdown
Raw Normal View History

2025-10-13 17:19:47 +08:00
# 权限管理功能使用说明
## 📋 功能概述
本次开发完成了完整的权限管理系统,包括:
1. **菜单权限管理** - 管理系统菜单树和菜单项
2. **操作权限管理** - 为不同角色分配菜单和按钮操作权限
3. **超级管理员** - 15900000000 账号拥有所有权限
---
## 🗂️ 部署步骤
### 第一步:执行数据库初始化脚本
在数据库中执行 `权限管理功能初始化SQL.sql` 文件,该脚本会:
- ✅ 创建"权限管理"父菜单
- ✅ 创建"菜单权限管理"子菜单
- ✅ 创建"操作权限管理"子菜单
- ✅ 为这些菜单添加对应的按钮权限
- ✅ 创建或更新超级管理员角色ID=1
- ✅ 设置 15900000000 为超级管理员账号
- ✅ 为超级管理员分配所有菜单权限
- ✅ 为运送清单功能添加完整的权限点
**执行方式**
```sql
-- 在MySQL客户端或管理工具中执行
source /path/to/权限管理功能初始化SQL.sql;
-- 或直接复制粘贴SQL内容执行
```
### 第二步:重新编译并启动后端
```bash
# 进入后端项目根目录
cd c:\cattleTransport\tradeCattle
# 清理并编译安装所有模块
mvn clean install -DskipTests
# 进入业务模块
cd aiotagro-cattle-trade
# 启动后端服务
mvn spring-boot:run
# 或使用jar包启动
java -jar target/aiotagro-cattletrade-1.0.1.jar
```
**后端服务地址**`http://127.0.0.1:16200`
### 第三步:启动前端
```bash
# 进入前端项目目录
cd c:\cattleTransport\pc-cattle-transportation
# 安装依赖(首次或有新依赖时)
npm install
# 启动开发服务器
npm run dev
```
**前端访问地址**`http://localhost:8080`
---
## 👤 超级管理员账号
### 登录信息
- **账号**`15900000000`
- **密码**`123456` 如果是SQL脚本新创建的账号
- **角色**超级管理员roleId=1
- **权限**:拥有系统所有权限(*:*:*
### 特权说明
超级管理员具有以下特权:
1.**绕过所有权限检查** - 自动拥有所有操作权限
2.**查看所有数据** - 不受数据权限限制,可以看到所有用户创建的数据
3.**管理权限** - 可以为其他角色分配权限
4.**管理菜单** - 可以增删改菜单和按钮权限
---
## 🎯 功能使用指南
### 1. 菜单权限管理
**访问路径**:系统主菜单 → 权限管理 → 菜单权限管理
**功能列表**
-**查看菜单树** - 以树形结构展示所有系统菜单
-**新增菜单** - 添加新的菜单或按钮权限
-**编辑菜单** - 修改菜单信息
-**删除菜单** - 软删除菜单is_delete=1
**字段说明**
| 字段 | 说明 | 示例 |
|------|------|------|
| 菜单名称 | 显示在系统中的菜单名称 | 权限管理 |
| 菜单类型 | 1=菜单页面2=按钮(操作) | 1 |
| 路由地址 | 前端路由路径 | /permission/menu |
| 组件路径 | Vue组件路径 | permission/menuPermission |
| 权限标识 | 后端权限检查标识 | permission:menu:view |
| 图标 | Element Plus图标名称 | el-icon-lock |
| 排序 | 菜单显示顺序 | 1 |
**操作步骤**
1. 点击"新增菜单"按钮
2. 选择上级菜单(可选,默认为顶级菜单)
3. 选择菜单类型(菜单/按钮)
4. 填写必填信息:菜单名称、权限标识
5. 如果是菜单类型,还需填写路由地址和组件路径
6. 设置排序号
7. 点击"确定"保存
---
### 2. 操作权限管理
**访问路径**:系统主菜单 → 权限管理 → 操作权限管理
**功能列表**
-**角色管理** - 新增、编辑、删除角色
-**权限分配** - 为角色分配菜单和按钮权限
-**查看权限** - 查看角色当前拥有的权限
**左侧:角色列表**
- 显示所有系统角色
- 点击角色行可查看和编辑该角色的权限
- 可以新增、编辑、删除角色(超级管理员角色不可删除)
**右侧:权限树**
- 以树形结构显示所有菜单和按钮权限
- 勾选表示该角色拥有该权限
- 支持级联选择(选中父菜单会自动选中子项)
**操作步骤**
#### 新增角色
1. 点击左侧"新增角色"按钮
2. 输入角色名称和描述
3. 点击"确定"保存
#### 为角色分配权限
1. 在左侧角色列表中点击选中某个角色
2. 右侧会显示权限树
3. 勾选该角色需要的菜单和按钮权限
4. 点击右上角"保存权限"按钮
---
## 🔐 权限标识规范
系统采用统一的权限标识命名规范:`模块:资源:操作`
### 示例
| 权限标识 | 说明 | 对应功能 |
|---------|------|---------|
| `permission:menu:view` | 权限-菜单-查看 | 查看菜单权限管理页面 |
| `permission:menu:list` | 权限-菜单-列表 | 查询菜单列表 |
| `permission:menu:add` | 权限-菜单-新增 | 新增菜单 |
| `permission:menu:edit` | 权限-菜单-编辑 | 编辑菜单 |
| `permission:menu:delete` | 权限-菜单-删除 | 删除菜单 |
| `permission:menu:assign` | 权限-菜单-分配 | 分配菜单权限给角色 |
| `permission:operation:view` | 权限-操作-查看 | 查看操作权限管理页面 |
| `permission:operation:list` | 权限-操作-列表 | 查询角色和权限列表 |
| `permission:operation:assign` | 权限-操作-分配 | 分配操作权限 |
| `permission:operation:role` | 权限-操作-角色 | 管理角色(增删改) |
| `delivery:list` | 运送-清单-列表 | 查看运送清单列表 |
| `delivery:add` | 运送-清单-新增 | 新增运送清单 |
| `delivery:edit` | 运送-清单-编辑 | 编辑运送清单 |
| `delivery:delete` | 运送-清单-删除 | 删除运送清单 |
| `delivery:view` | 运送-清单-查看 | 查看运送清单详情 |
| `delivery:check` | 运送-清单-核验 | 核验运送清单 |
| `delivery:assign` | 运送-清单-分配 | 分配设备 |
| `delivery:load` | 运送-清单-装车 | 装车操作 |
| `*:*:*` | 所有权限 | 超级管理员特有 |
---
## 🔧 前端权限控制
### 按钮级权限指令
在前端使用 `v-hasPermi` 指令控制按钮的显示/隐藏:
```vue
<!-- 单个权限 -->
<el-button v-hasPermi="['delivery:add']" @click="handleAdd">
新增
</el-button>
<!-- 多个权限(满足其一即可) -->
<el-button v-hasPermi="['delivery:edit', 'delivery:view']" @click="handleEdit">
编辑
</el-button>
```
### 角色级权限指令
使用 `v-hasRole` 指令控制基于角色的显示:
```vue
<el-button v-hasRole="['admin']" @click="handleAdmin">
管理员功能
</el-button>
```
### 编程式权限判断
```javascript
import { useUserStore } from '@/store/user';
const userStore = useUserStore();
// 判断是否有某个权限
if (userStore.hasPermission('delivery:add')) {
// 有权限,执行操作
}
// 判断是否有某个角色
if (userStore.hasRole('admin')) {
// 有角色,执行操作
}
```
---
## 🛡️ 后端权限控制
### 接口级权限注解
在Controller方法上使用 `@SaCheckPermission` 注解:
```java
@RestController
@RequestMapping("/delivery")
public class DeliveryController {
// 单个权限
@SaCheckPermission("delivery:list")
@PostMapping("/pageQuery")
public PageResultResponse<Delivery> pageQuery(@RequestBody DeliveryQueryDto dto) {
// ...
}
// 多个权限(满足其一即可)
@SaCheckPermission(value = {"delivery:add", "delivery:create"}, mode = SaMode.OR)
@PostMapping("/create")
public AjaxResult create(@RequestBody DeliveryCreateDto dto) {
// ...
}
}
```
### 数据权限控制
使用 `DataScopeUtil` 工具类进行数据权限过滤:
```java
// 普通用户只能看自己创建的数据,超级管理员可以看所有数据
LambdaQueryWrapper<Delivery> wrapper = new LambdaQueryWrapper<>();
DataScopeUtil.applyDataScope(wrapper, Delivery::getCreatedBy);
List<Delivery> list = this.list(wrapper);
// 用户可以看到自己创建或自己核验的数据
LambdaQueryWrapper<Delivery> wrapper = new LambdaQueryWrapper<>();
DataScopeUtil.applyDataScopeWithChecker(wrapper, Delivery::getCreatedBy, Delivery::getCheckBy);
List<Delivery> list = this.list(wrapper);
```
### 编程式权限判断
```java
import com.aiotagro.common.core.utils.SecurityUtil;
// 判断是否超级管理员
if (SecurityUtil.isSuperAdmin()) {
// 是超级管理员,执行特殊逻辑
}
// 判断是否有某个权限
if (SecurityUtil.hasPermission("delivery:add")) {
// 有权限,执行操作
}
// 获取当前用户ID
Integer userId = SecurityUtil.getCurrentUserId();
// 获取当前用户角色ID
Integer roleId = SecurityUtil.getRoleId();
// 获取当前用户权限列表
List<String> permissions = SecurityUtil.getPermissions();
```
---
## 📊 数据库表结构
### sys_menu菜单表
| 字段 | 类型 | 说明 |
|------|------|------|
| id | int | 主键 |
| parent_id | int | 父菜单ID0=顶级菜单) |
| type | tinyint | 类型1=菜单2=按钮) |
| name | varchar | 菜单名称 |
| route_url | varchar | 路由地址 |
| page_url | varchar | 组件路径 |
| authority | varchar | 权限标识 |
| icon | varchar | 图标 |
| sort | int | 排序 |
| is_delete | tinyint | 是否删除0=否1=是) |
| create_time | datetime | 创建时间 |
| update_time | datetime | 更新时间 |
### sys_role角色表
| 字段 | 类型 | 说明 |
|------|------|------|
| id | int | 主键 |
| name | varchar | 角色名称 |
| description | varchar | 角色描述 |
| is_delete | tinyint | 是否删除0=否1=是) |
| create_time | datetime | 创建时间 |
| update_time | datetime | 更新时间 |
### sys_role_menu角色菜单关联表
| 字段 | 类型 | 说明 |
|------|------|------|
| id | int | 主键 |
| role_id | int | 角色ID |
| menu_id | int | 菜单ID |
### sys_user用户表
| 字段 | 类型 | 说明 |
|------|------|------|
| id | int | 主键 |
| mobile | varchar | 手机号 |
| name | varchar | 用户名 |
| password | varchar | 密码MD5加密 |
| role_id | int | 角色ID |
| user_type | int | 用户类型 |
| status | tinyint | 状态1=启用) |
| is_delete | tinyint | 是否删除 |
| create_time | datetime | 创建时间 |
---
## 🧪 测试指南
### 1. 超级管理员测试
**登录账号**15900000000 / 123456
**验证点**
- ✅ 登录成功后,所有菜单都可见
- ✅ 所有按钮都可见不受v-hasPermi限制
- ✅ 可以查看所有用户创建的数据
- ✅ 可以进入权限管理模块
- ✅ 可以新增、编辑、删除菜单
- ✅ 可以新增、编辑、删除角色
- ✅ 可以为角色分配权限
### 2. 普通角色测试
**步骤**
1. 使用超级管理员登录
2. 进入"操作权限管理"
3. 新增一个测试角色(如"运输管理员"
4. 为该角色分配部分权限(如只分配运送清单相关权限)
5. 在用户管理中创建或修改一个测试用户,指定其角色为"运输管理员"
6. 退出超级管理员,使用测试用户登录
**验证点**
- ✅ 登录后只能看到被分配的菜单
- ✅ 只能看到被分配的按钮其他按钮被v-hasPermi隐藏
- ✅ 只能看到自己创建的数据(数据权限)
- ✅ 无权限的操作会被后端拦截返回403
### 3. 权限管理功能测试
#### 菜单权限管理
1. 进入"菜单权限管理"页面
2. 测试新增一个测试菜单
3. 测试编辑菜单信息
4. 测试删除菜单(软删除)
5. 验证菜单树的显示是否正确
#### 操作权限管理
1. 进入"操作权限管理"页面
2. 左侧新增一个测试角色
3. 点击该角色,右侧显示权限树
4. 勾选部分菜单和按钮权限
5. 点击"保存权限"
6. 刷新页面,验证权限是否保存成功
7. 测试编辑和删除角色
---
## ❗ 常见问题
### Q1: 执行SQL脚本后菜单没有出现
**解决方案**
1. 检查SQL脚本是否执行成功查看数据库是否有数据
2. 检查用户的角色是否被分配了相应菜单权限
3. 退出重新登录,刷新权限缓存
### Q2: 按钮被v-hasPermi隐藏了但我应该有权限
**解决方案**
1. 检查登录接口返回的permissions字段是否包含该权限
2. 检查Pinia store中是否正确保存了permissions
3. 退出重新登录,刷新权限
4. 如果是超级管理员检查permissions是否包含"*:*:*"
### Q3: 后端接口返回403提示无权限
**解决方案**
1. 检查Controller方法上的@SaCheckPermission注解
2. 检查用户的角色是否被分配了该权限
3. 检查Sa-Token配置是否正确
4. 查看后端日志,确认权限检查的详细信息
### Q4: 超级管理员看不到其他用户的数据?
**解决方案**
1. 检查Service层是否正确使用了DataScopeUtil
2. 检查SecurityUtil.isSuperAdmin()方法是否正确判断
3. 检查用户的roleId是否为1
### Q5: 菜单树显示不正常,层级错乱?
**解决方案**
1. 检查sys_menu表的parent_id字段是否正确
2. 检查sort字段调整排序
3. 检查is_delete字段确认菜单未被软删除
---
## 📝 开发文档
### 新增模块权限的步骤
如果要为一个新功能模块添加权限控制:
#### 1. 数据库添加菜单和权限
```sql
-- 添加父菜单
INSERT INTO `sys_menu` (`parent_id`, `type`, `name`, `route_url`, `page_url`, `authority`, `icon`, `sort`, `is_delete`, `create_time`)
VALUES (0, 1, '新模块', '/newmodule', null, 'newmodule:view', 'el-icon-setting', 30, 0, NOW());
SET @parent_id = LAST_INSERT_ID();
-- 添加子菜单
INSERT INTO `sys_menu` (`parent_id`, `type`, `name`, `route_url`, `page_url`, `authority`, `icon`, `sort`, `is_delete`, `create_time`)
VALUES (@parent_id, 1, '功能页面', '/newmodule/function', 'newmodule/function', 'newmodule:function:view', null, 1, 0, NOW());
SET @function_id = LAST_INSERT_ID();
-- 添加按钮权限
INSERT INTO `sys_menu` (`parent_id`, `type`, `name`, `authority`, `sort`, `is_delete`, `create_time`) VALUES
(@function_id, 2, '新增', 'newmodule:function:add', 1, 0, NOW()),
(@function_id, 2, '编辑', 'newmodule:function:edit', 2, 0, NOW()),
(@function_id, 2, '删除', 'newmodule:function:delete', 3, 0, NOW());
-- 为超级管理员分配新权限
INSERT INTO `sys_role_menu` (`role_id`, `menu_id`)
SELECT 1, id FROM `sys_menu` WHERE `authority` LIKE 'newmodule:%' AND `is_delete` = 0;
```
#### 2. 后端Controller添加权限注解
```java
@RestController
@RequestMapping("/newmodule")
public class NewModuleController {
@SaCheckPermission("newmodule:function:list")
@PostMapping("/list")
public AjaxResult list(@RequestBody QueryDto dto) {
// ...
}
@SaCheckPermission("newmodule:function:add")
@PostMapping("/add")
public AjaxResult add(@RequestBody AddDto dto) {
// ...
}
}
```
#### 3. 前端按钮添加权限指令
```vue
<el-button v-hasPermi="['newmodule:function:add']" @click="handleAdd">
新增
</el-button>
```
---
## 🎉 功能清单
本次开发完成的文件清单:
### 后端文件
-`RoleConstants.java` - 角色常量类
-`SecurityUtil.java` - 安全工具类(扩展)
-`DataScopeUtil.java` - 数据权限工具类
-`SysMenuController.java` - 菜单权限管理Controller
-`SysRoleController.java` - 角色管理Controller扩展
-`LoginServiceImpl.java` - 登录Service扩展存储权限信息
-`DeliveryController.java` - 运送清单Controller添加权限注解
-`DeliveryServiceImpl.java` - 运送清单Service添加数据权限
-`DeliveryCreateDto.java` - 运送清单创建DTO
### 前端文件
-`permission.js` - 权限管理API接口
-`menuPermission.vue` - 菜单权限管理页面
-`operationPermission.vue` - 操作权限管理页面
-`createDeliveryDialog.vue` - 新增运送清单对话框
-`user.ts` - 用户Store扩展添加权限判断
-`login.vue` - 登录页(扩展,保存权限)
-`loadingOrder.vue` - 运送清单列表(添加权限控制)
-`shipping.js` - 运送清单API扩展
### 数据库文件
-`权限管理功能初始化SQL.sql` - 数据库初始化脚本
### 文档文件
-`权限管理和运送清单新增功能实施计划.md` - 实施计划文档
-`权限管理功能使用说明.md` - 本使用说明文档
---
## 📞 技术支持
如有问题,请检查:
1. 后端日志:查看权限验证相关错误
2. 浏览器控制台:查看前端请求和权限判断
3. 数据库数据:确认菜单、角色、权限数据是否正确
4. Sa-Token文档https://sa-token.cc/
---
**祝使用愉快!** 🎊