MenuService.php 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. <?php
  2. namespace App\Services;
  3. use App\Authority;
  4. use App\Traits\ServiceAppAop;
  5. use App\Menu;
  6. use Illuminate\Database\Eloquent\Collection;
  7. use Illuminate\Support\Facades\Cache;
  8. class MenuService
  9. {
  10. use ServiceAppAop;
  11. protected $modelClass=Menu::class;
  12. public function getMenu()
  13. {
  14. if (!Cache::has("menus")){
  15. if (Cache::lock("menus",2)){
  16. $this->setMenu();
  17. Cache::lock("menus")->release();
  18. }else{
  19. sleep(1);
  20. return Cache::get("menus") ?? [];
  21. }
  22. }
  23. return Cache::get("menus");
  24. }
  25. public function setMenu()
  26. {
  27. //如果需要热更新 为所有用户个人菜单锁定缓存 标记TAGS 在此清除 Cache::tag("tags")->flush()
  28. Cache::forever("menus",Menu::query()
  29. ->select("id","name","parent_id","route","font","font_style")
  30. ->orderByRaw("level DESC,sequence")->get());
  31. }
  32. public function appendMenu(Menu $menu)
  33. {
  34. $menus = $this->getMenu();
  35. if ($menus){
  36. $menus->add($menu);
  37. Cache::forever("menus",$menus);
  38. }
  39. }
  40. //菜单与权限关联依据为 name与parent_id字段 当两个表中任意此字段发生变更 必须刷掉缓存
  41. public function getVisibleFunctionList($authorities = null,&$mapping = [])
  42. {
  43. /** @var Collection $authorities */
  44. if (!$authorities)$authorities = app("AuthorityService")->getUserAuthority();
  45. $authMap = [];
  46. foreach ($authorities as $authority){
  47. $item = $authority->toArray();
  48. $item["child"] = [];
  49. $authMap[$authority->id] = $item;
  50. }
  51. foreach ($authorities as $authority){
  52. if ($authority->id_parent){
  53. if (isset($authMap[$authority->id_parent]))$authMap[$authority->id_parent]["child"][] = $authMap[$authority->id];
  54. else $authMap = $this->formatAuthority($authMap,$authMap[$authority->id]);
  55. unset($authMap[$authority->id]);
  56. }
  57. }
  58. $menus = $this->getMenu();
  59. $menuMap = [];
  60. foreach ($menus as $menu){
  61. $menuMap[$menu->id] = [
  62. "id" => $menu->id,
  63. "child" => [],
  64. "name" => $menu->name,
  65. "font" => $menu->font,
  66. "fontStyle" => $menu->font_style,
  67. "route" => $menu->route,
  68. ];
  69. }
  70. foreach ($menus as $menu){
  71. if ($menu->parent_id){
  72. $menuMap[$menu->parent_id]["child"][] = $menuMap[$menu->id];
  73. unset($menuMap[$menu->id]);
  74. }
  75. }
  76. return array_values($this->formatMenu($menuMap,$authMap,$mapping));
  77. }
  78. /**
  79. * 递归格式化权限组
  80. *
  81. * @param array $authMap
  82. * @param array $authorities
  83. *
  84. * @return array|bool
  85. */
  86. private function formatAuthority(array $authMap,array $authorities)
  87. {
  88. foreach ($authMap as $index=>$data){
  89. if ($data["id"]==$authorities["id_parent"]){
  90. $authMap[$index]["child"][] = $authorities;
  91. unset($authMap[$authorities["id"]]);
  92. return $authMap;
  93. }else{
  94. if ($authMap[$index]["child"]){
  95. $re = $this->formatAuthority($authMap[$index]["child"],$authorities);
  96. if ($re){
  97. $authMap[$index]["child"] = $re;
  98. return $authMap;
  99. }
  100. }
  101. }
  102. }
  103. return false;
  104. }
  105. /**
  106. * 递归格式化菜单组
  107. *
  108. * @param array $menus
  109. * @param array $authorities
  110. * @param array $mapping
  111. *
  112. * @return array|bool
  113. */
  114. private function formatMenu(array $menus,array $authorities,&$mapping=[])
  115. {
  116. foreach ($menus as $index=>$menu){
  117. $mark = false;
  118. foreach ($authorities as $j=>$authority){
  119. if ($menu["name"] == $authority["name"]){
  120. $mapping[$menu["id"]] = $authority["id"];
  121. $mark = true;
  122. $authorities[$j]["mark"] = true;
  123. if ($authority["child"])$menus[$index]["child"] = array_values($this->formatMenu($menu["child"],$authority["child"],$mapping));
  124. }
  125. }
  126. if (!$mark)unset($menus[$index]);
  127. }
  128. foreach ($authorities as $authority){
  129. if (!isset($authority["mark"])){
  130. $menus[] = [
  131. "name" => $authority["name"],
  132. "route" => "",
  133. ];
  134. }
  135. }
  136. return $menus;
  137. }
  138. /**
  139. * 获取菜单与权限映射
  140. */
  141. public function getMenuAndAuthorityMapping()
  142. {
  143. $this->getVisibleFunctionList(Authority::query()->get(),$mapping);
  144. return $mapping;
  145. }
  146. }