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 @@