apiKey = (string)$apiKey; $this->deviceId = (string)$deviceId; $this->deviceKey = (string)$deviceKey; $this->debug = (bool)$debug; $this->timeout = max(1, intval($timeout)); if (!empty($server)) { $this->server = rtrim((string)$server, '/') . '/'; } } /** * 统一 HTTP 请求 */ private function requests($method, $endpoint, $fields = [], $contentType = 'application/json') { $curl = curl_init(); $headers = ['ApiKey: ' . $this->apiKey]; $postFields = $fields; if ($method === 'POST') { if ($contentType === 'application/json') { $postFields = json_encode($fields, JSON_UNESCAPED_UNICODE); $headers[] = 'Content-Type: application/json'; } // multipart/form-data 由 curl 自动带 boundary,不能手动设 Content-Type } curl_setopt_array($curl, [ CURLOPT_URL => $this->server . ltrim($endpoint, '/'), CURLOPT_RETURNTRANSFER => true, CURLOPT_MAXREDIRS => 1, CURLOPT_TIMEOUT => $this->timeout, CURLOPT_FOLLOWLOCATION => true, CURLINFO_HEADER_OUT => $this->debug, CURLOPT_VERBOSE => $this->debug, CURLOPT_CUSTOMREQUEST => $method, CURLOPT_POSTFIELDS => $postFields, CURLOPT_HTTPHEADER => $headers, ]); $response = curl_exec($curl); $info = curl_getinfo($curl); $errno = curl_errno($curl); $error = curl_error($curl); curl_close($curl); if ($this->debug) { \Yii::info('链科云打印请求: ' . json_encode($info, JSON_UNESCAPED_UNICODE), __METHOD__); } if ($response === false) { throw new CloudPrinterHttpException($error ?: 'curl 请求失败', $errno); } if (intval($info['http_code'] ?? 0) !== 200) { throw new CloudPrinterHttpException('HTTP ' . ($info['http_code'] ?? 0), intval($info['http_code'] ?? 0)); } $data = json_decode($response); if (!is_object($data)) { throw new CloudPrinterApiException('接口返回格式错误'); } if (intval($data->code ?? 0) !== 200) { throw new CloudPrinterApiException($data->msg ?? '链科云打印接口错误', intval($data->code ?? 0)); } return $data; } /** 获取设备信息 */ public function getDeviceInfo() { $data = [ 'deviceId' => $this->deviceId, 'deviceKey' => $this->deviceKey, ]; $response = $this->requests('GET', 'api/device/device_info?' . http_build_query($data)); return $response->data; } /** 异步刷新设备信息(含打印机列表) */ public function asyncRefreshDeviceInfo() { $data = [ 'deviceId' => $this->deviceId, 'deviceKey' => $this->deviceKey, ]; return $this->requests('GET', 'api/device/async_refresh_device_info?' . http_build_query($data)); } /** 获取打印机列表 */ public function getPrinterList() { $data = [ 'deviceId' => $this->deviceId, 'deviceKey' => $this->deviceKey, ]; $response = $this->requests('GET', 'api/external_api/printer_list?' . http_build_query($data)); return $response->data->row ?? []; } /** 获取打印机参数 */ public function getPrinterParams($printerModel) { $data = [ 'deviceId' => $this->deviceId, 'deviceKey' => $this->deviceKey, 'printerModel' => $printerModel, ]; $response = $this->requests('GET', 'api/print/printer_params?' . http_build_query($data)); return $response->data; } /** * 发起打印任务(文件上传) * * @param string $devicePort USB 口 * @param string $printerModel 驱动名 * @param int $paperSize 纸张代码,A4 一般为 9 * @param \CURLFile $file 待打印文件 * @param array $optionalArray 额外参数(份数、颜色等) */ public function addJob($devicePort, $printerModel, $paperSize, $file, $optionalArray = []) { $data = array_merge([ 'deviceId' => $this->deviceId, 'deviceKey' => $this->deviceKey, 'devicePort' => $devicePort, 'printerModel' => $printerModel, 'dmPaperSize' => $paperSize, 'jobFile' => $file, ], $optionalArray); $response = $this->requests('POST', 'api/print/job', $data, 'multipart/form-data'); \Yii::info("发起打印任务",json_encode($response->data)); return $response->data; } /** * 通过本地文件路径发起打印 */ public function addJobByPath($devicePort, $printerModel, $paperSize, $filePath, $optionalArray = []) { $realPath = realpath($filePath); if ($realPath === false || !is_file($realPath)) { throw new CloudPrinterApiException('打印文件不存在'); } $mime = function_exists('mime_content_type') ? mime_content_type($realPath) : ''; if (empty($mime)) { $mime = 'application/octet-stream'; } $file = new \CURLFile($realPath, $mime, basename($realPath)); return $this->addJob($devicePort, $printerModel, $paperSize, $file, $optionalArray); } /** 查询任务状态 */ public function getJobStatus($devicePort, $taskId) { $data = [ 'deviceId' => $this->deviceId, 'deviceKey' => $this->deviceKey, 'devicePort' => $devicePort, 'task_id' => $taskId, ]; $response = $this->requests('GET', 'api/print/job?' . http_build_query($data)); return $response->data; } /** 取消任务 */ public function cancelJob($devicePort, $taskId) { $data = [ 'deviceId' => $this->deviceId, 'deviceKey' => $this->deviceKey, 'devicePort' => $devicePort, 'task_id' => $taskId, ]; return $this->requests('DELETE', 'api/print/job?' . http_build_query($data)); } }