Become a sponsor

概述
角色管理是 RBAC 权限体系的核心,通过角色关联菜单实现权限分配。
| 特性 | 说明 |
|---|---|
| 基类 | BaseLogic(系统共享,不隔离) |
| 关联 | 与 Menu 多对多(通过 RoleMenu 中间表) |
| 数据权限 | data_scope 字段控制(1=全部 2=本部门 3=仅本人) |
系统内置三套租户角色模板,用于按套餐等级快速授权:
| 角色名称 | 定位 | 菜单范围 |
|---|---|---|
| 租户-标准版 | 基础功能 | 核心业务模块 |
| 租户-专业版 | 进阶功能 | 核心 + 高级模块 |
| 租户-旗舰版 | 全功能 | 全部菜单(最全) |
创建租户后,通过「角色管理 → 授权菜单」为对应角色分配菜单权限。详见 租户管理。
| 方法 | 路径 | 权限码 | 说明 |
|---|---|---|---|
| GET | /api/role/page | sys:role:page | 分页列表 |
| GET | /api/role/list | sys:role:list | 全量列表 |
| GET | /api/role/detail/:id | sys:role:detail | 详情 |
| POST | /api/role/add | sys:role:add | 新增 |
| PUT | /api/role/update | sys:role:update | 修改 |
| DELETE | /api/role/delete/:id | sys:role:delete | 删除 |
| DELETE | /api/role/batchDelete | sys:role:batchDelete | 批量删除 |
| GET | /api/role/menu/list/:id | - | 获取角色菜单 |
| POST | /api/role/menu/save | sys:role:authorize | 保存角色菜单 |
// app/logic/RoleLogic.php
/**
* 保存角色菜单关联(事务保护)
*
* 处理流程:
* 1. 开启事务
* 2. 先删除该角色原有的全部菜单关联(全量覆盖式保存)
* 3. 遍历新菜单 ID,组装关联记录
* 4. 批量写入关联记录
* 5. 提交事务
*/
public function saveMenus(int $roleId, array $menuIds): bool
{
Db::startTrans();
try {
RoleMenu::where('role_id', $roleId)->delete();
$data = [];
foreach ($menuIds as $menuId) {
$data[] = [
'role_id' => $roleId,
'menu_id' => $menuId,
'create_user' => request()->userInfo->username ?? '',
'create_time' => date('Y-m-d H:i:s'),
];
}
if (!empty($data)) {
(new RoleMenu())->saveAll($data);
}
Db::commit();
return true;
} catch (\Exception $e) {
Db::rollback();
throw $e;
}
}// app/controller/RoleController.php
class RoleController extends BaseController
{
protected RoleLogic $logic;
protected function initialize(): void
{
$this->logic = new RoleLogic();
}
#[Log('角色管理-查询分页记录', Log::TYPE_QUERY)]
#[Permission('sys:role:page', '角色分页')]
public function page(): Json
{
return parent::_index($this->logic);
}
#[Log('角色管理-查询全量列表', Log::TYPE_QUERY)]
public function list(): Json
{
return parent::_list($this->logic);
}
#[Log('角色管理-查询详情', Log::TYPE_QUERY, '查询角色ID:{id}')]
public function detail(int $id): Json
{
return parent::_detail($this->logic, $id);
}
#[Log('角色管理-新增记录', Log::TYPE_ADD, '新增角色:{name}')]
#[Permission('sys:role:add', '添加角色')]
public function add(): Json
{
return parent::_add($this->logic, $this->getJsonBody());
}
#[Log('角色管理-修改记录', Log::TYPE_UPDATE, '修改角色ID:{id}')]
#[Permission('sys:role:update', '修改角色')]
public function update(): Json
{
$data = $this->getJsonBody();
$id = $data['id'] ?? 0;
if (empty($id)) {
return $this->fail('缺少id参数');
}
return parent::_edit($this->logic, $id, $data);
}
#[Log('角色管理-删除记录', Log::TYPE_DELETE, '删除角色ID:{id}')]
#[Permission('sys:role:delete', '删除角色')]
public function delete(int $id): Json
{
return parent::_remove($this->logic, $id);
}
#[Log('角色管理-批量删除记录', Log::TYPE_DELETE)]
#[Permission('sys:role:delete', '删除角色')]
public function batchDelete(): Json
{
$ids = $this->getJsonBody()['ids'] ?? [];
return parent::_batchRemove($this->logic, $ids);
}
// 获取角色菜单(带选中状态)
#[Log('角色管理-查询菜单权限', Log::TYPE_QUERY, '查询角色ID:{id}的菜单权限')]
public function menuList(int $id): Json
{
$result = $this->logic->getMenuListWithChecked($id);
return $this->success($result);
}
// 保存角色菜单
#[Log('角色管理-保存菜单权限', Log::TYPE_AUTHORIZE, '保存角色ID:{roleId}的菜单权限')]
#[Permission('sys:role:authorize', '授权角色菜单')]
public function menuSave(): Json
{
$data = $this->getJsonBody();
$roleId = $data['roleId'] ?? 0;
$menuIds = $data['menuIds'] ?? [];
if (empty($roleId)) {
return $this->fail('缺少roleId参数');
}
try {
$this->logic->saveMenus($roleId, $menuIds);
return $this->success(null, '保存成功');
} catch (\Exception $e) {
return $this->fail($e->getMessage());
}
}
}权限生效
权限分配后,拥有该角色的用户需重新登录才能获取最新权限。权限变更时相关缓存会自动失效。