$baseUri, 'timeout' => 60, 'connect_timeout' => 5, 'verify' => false, 'http_errors' => false, 'headers' => [ 'Referer' => \request()->fullUrl() ?? '', 'User-Agent' => 'madong-app-plugin', 'Accept' => 'application/json;charset=UTF-8', ], ]); } /** * 获取授权市场的购买应用 * * @param array $params * * @return array */ public function getPurchasedModules(array $params = []): array { try { $config = [ 'auth_code' => config('madong.auth_code', ''), 'auth_secret' => config('madong.auth_secret', ''), 'page' => config('madong.page', 1), 'limit' => config('madong.limit', 999), 'market_host' => config('madong.market_host', 'https://madong.tech'), ]; $args = Dict::of($config); //优先使用传入的参数 if (!empty($params['auth_code'])) { $args->put('auth_code', $params['auth_code']); } if (!empty($params['auth_secret'])) { $args->put('auth_secret', $params['auth_secret']); } if (!empty($params['page'])) { $args->put('page', $params['page']); } if (!empty($params['limit'])) { $args->put('limit', $params['limit']); } if (!empty($params['market_host'])) { $args->put('market_host', $params['market_host']); } if (empty($args->get('auth_code')) || empty($args->get('auth_secret'))) { return []; } // 所有请求都通过远程 curl 获取 return $this->getPurchasedModulesFromRemote($args->toArray()); } catch (\Throwable $e) { \support\Log::error('getPurchasedModules error: ' . $e->getMessage()); return []; } } /** * 获取远程模块 * * @param array $args * * @return array * @throws \GuzzleHttp\Exception\GuzzleException */ public function getPurchasedModulesFromRemote(array $args): array { try { $client = $this->createHttpClient($args['market_host']); $sign = md5($args['auth_code'] . $args['auth_secret'] . (string)time()); $response = $client->get('/api/madong/apps', [ 'query' => [ 'auth_code' => $args['auth_code'], 'auth_secret' => $args['auth_secret'], 'timestamp' => time(), 'sign' => $sign, 'page' => 1, 'limit' => 999, ], ]); $content = $response->getBody()->getContents(); $data = json_decode($content, true); // 如果返回格式错误,记录日志并返回空数组 if (json_last_error() !== JSON_ERROR_NONE) { \support\Log::error('getPurchasedModulesFromRemote: JSON解析失败 - ' . json_last_error_msg()); return []; } // 检查并验证返回的数据结构 if (!is_array($data)) { \support\Log::error('getPurchasedModulesFromRemote: 返回数据不是数组 - ' . $content); return []; } // API返回格式: {code: int, msg: string, data: {items: array, total: int}} if (isset($data['code']) && $data['code'] !== 0) { \support\Log::error('getPurchasedModulesFromRemote: API返回错误 - ' . ($data['msg'] ?? '未知错误')); return []; } // 提取 items 列表 if (isset($data['data']) && is_array($data['data']) && isset($data['data']['items'])) { $items = $data['data']['items']; if (!is_array($items)) { \support\Log::error('getPurchasedModulesFromRemote: items 不是数组'); return []; } return $items; } // 没有找到items,返回空数组 return []; } catch (\Exception $e) { \support\Log::error('getPurchasedModulesFromRemote error: ' . $e->getMessage()); return []; } } /** * 获取远程模块的更新列表 * * @param string $authCode 授权码 * @param string $secretKey 密钥 * @param array $filters 过滤条件 * * @return array */ public function getRemoteUpdateList(string $authCode, string $secretKey, array $filters = []): array { try { $config = [ 'auth_code' => $authCode, 'auth_secret' => $secretKey, 'market_host' => config('madong.market_host', 'https://madong.tech'), ] + $filters; // 所有请求都通过远程 curl 获取 return $this->getRemoteUpdateListFromRemote($config); } catch (\Exception) { return []; } } /** * 从远程获取模块更新列表 * * @param array $args * * @return array */ private function getRemoteUpdateListFromRemote(array $args): array { try { $client = $this->createHttpClient($args['market_host']); $sign = md5($args['auth_code'] . $args['auth_secret'] . (string)time()); $response = $client->get('/api/madong/apps', [ 'query' => [ 'auth_code' => $args['auth_code'], 'auth_secret' => $args['auth_secret'], 'timestamp' => time(), 'sign' => $sign, 'page' => 1, 'limit' => 999, ], ]); $content = $response->getBody()->getContents(); $data = json_decode($content, true); // 如果返回格式错误,记录日志并返回空数组 if (json_last_error() !== JSON_ERROR_NONE) { \support\Log::error('getRemoteUpdateListFromRemote: JSON解析失败 - ' . json_last_error_msg()); return []; } // 检查并验证返回的数据结构 if (!is_array($data)) { \support\Log::error('getRemoteUpdateListFromRemote: 返回数据不是数组 - ' . $content); return []; } // API返回格式: {code: int, msg: string, data: {items: array, total: int}} // 检查code,非0表示错误 if (isset($data['code']) && $data['code'] !== 0) { \support\Log::error('getRemoteUpdateListFromRemote: API返回错误 - ' . ($data['msg'] ?? '未知错误')); return []; } // 提取 items 列表 if (isset($data['data']) && is_array($data['data']) && isset($data['data']['items'])) { $items = $data['data']['items']; if (!is_array($items)) { \support\Log::error('getRemoteUpdateListFromRemote: items 不是数组'); return []; } return $items; } // 没有找到items,返回空数组 return []; } catch (\Exception $e) { \support\Log::error('getRemoteUpdateListFromRemote error: ' . $e->getMessage()); return []; } } /** * 获取远程模块下载服务 * * @param string $authCode 授权码 * @param string $secretKey 密钥 * @param string $appId 应用ID * @param string $version 版本号 * * @return array */ public function getRemoteDownloadService(string $authCode, string $secretKey, string $appId, string $version): array { try { $config = [ 'auth_code' => $authCode, 'auth_secret' => $secretKey, 'app_id' => $appId, 'version' => $version, 'market_host' => config('madong.market_host', 'https://madong.tech'), ]; // 所有请求都通过远程 curl 获取 return $this->getRemoteDownloadServiceFromRemote($config); } catch (\Exception $e) { \support\Log::error('getRemoteDownloadService error: ' . $e->getMessage()); return []; } } /** * 从远程获取模块下载服务 * * @param array $args * * @return array */ private function getRemoteDownloadServiceFromRemote(array $args): array { try { $client = $this->createHttpClient($args['market_host']); $sign = md5($args['auth_code'] . $args['auth_secret'] . (string)time()); // 记录请求参数 \support\Log::info('getRemoteDownloadServiceFromRemote 请求参数', [ 'market_host' => $args['market_host'], 'app_id' => $args['app_id'], 'version' => $args['version'], 'auth_code' => $args['auth_code'], 'auth_secret_prefix' => substr($args['auth_secret'], 0, 4) . '***', ]); $response = $client->get('/api/madong/apps/download', [ 'query' => [ 'auth_code' => $args['auth_code'], 'auth_secret' => $args['auth_secret'], 'app_id' => $args['app_id'], 'version' => $args['version'], 'timestamp' => time(), 'sign' => $sign, ], ]); $content = $response->getBody()->getContents(); $data = json_decode($content, true); // 记录响应内容 \support\Log::info('getRemoteDownloadServiceFromRemote 响应内容', [ 'status_code' => $response->getStatusCode(), 'content_length' => strlen($content), 'content_preview' => substr($content, 0, 500), ]); // 如果返回格式错误,记录日志并返回空数组 if (json_last_error() !== JSON_ERROR_NONE) { \support\Log::error('getRemoteDownloadServiceFromRemote: JSON解析失败 - ' . json_last_error_msg(), [ 'content' => $content, ]); return []; } // 检查并验证返回的数据结构 if (!is_array($data)) { \support\Log::error('getRemoteDownloadServiceFromRemote: 返回数据不是数组 - ' . $content); return []; } // API返回格式: {code: int, msg: string, data: {...}} // 检查code,非0表示错误 if (isset($data['code']) && $data['code'] !== 0) { \support\Log::error('getRemoteDownloadServiceFromRemote: API返回错误', [ 'code' => $data['code'], 'msg' => $data['msg'] ?? '未知错误', 'data' => $data['data'] ?? null, ]); return []; } // 确保返回的是下载服务数据 if (isset($data['data']) && is_array($data['data'])) { \support\Log::info('getRemoteDownloadServiceFromRemote: 成功获取下载链接', [ 'has_url' => isset($data['data']['url']), 'url_length' => isset($data['data']['url']) ? strlen($data['data']['url']) : 0, ]); return $data['data']; } return []; } catch (\Exception $e) { \support\Log::error('getRemoteDownloadServiceFromRemote error', [ 'message' => $e->getMessage(), 'file' => $e->getFile(), 'line' => $e->getLine(), 'trace' => $e->getTraceAsString(), ]); return []; } } /** * 验证远程授权 * * @param string $authCode 授权码 * @param string $secretKey 密钥 * * @return array * @throws \GuzzleHttp\Exception\GuzzleException * @throws \core\exception\handler\AdminException */ public function verifyRemoteAuthorization(string $authCode, string $secretKey): array { try { $config = [ 'auth_code' => $authCode, 'auth_secret' => $secretKey, 'market_host' => config('madong.market_host', 'https://madong.tech'), ]; // 所有请求都通过远程 curl 获取 return $this->verifyRemoteAuthorizationFromRemote($config); } catch (\Exception $e) { throw new AdminException($e->getMessage()); } } /** * 从远程验证授权 * * @param array $args * * @return array * @throws \GuzzleHttp\Exception\GuzzleException * @throws \core\exception\handler\AdminException */ private function verifyRemoteAuthorizationFromRemote(array $args): array { try { $client = $this->createHttpClient($args['market_host']); $sign = md5($args['auth_code'] . $args['auth_secret'] . (string)time()); $response = $client->get('/api/madong/authorization/verify', [ 'query' => [ 'auth_code' => $args['auth_code'], 'auth_secret' => $args['auth_secret'], 'timestamp' => time(), 'sign' => $sign, ], ]); $content = $response->getBody()->getContents(); $data = json_decode($content, true); // 如果返回格式错误,记录日志 if (json_last_error() !== JSON_ERROR_NONE) { throw new \Exception('JSON解析失败: ' . json_last_error_msg()); } // 检查并验证返回的数据结构 if (!is_array($data)) { throw new \Exception('返回数据不是数组'); } // 检查返回的code是否为0 if (isset($data['code']) && $data['code'] !== 0) { throw new \Exception($data['msg'] ?? '授权验证失败'); } // 确保返回的是授权验证数据 if (isset($data['data']) && is_array($data['data'])) { return $data['data']; } return $data; } catch (\Exception $e) { throw new AdminException($e->getMessage()); } } /** * 获取远程应用升级日志 * * @param string $authCode 授权码 * @param string $secretKey 密钥 * @param string $appCode 应用编码 * @param int $limit 限制数量 * * @return array */ public function getRemoteUpdateLogs(string $authCode, string $secretKey, string $appCode, int $limit = 100): array { try { $config = [ 'auth_code' => $authCode, 'auth_secret' => $secretKey, 'code' => $appCode, 'limit' => $limit, 'market_host' => config('madong.market_host', 'https://madong.tech'), ]; // 所有请求都通过远程 curl 获取 return $this->getRemoteUpdateLogsFromRemote($config); } catch (\Exception $e) { \support\Log::error('getRemoteUpdateLogs error: ' . $e->getMessage()); return []; } } /** * 从远程获取应用升级日志 * * @param array $args * * @return array */ private function getRemoteUpdateLogsFromRemote(array $args): array { try { $client = $this->createHttpClient($args['market_host']); $sign = md5($args['auth_code'] . $args['auth_secret'] . (string)time()); $response = $client->get('/api/madong/apps/update-logs', [ 'query' => [ 'auth_code' => $args['auth_code'], 'auth_secret' => $args['auth_secret'], 'code' => $args['code'], 'limit' => $args['limit'], 'timestamp' => time(), 'sign' => $sign, ], ]); $content = $response->getBody()->getContents(); $data = json_decode($content, true); // 如果返回格式错误,记录日志并返回空数组 if (json_last_error() !== JSON_ERROR_NONE) { \support\Log::error('getRemoteUpdateLogsFromRemote: JSON解析失败 - ' . json_last_error_msg()); return []; } // 检查并验证返回的数据结构 if (!is_array($data)) { \support\Log::error('getRemoteUpdateLogsFromRemote: 返回数据不是数组 - ' . $content); return []; } // API返回格式: {code: int, msg: string, data: {...}} // 检查code,非0表示错误 if (isset($data['code']) && $data['code'] !== 0) { \support\Log::error('getRemoteUpdateLogsFromRemote: API返回错误 - ' . ($data['msg'] ?? '未知错误')); return []; } // 确保返回的是升级日志数据 if (isset($data['data']) && is_array($data['data'])) { return $data['data']; } return []; } catch (\Exception $e) { \support\Log::error('getRemoteUpdateLogsFromRemote error: ' . $e->getMessage()); return []; } } }