[ 'title' => 'OpenAPI模块', 'icon' => 'fa-plug', 'order' => 10, 'children' => [ [ 'title' => 'OpenAPI应用管理', 'uri' => 'openapi-apps', 'icon' => 'fa-key', 'order' => 10, ], [ 'title' => 'API密钥管理', 'uri' => 'openapi-keys', 'icon' => 'fa-key', 'order' => 20, ], [ 'title' => 'API调用日志', 'uri' => 'openapi-logs', 'icon' => 'fa-list-alt', 'order' => 30, ], ], ], 'thirdparty' => [ 'title' => 'ThirdParty模块', 'icon' => 'fa-server', 'order' => 20, 'children' => [ [ 'title' => '第三方服务管理', 'uri' => 'thirdparty/services', 'icon' => 'fa-server', 'order' => 10, ], [ 'title' => '认证凭证管理', 'uri' => 'thirdparty/credentials', 'icon' => 'fa-shield-alt', 'order' => 20, ], [ 'title' => '调用日志管理', 'uri' => 'thirdparty/logs', 'icon' => 'fa-file-text', 'order' => 30, ], [ 'title' => '配额管理', 'uri' => 'thirdparty/quotas', 'icon' => 'fa-tachometer-alt', 'order' => 40, ], [ 'title' => '监控记录', 'uri' => 'thirdparty/monitors', 'icon' => 'fa-heartbeat', 'order' => 50, ], [ 'title' => '统计报告', 'uri' => 'thirdparty/reports/overview', 'icon' => 'fa-chart-bar', 'order' => 60, ], ], ], ]; /** * 执行命令 * * @return int */ public function handle(): int { try { // 检查父菜单是否存在 if (!$this->checkParentMenu()) { $this->error("父菜单 '外接管理' (ID: {$this->parentMenuId}) 不存在"); return 1; } $this->info("开始重构外接管理菜单结构..."); // 显示当前菜单结构 $this->displayCurrentStructure(); // 确认操作 if (!$this->option('force') && !$this->confirm('确定要重构菜单结构吗?这将删除现有的子菜单并重新创建。')) { $this->info('操作已取消'); return 0; } // 备份现有菜单 $this->backupCurrentMenus(); // 删除现有子菜单 $this->deleteExistingSubMenus(); // 创建新的菜单结构 $this->createNewMenuStructure(); // 显示新的菜单结构 $this->displayNewStructure(); $this->info("✅ 菜单结构重构完成!"); return 0; } catch (\Exception $e) { $this->error("重构菜单失败: " . $e->getMessage()); return 1; } } /** * 检查父菜单是否存在 * * @return bool */ protected function checkParentMenu(): bool { return DB::table('admin_menu') ->where('id', $this->parentMenuId) ->where('title', '外接管理') ->exists(); } /** * 显示当前菜单结构 * * @return void */ protected function displayCurrentStructure(): void { $this->info("\n当前菜单结构:"); $this->line("外接管理 (fa-plug)"); $currentMenus = DB::table('admin_menu') ->where('parent_id', $this->parentMenuId) ->orderBy('order') ->get(['title', 'uri', 'icon']); foreach ($currentMenus as $menu) { $icon = $menu->icon ? "({$menu->icon})" : ''; $this->line(" ├── {$menu->title} {$icon} -> {$menu->uri}"); } } /** * 备份现有菜单 * * @return void */ protected function backupCurrentMenus(): void { $timestamp = now()->format('Y_m_d_H_i_s'); $backupTable = "kku_admin_menu_backup_{$timestamp}"; // 创建备份表 DB::statement("CREATE TABLE {$backupTable} AS SELECT * FROM kku_admin_menu WHERE parent_id = {$this->parentMenuId}"); $this->info("✓ 已备份现有菜单到表: {$backupTable}"); } /** * 删除现有子菜单 * * @return void */ protected function deleteExistingSubMenus(): void { $deletedCount = DB::table('admin_menu') ->where('parent_id', $this->parentMenuId) ->delete(); $this->info("✓ 删除了 {$deletedCount} 个现有子菜单"); } /** * 创建新的菜单结构 * * @return void */ protected function createNewMenuStructure(): void { $now = now(); foreach ($this->menuStructure as $moduleKey => $module) { // 创建模块菜单(二级菜单) $moduleId = DB::table('admin_menu')->insertGetId([ 'parent_id' => $this->parentMenuId, 'order' => $module['order'], 'title' => $module['title'], 'icon' => $module['icon'], 'uri' => '', 'extension' => '', 'show' => 1, 'created_at' => $now, 'updated_at' => $now, ]); $this->line("✓ 创建模块菜单: {$module['title']} (ID: {$moduleId})"); // 创建模块下的子菜单(三级菜单) foreach ($module['children'] as $child) { $childId = DB::table('admin_menu')->insertGetId([ 'parent_id' => $moduleId, 'order' => $child['order'], 'title' => $child['title'], 'icon' => $child['icon'], 'uri' => $child['uri'], 'extension' => '', 'show' => 1, 'created_at' => $now, 'updated_at' => $now, ]); $this->line(" ├── 创建子菜单: {$child['title']} (ID: {$childId}) -> {$child['uri']}"); } } } /** * 显示新的菜单结构 * * @return void */ protected function displayNewStructure(): void { $this->info("\n新的菜单结构:"); $this->line("外接管理 (fa-plug)"); // 获取二级菜单 $modules = DB::table('admin_menu') ->where('parent_id', $this->parentMenuId) ->orderBy('order') ->get(['id', 'title', 'icon']); foreach ($modules as $module) { $icon = $module->icon ? "({$module->icon})" : ''; $this->line("├── {$module->title} {$icon}"); // 获取三级菜单 $children = DB::table('admin_menu') ->where('parent_id', $module->id) ->orderBy('order') ->get(['title', 'uri', 'icon']); foreach ($children as $child) { $childIcon = $child->icon ? "({$child->icon})" : ''; $this->line("│ ├── {$child->title} {$childIcon} -> {$child->uri}"); } } } /** * 获取菜单统计信息 * * @return array */ protected function getMenuStats(): array { $modules = DB::table('admin_menu') ->where('parent_id', $this->parentMenuId) ->count(); $totalChildren = DB::table('admin_menu as parent') ->join('admin_menu as child', 'parent.id', '=', 'child.parent_id') ->where('parent.parent_id', $this->parentMenuId) ->count(); return [ 'modules' => $modules, 'total_children' => $totalChildren, ]; } /** * 验证菜单结构 * * @return bool */ protected function validateMenuStructure(): bool { $stats = $this->getMenuStats(); $expectedModules = count($this->menuStructure); $expectedChildren = array_sum(array_map(fn($module) => count($module['children']), $this->menuStructure)); if ($stats['modules'] !== $expectedModules) { $this->warn("模块数量不匹配: 期望 {$expectedModules} 个,实际 {$stats['modules']} 个"); return false; } if ($stats['total_children'] !== $expectedChildren) { $this->warn("子菜单数量不匹配: 期望 {$expectedChildren} 个,实际 {$stats['total_children']} 个"); return false; } return true; } }