$id > 0))); sort($ids, SORT_NUMERIC); return $ids; } public static function roleAdminIds(array $roleIds): array { return $roleIds === [] ? [] : self::ids(AdminRole::whereIn('role_id', $roleIds)->column('admin_id')); } /** 菜单父节点变更也影响只获授子节点的账号。 */ public static function menuAdminIds(int $menuId): array { $menuIds = [$menuId]; $rows = SystemMenu::field('id,pid')->select()->toArray(); do { $count = count($menuIds); foreach ($rows as $row) { if (in_array((int) $row['pid'], $menuIds, true)) { $menuIds[] = (int) $row['id']; } } $menuIds = self::ids($menuIds); } while (count($menuIds) !== $count); return self::roleAdminIds(self::ids(SystemRoleMenu::whereIn('menu_id', $menuIds)->column('role_id'))); } /** 调用者必须已开启事务;与密码登录、SSO签发和续期共用账号锁。 */ public static function revoke(array $adminIds): array { $adminIds = self::ids($adminIds); if ($adminIds === []) { return []; } Admin::whereIn('id', $adminIds)->order('id')->lock(true)->field('id')->select(); $tokens = AdminSession::whereIn('admin_id', $adminIds)->column('token'); AdminSession::whereIn('admin_id', $adminIds)->update(['expire_time' => time() - 1, 'update_time' => time()]); return $tokens; } public static function clearCommitted(array $adminIds, array $tokens): void { // DB是有效性的准绳;缓存故障不能把已提交操作伪报失败,也不能恢复旧会话。 foreach ($tokens as $token) { try { (new AdminTokenCache())->deleteAdminInfo((string) $token); } catch (\Throwable $error) { Log::warning('账号变更已提交,会话缓存清理失败'); } } foreach (self::ids($adminIds) as $adminId) { try { (new AdminAuthCache($adminId))->clearAuthCache(); } catch (\Throwable $error) { Log::warning('账号变更已提交,权限缓存清理失败:admin_id=' . $adminId); } } } }