Files
sam-api/app/Console/Commands/BendingImportImages.php

116 lines
3.9 KiB
PHP
Raw Normal View History

<?php
namespace App\Console\Commands;
use App\Models\BendingItem;
use App\Models\Commons\File;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
/**
* 레거시 이미지 R2 업로드 + bending_items 연결
*
* 실행: php artisan bending:import-images [--dry-run] [--tenant_id=287]
*/
class BendingImportImages extends Command
{
protected $signature = 'bending:import-images
{--tenant_id=287 : 테넌트 ID}
{--dry-run : 미리보기}
{--legacy-path=/home/kkk/sam/5130/bending/img : 레거시 이미지 경로}';
protected $description = '레거시 절곡품 이미지 → R2 업로드 + bending_items 연결';
public function handle(): int
{
$tenantId = (int) $this->option('tenant_id');
$dryRun = $this->option('dry-run');
$legacyPath = $this->option('legacy-path');
$items = BendingItem::where('tenant_id', $tenantId)
->whereNotNull('legacy_bending_id')
->get();
$chandjMap = DB::connection('chandj')->table('bending')
->whereNotNull('imgdata')
->where('imgdata', '!=', '')
->pluck('imgdata', 'num');
$this->info("bending_items: {$items->count()}건 / chandj imgdata: {$chandjMap->count()}");
$uploaded = 0;
$skipped = 0;
$notFound = 0;
$errors = 0;
foreach ($items as $bi) {
$imgFile = $chandjMap[$bi->legacy_bending_id] ?? null;
if (! $imgFile) {
$skipped++;
continue;
}
$filePath = "{$legacyPath}/{$imgFile}";
if (! file_exists($filePath)) {
$this->warn(" ⚠️ 파일 없음: {$imgFile} (#{$bi->legacy_bending_id})");
$notFound++;
continue;
}
$existing = File::where('document_type', 'bending_item')
->where('document_id', $bi->id)
->where('field_key', 'bending_diagram')
->whereNull('deleted_at')
->first();
if ($existing) {
$skipped++;
continue;
}
if ($dryRun) {
$this->line(" [DRY] #{$bi->legacy_bending_id}{$bi->id} ({$bi->item_name}) ← {$imgFile}");
$uploaded++;
continue;
}
try {
$extension = pathinfo($imgFile, PATHINFO_EXTENSION);
$storedName = bin2hex(random_bytes(8)) . '.' . $extension;
$directory = sprintf('%d/bending/%s/%s', $tenantId, date('Y'), date('m'));
$r2Path = $directory . '/' . $storedName;
Storage::disk('r2')->put($r2Path, file_get_contents($filePath));
File::create([
'tenant_id' => $tenantId,
'display_name' => $imgFile,
'stored_name' => $storedName,
'file_path' => $r2Path,
'file_size' => filesize($filePath),
'mime_type' => mime_content_type($filePath),
'file_type' => 'image',
'field_key' => 'bending_diagram',
'document_id' => $bi->id,
'document_type' => 'bending_item',
'is_temp' => false,
'uploaded_by' => 1,
'created_by' => 1,
]);
$this->line(" ✅ #{$bi->legacy_bending_id}{$bi->id} ({$bi->item_name}) ← {$imgFile}");
$uploaded++;
} catch (\Throwable $e) {
$this->error(" ❌ #{$bi->legacy_bending_id}: {$e->getMessage()}");
$errors++;
}
}
$this->newLine();
$this->info("완료: 업로드 {$uploaded}, 스킵 {$skipped}, 파일없음 {$notFound}, 오류 {$errors}");
return 0;
}
}