简介
权限管理是企业级应用中的核心模块之一,它确保系统中的不同用户能够访问和操作与其角色相匹配的资源。通过权限管理,系统可以实现对资源的精细控制,防止未授权访问和操作。本文将详细介绍一个基于Spring Boot的权限管理模块的实现过程,涵盖权限的增删改查、权限分配等功能,并详细介绍每个接口的访问路径、入参、出参以及具体实现。
代码结构
项目的主要代码结构如下:
- EntitlementController.java: 权限管理的控制器,负责处理HTTP请求。
- EntitlementService.java: 权限管理的服务接口,定义了权限管理的核心业务逻辑。
- EntitlementServiceImpl.java: 权限管理服务的具体实现类。
- SysEntitlement.java: 系统权限实体类,对应数据库中的权限表。
- SysRoleEntRela.java: 角色与权限的关联表实体类。
- SysEntitlementMapper.xml: MyBatis的Mapper文件,定义了权限相关的SQL操作。
功能实现解析
1. 权限管理功能
1.1 权限查询
接口路径: /api/entitlement/list
请求方法: GET
入参:
entId
(可选): 权限ID,用于精确查询。entName
(可选): 权限名称,用于模糊查询。stratPage
(可选): 起始页,默认为1。limit
(可选): 每页条数,默认为10。
出参:
current
: 当前页码。total
: 总条数。records
: 权限列表,包含权限ID、权限名称、菜单图标、菜单URI、组件名称等信息。hasNext
: 是否还有下一页。
具体实现:
-
参数校验:检查分页参数是否为空,如果为空则设置默认值。
if (ObjectUtil.isEmpty(stratPage)){ stratPage = 1; } if (ObjectUtil.isEmpty(limit)){ limit = 10; }
-
查询权限列表:调用
entitlementMapper.selectEntitlementList
方法,根据权限ID或权限名称进行模糊查询,并返回分页结果。List<SysEntitlement> records = entitlementMapper.selectEntitlementList(entId, entName, stratPage, limit);
-
返回结果:将查询结果封装到
EntitlementListDTO
对象中返回。EntitlementListDTO entitlementListDTO = new EntitlementListDTO(); entitlementListDTO.setCurrent(current); entitlementListDTO.setTotal(total); entitlementListDTO.setRecords(records); entitlementListDTO.setHasNext(hasNext); return ResSerialization.success(entitlementListDTO);
示例请求:
GET /api/entitlement/list?entName=admin&stratPage=1&limit=10
示例响应:
{
"current": 1,
"total": 5,
"records": [
{
"entId": "ENT_12345",
"entName": "admin",
"menuIcon": "icon-admin",
"menuUri": "/admin",
"componentName": "AdminComponent",
"createdAt": "2025-01-01 12:00:00",
"updatedAt": "2025-01-01 12:00:00"
}
],
"hasNext": false
}
1.2 权限创建
接口路径: /api/entitlement
请求方法: POST
入参:
entName
: 权限名称,必填。menuIcon
: 菜单图标,必填。menuUri
: 菜单URI,必填。componentName
: 组件名称,必填。entType
: 权限类型,必填。quickJump
: 快速开始菜单,必填。state
: 状态,必填。pid
: 父ID,必填。entSort
: 排序字段,必填。
出参:
code
: 响应码,200表示成功。message
: 响应消息。data
: 返回的数据,通常为空。
具体实现:
-
参数校验:检查权限名称、菜单图标、菜单URI、组件名称等是否为空,如果为空则抛出相应的异常。
if (ObjectUtil.isEmpty(entitlementCreateVO.getEntName())){ throw new QLException(ENT_NAME_NOT_NULL); } if (ObjectUtil.isEmpty(entitlementCreateVO.getMenuIcon())){ throw new QLException(MENU_ICON_NOT_NULL); } if (ObjectUtil.isEmpty(entitlementCreateVO.getMenuUri())){ throw new QLException(MENU_URI_NOT_NULL); } if (ObjectUtil.isEmpty(entitlementCreateVO.getComponentName())){ throw new QLException(COMPONENT_NAME_NOT_NULL); }
-
保存权限信息:将
EntitlementCreateVO
中的属性复制到SysEntitlement
对象中,并保存到权限表中。SysEntitlement sysEntitlement = BeanUtil.copyProperties(entitlementCreateVO, SysEntitlement.class); sysEntitlement.setEntId("ENT_" + IdUtil.fastSimpleUUID()); sysEntitlement.setCreatedAt(new Date()); sysEntitlement.setUpdatedAt(new Date()); OperationUtil.executeOperation(() -> this.save(sysEntitlement), ENTITLEMENT_SAVE_ERROR);
-
返回结果:返回创建操作的结果。
return ResSerialization.success();
示例请求:
POST /api/entitlement
Content-Type: application/json
{
"entName": "admin",
"menuIcon": "icon-admin",
"menuUri": "/admin",
"componentName": "AdminComponent",
"entType": "PB",
"quickJump": 1,
"state": 1,
"pid": "ENT_0",
"entSort": 1
}
示例响应:
{
"code": 200,
"message": "成功",
"data": null
}
1.3 权限更新
接口路径: /api/entitlement/{entId}
请求方法: PUT
入参:
entId
: 权限ID,路径参数。entName
: 权限名称,必填。menuIcon
: 菜单图标,必填。menuUri
: 菜单URI,必填。componentName
: 组件名称,必填。entType
: 权限类型,必填。quickJump
: 快速开始菜单,必填。state
: 状态,必填。pid
: 父ID,必填。entSort
: 排序字段,必填。
出参:
code
: 响应码,200表示成功。message
: 响应消息。data
: 返回的数据,通常为空。
具体实现:
-
参数校验:检查权限名称、菜单图标、菜单URI、组件名称等是否为空,如果为空则抛出相应的异常。
if (ObjectUtil.isEmpty(entitlementUpdateVO.getEntName())){ throw new QLException(ENT_NAME_NOT_NULL); } if (ObjectUtil.isEmpty(entitlementUpdateVO.getMenuIcon())){ throw new QLException(MENU_ICON_NOT_NULL); } if (ObjectUtil.isEmpty(entitlementUpdateVO.getMenuUri())){ throw new QLException(MENU_URI_NOT_NULL); } if (ObjectUtil.isEmpty(entitlementUpdateVO.getComponentName())){ throw new QLException(COMPONENT_NAME_NOT_NULL); }
-
更新权限信息:将
EntitlementUpdateVO
中的属性复制到SysEntitlement
对象中,并更新权限表。SysEntitlement sysEntitlement = BeanUtil.copyProperties(entitlementUpdateVO, SysEntitlement.class); sysEntitlement.setUpdatedAt(new Date()); OperationUtil.executeOperation(() -> this.updateById(sysEntitlement), ENTITLEMENT_UPDATE_ERROR);
-
返回结果:返回更新操作的结果。
return ResSerialization.success();
示例请求:
PUT /api/entitlement/ENT_12345
Content-Type: application/json
{
"entName": "admin",
"menuIcon": "icon-admin",
"menuUri": "/admin",
"componentName": "AdminComponent",
"entType": "PB",
"quickJump": 1,
"state": 1,
"pid": "ENT_0",
"entSort": 1
}
示例响应:
{
"code": 200,
"message": "成功",
"data": null
}
1.4 权限删除
接口路径: /api/entitlement/{entId}
请求方法: DELETE
入参:
entId
: 权限ID,路径参数。
出参:
code
: 响应码,200表示成功。message
: 响应消息。data
: 返回的数据,通常为空。
具体实现:
-
删除权限信息:根据权限ID删除权限表中的记录。
boolean isDelete = this.removeById(entId); if (!isDelete){ throw new QLException(ENTITLEMENT_REMOVE_ERROR); }
-
删除角色与权限的关联信息:删除角色与权限的关联表中的记录。
LambdaQueryWrapper<SysRoleEntRela> wrapper = new LambdaQueryWrapper<>(); wrapper.eq(SysRoleEntRela::getEntId, entId); sysRoleEntRelaMapper.delete(wrapper);
-
返回结果:返回删除操作的结果。
return ResSerialization.success();
示例请求:
DELETE /api/entitlement/ENT_12345
示例响应:
{
"code": 200,
"message": "成功",
"data": null
}
2. 权限控制
在EntitlementController
中,使用了SaCheckRole
注解进行权限控制。例如,创建权限和更新权限的操作需要特定的角色权限才能执行。通过StpUtil.getLoginIdAsLong()
方法获取当前登录用户的ID,并进行权限校验。
@SaCheckRole(value = {"admin", "super_admin"}, mode = SaMode.OR)
@PostMapping()
ResSerialization<String> createEntitlement(@RequestBody EntitlementCreateVO entitlementCreateVO){
// 创建权限逻辑
}
@SaCheckRole(value = {"admin", "super_admin"}, mode = SaMode.OR)
@PutMapping("/{entId}")
ResSerialization<String> updateEntitlement(@PathVariable String entId, @RequestBody EntitlementUpdateVO entitlementUpdateVO){
// 更新权限逻辑
}
总结
通过本文的详细解析,我们深入探讨了一个基于Spring Boot的权限管理模块的实现过程。该模块涵盖了权限的增删改查、权限分配等功能,并通过Sa-Token实现了权限控制。通过合理的代码结构和清晰的业务逻辑,确保了系统的高效性和可维护性。
希望本文的解析能够为开发者提供有价值的参考,帮助大家在实际项目中更好地设计和实现权限管理模块。如果你正在构建一个类似的系统,不妨借鉴本文的思路和代码实现,相信它会为你的项目带来更多的灵活性和稳定性。
让我们一起在代码的世界里,构建更加安全、高效的系统吧! 🚀