feat: [document] 양식 디자이너(Block Builder) Phase 2 - 블록 런타임 렌더러

- BlockRendererService: view/edit/print 3모드 렌더링 지원
  - edit 모드: 폼 필드(input/select/textarea/checkbox) 생성
  - view 모드: 읽기 전용 데이터 표시
  - print 모드: 인쇄 최적화 레이아웃
- 데이터 바인딩: block.binding → document_data.field_key 매핑
- 체크박스 그룹: 콤마 구분 값으로 저장/복원
- 테이블 셀 편집: tbl_{blockId}_r{row}_c{col} 키로 EAV 저장
- edit.blade.php: 블록 빌더 서식 분기 (blockFormContainer)
- show.blade.php: 블록 빌더 조회 모드 분기
- DocumentController: renderBlockHtml() 메서드 추가
This commit is contained in:
김보곤
2026-03-06 10:14:39 +09:00
parent 10b3490d9c
commit b60f2109af
4 changed files with 375 additions and 64 deletions

View File

@@ -6,6 +6,7 @@
use App\Models\Documents\DocumentData;
use App\Models\DocumentTemplate;
use App\Models\Items\Item;
use App\Services\BlockRendererService;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\DB;
@@ -80,6 +81,7 @@ public function create(Request $request): View|Response
'templates' => $templates,
'isCreate' => true,
'linkedItemSpecs' => $template ? $this->getLinkedItemSpecs($template) : [],
'blockHtml' => $template ? $this->renderBlockHtml($template, null) : '',
]);
}
@@ -123,6 +125,7 @@ public function edit(int $id): View|Response
'templates' => $templates,
'isCreate' => false,
'linkedItemSpecs' => $this->getLinkedItemSpecs($document->template),
'blockHtml' => $this->renderBlockHtml($document->template, $document),
]);
}
@@ -165,6 +168,7 @@ public function print(int $id): View
return view('documents.print', [
'document' => $document,
'workOrderItems' => $workOrderItems,
'blockHtml' => $this->renderBlockHtml($document->template, $document, 'print'),
]);
}
@@ -274,6 +278,7 @@ public function show(int $id): View
'salesOrder' => $salesOrder,
'materialInputLots' => $materialInputLots,
'itemLotMap' => $itemLotMap ?? collect(),
'blockHtml' => $this->renderBlockHtml($document->template, $document, 'view'),
]);
}
@@ -416,6 +421,30 @@ private function buildInspectionResolveMap(object $workOrder, $workOrderItems, ?
];
}
/**
* 블록 빌더 서식의 HTML 렌더링
*/
private function renderBlockHtml(DocumentTemplate $template, ?Document $document, string $mode = 'edit'): string
{
if (! $template->isBlockBuilder() || empty($template->schema)) {
return '';
}
$schema = $template->schema;
// document_data에서 field_key => field_value 맵 생성
$data = [];
if ($document && $document->data) {
foreach ($document->data as $d) {
$data[$d->field_key] = $d->field_value;
}
}
$renderer = new BlockRendererService;
return $renderer->render($schema, $mode, $data);
}
/**
* 템플릿에 연결된 품목들의 규격 정보 (thickness, width, length) 조회
*/