generateQrCodeImage($content, $fileName); if (!$tempPath) { throw new BusinessException('二维码生成失败'); } try { // 上传到 OSS $ossService = new OssService(); $ossPath = 'qr/' . $fileName; $ossUrl = $ossService->uploadImage($tempPath, $ossPath); // 删除临时文件 if (file_exists($tempPath)) { unlink($tempPath); } return [ 'path' => $ossPath, 'url' => $ossUrl, ]; } catch (\Throwable $e) { // 删除临时文件 if (file_exists($tempPath)) { unlink($tempPath); } throw new BusinessException('二维码上传失败:' . $e->getMessage()); } } /** * 生成二维码图片(使用 QR Server API 或本地库) * * @param string $content 二维码内容 * @param string $fileName 文件名 * @return string 临时文件路径,失败返回 false */ private function generateQrCodeImage(string $content, string $fileName) { $tempDir = runtime_path() . '/qr_temp/'; if (!is_dir($tempDir)) { mkdir($tempDir, 0755, true); } $tempPath = $tempDir . $fileName; // 方式1: 使用 endroid/qr-code 库(推荐) if (class_exists('\Endroid\QrCode\QrCode')) { return $this->generateWithEndroid($content, $tempPath); } // 方式2: 使用在线 API(备用方案) return $this->generateWithApi($content, $tempPath); } /** * 使用 endroid/qr-code 生成二维码 */ private function generateWithEndroid(string $content, string $tempPath): string { try { // 5.x 版本使用静态工厂方法 if (method_exists(\Endroid\QrCode\QrCode::class, 'create')) { $qrCode = \Endroid\QrCode\QrCode::create($content) ->setSize(300) ->setMargin(10); } else { // 4.x 及以下版本 $qrCode = new \Endroid\QrCode\QrCode($content); if (method_exists($qrCode, 'setSize')) { $qrCode->setSize(300); } if (method_exists($qrCode, 'setMargin')) { $qrCode->setMargin(10); } } // 获取 Writer if (class_exists('\Endroid\QrCode\Writer\PngWriter')) { $writer = new \Endroid\QrCode\Writer\PngWriter(); } else { // 旧版本可能使用不同的命名空间 $writer = new \Endroid\QrCode\Writer(); } $result = $writer->write($qrCode); // 保存文件 if (method_exists($result, 'getString')) { file_put_contents($tempPath, $result->getString()); } else { // 更旧版本可能直接返回字符串 file_put_contents($tempPath, $result); } return $tempPath; } catch (\Throwable $e) { // 如果 endroid 库使用失败,回退到在线 API error_log('endroid/qr-code 生成失败: ' . $e->getMessage() . ',使用在线 API 备用方案'); return $this->generateWithApi($content, $tempPath); } } /** * 使用在线 API 生成二维码(备用方案) */ private function generateWithApi(string $content, string $tempPath): string { $apiUrl = 'https://api.qrserver.com/v1/create-qr-code/?'; $params = [ 'size' => '300x300', 'data' => $content, 'margin' => '10', ]; $url = $apiUrl . http_build_query($params); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 30); $imageData = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($httpCode !== 200 || !$imageData) { return false; } file_put_contents($tempPath, $imageData); return $tempPath; } /** * 删除 OSS 上的二维码文件 * * @param string $ossPath OSS路径 * @return bool */ public function deleteQrCode(string $ossPath): bool { try { $ossService = new OssService(); return $ossService->deleteFile($ossPath); } catch (\Throwable $e) { return false; } } }