feat:템플릿 편집 모달 확장 (PDF 관리 + 서식 필드 관리)
백엔드: - uploadTemplatePdf: 템플릿 PDF 업로드/교체 API - removeTemplatePdf: 템플릿 PDF 제거 API - destroyTemplateItem: 개별 필드 아이템 삭제 API (signer_count 자동 재계산) - updateTemplate 응답에 items 관계 포함 프론트엔드: - 모달 폭 420px → 680px 확장 - 3개 탭 구성: 기본 정보 / PDF 파일 / 서식 필드 - PDF 탭: 현재 파일 정보, 다운로드, 교체, 제거 기능 - 서식 필드 탭: 필드 목록 테이블 (유형/라벨/서명자/페이지/위치/필수), 개별 삭제 - 편집 시 상세 데이터(items 포함) 로드 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -732,7 +732,89 @@ public function updateTemplate(Request $request, int $id): JsonResponse
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => '템플릿이 수정되었습니다.',
|
||||
'data' => $template->fresh()->load('creator:id,name'),
|
||||
'data' => $template->fresh()->load(['creator:id,name', 'items'])->loadCount('items'),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 템플릿 PDF 교체
|
||||
*/
|
||||
public function uploadTemplatePdf(Request $request, int $id): JsonResponse
|
||||
{
|
||||
$request->validate([
|
||||
'file' => 'required|file|mimes:pdf|max:20480',
|
||||
]);
|
||||
|
||||
$tenantId = session('selected_tenant_id', 1);
|
||||
$template = EsignFieldTemplate::forTenant($tenantId)->findOrFail($id);
|
||||
|
||||
// 기존 파일 삭제
|
||||
if ($template->file_path && Storage::disk('local')->exists($template->file_path)) {
|
||||
Storage::disk('local')->delete($template->file_path);
|
||||
}
|
||||
|
||||
$file = $request->file('file');
|
||||
$filePath = $file->store("esign/{$tenantId}/templates", 'local');
|
||||
|
||||
$template->update([
|
||||
'file_path' => $filePath,
|
||||
'file_name' => $file->getClientOriginalName(),
|
||||
'file_hash' => hash_file('sha256', $file->getRealPath()),
|
||||
'file_size' => $file->getSize(),
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'PDF가 교체되었습니다.',
|
||||
'data' => $template->fresh()->load(['creator:id,name', 'items'])->loadCount('items'),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 템플릿 PDF 제거
|
||||
*/
|
||||
public function removeTemplatePdf(int $id): JsonResponse
|
||||
{
|
||||
$tenantId = session('selected_tenant_id', 1);
|
||||
$template = EsignFieldTemplate::forTenant($tenantId)->findOrFail($id);
|
||||
|
||||
if ($template->file_path && Storage::disk('local')->exists($template->file_path)) {
|
||||
Storage::disk('local')->delete($template->file_path);
|
||||
}
|
||||
|
||||
$template->update([
|
||||
'file_path' => null,
|
||||
'file_name' => null,
|
||||
'file_hash' => null,
|
||||
'file_size' => null,
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'PDF가 제거되었습니다.',
|
||||
'data' => $template->fresh()->load(['creator:id,name', 'items'])->loadCount('items'),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 템플릿 필드 아이템 삭제
|
||||
*/
|
||||
public function destroyTemplateItem(int $templateId, int $itemId): JsonResponse
|
||||
{
|
||||
$tenantId = session('selected_tenant_id', 1);
|
||||
$template = EsignFieldTemplate::forTenant($tenantId)->findOrFail($templateId);
|
||||
$item = EsignFieldTemplateItem::where('template_id', $template->id)->findOrFail($itemId);
|
||||
|
||||
$item->delete();
|
||||
|
||||
// signer_count 재계산
|
||||
$maxOrder = EsignFieldTemplateItem::where('template_id', $template->id)->max('signer_order');
|
||||
$template->update(['signer_count' => $maxOrder ?: 0]);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => '필드가 삭제되었습니다.',
|
||||
'data' => $template->fresh()->load(['creator:id,name', 'items'])->loadCount('items'),
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user