setMenu(); Cache::lock("menus")->release(); }else{ sleep(1); return Cache::get("menus") ?? []; } } return Cache::get("menus"); } public function removeMenuMapping() { Cache::tags("AUTHORITY_MENU_MAPPING")->flush(); } public function setMenu() { //如果需要热更新 为所有用户个人菜单锁定缓存 标记TAGS 在此清除 Cache::tag("tags")->flush() Cache::forever("menus",Menu::query() ->select("id","name","parent_id","route","font","font_style") ->orderByRaw("level DESC,sequence")->get()); $this->removeMenuMapping(); } public function appendMenu(Menu $menu) { $menus = $this->getMenu(); if ($menus){ $menus->add($menu); Cache::forever("menus",$menus); } $this->removeMenuMapping(); } //菜单与权限关联依据为 name与parent_id字段 当两个表中任意此字段发生变更 必须刷掉缓存 public function getVisibleFunctionList($authorities = null,&$mapping = []):array { $userId = Auth::id(); $isCache = !$authorities && !$mapping && $userId; if ($isCache && Cache::tags("AUTHORITY_MENU_MAPPING")->has("am_mapping_".$userId)) return Cache::tags("AUTHORITY_MENU_MAPPING")->get("am_mapping_".$userId); /** @var Collection $authorities */ if (!$authorities)$authorities = app("AuthorityService")->getUserAuthorityData(); $authMap = app("AuthorityService")->format($authorities); $menus = $this->format($this->getMenu()); $result = array_values($this->formatMenu($menus,$authMap,$mapping)); if ($isCache)Cache::tags("AUTHORITY_MENU_MAPPING")->forever("am_mapping_".$userId,$result); return $result; } public function getVisibleMenuListAll() { $key = "am_mapping_all"; if (Cache::tags("AUTHORITY_MENU_MAPPING")->has($key)) return Cache::tags("AUTHORITY_MENU_MAPPING")->get($key); /** @var Collection $authorities */ $authorities = app("AuthorityService")->getUserAuthorityData(true); //获取超管权限(全量) $authMap = app("AuthorityService")->format($authorities); $menus = $this->format($this->getMenu());//菜单权限(全量) $result = array_values($this->formatMenu($menus,$authMap)); Cache::tags("AUTHORITY_MENU_MAPPING")->forever($key,$result); return $result; } /** * 格式化为树状结构 * * @param Collection $menus * @return array */ public function format(Collection $menus):array { $menuMap = []; foreach ($menus as $menu){ $menuMap[$menu->id] = [ "id" => $menu->id, "child" => [], "name" => $menu->name, "font" => $menu->font, "fontStyle" => $menu->font_style, "route" => $menu->route, ]; } foreach ($menus as $menu){ if ($menu->parent_id){ $menuMap[$menu->parent_id]["child"][] = $menuMap[$menu->id]; unset($menuMap[$menu->id]); } } return $menuMap; } /** * 递归格式化菜单组 * * @param array $menus * @param array $authorities * @param array $mapping * * @return array */ private function formatMenu(array $menus,array $authorities,array &$mapping=[]):array { foreach ($menus as $index=>$menu){ $mark = false; foreach ($authorities as $j=>$authority){ if ($menu["name"] == $authority["name"]){ $mapping[$menu["id"]] = $authority["id"]; $menus[$index]["authId"] = $authority["id"]; $mark = true; $authorities[$j]["mark"] = true; if ($authority["child"])$menus[$index]["child"] = array_values($this->formatMenu($menu["child"],$authority["child"],$mapping)); } } if (!$mark)unset($menus[$index]); } foreach ($authorities as $authority){ if (!isset($authority["mark"])){ $menus[] = [ "name" => $authority["name"], "route" => "", ]; } } return $menus; } /** * 获取菜单与权限映射 */ public function getMenuAndAuthorityMapping():array { $mapping = []; $this->getVisibleFunctionList(Authority::query()->get(),$mapping); return $mapping; } /** * 获取唯一名称 */ public function getUniqueName(Menu $menu) { if (!$menu->parent_id)return $menu->name; $menus = $this->getMenu(); $menuMap = []; foreach ($menus as $m)$menuMap[$m->id] = $m; $names = []; while ($menu){ $names[] = $menu->name; if ($menu->parent_id)$menu = $menuMap[$menu->parent_id] ?? null; else $menu = null; } $name = ""; for ($i=count($names)-1;$i>=0;$i--){ $name .= $names[$i]; if ($i!=0)$name .= "-"; } return $name; } }