diff --git a/app/Http/Controllers/ESign/EsignApiController.php b/app/Http/Controllers/ESign/EsignApiController.php index fb0f732d..fb8bb878 100644 --- a/app/Http/Controllers/ESign/EsignApiController.php +++ b/app/Http/Controllers/ESign/EsignApiController.php @@ -337,9 +337,11 @@ public function store(Request $request): JsonResponse if ($template && $template->items->isNotEmpty()) { $contract->loadMissing('signers'); + // 템플릿 signer_order를 역할(role)로 매핑: 1=creator(갑/회사), 2=counterpart(을/파트너) $signerMap = []; foreach ($contract->signers as $signer) { - $signerMap[$signer->sign_order] = $signer->id; + $templateOrder = $signer->role === 'creator' ? 1 : 2; + $signerMap[$templateOrder] = $signer->id; } $variableValues = $this->buildVariableMap($contract, $template); @@ -366,6 +368,7 @@ public function store(Request $request): JsonResponse 'field_label' => $item->field_label, 'field_variable' => $item->field_variable, 'font_size' => $item->font_size, + 'text_align' => $item->text_align ?? 'L', 'field_value' => $fieldValue, 'is_required' => $item->is_required, 'sort_order' => $item->sort_order, @@ -837,6 +840,7 @@ public function storeTemplate(Request $request): JsonResponse 'items.*.field_label' => 'nullable|string|max:100', 'items.*.field_variable' => 'nullable|string|max:50', 'items.*.font_size' => 'nullable|integer|min:6|max:72', + 'items.*.text_align' => 'nullable|string|in:L,C,R', 'items.*.is_required' => 'nullable|boolean', ]); @@ -900,6 +904,7 @@ public function storeTemplate(Request $request): JsonResponse 'field_label' => $item['field_label'] ?? null, 'field_variable' => $item['field_variable'] ?? null, 'font_size' => $item['font_size'] ?? null, + 'text_align' => $item['text_align'] ?? 'L', 'is_required' => $item['is_required'] ?? true, 'sort_order' => $i, ]); @@ -1067,6 +1072,7 @@ public function updateTemplateItems(Request $request, int $templateId): JsonResp 'items.*.field_label' => 'nullable|string|max:100', 'items.*.field_variable' => 'nullable|string|max:50', 'items.*.font_size' => 'nullable|integer|min:6|max:72', + 'items.*.text_align' => 'nullable|string|in:L,C,R', 'items.*.is_required' => 'nullable|boolean', ]); @@ -1093,6 +1099,7 @@ public function updateTemplateItems(Request $request, int $templateId): JsonResp 'field_label' => $itemData['field_label'] ?? '', 'field_variable' => $itemData['field_variable'] ?? null, 'font_size' => $itemData['font_size'] ?? null, + 'text_align' => $itemData['text_align'] ?? 'L', 'is_required' => $itemData['is_required'] ?? true, 'sort_order' => $i, ]); @@ -1340,8 +1347,8 @@ private function buildVariableMap(EsignContract $contract, EsignFieldTemplate $t { $map = []; - // 시스템 변수: 서명자 정보 - $signers = $contract->signers->sortBy('sign_order'); + // 시스템 변수: 서명자 정보 (역할 기반: 1=creator/갑/회사, 2=counterpart/을/파트너) + $signers = $contract->signers->sortBy(fn($s) => $s->role === 'creator' ? 1 : 2); $idx = 1; foreach ($signers as $signer) { $map["signer{$idx}_name"] = $signer->name; diff --git a/app/Models/ESign/EsignFieldTemplateItem.php b/app/Models/ESign/EsignFieldTemplateItem.php index b4100932..98635d4c 100644 --- a/app/Models/ESign/EsignFieldTemplateItem.php +++ b/app/Models/ESign/EsignFieldTemplateItem.php @@ -21,6 +21,7 @@ class EsignFieldTemplateItem extends Model 'field_label', 'field_variable', 'font_size', + 'text_align', 'is_required', 'sort_order', ]; diff --git a/app/Models/ESign/EsignSignField.php b/app/Models/ESign/EsignSignField.php index 132941ea..0762bc57 100644 --- a/app/Models/ESign/EsignSignField.php +++ b/app/Models/ESign/EsignSignField.php @@ -22,6 +22,7 @@ class EsignSignField extends Model 'field_label', 'field_variable', 'font_size', + 'text_align', 'field_value', 'is_required', 'sort_order', diff --git a/app/Services/ESign/PdfSignatureService.php b/app/Services/ESign/PdfSignatureService.php index c6e6abe8..6f8111ce 100644 --- a/app/Services/ESign/PdfSignatureService.php +++ b/app/Services/ESign/PdfSignatureService.php @@ -168,7 +168,7 @@ private function overlayDate(Fpdi $pdf, EsignSignField $field, float $x, float $ $dateText = now()->format('Y-m-d'); } - $this->renderText($pdf, $dateText, $x, $y, $w, $h, $field->font_size); + $this->renderText($pdf, $dateText, $x, $y, $w, $h, $field->font_size, $field->text_align ?? 'L'); } /** @@ -181,7 +181,7 @@ private function overlayText(Fpdi $pdf, EsignSignField $field, float $x, float $ return; } - $this->renderText($pdf, $text, $x, $y, $w, $h, $field->font_size); + $this->renderText($pdf, $text, $x, $y, $w, $h, $field->font_size, $field->text_align ?? 'L'); } /** @@ -193,29 +193,30 @@ private function overlayCheckbox(Fpdi $pdf, EsignSignField $field, float $x, flo return; } - $this->renderText($pdf, "\xe2\x9c\x93", $x, $y, $w, $h, $field->font_size); // ✓ (UTF-8) + $this->renderText($pdf, "\xe2\x9c\x93", $x, $y, $w, $h, $field->font_size, 'C'); // ✓ (UTF-8) } /** * 텍스트를 지정 영역에 렌더링하는 공통 메서드. */ - private function renderText(Fpdi $pdf, string $text, float $x, float $y, float $w, float $h, ?int $fieldFontSize = null): void + private function renderText(Fpdi $pdf, string $text, float $x, float $y, float $w, float $h, ?int $fieldFontSize = null, string $textAlign = 'L'): void { - // 필드에 지정된 폰트 크기 우선, 없으면 영역 높이 기반 자동 산출 + // 필드에 지정된 폰트 크기 우선, 없으면 영역 높이 기반 자동 산출 (2배 확대) if ($fieldFontSize && $fieldFontSize >= 4) { $fontSize = $fieldFontSize; } else { - $fontSize = min($h * 0.7, 12); - if ($fontSize < 4) { - $fontSize = 4; + $fontSize = min($h * 1.4, 24); + if ($fontSize < 6) { + $fontSize = 6; } } $pdf->SetFont($this->getKoreanFont(), '', $fontSize); $pdf->SetTextColor(0, 0, 0); - // 텍스트를 영역 중앙에 배치 + // 텍스트를 지정된 정렬 방식으로 배치 (L=왼쪽, C=가운데, R=오른쪽) + $align = in_array($textAlign, ['L', 'C', 'R']) ? $textAlign : 'L'; $pdf->SetXY($x, $y); - $pdf->Cell($w, $h, $text, 0, 0, 'C', false, '', 0, false, 'T', 'M'); + $pdf->Cell($w, $h, $text, 0, 0, $align, false, '', 0, false, 'T', 'M'); } } diff --git a/resources/views/esign/template-fields.blade.php b/resources/views/esign/template-fields.blade.php index 36f7138d..f8d94efe 100644 --- a/resources/views/esign/template-fields.blade.php +++ b/resources/views/esign/template-fields.blade.php @@ -461,6 +461,21 @@ className="w-full border rounded px-2 py-1 text-xs mt-0.5" /> className="w-full border rounded px-2 py-1 text-xs mt-0.5" /> + {['text', 'date'].includes(selectedField.field_type) && ( +