diff --git a/src/plugin/admin/app/common/Tree.php b/src/plugin/admin/app/common/Tree.php index 7191024..56707fd 100644 --- a/src/plugin/admin/app/common/Tree.php +++ b/src/plugin/admin/app/common/Tree.php @@ -4,6 +4,17 @@ namespace plugin\admin\app\common; class Tree { + + /** + * 获取完整的树结构,包含祖先节点 + */ + const INCLUDE_ANCESTORS = 0; + + /** + * 获取部分树,不包含祖先节点 + */ + const EXCLUDE_ANCESTORS = 1; + /** * 数据 * @var array @@ -89,10 +100,24 @@ class Tree /** * 获取树 * @param array $include + * @param int $type * @return array|null */ - public function getTree(array $include = []): ?array + public function getTree(array $include = [], int $type = 0): ?array { + if ($type === static::EXCLUDE_ANCESTORS) { + $items = []; + $include = array_unique($include); + foreach ($include as $id) { + if (!isset($this->hashTree[$id])) { + return []; + } + $items[] = $this->hashTree[$id]; + } + return static::arrayValues($items); + } + + // $type === static::INCLUDE_ANCESTORS $hash_tree = $this->hashTree; $items = []; if ($include) { @@ -120,7 +145,7 @@ class Tree } $formatted_items = []; foreach ($items as $item) { - if (!$item[$this->pidName]) { + if (!$item[$this->pidName] || !isset($hash_tree[$item[$this->pidName]])) { $formatted_items[] = $item; } } diff --git a/src/plugin/admin/app/controller/Crud.php b/src/plugin/admin/app/controller/Crud.php index 7b77841..cefff89 100644 --- a/src/plugin/admin/app/controller/Crud.php +++ b/src/plugin/admin/app/controller/Crud.php @@ -147,6 +147,7 @@ class Crud extends Base } /** + * 格式化数据 * @param $query * @param $format * @param $limit @@ -335,9 +336,11 @@ class Crud extends Base /** * 格式化树 * @param $items + * @param array $include + * @param int $type * @return Response */ - protected function formatTree($items, array $include = []): Response + protected function formatTree($items, array $include = [], int $type = 0): Response { $items_map = []; foreach ($items as $item) { @@ -349,7 +352,7 @@ class Crud extends Base ]; } $tree = new Tree($items_map); - return $this->json(0, 'ok', $tree->getTree($include)); + return $this->json(0, 'ok', $tree->getTree($include, $type)); } /** diff --git a/src/plugin/admin/app/controller/RoleController.php b/src/plugin/admin/app/controller/RoleController.php index a1f8243..df61d6b 100644 --- a/src/plugin/admin/app/controller/RoleController.php +++ b/src/plugin/admin/app/controller/RoleController.php @@ -2,6 +2,7 @@ namespace plugin\admin\app\controller; +use plugin\admin\app\common\Auth; use plugin\admin\app\common\Tree; use plugin\admin\app\model\Role; use plugin\admin\app\model\Rule; @@ -36,6 +37,48 @@ class RoleController extends Crud return view('role/index'); } + /** + * 查询 + * @param Request $request + * @return Response + * @throws BusinessException + */ + public function select(Request $request): Response + { + $id = $request->get('id'); + [$where, $format, $limit, $field, $order] = $this->selectInput($request); + $role_ids = Auth::getDescendantRoleIds(true); + if (!$id) { + $where['id'] = ['in', $role_ids]; + } elseif (!in_array($id, $role_ids)) { + throw new BusinessException('无权限'); + } + $query = $this->doSelect($where, $field, $order); + return $this->doFormat($query, $format, $limit); + } + + /** + * 格式化数据 + * @param $query + * @param $format + * @param $limit + * @return Response + */ + protected function doFormat($query, $format, $limit): Response + { + if (in_array($format, ['select', 'tree', 'table_tree'])) { + $items = $query->get(); + if ($format == 'select') { + return $this->formatSelect($items); + } elseif ($format == 'tree') { + return $this->formatTree($items); + } + return $this->formatTableTree($items); + } + $paginator = $query->paginate($limit); + return json(['code' => 0, 'msg' => 'ok', 'count' => $paginator->total(), 'data' => $paginator->items()]); + } + /** * 插入 * @param Request $request @@ -46,9 +89,14 @@ class RoleController extends Crud { if ($request->method() === 'POST') { $data = $this->insertInput($request); - if (isset($data['pid']) && $data['pid'] == 0) { - return $this->json(1, '请选择父级权限组'); + $pid = $data['pid'] ?? null; + if ($pid) { + return $this->json(1, '请选择父级角色组'); } + if (!Auth::isSupperAdmin() && !in_array($pid, Auth::getDescendantRoleIds(true))) { + return $this->json(1, '父级角色组超出权限范围'); + } + $id = $this->doInsert($data); return $this->json(0, 'ok', ['id' => $id]); } @@ -67,6 +115,11 @@ class RoleController extends Crud return view('role/update'); } [$id, $data] = $this->updateInput($request); + $is_supper_admin = Auth::isSupperAdmin(); + $descendant_role_ids = Auth::getDescendantRoleIds(); + if (!$is_supper_admin && !in_array($id, $descendant_role_ids)) { + return $this->json(1, '无数据权限'); + } // id为1的权限权限固定为* if (isset($data['rules']) && $id == 1) { $data['rules'] = '*'; @@ -75,14 +128,20 @@ class RoleController extends Crud if (isset($data['pid']) && $id == 1) { $data['pid'] = 0; } - if (isset($data['pid'])) { - if ($data['pid'] == $id) { + + if (key_exists('pid', $data)) { + $pid = $data['pid']; + if (!$pid) { + return $this->json(1, '请选择父级角色组'); + } + if ($pid == $id) { return $this->json(1, '父级不能是自己'); } - if ($data['pid'] == 0) { - return $this->json(1, '请选择父级权限组'); + if (!$is_supper_admin && !in_array($pid, Auth::getDescendantRoleIds(true))) { + return $this->json(1, '父级超出权限范围'); } } + $this->doUpdate($id, $data); return $this->json(0); } @@ -91,6 +150,7 @@ class RoleController extends Crud * 删除 * @param Request $request * @return Response + * @throws BusinessException */ public function delete(Request $request): Response { @@ -98,11 +158,13 @@ class RoleController extends Crud if (in_array(1, $ids)) { return $this->json(1, '无法删除超级管理员角色'); } + if (!Auth::isSupperAdmin() && array_diff($ids, Auth::getDescendantRoleIds())) { + return $this->json(1, '无删除权限'); + } $this->doDelete($ids); return $this->json(0); } - /** * 获取角色权限 * @param Request $request @@ -114,6 +176,9 @@ class RoleController extends Crud if (empty($role_id)) { return $this->json(0, 'ok', []); } + if (!Auth::isSupperAdmin() && !in_array($role_id, Auth::getDescendantRoleIds(true))) { + return $this->json(1, '角色组超出权限范围'); + } $rule_id_string = Role::where('id', $role_id)->value('rules'); if ($rule_id_string === '') { return $this->json(0, 'ok', []); diff --git a/src/plugin/admin/app/controller/RuleController.php b/src/plugin/admin/app/controller/RuleController.php index edaa904..5c085b1 100644 --- a/src/plugin/admin/app/controller/RuleController.php +++ b/src/plugin/admin/app/controller/RuleController.php @@ -308,25 +308,6 @@ class RuleController extends Crud return false; } - /** - * 递归删除某些key - * @param $array - * @param $keys - * @return void - */ - protected function recursiveRemove(&$array, $keys) - { - if (!is_array($array)) { - return; - } - foreach ($keys as $key) { - unset($array[$key]); - } - foreach ($array as &$item) { - $this->recursiveRemove($item, $keys); - } - } - /** * 获取权限规则 * @param $roles diff --git a/src/plugin/admin/app/view/role/index.html b/src/plugin/admin/app/view/role/index.html index 1108b53..889d7c6 100644 --- a/src/plugin/admin/app/view/role/index.html +++ b/src/plugin/admin/app/view/role/index.html @@ -31,7 +31,7 @@