diff --git a/src/plugin/admin/app/common/Tree.php b/src/plugin/admin/app/common/Tree.php new file mode 100644 index 0000000..e9aaf20 --- /dev/null +++ b/src/plugin/admin/app/common/Tree.php @@ -0,0 +1,145 @@ +pidName = $pid_name; + if (is_object($data) && method_exists($data, 'toArray')) { + $this->data = $data->toArray(); + } else { + $this->data = (array)$data; + } + $this->hashTree = $this->getHashTree(); + } + + /** + * 获取子孙节点 + * @param int $id + * @param bool $with_self + * @return array + */ + public function getDescendants(int $id, bool $with_self = false): array + { + if (!isset($this->hashTree[$id])) { + return []; + } + $items = []; + if ($with_self) { + $item = $this->hashTree[$id]; + unset($item['children']); + $items[$item['id']] = $item; + } + foreach ($this->hashTree[$id]['children'] ?? [] as $item) { + unset($item['children']); + $items[$item['id']] = $item; + $items = array_merge($items, $this->getDescendants($item['id'])); + } + return array_values($items); + } + + /** + * 获取哈希树 + * @param array $data + * @return array + */ + protected function getHashTree(array $data = []): array + { + $data = $data ?: $this->data; + $hash_tree = []; + foreach ($data as $item) { + $hash_tree[$item['id']] = $item; + } + foreach ($hash_tree as $index => $item) { + if ($item[$this->pidName] && isset($hash_tree[$item[$this->pidName]])) { + $hash_tree[$item[$this->pidName]]['children'][$hash_tree[$index]['id']] = &$hash_tree[$index]; + } + } + return $hash_tree; + } + + /** + * 获取树 + * @param array $include + * @return array|null + */ + public function getTree(array $include = []): ?array + { + $hash_tree = $this->hashTree; + $items = []; + if ($include) { + $map = []; + foreach ($include as $id) { + if (!isset($hash_tree[$id])) { + continue; + } + $item = $hash_tree[$id]; + $max_depth = 100; + while ($max_depth-- > 0 && $item[$this->pidName] && isset($hash_tree[$item[$this->pidName]])) { + $last_item = $item; + $item = $hash_tree[$item[$this->pidName]]; + $item_id = $item['id']; + if (empty($map[$item_id])) { + $map[$item_id] = 1; + $item['children'] = []; + } + $item['children'][$last_item['id']] = $last_item; + } + $items[$item['id']] = $item; + } + } else { + $items = $hash_tree; + } + $formatted_items = []; + foreach ($items as $item) { + if (!$item[$this->pidName]) { + $formatted_items[] = $item; + } + } + $formatted_items = array_values($formatted_items); + foreach ($formatted_items as &$item) { + $this->arrayValues($item); + } + return $formatted_items; + } + + /** + * 递归重建数组下标 + * @return void + */ + protected function arrayValues(&$array) + { + if (!is_array($array) || !isset($array['children'])) { + return; + } + $array['children'] = array_values($array['children']); + foreach ($array['children'] as &$child) { + $this->arrayValues($child); + } + } + +} \ No newline at end of file diff --git a/src/plugin/admin/app/controller/Crud.php b/src/plugin/admin/app/controller/Crud.php index 0c71c35..95260b7 100644 --- a/src/plugin/admin/app/controller/Crud.php +++ b/src/plugin/admin/app/controller/Crud.php @@ -302,7 +302,7 @@ class Crud extends Base * @param $items * @return Response */ - protected function formatTree($items): Response + protected function formatTree($items, array $include = []): Response { $items_map = []; foreach ($items as $item) { @@ -314,7 +314,7 @@ class Crud extends Base ]; } $tree = new Tree($items_map); - return $this->json(0, 'ok', $tree->getTree()); + return $this->json(0, 'ok', $tree->getTree($include)); } /** diff --git a/src/plugin/admin/app/controller/RoleController.php b/src/plugin/admin/app/controller/RoleController.php index f56dbfb..a1f8243 100644 --- a/src/plugin/admin/app/controller/RoleController.php +++ b/src/plugin/admin/app/controller/RoleController.php @@ -110,7 +110,7 @@ class RoleController extends Crud */ public function rules(Request $request): Response { - $role_id = $request->get('role'); + $role_id = $request->get('id'); if (empty($role_id)) { return $this->json(0, 'ok', []); } @@ -119,12 +119,11 @@ class RoleController extends Crud return $this->json(0, 'ok', []); } $rules = Rule::get(); - $ids = []; + $include = []; if ($rule_id_string !== '*') { - $ids = explode(',', $rule_id_string); + $include = explode(',', $rule_id_string); } - $tree = new Tree($rules); - return $this->json(0, 'ok', $tree->getTree($ids)); + return $this->formatTree($rules, $include); } } diff --git a/src/plugin/admin/app/model/AdminRole.php b/src/plugin/admin/app/model/AdminRole.php new file mode 100644 index 0000000..051b5f5 --- /dev/null +++ b/src/plugin/admin/app/model/AdminRole.php @@ -0,0 +1,31 @@ +