diff --git a/resources/views/document-templates/partials/preview-modal.blade.php b/resources/views/document-templates/partials/preview-modal.blade.php index fb3f186e..b2727b00 100644 --- a/resources/views/document-templates/partials/preview-modal.blade.php +++ b/resources/views/document-templates/partials/preview-modal.blade.php @@ -35,12 +35,29 @@ function closePreviewModal() { if (e.key === 'Escape') closePreviewModal(); }); - // 이미지 URL 헬퍼 (file_id 기반 R2 프록시) + // 이미지 URL 헬퍼 (file_id 기반 R2 프록시 + image_path R2 presigned URL) function _previewImageUrl(section) { if (section.image_url) return section.image_url; if (section.file_id) return '/files/' + section.file_id + '/view'; if (!section.image_path) return ''; if (section.image_path.startsWith('http')) return section.image_path; + // R2 상대경로 — presigned URL 요청 (동기) + try { + const xhr = new XMLHttpRequest(); + xhr.open('POST', '{{ config("services.api.internal_url") ?: config("services.api.base_url") }}/api/v1/files/presigned-url-by-path', false); + xhr.setRequestHeader('Content-Type', 'application/json'); + xhr.setRequestHeader('X-API-KEY', '{{ config("services.api.key") }}'); + xhr.setRequestHeader('X-TENANT-ID', '{{ session("selected_tenant_id", 1) }}'); + @if(config('services.api.internal_url')) + xhr.setRequestHeader('Host', '{{ parse_url(config("services.api.base_url"), PHP_URL_HOST) }}'); + @endif + xhr.send(JSON.stringify({ path: section.image_path })); + if (xhr.status === 200) { + const result = JSON.parse(xhr.responseText); + const url = result.data?.url; + if (url) { section.image_url = url; return url; } + } + } catch (e) { console.warn('Preview image URL fetch failed:', e); } return ''; }