diff --git a/app/Http/Controllers/ESign/EsignPublicController.php b/app/Http/Controllers/ESign/EsignPublicController.php index 61796a81..192fecb2 100644 --- a/app/Http/Controllers/ESign/EsignPublicController.php +++ b/app/Http/Controllers/ESign/EsignPublicController.php @@ -361,6 +361,7 @@ public function submitSignature(Request $request, string $token): JsonResponse Log::error('PDF 서명 합성 실패', [ 'contract_id' => $contract->id, 'error' => $e->getMessage(), + 'trace' => $e->getTraceAsString(), ]); } @@ -637,6 +638,26 @@ public function downloadDocument(string $token): StreamedResponse|JsonResponse // 서명 완료된 PDF가 있으면 우선 제공 if ($contract->signed_file_path && Storage::disk('local')->exists($contract->signed_file_path)) { $filePath = $contract->signed_file_path; + } elseif ($contract->status === 'completed') { + // 계약 완료 상태인데 서명 PDF가 없으면 재생성 시도 + try { + $pdfService = new PdfSignatureService; + $filePath = $pdfService->mergeSignatures($contract); + Log::info('서명 PDF 재생성 성공', ['contract_id' => $contract->id, 'path' => $filePath]); + } catch (\Throwable $e) { + Log::error('서명 PDF 재생성 실패', [ + 'contract_id' => $contract->id, + 'error' => $e->getMessage(), + 'trace' => $e->getTraceAsString(), + ]); + // 재생성 실패 시 미리보기 PDF 폴백 (서명 제외, 텍스트/날짜/체크박스만) + try { + $filePath = $pdfService->generatePreview($contract); + } catch (\Throwable $e2) { + Log::warning('미리보기 PDF 생성도 실패, 원본 제공', ['error' => $e2->getMessage()]); + $filePath = $contract->original_file_path; + } + } } else { // 서명 전: 텍스트/날짜/체크박스 필드가 합성된 미리보기 PDF 생성 try { @@ -774,6 +795,12 @@ private function sendCompletionAlimtalk(EsignContract $contract, EsignSigner $si [$signer->access_token, $signer->access_token], urldecode($btn[$urlKey]) ); + // 완료 알림톡: 버튼 URL을 문서 다운로드 엔드포인트로 강제 변경 + // 템플릿 버튼 URL이 서명 페이지(/esign/sign/{token})를 가리키므로 + // 완료된 계약서 PDF 다운로드(/esign/sign/{token}/api/document)로 교체 + if (str_contains($btn[$urlKey], '/esign/sign/') && ! str_contains($btn[$urlKey], '/api/document')) { + $btn[$urlKey] = $documentUrl; + } } } }