Menu.php 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. <?php
  2. namespace app\common\library;
  3. use Throwable;
  4. use app\admin\model\AdminRule;
  5. use app\admin\model\UserRule;
  6. /**
  7. * 后台菜单类
  8. */
  9. class Menu
  10. {
  11. /**
  12. * @param array $menu
  13. * @param int|string $parent 父级规则name或id
  14. * @param string $mode 添加模式(规则重复时):cover=覆盖旧菜单,rename=重命名新菜单,ignore=忽略
  15. * @param string $position 位置:backend=后台,frontend=前台
  16. * @return void
  17. * @throws Throwable
  18. */
  19. public static function create(array $menu, int|string $parent = 0, string $mode = 'cover', string $position = 'backend'): void
  20. {
  21. $pid = 0;
  22. $model = $position == 'backend' ? new AdminRule() : new UserRule();
  23. $parentRule = $model->where((is_numeric($parent) ? 'id' : 'name'), $parent)->find();
  24. if ($parentRule) {
  25. $pid = $parentRule['id'];
  26. }
  27. foreach ($menu as $item) {
  28. if (!self::requiredAttrCheck($item)) {
  29. continue;
  30. }
  31. // 属性
  32. $item['status'] = '1';
  33. if (!isset($item['pid']) && $pid) {
  34. $item['pid'] = $pid;
  35. }
  36. $oldMenu = $model->where('name', $item['name'])->find();
  37. if ($oldMenu) {
  38. // 存在相关名称的菜单规则
  39. if ($mode == 'cover') {
  40. $oldMenu->save($item);
  41. } elseif ($mode == 'rename') {
  42. $count = $model->where('name', $item['name'])->count();
  43. $item['name'] = $item['name'] . '-conflicting-' . $count;
  44. $item['title'] = $item['title'] . '-conflicting-' . $count;
  45. $oldMenu = $model->create($item);
  46. } elseif ($mode == 'ignore') {
  47. $oldMenu = $menu;
  48. }
  49. } else {
  50. $oldMenu = $model->create($item);
  51. }
  52. if (isset($item['children']) && $item['children']) {
  53. self::create($item['children'], $oldMenu['name'], $mode, $position);
  54. }
  55. }
  56. }
  57. /**
  58. * 删菜单
  59. * @param string|int $id 规则name或id
  60. * @param bool $recursion 是否递归删除子级菜单、是否删除自身,是否删除上级空菜单
  61. * @param string $position 位置:backend=后台,frontend=前台
  62. * @return bool
  63. * @throws Throwable
  64. */
  65. public static function delete(string|int $id, bool $recursion = false, string $position = 'backend'): bool
  66. {
  67. if (!$id) {
  68. return true;
  69. }
  70. $model = $position == 'backend' ? new AdminRule() : new UserRule();
  71. $menuRule = $model->where((is_numeric($id) ? 'id' : 'name'), $id)->find();
  72. if (!$menuRule) {
  73. return true;
  74. }
  75. $children = $model->where('pid', $menuRule['id'])->select()->toArray();
  76. if ($recursion && $children) {
  77. foreach ($children as $child) {
  78. self::delete($child['id'], true, $position);
  79. }
  80. }
  81. if (!$children || $recursion) {
  82. $menuRule->delete();
  83. self::delete($menuRule->pid, false, $position);
  84. }
  85. return true;
  86. }
  87. /**
  88. * 启用菜单
  89. * @param string|int $id 规则name或id
  90. * @param string $position 位置:backend=后台,frontend=前台
  91. * @return bool
  92. * @throws Throwable
  93. */
  94. public static function enable(string|int $id, string $position = 'backend'): bool
  95. {
  96. $model = $position == 'backend' ? new AdminRule() : new UserRule();
  97. $menuRule = $model->where((is_numeric($id) ? 'id' : 'name'), $id)->find();
  98. if (!$menuRule) {
  99. return false;
  100. }
  101. $menuRule->status = '1';
  102. $menuRule->save();
  103. return true;
  104. }
  105. /**
  106. * 禁用菜单
  107. * @param string|int $id 规则name或id
  108. * @param string $position 位置:backend=后台,frontend=前台
  109. * @return bool
  110. * @throws Throwable
  111. */
  112. public static function disable(string|int $id, string $position = 'backend'): bool
  113. {
  114. $model = $position == 'backend' ? new AdminRule() : new UserRule();
  115. $menuRule = $model->where((is_numeric($id) ? 'id' : 'name'), $id)->find();
  116. if (!$menuRule) {
  117. return false;
  118. }
  119. $menuRule->status = '0';
  120. $menuRule->save();
  121. return true;
  122. }
  123. public static function requiredAttrCheck($menu): bool
  124. {
  125. $attrs = ['type', 'title', 'name'];
  126. foreach ($attrs as $attr) {
  127. if (!array_key_exists($attr, $menu)) {
  128. return false;
  129. }
  130. if (!$menu[$attr]) {
  131. return false;
  132. }
  133. }
  134. return true;
  135. }
  136. }