- 동적 필드/연결 모델 추가 (SectionField, Link, LinkValue, Preset) - 통합 검색 API (SourceTableSearchController) - items/processes/lots/users - 템플릿 편집 UI: 소스 테이블 드롭다운 + datalist 검색/선택 - 문서 작성/인쇄/상세 뷰: getFieldValue() 기반 동적 렌더링 - DocumentTemplateApiController: source_table 기반 저장/복제 - DocumentController: sectionFields/links eager loading 추가 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
251 lines
12 KiB
PHP
251 lines
12 KiB
PHP
@extends('layouts.app')
|
|
|
|
@section('title', '문서 인쇄 - ' . $document->title)
|
|
|
|
@section('content')
|
|
<div class="max-w-7xl mx-auto">
|
|
{{-- 상단 버튼 --}}
|
|
<div class="flex justify-between items-center mb-4 print:hidden">
|
|
<div>
|
|
<h1 class="text-xl font-bold text-gray-800">{{ $document->title }}</h1>
|
|
<p class="text-sm text-gray-500">{{ $document->document_no }}</p>
|
|
</div>
|
|
<div class="flex items-center gap-2">
|
|
<a href="{{ route('documents.show', $document->id) }}"
|
|
class="bg-gray-200 hover:bg-gray-300 text-gray-700 px-4 py-2 rounded-lg transition text-sm">
|
|
상세보기
|
|
</a>
|
|
<a href="{{ route('documents.index') }}"
|
|
class="bg-gray-200 hover:bg-gray-300 text-gray-700 px-4 py-2 rounded-lg transition text-sm">
|
|
목록
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- 성적서 본문 --}}
|
|
<div class="bg-white border border-gray-300 p-8 print:p-4 print:border-0" id="printArea">
|
|
|
|
@php
|
|
$template = $document->template;
|
|
$hasComplexCol = $template->columns->contains(fn($c) => $c->column_type === 'complex' && $c->sub_labels);
|
|
@endphp
|
|
|
|
{{-- 섹션별 검사 테이블 --}}
|
|
@if($template->sections && $template->sections->count() > 0)
|
|
@foreach($template->sections as $sectionIndex => $section)
|
|
|
|
{{-- 섹션 제목 --}}
|
|
@if($template->sections->count() > 1)
|
|
<div class="mb-2 {{ $sectionIndex > 0 ? 'mt-8' : '' }}">
|
|
<h3 class="text-sm font-semibold text-gray-700">{{ $section->title }}</h3>
|
|
</div>
|
|
@endif
|
|
|
|
{{-- 검사 기준 이미지 --}}
|
|
@if($section->image_path)
|
|
<div class="mb-4">
|
|
<img src="{{ asset($section->image_path) }}" alt="{{ $section->title }}" class="max-w-md h-auto border">
|
|
</div>
|
|
@endif
|
|
|
|
{{-- 검사 데이터 테이블 --}}
|
|
@if($section->items->count() > 0 && $template->columns->count() > 0)
|
|
<table class="w-full border-collapse text-sm mb-2" style="border: 1px solid #333;">
|
|
{{-- 테이블 헤더 --}}
|
|
<thead>
|
|
<tr>
|
|
@foreach($template->columns as $col)
|
|
@if($col->column_type === 'complex' && $col->sub_labels)
|
|
<th colspan="{{ count($col->sub_labels) }}"
|
|
class="doc-th"
|
|
style="min-width: {{ $col->width ?: '80px' }}">
|
|
{{ $col->label }}
|
|
</th>
|
|
@else
|
|
<th rowspan="{{ $hasComplexCol ? 2 : 1 }}"
|
|
class="doc-th"
|
|
style="min-width: {{ $col->width ?: '60px' }}">
|
|
{{ $col->label }}
|
|
</th>
|
|
@endif
|
|
@endforeach
|
|
</tr>
|
|
{{-- 서브 라벨 행 (complex 컬럼) --}}
|
|
@if($hasComplexCol)
|
|
<tr>
|
|
@foreach($template->columns as $col)
|
|
@if($col->column_type === 'complex' && $col->sub_labels)
|
|
@foreach($col->sub_labels as $subLabel)
|
|
<th class="doc-th text-xs font-normal" style="min-width: 60px">
|
|
{{ $subLabel }}
|
|
</th>
|
|
@endforeach
|
|
@endif
|
|
@endforeach
|
|
</tr>
|
|
@endif
|
|
</thead>
|
|
|
|
{{-- 테이블 바디 --}}
|
|
<tbody>
|
|
@foreach($section->items as $rowIndex => $item)
|
|
<tr>
|
|
@foreach($template->columns as $col)
|
|
@if($col->column_type === 'complex' && $col->sub_labels)
|
|
{{-- complex: 서브 라벨별 측정값 --}}
|
|
@foreach($col->sub_labels as $subIndex => $subLabel)
|
|
@php
|
|
$fieldKey = "s{$section->id}_r{$rowIndex}_c{$col->id}_sub{$subIndex}";
|
|
$savedVal = $document->data->where('field_key', $fieldKey)->first()?->field_value ?? '';
|
|
@endphp
|
|
<td class="doc-td font-mono text-center">
|
|
{{ $savedVal ?: '-' }}
|
|
</td>
|
|
@endforeach
|
|
|
|
@elseif($col->column_type === 'select')
|
|
{{-- select: 판정 --}}
|
|
@php
|
|
$fieldKey = "s{$section->id}_r{$rowIndex}_c{$col->id}";
|
|
$savedVal = $document->data->where('field_key', $fieldKey)->first()?->field_value ?? '';
|
|
@endphp
|
|
<td class="doc-td text-center">
|
|
@if($savedVal)
|
|
<span class="{{ in_array($savedVal, ['적합', '합격', 'OK']) ? 'text-blue-700' : 'text-red-600' }} font-medium">
|
|
{{ $savedVal }}
|
|
</span>
|
|
@else
|
|
-
|
|
@endif
|
|
</td>
|
|
|
|
@elseif($col->column_type === 'check')
|
|
{{-- check: OK 체크 --}}
|
|
@php
|
|
$fieldKey = "s{$section->id}_r{$rowIndex}_c{$col->id}";
|
|
$savedVal = $document->data->where('field_key', $fieldKey)->first()?->field_value ?? '';
|
|
@endphp
|
|
<td class="doc-td text-center">
|
|
@if($savedVal === 'OK')
|
|
<span class="text-blue-700 font-bold">OK</span>
|
|
@else
|
|
-
|
|
@endif
|
|
</td>
|
|
|
|
@elseif($col->column_type === 'measurement')
|
|
{{-- measurement: 수치 --}}
|
|
@php
|
|
$fieldKey = "s{$section->id}_r{$rowIndex}_c{$col->id}";
|
|
$savedVal = $document->data->where('field_key', $fieldKey)->first()?->field_value ?? '';
|
|
@endphp
|
|
<td class="doc-td font-mono text-center">
|
|
{{ $savedVal ?: '-' }}
|
|
</td>
|
|
|
|
@else
|
|
{{-- text: 정적 데이터 또는 입력 텍스트 --}}
|
|
@php
|
|
$staticValue = match(true) {
|
|
str_contains(strtolower($col->label), 'no') && strlen($col->label) <= 4 => $rowIndex + 1,
|
|
in_array($col->label, ['검사항목', '항목']) => $item->getFieldValue('item'),
|
|
in_array($col->label, ['검사기준', '기준']) => $item->getFieldValue('standard'),
|
|
in_array($col->label, ['검사방식', '방식', '검사방법']) => $item->getFieldValue('method'),
|
|
in_array($col->label, ['검사주기', '주기']) => $item->getFieldValue('frequency'),
|
|
in_array($col->label, ['규격', '적용규격', '관련규정']) => $item->getFieldValue('regulation'),
|
|
in_array($col->label, ['분류', '카테고리']) => $item->getFieldValue('category'),
|
|
default => null,
|
|
};
|
|
@endphp
|
|
@if($staticValue !== null)
|
|
<td class="doc-td {{ is_numeric($staticValue) ? 'text-center' : '' }}">
|
|
{{ $staticValue }}
|
|
</td>
|
|
@else
|
|
@php
|
|
$fieldKey = "s{$section->id}_r{$rowIndex}_c{$col->id}";
|
|
$savedVal = $document->data->where('field_key', $fieldKey)->first()?->field_value ?? '';
|
|
@endphp
|
|
<td class="doc-td text-center">
|
|
{{ $savedVal ?: '-' }}
|
|
</td>
|
|
@endif
|
|
@endif
|
|
@endforeach
|
|
</tr>
|
|
@endforeach
|
|
</tbody>
|
|
</table>
|
|
@endif
|
|
|
|
@endforeach
|
|
@endif
|
|
|
|
{{-- 종합판정 --}}
|
|
@if($template->footer_judgement_label)
|
|
<div class="mt-6 flex justify-end">
|
|
<table class="border-collapse text-sm" style="border: 1px solid #333; min-width: 200px;">
|
|
<tr>
|
|
<td class="doc-th font-semibold text-center" style="width: 100px;">
|
|
{{ $template->footer_judgement_label ?? '종합판정' }}
|
|
</td>
|
|
<td class="doc-td text-center" style="min-width: 100px;">
|
|
@php
|
|
$judgementVal = $document->data->where('field_key', 'footer_judgement')->first()?->field_value ?? '';
|
|
@endphp
|
|
@if($judgementVal)
|
|
<span class="{{ in_array($judgementVal, ['적합', '합격']) ? 'text-blue-700' : 'text-red-600' }} font-semibold">
|
|
{{ $judgementVal }}
|
|
</span>
|
|
@else
|
|
<span class="text-gray-400">미완료</span>
|
|
@endif
|
|
</td>
|
|
</tr>
|
|
@php
|
|
$remarkVal = $document->data->where('field_key', 'footer_remark')->first()?->field_value ?? '';
|
|
@endphp
|
|
@if($remarkVal)
|
|
<tr>
|
|
<td class="doc-th font-semibold text-center">
|
|
{{ $template->footer_remark_label ?? '비고' }}
|
|
</td>
|
|
<td class="doc-td">{{ $remarkVal }}</td>
|
|
</tr>
|
|
@endif
|
|
</table>
|
|
</div>
|
|
@endif
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<style>
|
|
/* 성적서 테이블 공통 스타일 */
|
|
.doc-th {
|
|
border: 1px solid #555;
|
|
padding: 6px 8px;
|
|
background-color: #f9fafb;
|
|
font-weight: 500;
|
|
font-size: 0.8125rem;
|
|
text-align: center;
|
|
color: #374151;
|
|
white-space: nowrap;
|
|
}
|
|
.doc-td {
|
|
border: 1px solid #999;
|
|
padding: 5px 8px;
|
|
font-size: 0.8125rem;
|
|
color: #1f2937;
|
|
vertical-align: middle;
|
|
}
|
|
|
|
/* 인쇄 스타일 */
|
|
@media print {
|
|
body { background: white; }
|
|
.doc-th { background-color: #f3f4f6 !important; -webkit-print-color-adjust: exact; }
|
|
.doc-td { border-color: #666 !important; }
|
|
}
|
|
</style>
|
|
@endsection
|