update(['status' => 'normal']); return true; } /** * 禁用菜单 * @param string $name * @return boolean */ public static function disable($name) { $ids = self::getAuthRuleIdsByName($name); if (!$ids) { return false; } AuthRule::where('id', 'in', $ids)->update(['status' => 'hidden']); return true; } /** * 升级菜单 * @param string $name 插件名称 * @param array $menu 新菜单 * @return bool */ public static function upgrade($name, $menu) { $ids = self::getAuthRuleIdsByName($name); $old = AuthRule::where('id', 'in', $ids)->select(); $old = collection($old)->toArray(); $old = array_column($old, null, 'name'); Db::startTrans(); try { self::menuUpdate($menu, $old); $ids = []; foreach ($old as $index => $item) { if (!isset($item['keep'])) { $ids[] = $item['id']; } } if ($ids) { //旧版本的菜单需要做删除处理 $config = Service::config($name); $menus = isset($config['menus']) ? $config['menus'] : []; $where = ['id' => ['in', $ids]]; if ($menus) { //必须是旧版本中的菜单,可排除用户自主创建的菜单 $where['name'] = ['in', $menus]; } AuthRule::where($where)->delete(); } Db::commit(); } catch (PDOException $e) { Db::rollback(); return false; } Menu::refresh($name, $menu); return true; } /** * 刷新插件菜单配置缓存 * @param string $name * @param array $menu */ public static function refresh($name, $menu = []) { if (!$menu) { // $menu为空时表示首次安装,首次安装需刷新插件菜单标识缓存 $menuIds = Menu::getAuthRuleIdsByName($name); $menus = Db::name("auth_rule")->where('id', 'in', $menuIds)->column('name'); } else { // 刷新新的菜单缓存 $getMenus = function ($menu) use (&$getMenus) { $result = []; foreach ($menu as $index => $item) { $result[] = $item['name']; $result = array_merge($result, isset($item['sublist']) && is_array($item['sublist']) ? $getMenus($item['sublist']) : []); } return $result; }; $menus = $getMenus($menu); } //刷新新的插件核心菜单缓存 Service::config($name, ['menus' => $menus]); } /** * 导出指定名称的菜单规则 * @param string $name * @return array */ public static function export($name) { $ids = self::getAuthRuleIdsByName($name); if (!$ids) { return []; } $menuList = []; $menu = AuthRule::getByName($name); if ($menu) { $ruleList = collection(AuthRule::where('id', 'in', $ids)->select())->toArray(); $menuList = Tree::instance()->init($ruleList)->getTreeArray($menu['id']); } return $menuList; } /** * 菜单升级 * @param array $newMenu * @param array $oldMenu * @param int $parent * @throws Exception */ private static function menuUpdate($newMenu, &$oldMenu, $parent = 0) { if (!is_numeric($parent)) { $parentRule = AuthRule::getByName($parent); $pid = $parentRule ? $parentRule['id'] : 0; } else { $pid = $parent; } $allow = array_flip(['file', 'name', 'title', 'url', 'icon', 'condition', 'remark', 'ismenu', 'menutype', 'extend', 'weigh']); foreach ($newMenu as $k => $v) { $hasChild = isset($v['sublist']) && $v['sublist'] ? true : false; $data = array_intersect_key($v, $allow); $data['ismenu'] = isset($data['ismenu']) ? $data['ismenu'] : ($hasChild ? 1 : 0); $data['icon'] = isset($data['icon']) ? $data['icon'] : ($hasChild ? 'fa fa-list' : 'fa fa-circle-o'); $data['pid'] = $pid; $data['status'] = 'normal'; if (!isset($oldMenu[$data['name']])) { $menu = AuthRule::create($data); } else { $menu = $oldMenu[$data['name']]; //更新旧菜单 AuthRule::update($data, ['id' => $menu['id']]); $oldMenu[$data['name']]['keep'] = true; } if ($hasChild) { self::menuUpdate($v['sublist'], $oldMenu, $menu['id']); } } } /** * 根据名称获取规则IDS * @param string $name * @return array */ public static function getAuthRuleIdsByName($name) { $ids = []; $menu = AuthRule::getByName($name); if ($menu) { // 必须将结果集转换为数组 $ruleList = collection(AuthRule::order('weigh', 'desc')->field('id,pid,name')->select())->toArray(); // 构造菜单数据 $ids = Tree::instance()->init($ruleList)->getChildrenIds($menu['id'], true); } return $ids; } }