diff --git a/app/CodeFec/Itf/Itf/Itf.php b/app/CodeFec/Itf/Itf/Itf.php index bc815cc85..2305679c1 100644 --- a/app/CodeFec/Itf/Itf/Itf.php +++ b/app/CodeFec/Itf/Itf/Itf.php @@ -7,23 +7,23 @@ class Itf implements ItfInterface { - public array $list=[]; + public array $list = []; public function add($class, $id, $data): bool { - $this->list = Arr::add($this->list, $class.".".$class."_".$id, $data); + $this->list = Arr::add($this->list, $class . "." . $class . "_" . $id, $data); return true; } - + public function re($class, $id, $data): bool { - $this->list[$class][$class."_".$id] = $data; + $this->list[$class][$class . "_" . $id] = $data; return true; } - + public function del($class, $id): bool { - $this->list[$class]=array_diff_key($this->list[$class], [$class."_".$id => $this->list[$class][$class."_".$id]]); + $this->list[$class] = array_diff_key($this->list[$class], [$class . "_" . $id => $this->list[$class][$class . "_" . $id]]); return true; } @@ -40,9 +40,14 @@ public function get($class): array } return []; } - + public function all(): array { return $this->list; } + + public function _del($class) + { + $this->list[$class] = []; + } } diff --git a/app/CodeFec/Itf/Itf/ItfInterface.php b/app/CodeFec/Itf/Itf/ItfInterface.php index 79400edf3..c490be98c 100644 --- a/app/CodeFec/Itf/Itf/ItfInterface.php +++ b/app/CodeFec/Itf/Itf/ItfInterface.php @@ -32,4 +32,8 @@ public function re($class, $id,$data); */ public function del($class, $id); + /** + * @param $class + */ + public function _del($class); } \ No newline at end of file diff --git a/app/CodeFec/Menu/default.php b/app/CodeFec/Menu/default.php index 081d3998c..cd7473e89 100644 --- a/app/CodeFec/Menu/default.php +++ b/app/CodeFec/Menu/default.php @@ -143,6 +143,19 @@ ', 'parent_id' => 5, ]); + +menu()->add(504, [ + 'url' => '/admin/setting/menu', + 'name' => '页头导航', + 'icon' => ' + + + + + +', + 'parent_id' => 5, +]); menu()->add(522, [ 'url' => '/admin/server/backup', 'name' => '备份', diff --git a/app/Controller/Admin/MenuController.php b/app/Controller/Admin/MenuController.php new file mode 100644 index 000000000..d61e43e91 --- /dev/null +++ b/app/Controller/Admin/MenuController.php @@ -0,0 +1,132 @@ + $this->page()]); + } + + #[GetMapping(path: 'create')] + public function create() + { + return view('admin.setting.menu.create'); + } + + #[GetMapping(path: '{id}/edit')] + public function edit($id) + { + if (!in_array($id, _menu_keys())) { + return admin_abort('菜单不存在', 403); + } + $data = _menu_get_data($id); + if (arr_has($data, 'quanxian')) { + unset($data['quanxian']); + } + return view('admin.setting.menu.edit', ['data' => $data]); + } + + #[PostMapping(path: 'create')] + public function store() + { + $data = $this->request->input('data'); + $data = json_decode($data, true); + if (arr_has($data, 'parent_id') && data_get($data, 'parent_id') && !in_array($data['parent_id'], _menu_keys())) { + return Json_Api(403, false, ['msg' => '上级id不存在']); + } + $data['sort'] = (int)$data['sort']; + if (arr_has($data, 'parent_id') && data_get($data, 'parent_id')) { + $data['parent_id'] = (int)$data['parent_id']; + } else { + unset($data['parent_id']); + } + if (arr_has($data, 'parent_id') && data_get($data, 'parent_id') && arr_has(_menu_get_data($data['parent_id']), 'parent_id')) { + return Json_Api(403, false, ['msg' => '子菜单不能作为上级菜单使用']); + } + $prefix_name = config('cache.default.prefix') . 'menu'; + redis()->hSetNx($prefix_name, (string)((int)max(_menu_keys()) + 1), _menu_instance()->serialize($data)); + return Json_Api(200, true, ['msg' => '创建成功!']); + } + + #[PostMapping(path: 'update')] + public function update() + { + $data = $this->request->input('data'); + $data = json_decode($data, true); + if (!in_array($this->request->input('id'), _menu_keys())) { + return Json_Api(403, false, ['msg' => '被修改的菜单id不存在']); + } + if (arr_has($data, 'parent_id') && data_get($data, 'parent_id') && !in_array($data['parent_id'], _menu_keys())) { + return Json_Api(403, false, ['msg' => '上级id不存在']); + } + $data['sort'] = (int)$data['sort']; + if (arr_has($data, 'parent_id') && data_get($data, 'parent_id')) { + $data['parent_id'] = (int)$data['parent_id']; + } else { + unset($data['parent_id']); + } + if (arr_has($data, 'parent_id') && data_get($data, 'parent_id') && arr_has(_menu_get_data($data['parent_id']), 'parent_id')) { + return Json_Api(403, false, ['msg' => '子菜单不能作为上级菜单使用']); + } + $_data = _menu_get_data($this->request->input('id')); + $data = array_merge($_data, $data); + if (arr_has($data, 'quanxian')) { + $data['quanxian'] = _menu_instance()->serialize($data['quanxian']); + } + $prefix_name = config('cache.default.prefix') . 'menu'; + redis()->hDel($prefix_name, (string)$this->request->input('id')); + redis()->hSetNx($prefix_name, (string)$this->request->input('id'), _menu_instance()->serialize($data)); + return Json_Api(200, true, ['msg' => '修改成功!']); + } + + #[PostMapping(path: "delete")] + public function delete() + { + $id = $this->request->input('id'); + if (!in_array($this->request->input('id'), _menu_keys())) { + return Json_Api(403, false, ['msg' => '被删除的菜单id不存在']); + } + if (arr_has(Itf()->get('menu'), $id)) { + return Json_Api(403, false, ['msg' => '这是不可删除的菜单']); + } + $prefix_name = config('cache.default.prefix') . 'menu'; + redis()->hDel($prefix_name, (string)$this->request->input('id')); + return Json_Api(200, true, ['msg' => '删除成功!']); + } + + private function page() + { + //_menu() + $currentPage = (int)request()->input('page', 1); + $perPage = (int)request()->input('per_page', 15); + + // 这里根据 $currentPage 和 $perPage 进行数据查询,以下使用 Collection 代替 + $collection = new Collection(_menu()); + + $data = array_values($collection->forPage($currentPage, $perPage)->toArray()); + return new LengthAwarePaginator($data, count(_menu()), $perPage, $currentPage); + } +} diff --git a/app/Model/AdminUser.php b/app/Model/AdminUser.php index 5120adbed..212f8d1e8 100755 --- a/app/Model/AdminUser.php +++ b/app/Model/AdminUser.php @@ -25,4 +25,6 @@ class AdminUser extends Model * @var array */ protected $fillable = ['id', 'username', 'email', 'avatar', 'password', 'created_at', 'updated_at']; + + public $hidden = ['password']; } diff --git a/app/Plugins/Core/Menu.php b/app/Plugins/Core/Menu.php new file mode 100644 index 000000000..078373366 --- /dev/null +++ b/app/Plugins/Core/Menu.php @@ -0,0 +1,144 @@ +db() as $id => $data) { + $data['id'] = (int) $id; + $menu[$id] = $data; + } + $keys = array_keys($menu); + $news_key = array_column($menu, 'sort'); + array_multisort($news_key, SORT_ASC, $menu, $keys); + return array_combine($keys, $menu); + } + + /** + * get all keys. + * @throws \RedisException + * @return int[]|string[] + */ + public function get_keys() + { + return array_keys($this->get()); + } + + /** + * get menu data. + * @param mixed $id + * @throws \RedisException + * @return null|mixed + */ + public function get_data($id) + { + $id = (int) $id; + if (! in_array($id, $this->get_keys())) { + return null; + } + return $this->get()[$id]; + } + + /** + * get all Itf menu. + */ + private function Itf(): array + { + $menu = []; + foreach (Itf()->get('menu') as $k => $value) { + $k = core_Itf_id('menu', $k); + if (Arr::has($value, 'quanxian') && $value['quanxian'] instanceof \Closure) { + $value['quanxian'] = $this->serialize($value['quanxian']); + } + $value['Itf'] = true; + $menu[$k] = $value; + } + return $menu; + } + + /** + * get all database menu. + * @throws \RedisException + */ + private function db(): array + { + $prefix_name = config('cache.default.prefix') . 'menu'; + foreach ($this->Itf() as $id => $item) { + if (! redis()->hExists($prefix_name, (string) $id)) { + redis()->hSetNx($prefix_name, (string) $id, $this->serialize($item)); + } + } + + Itf()->_del('menu'); + $all = redis()->hGetAll($prefix_name); + $result = []; + foreach ($all as $id => $data) { + $_data = $this->unserialize($data); + if (Arr::has($_data, 'quanxian')) { + $_data['quanxian'] = $this->unserialize($_data['quanxian']); + } + if (! arr_has($_data, 'sort')) { + $_data['sort'] = $id; + } + if (! arr_has($_data, 'hidden')) { + $_data['hidden'] = false; + } + $result[(int) $id] = $_data; + } + return $result; + } + + /** + * @param $data + * @return string + */ + public function serialize($data): string + { + return \Opis\Closure\serialize($data); + } + + /** + * @param $data + * @return mixed + */ + private function unserialize($data) + { + return @\Opis\Closure\unserialize($data, ['allowed_classes' => true]); + } + + + public function backup() + { + + $menu_serialize = $this->serialize($this->get()); + $menu = json_encode($this->get(),JSON_PRETTY_PRINT,JSON_UNESCAPED_UNICODE); + if (! is_dir(BASE_PATH . '/runtime/backup')) { + System::exec('cd ' . BASE_PATH . '/runtime' . '&& mkdir ' . 'backup'); + } + if (! is_dir(BASE_PATH . '/runtime/backup/menu')) { + System::exec('cd ' . BASE_PATH . '/runtime/backup' . '&& mkdir ' . 'menu'); + } + file_put_contents(BASE_PATH."/runtime/backup/menu/menu_serialize.txt",$menu_serialize); + file_put_contents(BASE_PATH."/runtime/backup/menu/menu.json",$menu); + return true; + } +} diff --git a/app/Plugins/Core/helpers.php b/app/Plugins/Core/helpers.php index 1caa13cdd..544ed14fc 100755 --- a/app/Plugins/Core/helpers.php +++ b/app/Plugins/Core/helpers.php @@ -15,8 +15,6 @@ use DivineOmega\PHPSummary\SummaryTool; use JetBrains\PhpStorm\Pure; - - if (! function_exists('plugins_core_user_reg_defuc')) { function plugins_core_user_reg_defuc() { @@ -79,8 +77,8 @@ function core_Str_menu_url(string $path): string if (! function_exists('core_menu_pd')) { function core_menu_pd(string $id) { - foreach (Itf()->get('menu') as $value) { - if (arr_has($value, 'parent_id') && 'menu_' . $value['parent_id'] === (string) $id) { + foreach (_menu() as $value) { + if (arr_has($value, 'parent_id') && (string) $value['parent_id'] === (string) $id) { return true; } } @@ -99,8 +97,8 @@ function core_Itf_id($name, $id) function core_menu_pdArr($id): array { $arr = []; - foreach (Itf()->get('menu') as $key => $value) { - if (arr_has($value, 'parent_id') && 'menu_' . $value['parent_id'] === $id) { + foreach (_menu() as $key => $value) { + if (arr_has($value, 'parent_id') && (string) $value['parent_id'] === (string) $id) { $arr[$key] = $value; } } diff --git a/app/Plugins/Topic/bootstrap.php b/app/Plugins/Topic/bootstrap.php index f50d2c4f3..6c987d50e 100644 --- a/app/Plugins/Topic/bootstrap.php +++ b/app/Plugins/Topic/bootstrap.php @@ -69,7 +69,9 @@ ', - 'quanxian' => 1000, + 'quanxian' => (function () { + return true; + }), ]); Itf_Setting()->add( diff --git a/app/Plugins/User/menu.php b/app/Plugins/User/menu.php index f46eec999..ae9b7cdfa 100755 --- a/app/Plugins/User/menu.php +++ b/app/Plugins/User/menu.php @@ -89,5 +89,7 @@ ', - 'quanxian' => 1, + 'quanxian' => (function(){ + return true; + }), ]); \ No newline at end of file diff --git a/app/Themes/CodeFec/resources/views/layouts/themes/menu.blade.php b/app/Themes/CodeFec/resources/views/layouts/themes/menu.blade.php index bbc96da82..b74206436 100755 --- a/app/Themes/CodeFec/resources/views/layouts/themes/menu.blade.php +++ b/app/Themes/CodeFec/resources/views/layouts/themes/menu.blade.php @@ -1,11 +1,9 @@