addOrEditMenu($menuInfo, $key); } /** * 获取菜单列表 * @param string $show * @param string $category * @return array|mixed|string */ public function getMenusList($show = '', $category = 'admin') { // 判断并获取缓存 if (empty($show)) { if (Cache::has($category . 'MenusList')) { return Cache::get($category . 'MenusList'); } } else { if (Cache::has($category . 'MenusShowList')) { return Cache::get($category . 'MenusShowList'); } } return $this->sortMenuAndCache($show, $category); } /** * 排序子菜单并缓存 * --------------------------------- * array_column($array,$name) * $array => 要查询的数组 * $name => 在数组中要返回的字段值 *---------------------------------- * array_multisort($array1,$rule,$array2) * $array1 => 规定数组(规定以这个数组来排序) * $rule => 规定排列顺序。 * 可能的值: * SORT_ASC - 默认。按升序排列 (A-Z)。 * SORT_DESC - 按降序排列 (Z-A)。 * $array2 => 要规定的数组。(要排序的数组) */ public function sortMenuAndCache($show = '', $category = 'admin') { $menus = Menu::where('category', $category); if (!empty($show)) { $menus = $menus->where('show', $show); } $menus = $menus->orderBy('sort', 'desc')->get()->toArray(); if ($menus) { $menuList = $this->sortMenu($menus); foreach ($menuList as $key => $value) { if ($value['child']) { $sort = array_column($value['child'], 'sort'); array_multisort($sort, SORT_DESC, $value['child']); } } //缓存菜单数据 if (!empty($show)) { Cache::forever($category . 'MenusShowList', $menuList); } else { Cache::forever($category . 'MenusList', $menuList); } return $menuList; } return []; } /** * 递归菜单数据 * @param $menus * @param int $pid * @return array|string */ public function sortMenu($menus, $pid = 0) { $arr = []; if (empty($menus)) { return ''; } $num = 0; foreach ($menus as $key => $value) { if ($value['parent_id'] == $pid) { $arr[$num] = $value; $arr[$num]['child'] = self::sortMenu($menus, $value['id']); $num += 1; } } return $arr; } /** * 递归删除菜单 * @param $menuId * @return bool */ public function delMenu($menuId, $category = 'admin') { $menu = Menu::find($menuId); $subMenus = Menu::where('parent_id', $menuId)->get()->toArray(); if (count($subMenus) > 0) { // 如果有子菜单将子菜单删除 foreach ($subMenus as $subMenu) { self::delMenu($subMenu['id']); } } // $permission = Permission::where('name', $menu['slug']) // ->where('route', $menu['path']) // ->where('guard_name', 'admin')->first(); // // if ($permission) { // $permission->delete(); // } if ($menu) { $menu->delete(); } $this->sortMenuAndCache(1, $category); $this->sortMenuAndCache('', $category); return true; } /** * 获取单个菜单信息 * @param $menuId * @return bool */ public function getMenuInfo($menuId) { if (!isset($menuId)) { return false; } return Menu::find($menuId); } /** * 编辑菜单 * @param $menuInfo * @return bool */ public function editMenu($menuInfo) { if (!isset($menuInfo['id'])) { return false; } if ($menuInfo['id'] == $menuInfo['parent_id']) { return false; } return $this->addOrEditMenu($menuInfo); } protected function addOrEditMenu($menuInfo, $key = 'id') { // 判断层级 if ($menuInfo['parent_id'] == 0) { $menuInfo['tier'] = 1; $degree = ''; } else { $menuParent = Menu::find($menuInfo['parent_id']); $menuInfo['tier'] = $menuParent->tier + 1; $degree = $menuParent->degree . '|'; } // 判断分类 if (!isset($menuInfo['category'])) { $menuInfo['category'] = 'admin'; } if (!isset($menuInfo['can_del'])) { $menuInfo['can_del'] = 1; } // 增加部门标识(如果为空则自动生成拼音) if (!isset($menuInfo['slug']) || empty($menuInfo['slug'])) { $cn = "/[\x{4e00}-\x{9fa5}a-zA-Z0-9\/]/u"; // 提取字母中文以及'/' preg_match_all($cn, $menuInfo['path'], $pathResult); $pathResult = implode('', $pathResult[0]); $menuInfo['slug'] = lcfirst(implode(array_map(function ($item) { return ucfirst($item); }, pinyin($pathResult)))); } // 更新前数据 if (isset($menuInfo[$key]) && !empty($menuInfo[$key])) { $oldMenu = Menu::where($key, $menuInfo[$key])->first(); if ($oldMenu) { $permissionName = $oldMenu['slug']; } } else { $menuHas = Menu::where('slug', $menuInfo['slug'])->first(); if ($menuHas) { return 'has'; } $permissionName = $menuInfo['slug']; } $menu = Menu::updateOrCreate([$key => $menuInfo[$key] ?? ''], $menuInfo); $menu->degree = $degree . $menu->id; // 保存数据 $menu->save(); // 修改子树中数据,未改变层级不进行调整 if (isset($menuInfo[$key]) && isset($oldMenu['degree']) && $oldMenu['degree'] != $menu['degree']) { // 如果改变父级,联动改变其下属所有子集 // 层级 $diffTier = $oldMenu['tier'] - $menuInfo['tier']; // 查找子数据数组(array) $childMenus = Menu::where('degree', 'like', $oldMenu['degree'] . '|%')->get(); foreach ($childMenus as $childMenu) { // 第一条子数据 // 修改树路径:修改的树|更新的树|子树 $degree = str_replace($oldMenu['degree'] . '|', $menu['degree'] . '|', $childMenu['degree']); // 获取详情 $_menu = Menu::where('id', $childMenu['id'])->first(); // 路劲数据 $_menu->degree = $degree; // 层级 $_menu->tier = $_menu->tier - $diffTier; // 保存 $_menu->save(); } } // 权限 $permissionInfo['title'] = $menuInfo['title']; $permissionInfo['name'] = $menuInfo['slug']; $permissionInfo['route'] = $menuInfo['path']; $permissionInfo['guard_name'] = $menuInfo['category']; // Permission::updateOrCreate(['name' => $permissionName ?? ''], $permissionInfo); $this->sortMenuAndCache(1, $menuInfo['category']); $this->sortMenuAndCache('', $menuInfo['category']); return $menu; } }