From 51aad4e5228e1bc263fd48c33f0367366d0e9d2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B6=8C=ED=98=81=EC=84=B1?= Date: Wed, 11 Feb 2026 15:58:39 +0900 Subject: [PATCH] =?UTF-8?q?feat(API):=20=EA=B2=80=EC=82=AC=20=EB=AC=B8?= =?UTF-8?q?=EC=84=9C/=EC=84=B1=EC=A0=81=EC=84=9C=20=EC=97=B0=EB=8F=99=20?= =?UTF-8?q?=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - DocumentService: formatTemplateForReact 필드명 정합성 수정 (column_type, sub_labels, section title/image_path) - WorkOrderService: process.options 로딩, 검사데이터 document_data 변환 로직 추가 - StoreItemInspectionRequest: templateValues 유효성 규칙 추가 Co-Authored-By: Claude Opus 4.6 --- .../WorkOrder/StoreItemInspectionRequest.php | 2 + app/Services/DocumentService.php | 14 ++--- app/Services/WorkOrderService.php | 57 +++++++++++++++++-- 3 files changed, 62 insertions(+), 11 deletions(-) diff --git a/app/Http/Requests/WorkOrder/StoreItemInspectionRequest.php b/app/Http/Requests/WorkOrder/StoreItemInspectionRequest.php index ef74550..b5dba3a 100644 --- a/app/Http/Requests/WorkOrder/StoreItemInspectionRequest.php +++ b/app/Http/Requests/WorkOrder/StoreItemInspectionRequest.php @@ -37,6 +37,8 @@ public function rules(): array 'inspection_data.gapPoints.*.right' => 'nullable|numeric', 'inspection_data.judgment' => ['nullable', Rule::in(['pass', 'fail'])], 'inspection_data.nonConformingContent' => 'nullable|string|max:1000', + 'inspection_data.templateValues' => 'nullable|array', + 'inspection_data.templateValues.*' => 'nullable', ]; } diff --git a/app/Services/DocumentService.php b/app/Services/DocumentService.php index 012ffd6..84373d7 100644 --- a/app/Services/DocumentService.php +++ b/app/Services/DocumentService.php @@ -646,10 +646,8 @@ public function formatTemplateForReact(DocumentTemplate $template): array 'id' => $field->id, 'field_key' => $field->field_key, 'label' => $field->label, - 'input_type' => $field->input_type, - 'options' => $field->options, + 'field_type' => $field->field_type, 'default_value' => $field->default_value, - 'is_required' => $field->is_required, 'sort_order' => $field->sort_order, ])->toArray(), 'section_fields' => $template->sectionFields->map(fn ($field) => [ @@ -664,7 +662,9 @@ public function formatTemplateForReact(DocumentTemplate $template): array ])->toArray(), 'sections' => $template->sections->map(fn ($section) => [ 'id' => $section->id, - 'name' => $section->name, + 'name' => $section->title, + 'title' => $section->title, + 'image_path' => $section->image_path, 'sort_order' => $section->sort_order, 'items' => $section->items->map(function ($item) use ($methodCodes) { // method 코드를 한글 이름으로 변환 @@ -693,10 +693,10 @@ public function formatTemplateForReact(DocumentTemplate $template): array 'columns' => $template->columns->map(fn ($col) => [ 'id' => $col->id, 'label' => $col->label, - 'input_type' => $col->input_type, - 'options' => $col->options, + 'column_type' => $col->column_type, + 'sub_labels' => $col->sub_labels, + 'group_name' => $col->group_name, 'width' => $col->width, - 'is_required' => $col->is_required, 'sort_order' => $col->sort_order, ])->toArray(), ]; diff --git a/app/Services/WorkOrderService.php b/app/Services/WorkOrderService.php index d8e2c92..5e6bcc0 100644 --- a/app/Services/WorkOrderService.php +++ b/app/Services/WorkOrderService.php @@ -53,7 +53,7 @@ public function index(array $params) 'team:id,name', 'salesOrder' => fn ($q) => $q->select('id', 'order_no', 'client_id', 'client_name', 'site_name', 'quantity', 'received_at', 'delivery_date')->withCount('rootNodes'), 'salesOrder.client:id,name', - 'process:id,process_name,process_code,department', + 'process:id,process_name,process_code,department,options', 'items:id,work_order_id,item_id,item_name,specification,quantity,unit,status,options,sort_order,source_order_item_id', 'items.sourceOrderItem:id,order_node_id,floor_code,symbol_code', 'items.sourceOrderItem.node:id,name,code', @@ -208,7 +208,7 @@ public function show(int $id) 'salesOrder' => fn ($q) => $q->select('id', 'order_no', 'site_name', 'client_id', 'client_contact', 'received_at', 'writer_id', 'created_at', 'quantity')->withCount('rootNodes'), 'salesOrder.client:id,name', 'salesOrder.writer:id,name', - 'process:id,process_name,process_code,work_steps,department', + 'process:id,process_name,process_code,work_steps,department,options', 'process.steps' => fn ($q) => $q->where('is_active', true)->orderBy('sort_order'), 'items.sourceOrderItem:id,order_node_id,floor_code,symbol_code', 'items.sourceOrderItem.node:id,name,code', @@ -1796,10 +1796,15 @@ public function createInspectionDocument(int $workOrderId, array $inspectionData ->latest() ->first(); + // 프론트 InspectionData를 document_data 레코드 형식으로 변환 + $documentDataRecords = $this->transformInspectionDataToDocumentRecords( + $inspectionData['data'] ?? [] + ); + if ($existingDocument) { $document = $documentService->update($existingDocument->id, [ 'title' => $inspectionData['title'] ?? $existingDocument->title, - 'data' => $inspectionData['data'] ?? [], + 'data' => $documentDataRecords, ]); $action = 'inspection_document_updated'; @@ -1809,7 +1814,7 @@ public function createInspectionDocument(int $workOrderId, array $inspectionData 'title' => $inspectionData['title'] ?? "중간검사성적서 - {$workOrder->work_order_no}", 'linkable_type' => 'work_order', 'linkable_id' => $workOrderId, - 'data' => $inspectionData['data'] ?? [], + 'data' => $documentDataRecords, 'approvers' => $inspectionData['approvers'] ?? [], ]; @@ -1835,6 +1840,50 @@ public function createInspectionDocument(int $workOrderId, array $inspectionData ]; } + /** + * 프론트 InspectionData 배열을 document_data 레코드 형식으로 변환 + * + * 프론트에서 보내는 형식: + * [{ productName, specification, judgment, nonConformingContent, templateValues: { section_X_item_Y: "ok"|number } }] + * + * document_data 테이블 형식: + * [{ field_key, field_value, row_index, section_id?, column_id? }] + */ + private function transformInspectionDataToDocumentRecords(array $rawItems): array + { + $records = []; + + foreach ($rawItems as $rowIdx => $item) { + // templateValues의 각 키-값을 document_data 레코드로 변환 + $templateValues = $item['templateValues'] ?? []; + foreach ($templateValues as $key => $value) { + $records[] = [ + 'field_key' => $key, + 'field_value' => is_array($value) ? json_encode($value) : (string) $value, + 'row_index' => $rowIdx, + ]; + } + + // 판정, 부적합 내용 등 메타 필드도 저장 + if (isset($item['judgment'])) { + $records[] = [ + 'field_key' => '_judgment', + 'field_value' => (string) $item['judgment'], + 'row_index' => $rowIdx, + ]; + } + if (! empty($item['nonConformingContent'])) { + $records[] = [ + 'field_key' => '_nonConformingContent', + 'field_value' => (string) $item['nonConformingContent'], + 'row_index' => $rowIdx, + ]; + } + } + + return $records; + } + /** * 작업지시 기본정보 빌드 (검사 문서 렌더링용) */