From 3bf063eccd82a14a0cd84c6230d1f446c111cf70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=B3=B4=EA=B3=A4?= Date: Sat, 21 Mar 2026 14:45:23 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20[=EB=AC=B8=EC=84=9C=EC=96=91=EC=8B=9D]?= =?UTF-8?q?=20=EB=AF=B8=EB=A6=AC=EB=B3=B4=EA=B8=B0=20=EC=84=B9=EC=85=98=20?= =?UTF-8?q?=EC=9D=B4=EB=AF=B8=EC=A7=80=20R2=20=EC=83=81=EB=8C=80=EA=B2=BD?= =?UTF-8?q?=EB=A1=9C=20presigned=20URL=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../partials/preview-modal.blade.php | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) 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 ''; }