Files
sam-manage/app/Services/ConstructionSitePhotoService.php
2026-02-25 11:45:01 +09:00

183 lines
5.5 KiB
PHP

<?php
namespace App\Services;
use App\Helpers\AiTokenHelper;
use App\Models\Juil\ConstructionSitePhoto;
use App\Models\Juil\ConstructionSitePhotoRow;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
class ConstructionSitePhotoService
{
public function __construct(
private readonly GoogleCloudService $googleCloudService
) {}
public function getList(array $params): LengthAwarePaginator
{
$query = ConstructionSitePhoto::with(['user', 'rows'])
->orderBy('work_date', 'desc')
->orderBy('id', 'desc');
if (! empty($params['search'])) {
$search = $params['search'];
$query->where(function ($q) use ($search) {
$q->where('site_name', 'like', "%{$search}%")
->orWhere('description', 'like', "%{$search}%");
});
}
if (! empty($params['date_from'])) {
$query->where('work_date', '>=', $params['date_from']);
}
if (! empty($params['date_to'])) {
$query->where('work_date', '<=', $params['date_to']);
}
$perPage = (int) ($params['per_page'] ?? 12);
return $query->paginate($perPage);
}
public function create(array $data): ConstructionSitePhoto
{
$photo = ConstructionSitePhoto::create([
'tenant_id' => session('selected_tenant_id'),
'user_id' => Auth::id(),
'site_name' => $data['site_name'],
'work_date' => $data['work_date'],
'description' => $data['description'] ?? null,
]);
// 기본 빈 행 1개 자동 생성
$photo->rows()->create(['sort_order' => 0]);
return $photo->load('rows');
}
public function uploadPhoto(ConstructionSitePhotoRow $row, $file, string $type): bool
{
if (! in_array($type, ['before', 'during', 'after'])) {
return false;
}
$photo = $row->constructionSitePhoto;
$extension = $file->getClientOriginalExtension();
$timestamp = now()->format('Ymd_His');
$objectName = "construction-site-photos/{$photo->tenant_id}/{$photo->id}/{$row->id}_{$timestamp}_{$type}.{$extension}";
// 기존 사진이 있으면 GCS에서 삭제
$oldPath = $row->{$type.'_photo_path'};
if ($oldPath) {
$this->googleCloudService->deleteFromStorage($oldPath);
}
// 임시 파일로 저장 후 GCS 업로드
$tempPath = $file->getRealPath();
$result = $this->googleCloudService->uploadToStorage($tempPath, $objectName);
if (! $result) {
Log::error('ConstructionSitePhoto: GCS 업로드 실패', [
'photo_id' => $photo->id,
'row_id' => $row->id,
'type' => $type,
]);
return false;
}
$row->update([
$type.'_photo_path' => $objectName,
$type.'_photo_gcs_uri' => $result['uri'],
$type.'_photo_size' => $result['size'],
]);
AiTokenHelper::saveGcsStorageUsage('공사현장사진대지-GCS저장', $result['size']);
return true;
}
public function update(ConstructionSitePhoto $photo, array $data): ConstructionSitePhoto
{
$photo->update([
'site_name' => $data['site_name'],
'work_date' => $data['work_date'],
'description' => $data['description'] ?? null,
]);
return $photo->fresh()->load('rows');
}
public function delete(ConstructionSitePhoto $photo): bool
{
// rows 순회하여 모든 GCS 파일 삭제
foreach ($photo->rows as $row) {
foreach (['before', 'during', 'after'] as $type) {
$path = $row->{$type.'_photo_path'};
if ($path) {
$this->googleCloudService->deleteFromStorage($path);
}
}
}
return $photo->delete();
}
public function deletePhotoByType(ConstructionSitePhotoRow $row, string $type): bool
{
if (! in_array($type, ['before', 'during', 'after'])) {
return false;
}
$path = $row->{$type.'_photo_path'};
if ($path) {
$this->googleCloudService->deleteFromStorage($path);
}
$row->update([
$type.'_photo_path' => null,
$type.'_photo_gcs_uri' => null,
$type.'_photo_size' => null,
]);
return true;
}
public function addRow(ConstructionSitePhoto $photo): ConstructionSitePhotoRow
{
$nextOrder = ($photo->rows()->max('sort_order') ?? -1) + 1;
return $photo->rows()->create(['sort_order' => $nextOrder]);
}
public function deleteRow(ConstructionSitePhotoRow $row): bool
{
// 행의 GCS 파일 삭제
foreach (['before', 'during', 'after'] as $type) {
$path = $row->{$type.'_photo_path'};
if ($path) {
$this->googleCloudService->deleteFromStorage($path);
}
}
$photoId = $row->construction_site_photo_id;
$row->delete();
// 나머지 행 순서 재정렬
$remainingRows = ConstructionSitePhotoRow::where('construction_site_photo_id', $photoId)
->orderBy('sort_order')
->get();
foreach ($remainingRows as $i => $r) {
if ($r->sort_order !== $i) {
$r->update(['sort_order' => $i]);
}
}
return true;
}
}