Files
cattleTransportation/权限管理功能使用说明.md
2025-10-13 17:19:47 +08:00

16 KiB
Raw Blame History

权限管理功能使用说明

📋 功能概述

本次开发完成了完整的权限管理系统,包括:

  1. 菜单权限管理 - 管理系统菜单树和菜单项
  2. 操作权限管理 - 为不同角色分配菜单和按钮操作权限
  3. 超级管理员 - 15900000000 账号拥有所有权限

🗂️ 部署步骤

第一步:执行数据库初始化脚本

在数据库中执行 权限管理功能初始化SQL.sql 文件,该脚本会:

  • 创建"权限管理"父菜单
  • 创建"菜单权限管理"子菜单
  • 创建"操作权限管理"子菜单
  • 为这些菜单添加对应的按钮权限
  • 创建或更新超级管理员角色ID=1
  • 设置 15900000000 为超级管理员账号
  • 为超级管理员分配所有菜单权限
  • 为运送清单功能添加完整的权限点

执行方式

-- 在MySQL客户端或管理工具中执行
source /path/to/权限管理功能初始化SQL.sql;
-- 或直接复制粘贴SQL内容执行

第二步:重新编译并启动后端

# 进入后端项目根目录
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

第三步:启动前端

# 进入前端项目目录
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 指令控制按钮的显示/隐藏:

<!-- 单个权限 -->
<el-button v-hasPermi="['delivery:add']" @click="handleAdd">
    新增
</el-button>

<!-- 多个权限满足其一即可 -->
<el-button v-hasPermi="['delivery:edit', 'delivery:view']" @click="handleEdit">
    编辑
</el-button>

角色级权限指令

使用 v-hasRole 指令控制基于角色的显示:

<el-button v-hasRole="['admin']" @click="handleAdmin">
    管理员功能
</el-button>

编程式权限判断

import { useUserStore } from '@/store/user';

const userStore = useUserStore();

// 判断是否有某个权限
if (userStore.hasPermission('delivery:add')) {
    // 有权限,执行操作
}

// 判断是否有某个角色
if (userStore.hasRole('admin')) {
    // 有角色,执行操作
}

🛡️ 后端权限控制

接口级权限注解

在Controller方法上使用 @SaCheckPermission 注解:

@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 工具类进行数据权限过滤:

// 普通用户只能看自己创建的数据,超级管理员可以看所有数据
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);

编程式权限判断

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. 数据库添加菜单和权限

-- 添加父菜单
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添加权限注解

@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. 前端按钮添加权限指令

<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/

祝使用愉快! 🎊