FixAdminMenus.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. <?php
  2. namespace App\Console\Commands;
  3. use App\Module\System\Models\AdminMenu;
  4. use Illuminate\Console\Command;
  5. use Illuminate\Support\Str;
  6. class FixAdminMenus extends Command
  7. {
  8. /**
  9. * The name and signature of the console command.
  10. *
  11. * @var string
  12. */
  13. protected $signature = 'admin:fix-menus {module? : 指定要修复的模块,不指定则修复所有模块}';
  14. /**
  15. * The console command description.
  16. *
  17. * @var string
  18. */
  19. protected $description = '修复AdminMenu表中的菜单项';
  20. /**
  21. * 游戏系统设置菜单ID
  22. *
  23. * @var int
  24. */
  25. protected $systemMenuId = 259;
  26. /**
  27. * 游戏运营管理菜单ID
  28. *
  29. * @var int
  30. */
  31. protected $operationMenuId = 260;
  32. /**
  33. * 模块配置菜单映射
  34. *
  35. * @var array
  36. */
  37. protected $moduleConfigMenus = [];
  38. /**
  39. * 模块管理菜单映射
  40. *
  41. * @var array
  42. */
  43. protected $moduleManageMenus = [];
  44. /**
  45. * Execute the console command.
  46. *
  47. * @return int
  48. */
  49. public function handle()
  50. {
  51. $module = $this->argument('module');
  52. // 初始化模块菜单映射
  53. $this->initModuleMenus();
  54. if ($module) {
  55. $this->info("开始修复{$module}模块的菜单项...");
  56. $this->fixModuleMenus($module);
  57. } else {
  58. $this->info("开始修复所有模块的菜单项...");
  59. $modules = [
  60. 'Team', 'Pet', 'Farm', 'GameItems', 'Task', 'Activity', 'Article',
  61. 'Fund', 'Game', 'OAuth', 'Sms', 'System', 'User'
  62. ];
  63. foreach ($modules as $mod) {
  64. $this->fixModuleMenus($mod);
  65. }
  66. }
  67. $this->info("菜单项修复完成!");
  68. return 0;
  69. }
  70. /**
  71. * 初始化模块菜单映射
  72. *
  73. * @return void
  74. */
  75. protected function initModuleMenus()
  76. {
  77. // 获取游戏系统设置下的子菜单
  78. $systemSubMenus = AdminMenu::where('parent_id', $this->systemMenuId)->get();
  79. foreach ($systemSubMenus as $menu) {
  80. $moduleName = $this->guessModuleName($menu->title);
  81. if ($moduleName) {
  82. $this->moduleConfigMenus[$moduleName] = $menu->id;
  83. }
  84. }
  85. // 获取游戏运营管理下的子菜单
  86. $operationSubMenus = AdminMenu::where('parent_id', $this->operationMenuId)->get();
  87. foreach ($operationSubMenus as $menu) {
  88. $moduleName = $this->guessModuleName($menu->title);
  89. if ($moduleName) {
  90. $this->moduleManageMenus[$moduleName] = $menu->id;
  91. }
  92. }
  93. }
  94. /**
  95. * 根据菜单标题猜测模块名称
  96. *
  97. * @param string $title
  98. * @return string|null
  99. */
  100. protected function guessModuleName(string $title): ?string
  101. {
  102. $moduleMap = [
  103. '团队' => 'Team',
  104. '宠物' => 'Pet',
  105. '农场' => 'Farm',
  106. '游戏物品' => 'GameItems',
  107. '任务' => 'Task',
  108. '活动' => 'Activity',
  109. '文章' => 'Article',
  110. '资金' => 'Fund',
  111. '游戏' => 'Game',
  112. '认证' => 'OAuth',
  113. '短信' => 'Sms',
  114. '系统' => 'System',
  115. '用户' => 'User'
  116. ];
  117. foreach ($moduleMap as $keyword => $module) {
  118. if (Str::contains($title, $keyword)) {
  119. return $module;
  120. }
  121. }
  122. return null;
  123. }
  124. /**
  125. * 修复指定模块的菜单项
  126. *
  127. * @param string $module
  128. * @return void
  129. */
  130. protected function fixModuleMenus(string $module)
  131. {
  132. $this->info("修复{$module}模块的菜单项...");
  133. // 获取模块的后台控制器
  134. $controllerDir = app_path("Module/{$module}/AdminControllers");
  135. if (!is_dir($controllerDir)) {
  136. $this->warn(" - 未找到AdminControllers目录");
  137. return;
  138. }
  139. $controllers = array_filter(scandir($controllerDir), function($file) {
  140. return !in_array($file, ['.', '..']) &&
  141. !is_dir(app_path("Module/{$this->argument('module')}/AdminControllers/{$file}")) &&
  142. pathinfo($file, PATHINFO_EXTENSION) === 'php';
  143. });
  144. // 获取最大的order值
  145. $maxOrder = AdminMenu::max('order');
  146. $nextOrder = $maxOrder + 1;
  147. // 创建或获取模块配置菜单
  148. $configMenuId = $this->getOrCreateModuleConfigMenu($module, $nextOrder);
  149. $nextOrder++;
  150. // 创建或获取模块管理菜单
  151. $manageMenuId = $this->getOrCreateModuleManageMenu($module, $nextOrder);
  152. $nextOrder++;
  153. // 分类控制器
  154. $configControllers = [];
  155. $manageControllers = [];
  156. foreach ($controllers as $controller) {
  157. $controllerName = pathinfo($controller, PATHINFO_FILENAME);
  158. // 跳过Helper目录和文件
  159. if (Str::contains($controllerName, 'Helper')) {
  160. continue;
  161. }
  162. // 根据控制器名称判断是配置还是管理
  163. if (Str::contains($controllerName, ['Config', 'Type', 'Category', 'Rule'])) {
  164. $configControllers[] = $controllerName;
  165. } else {
  166. $manageControllers[] = $controllerName;
  167. }
  168. }
  169. // 添加配置菜单项
  170. foreach ($configControllers as $controller) {
  171. $this->addMenuItemForController($module, $controller, $configMenuId, $nextOrder);
  172. $nextOrder++;
  173. }
  174. // 添加管理菜单项
  175. foreach ($manageControllers as $controller) {
  176. $this->addMenuItemForController($module, $controller, $manageMenuId, $nextOrder);
  177. $nextOrder++;
  178. }
  179. }
  180. /**
  181. * 获取或创建模块配置菜单
  182. *
  183. * @param string $module
  184. * @param int $order
  185. * @return int
  186. */
  187. protected function getOrCreateModuleConfigMenu(string $module, int $order): int
  188. {
  189. if (isset($this->moduleConfigMenus[$module])) {
  190. return $this->moduleConfigMenus[$module];
  191. }
  192. $title = $this->getModuleTitle($module) . '配置';
  193. $icon = $this->getModuleIcon($module);
  194. $menu = AdminMenu::firstOrCreate(
  195. ['title' => $title, 'uri' => ''],
  196. [
  197. 'parent_id' => $this->systemMenuId,
  198. 'order' => $order,
  199. 'icon' => $icon,
  200. 'uri' => '',
  201. 'show' => 1
  202. ]
  203. );
  204. $this->info(" - 创建{$module}模块配置菜单: {$menu->title}, ID: {$menu->id}");
  205. $this->moduleConfigMenus[$module] = $menu->id;
  206. return $menu->id;
  207. }
  208. /**
  209. * 获取或创建模块管理菜单
  210. *
  211. * @param string $module
  212. * @param int $order
  213. * @return int
  214. */
  215. protected function getOrCreateModuleManageMenu(string $module, int $order): int
  216. {
  217. if (isset($this->moduleManageMenus[$module])) {
  218. return $this->moduleManageMenus[$module];
  219. }
  220. $title = $this->getModuleTitle($module) . '管理';
  221. $icon = $this->getModuleIcon($module);
  222. $menu = AdminMenu::firstOrCreate(
  223. ['title' => $title, 'uri' => ''],
  224. [
  225. 'parent_id' => $this->operationMenuId,
  226. 'order' => $order,
  227. 'icon' => $icon,
  228. 'uri' => '',
  229. 'show' => 1
  230. ]
  231. );
  232. $this->info(" - 创建{$module}模块管理菜单: {$menu->title}, ID: {$menu->id}");
  233. $this->moduleManageMenus[$module] = $menu->id;
  234. return $menu->id;
  235. }
  236. /**
  237. * 为控制器添加菜单项
  238. *
  239. * @param string $module
  240. * @param string $controllerName
  241. * @param int $parentId
  242. * @param int $order
  243. * @return void
  244. */
  245. protected function addMenuItemForController(string $module, string $controllerName, int $parentId, int $order)
  246. {
  247. // 获取控制器类
  248. $controllerClass = "App\\Module\\{$module}\\AdminControllers\\{$controllerName}";
  249. // 获取URI
  250. $uri = $this->getControllerUri($controllerName);
  251. // 获取标题
  252. $title = $this->getControllerTitle($controllerName);
  253. // 检查菜单项是否存在
  254. $menuExists = AdminMenu::where('uri', $uri)->exists();
  255. if (!$menuExists) {
  256. $menu = AdminMenu::create([
  257. 'parent_id' => $parentId,
  258. 'order' => $order,
  259. 'title' => $title,
  260. 'icon' => '',
  261. 'uri' => $uri,
  262. 'show' => 1
  263. ]);
  264. $this->info(" - 创建菜单项: {$menu->title}, URI: {$menu->uri}");
  265. } else {
  266. $this->info(" - 菜单项已存在: {$title}, URI: {$uri}");
  267. }
  268. }
  269. /**
  270. * 获取控制器的URI
  271. *
  272. * @param string $controllerName
  273. * @return string
  274. */
  275. protected function getControllerUri(string $controllerName): string
  276. {
  277. // 移除Controller后缀
  278. $name = str_replace('Controller', '', $controllerName);
  279. // 转换为kebab-case
  280. $uri = Str::kebab($name);
  281. return $uri;
  282. }
  283. /**
  284. * 获取控制器的标题
  285. *
  286. * @param string $controllerName
  287. * @return string
  288. */
  289. protected function getControllerTitle(string $controllerName): string
  290. {
  291. // 移除Controller后缀
  292. $name = str_replace('Controller', '', $controllerName);
  293. // 转换为标题
  294. $title = Str::title(Str::snake($name, ' '));
  295. return $title;
  296. }
  297. /**
  298. * 获取模块标题
  299. *
  300. * @param string $module
  301. * @return string
  302. */
  303. protected function getModuleTitle(string $module): string
  304. {
  305. $titleMap = [
  306. 'Team' => '👥 团队',
  307. 'Pet' => '🐾 宠物',
  308. 'Farm' => '🌱 农场',
  309. 'GameItems' => '🎁 游戏物品',
  310. 'Task' => '📋 任务',
  311. 'Activity' => '🎯 活动',
  312. 'Article' => '📝 文章',
  313. 'Fund' => '💰 资金',
  314. 'Game' => '🎮 游戏',
  315. 'OAuth' => '🔑 认证',
  316. 'Sms' => '📱 短信',
  317. 'System' => '⚙️ 系统',
  318. 'User' => '👤 用户'
  319. ];
  320. return $titleMap[$module] ?? $module;
  321. }
  322. /**
  323. * 获取模块图标
  324. *
  325. * @param string $module
  326. * @return string
  327. */
  328. protected function getModuleIcon(string $module): string
  329. {
  330. $iconMap = [
  331. 'Team' => 'fa-users',
  332. 'Pet' => 'fa-paw',
  333. 'Farm' => 'fa-leaf',
  334. 'GameItems' => 'fa-gift',
  335. 'Task' => 'fa-tasks',
  336. 'Activity' => 'fa-bullseye',
  337. 'Article' => 'fa-file-text',
  338. 'Fund' => 'fa-money',
  339. 'Game' => 'fa-gamepad',
  340. 'OAuth' => 'fa-key',
  341. 'Sms' => 'fa-mobile',
  342. 'System' => 'fa-cogs',
  343. 'User' => 'fa-user'
  344. ];
  345. return $iconMap[$module] ?? 'fa-circle';
  346. }
  347. }