get($url); if (!$response->successful()) { throw new \Exception("Failed to download image from URL: {$url}"); } $imageContent = $response->body(); $mimeType = $response->header('Content-Type', 'image/jpeg'); // 2. 创建临时文件 $extension = $this->getExtensionFromMimeType($mimeType); $tempFileName = 'temp_' . uniqid() . '.' . $extension; $tempPath = sys_get_temp_dir() . '/' . $tempFileName; file_put_contents($tempPath, $imageContent); // 3. 上传到春笋云 $uploadedUrl = $this->uploadToChunsun($tempPath, $tempFileName); // 4. 清理临时文件 @unlink($tempPath); return $uploadedUrl; } catch (\Exception $e) { Log::error('Chunsun upload failed', [ 'url' => $url, 'error' => $e->getMessage(), ]); throw $e; } } /** * 从本地文件上传图片到春笋云 */ public function uploadFromFile(string $localPath): string { try { if (!file_exists($localPath)) { throw new \Exception("Local file does not exist: {$localPath}"); } $fileName = basename($localPath); $uploadedUrl = $this->uploadToChunsun($localPath, $fileName); return $uploadedUrl; } catch (\Exception $e) { Log::error('Chunsun upload from file failed', [ 'path' => $localPath, 'error' => $e->getMessage(), ]); throw $e; } } /** * 上传到春笋云 */ private function uploadToChunsun(string $filePath, string $fileName): string { $uploadUrl = config('services.chunsun.upload_url', env('CHUNSUN_UPLOAD_URL', 'https://crmapi.dcjxb.yunzhixue.cn')); try { $response = Http::timeout(60) ->attach('file', file_get_contents($filePath), $fileName) ->post($uploadUrl); if (!$response->successful()) { Log::error('Chunsun upload HTTP error', [ 'status' => $response->status(), 'body' => $response->body(), 'url' => $uploadUrl, ]); throw new \Exception("Chunsun upload failed with status: {$response->status()}"); } $data = $response->json(); if (!isset($data['code']) || $data['code'] !== 200) { Log::error('Chunsun upload response error', [ 'response' => $data, ]); throw new \Exception("Chunsun upload failed: " . ($data['message'] ?? 'Unknown error')); } if (!isset($data['data']['url'])) { throw new \Exception('No URL in Chunsun upload response'); } Log::info('Chunsun upload successful', [ 'file' => $fileName, 'url' => $data['data']['url'], ]); return $data['data']['url']; } catch (\Exception $e) { Log::error('Chunsun upload exception', [ 'file' => $fileName, 'error' => $e->getMessage(), ]); throw $e; } } /** * 批量上传图片数组 */ public function uploadImagesFromArray(array $imageUrls): array { $uploadedUrls = []; foreach ($imageUrls as $index => $url) { $url = (string) $url; if ($url === '' || !preg_match('#^https?://#i', $url)) { // 非 http(s) URL 不处理(例如 data:、相对路径、本地路径),直接保留 $uploadedUrls[$index] = $url; continue; } try { $uploadedUrls[$index] = $this->uploadFromUrl($url); } catch (\Exception $e) { Log::warning('Failed to upload image', [ 'index' => $index, 'url' => $url, 'error' => $e->getMessage(), ]); // 保留原 URL 作为降级方案 $uploadedUrls[$index] = $url; } } return $uploadedUrls; } /** * 根据 MIME 类型获取文件扩展名 */ private function getExtensionFromMimeType(string $mimeType): string { $extensions = [ 'image/jpeg' => 'jpg', 'image/jpg' => 'jpg', 'image/png' => 'png', 'image/gif' => 'gif', 'image/webp' => 'webp', 'image/svg+xml' => 'svg', ]; return $extensions[$mimeType] ?? 'jpg'; } }