'https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/toyota.svg', 'Nissan' => 'https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/nissan.svg', 'Mitsubishi' => 'https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/mitsubishi.svg', 'Honda' => 'https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/honda.svg', 'Subaru' => 'https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/subaru.svg', 'Mazda' => 'https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/mazda.svg', 'Suzuki' => 'https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/suzuki.svg', 'Lexus' => 'https://upload.wikimedia.org/wikipedia/commons/7/75/Lexus.svg', 'Infiniti' => 'https://upload.wikimedia.org/wikipedia/commons/c/c3/Infiniti_logo.svg', 'BMW' => 'https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/bmw.svg', 'Mercedes-Benz' => 'https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/mercedes.svg', 'Audi' => 'https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/audi.svg', 'Volkswagen' => 'https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/volkswagen.svg', 'Porsche' => 'https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/porsche.svg', 'Land Rover' => 'https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/landrover.svg', 'Jeep' => 'https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/jeep.svg', 'Ford' => 'https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/ford.svg', 'Chevrolet' => 'https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/chevrolet.svg', 'Kia' => 'https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/kia.svg', 'Hyundai' => 'https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/hyundai.svg', 'Volvo' => 'https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/volvo.svg', 'Skoda' => 'https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/skoda.svg', 'Renault' => 'https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/renault.svg', 'Tesla' => 'https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/tesla.svg', 'Chery' => 'https://upload.wikimedia.org/wikipedia/commons/b/b6/Chery_logo.svg', 'Geely' => 'https://upload.wikimedia.org/wikipedia/commons/d/d4/Geely_logo.svg', ]; public function handle(): int { $section = DictSection::where('code', 'makes')->first(); if (! $section) { $this->error('Раздел справочника "makes" не найден.'); return 1; } Storage::disk('public')->makeDirectory('makes/logos'); $makes = DictValue::where('section_id', $section->id) ->whereNull('parent_id') ->get(['id', 'value', 'logo']); $this->info("Найдено {$makes->count()} марок. Начинаю загрузку..."); $downloaded = 0; $skipped = 0; foreach ($makes as $make) { $url = $this->logoUrls[$make->value] ?? null; if (! $url) { $this->line(" ⚠ {$make->value}: нет источника в карте логотипов"); continue; } $filename = 'makes/logos/'.Str::slug($make->value).'.svg'; // Пропускаем если файл уже есть и не --force if (! $this->option('force') && $make->logo && Storage::disk('public')->exists($make->logo)) { $this->line(" ✓ {$make->value}: пропущено (уже есть)"); $skipped++; continue; } try { $response = Http::timeout(15) ->withHeaders(['User-Agent' => 'TochaApp/1.0 (logo-downloader; contact@tocha.ru)']) ->get($url); if (! $response->successful()) { $this->warn(" ✗ {$make->value}: HTTP {$response->status()} → {$url}"); continue; } Storage::disk('public')->put($filename, $response->body()); $make->update(['logo' => $filename]); $this->info(" ↓ {$make->value}: сохранён → {$filename}"); $downloaded++; } catch (\Throwable $e) { $this->warn(" ✗ {$make->value}: {$e->getMessage()}"); } } $this->info("Готово: скачано {$downloaded}, пропущено {$skipped}."); return 0; } }