model = new AdminRule; } /** * 浏览 * @return Response * @throws Throwable */ public function index(Request $request): Response { return view('admin_rule/index'); } /** * 格式化树 * @param $items * @return Response */ protected function formatTree($items): Response { $format_items = []; //$primary_key = $this->model->getPk(); $primary_key = $this->model->getPk(); foreach ($items as $item) { $item->text = $item->title; //$item->value = (string)$item->$primary_key; $item->id = $item->$primary_key; $item->parent = $item->pid; if($item->pid == 0){ $item->parent = '#'; } unset($item->pid); $format_items[] = $item; } $tree = new Tree($format_items); return $this->success("操作成功", $tree->getTree()); } /** * 权限树形 * @param Request $request * @return Response * @throws BusinessException */ public function roletree(Request $request): Response { [$where, $format, $limit, $field, $order] = $this->selectInput($request); $query = $this->doSelect($where, $field, $order); $methods = [ 'select' => 'formatSelect', 'tree' => 'formatTree', 'table_tree' => 'formatTableTree', 'normal' => 'formatNormal', ]; $format = 'normal'; $items = $query->field('id,title as text,pid as parent,"menu" as type')->select(); /** * @var AdminRule $item */ foreach ($items as $key => $item) { $items[$key]->state = [ "selected" => false, ]; if($items[$key]->parent == 0){ $items[$key]->parent = '#'; } }; if (method_exists($this, "afterQuery")) { $items = call_user_func([$this, "afterQuery"], $items); } $format_function = $methods[$format] ?? 'formatNormal'; return call_user_func([$this, $format_function], $items, 0); } /** * 查询 * @param Request $request * @return Response * @throws BusinessException */ public function select(Request $request): Response { [$where, $format, $limit, $field, $order] = $this->selectInput($request); $query = $this->doSelect($where, $field, $order); return $this->doFormat($query, $format, 'all'); } /** * 刷新缓存 * @param \support\Request $request * @return Response */ public function buildcache(Request $request){ //缓存 $list = $this->get($request)->rawBody(); $list = json_decode($list,true); $fn = base_path() . '/plugin/admin/config/menu.php'; file_put_contents($fn, "success('ok'); } /** * 获取菜单 * @param Request $request * @return Response * @throws Exception */ function get(Request $request): Response { $is_supper_admin = Auth::isSuperAdmin(); if($is_supper_admin){ $rules = ['*']; }else{ $rules = $this->getRules(admin('roles')); } //return $this->success("操作成功", admin('roles')); $types = $request->get('type', '0,1'); $types = is_string($types) ? explode(',', $types) : [0, 1]; $items = AdminRule::order('weight', 'desc')->select(); $formatted_items = []; /** * @var AdminRule $item */ foreach ($items as $item) { $item['pid'] = (int)$item['pid']; $item['name'] = $item['title']; $item['value'] = $item['id']; $item['icon'] = $item->icon ? "{$item->icon}" : ''; $formatted_items[] = $item; } $tree = new Tree($formatted_items); $tree_items = $tree->getTree(); // 超级管理员权限为 * if (!in_array('*', $rules)) { $this->removeNotContain($tree_items, 'id', $rules); } $this->removeNotContain($tree_items, 'type', $types); $menus = $this->empty_filter(Tree::arrayValues($tree_items)); return $this->success("操作成功", $menus); } private function empty_filter($menus) { return array_map( function ($menu) { if (isset($menu['children'])) { $menu['children'] = $this->empty_filter($menu['children']); } return $menu; }, array_values(array_filter( $menus, function ($menu) { return $menu['type'] != 0 || isset($menu['children']) && count($this->empty_filter($menu['children'])) > 0; } )) ); } /** * 获取权限 * @param Request $request * @return Response * @throws Exception */ public function permission(Request $request): Response { $rules = $this->getRules(admin('roles')); // 超级管理员 if (in_array('*', $rules)) { return $this->success("操作成功", ['*']); } $keys = AdminRule::whereIn('id', $rules)->column('key'); $permissions = []; foreach ($keys as $key) { if (!$key = Util::controllerToUrlPath($key)) { continue; } $code = str_replace('/', '.', trim($key, '/')); $permissions[] = $code; } return $this->success("操作成功", $permissions); } /** * 同步规则 * @return void */ public function syncRules(): Response { //$items = $this->model->where('key', 'like', '%\\\\%')->get()->keyBy('key'); $items = $this->model->whereLike('key', '%\\\\%')->select(); $methods_in_db = []; $methods_in_files = []; /** * @var AdminRule $item */ foreach ($items as $item) { $class = $item->key; if (strpos($class, '@')) { $methods_in_db[$class] = $class; continue; } if (class_exists('\\plugin\\admin\\'.$class)) { $reflection = new \ReflectionClass('\\plugin\\admin\\'.$class); $properties = $reflection->getDefaultProperties(); $no_need_auth = array_merge($properties['noNeedLogin'] ?? [], $properties['noNeedAuth'] ?? []); $class = str_replace('plugin\admin\\','',$reflection->getName()); $pid = $item->id; $methods = $reflection->getMethods(\ReflectionMethod::IS_PUBLIC); foreach ($methods as $method) { $method_name = $method->getName(); if (strtolower($method_name) === 'index' || strpos($method_name, '__') === 0 || in_array($method_name, $no_need_auth)) { continue; } $name = "$class@$method_name"; $methods_in_files[$name] = $name; $title = Util::getCommentFirstLine($method->getDocComment()) ?: $method_name; /** * @var AdminRule $menu */ $menu = $items[$name] ?? []; if ($menu) { if ($menu->title != $title) { AdminRule::where('key', $name)->update(['title' => $title]); } continue; } if(!AdminRule::where('key', $name)->count('id')) { $menu = new AdminRule; $menu->pid = $pid; $menu->key = $name; $menu->title = $title; $menu->type = 2; $menu->save(); } } } } // 从数据库中删除已经不存在的方法 $menu_names_to_del = array_diff($methods_in_db, $methods_in_files); if ($menu_names_to_del) { AdminRule::whereIn('key', $menu_names_to_del)->delete(); } return $this->success("操作成功"); } /** * 查询前置方法 * @param Request $request * @return array * @throws BusinessException */ protected function selectInput(Request $request): array { [$where, $format, $limit, $field, $order] = parent::selectInput($request); // 允许通过type=0,1格式传递菜单类型 $types = $request->get('type'); if ($types && is_string($types)) { $where['type'] = ['symbol'=>'in', 'value1'=>explode(',', $types)]; } // 默认weight排序 if (!$field) { $field = 'weight'; $order = 'desc'; } return [$where, $format, $limit, $field, $order]; } /** * 添加 * @param Request $request * @return Response * @throws BusinessException|Throwable */ public function insert(Request $request): Response { if ($request->method() === 'GET') { $RuleList = $this->model->where('status',1)->order('id asc')->select(); $tree = new Tree($RuleList); return view('admin_rule/update',[ 'RuleList' => $tree->getTree() ]); } $data = $this->insertInput($request); if (empty($data['type'])) { $data['type'] = strpos($data['key'], '\\') ? 1 : 0; } $data['key'] = str_replace('\\\\', '\\', $data['key']); $key = $data['key'] ?? ''; if ($this->model->where('key', $key)->count('id')) { return $this->fail("菜单标识 $key 已经存在"); } $data['pid'] = empty($data['pid']) ? 0 : $data['pid']; $this->doInsert($data); return $this->success("操作成功"); } /** * 更新 * @param Request $request * @return Response * @throws BusinessException|Throwable */ public function update(Request $request): Response { if ($request->method() === 'GET') { $RuleList = $this->model->order('id asc')->select(); $ids = Request()->get('ids'); $tree = new Tree($RuleList); return view('admin_rule/update',[ 'RuleList' => $tree->getTree(), 'row' => $this->model->where('id',$ids)->find() ]); } [$id, $data] = $this->updateInput($request); if (!$row = $this->model->find($id)) { return $this->json(2, '记录不存在'); } if (isset($data['pid'])) { $data['pid'] = $data['pid'] ?: 0; if ($data['pid'] == $row['id']) { return $this->json(2, '不能将自己设置为上级菜单'); } } if (isset($data['key'])) { $data['key'] = str_replace('\\\\', '\\', $data['key']); } $this->doUpdate($id, $data); return $this->success("操作成功"); } /** * 删除 * @param Request $request * @return Response */ public function delete(Request $request): Response { $ids = $this->deleteInput($request); // 子规则一起删除 $delete_ids = $children_ids = $ids; while($children_ids) { $children_ids = $this->model->whereIn('pid', $children_ids)->column('id'); $delete_ids = array_merge($delete_ids, $children_ids); } $this->doDelete($delete_ids); return $this->success("操作成功"); } /** * 移除不包含某些数据的数组 * @param $array * @param $key * @param $values * @return void */ protected function removeNotContain(&$array, $key, $values) { foreach ($array as $k => &$item) { if (!is_array($item)) { continue; } if (!$this->arrayContain($item, $key, $values)) { unset($array[$k]); } else { if (!isset($item['children'])) { continue; } $this->removeNotContain($item['children'], $key, $values); } } } /** * 判断数组是否包含某些数据 * @param $array * @param $key * @param $values * @return bool */ protected function arrayContain(&$array, $key, $values): bool { if (!is_array($array)) { return false; } if (isset($array[$key]) && in_array($array[$key], $values)) { return true; } if (!isset($array['children'])) { return false; } foreach ($array['children'] as $item) { if ($this->arrayContain($item, $key, $values)) { return true; } } return false; } /** * 获取权限规则 * @param $roles * @return array */ protected function getRules($roles): array { $rules_strings = $roles ? AdminRole::whereIn('id', $roles)->column('rules') : []; $rules = []; foreach ($rules_strings as $rule_string) { if (!$rule_string) { continue; } $rules = array_merge($rules, explode(',', $rule_string)); } return $rules; } }