feat:템플릿 비주얼 필드 에디터 추가

PDF 위에서 드래그앤드롭으로 템플릿 필드를 편집하는 기능 구현:
- template-fields.blade.php 뷰 생성 (fields.blade.php 기반, signer_order 사용)
- updateTemplateItems API 추가 (필드 일괄 저장)
- 템플릿 카드/모달에 필드 편집 링크 추가

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
김보곤
2026-02-13 06:59:01 +09:00
parent a464cf40de
commit f83a62b479
5 changed files with 885 additions and 1 deletions

View File

@@ -818,6 +818,62 @@ public function destroyTemplateItem(int $templateId, int $itemId): JsonResponse
]);
}
/**
* 템플릿 필드 아이템 일괄 저장 (에디터에서 사용)
*/
public function updateTemplateItems(Request $request, int $templateId): JsonResponse
{
$request->validate([
'items' => 'present|array',
'items.*.signer_order' => 'required|integer|min:1',
'items.*.page_number' => 'required|integer|min:1',
'items.*.position_x' => 'required|numeric',
'items.*.position_y' => 'required|numeric',
'items.*.width' => 'required|numeric',
'items.*.height' => 'required|numeric',
'items.*.field_type' => 'required|in:signature,stamp,text,date,checkbox',
'items.*.field_label' => 'nullable|string|max:100',
'items.*.is_required' => 'nullable|boolean',
]);
$tenantId = session('selected_tenant_id', 1);
$template = EsignFieldTemplate::forTenant($tenantId)->findOrFail($templateId);
$items = $request->input('items', []);
DB::transaction(function () use ($template, $items) {
// 기존 아이템 삭제
EsignFieldTemplateItem::where('template_id', $template->id)->delete();
// 새 아이템 생성
foreach ($items as $i => $itemData) {
EsignFieldTemplateItem::create([
'template_id' => $template->id,
'signer_order' => $itemData['signer_order'],
'page_number' => $itemData['page_number'],
'position_x' => round($itemData['position_x'], 2),
'position_y' => round($itemData['position_y'], 2),
'width' => round($itemData['width'], 2),
'height' => round($itemData['height'], 2),
'field_type' => $itemData['field_type'],
'field_label' => $itemData['field_label'] ?? '',
'is_required' => $itemData['is_required'] ?? true,
'sort_order' => $i,
]);
}
// signer_count 업데이트
$maxOrder = collect($items)->max('signer_order') ?: 0;
$template->update(['signer_count' => $maxOrder]);
});
return response()->json([
'success' => true,
'message' => '템플릿 필드가 저장되었습니다.',
'data' => $template->fresh()->load('items'),
]);
}
/**
* 템플릿 복제
*/