importId); $import->update(['status' => 'processing']); try { $ai = AiSetting::get(); $imageB64 = base64_encode(Storage::disk('public')->get($import->image_path)); $prompt = <<post("{$ai->ollama_url}/api/generate", [ 'model' => $ai->ollama_model, 'prompt' => $prompt, 'images' => [$imageB64], 'stream' => false, ]); if ($response->failed()) { throw new \RuntimeException('Ollama API Fehler: ' . $response->status()); } $raw = $response->json('response', ''); $data = $this->parseJson($raw); if (!$data) { throw new \RuntimeException('Ollama-Antwort konnte nicht als JSON geparst werden: ' . $raw); } // Hersteller suchen oder anlegen $manufacturer = null; if (!empty($data['manufacturer'])) { $manufacturer = Manufacturer::firstOrCreate( ['name' => trim($data['manufacturer'])] ); } // Nagellack-Nummer eindeutig machen falls nötig $number = $data['number'] ?? ('import-' . $this->importId); if (NailPolish::where('number', $number)->exists()) { $number .= '-' . $this->importId; } $nailPolish = NailPolish::create([ 'name' => $data['name'] ?? 'Unbekannt', 'number' => $number, 'manufacturer_id' => $manufacturer?->id, 'image_path' => $import->image_path, ]); // Zur Sammlung des Users hinzufügen $import->user->nailPolishes()->syncWithoutDetaching([$nailPolish->id]); $import->update([ 'status' => 'done', 'result' => $data, 'nail_polish_id' => $nailPolish->id, ]); } catch (\Throwable $e) { Log::error('ProcessNailPolishImage fehlgeschlagen', [ 'import_id' => $this->importId, 'error' => $e->getMessage(), ]); $import->update([ 'status' => 'failed', 'error_message' => $e->getMessage(), ]); } } private function parseJson(string $raw): ?array { // JSON aus der Antwort extrahieren (Ollama kann Text drumherum haben) if (preg_match('/\{.*\}/s', $raw, $matches)) { $decoded = json_decode($matches[0], true); if (json_last_error() === JSON_ERROR_NONE) { return $decoded; } } return null; } }