271 lines
19 KiB
PHP
271 lines
19 KiB
PHP
|
|
{{--
|
||
|
|
절곡 중간검사 DATA 전용 렌더링
|
||
|
|
React BendingInspectionContent.tsx와 동일한 구조
|
||
|
|
|
||
|
|
데이터 소스: work_order_items.options.inspection_data (스냅샷)
|
||
|
|
- 제품 구조, 도면치수, 측정값이 모두 포함된 완전한 스냅샷
|
||
|
|
- 정책 변경 시에도 저장 시점의 문서 그대로 유지
|
||
|
|
|
||
|
|
필요 변수:
|
||
|
|
- $inspectionData: inspection_data 스냅샷 (array|null)
|
||
|
|
- $docData: document_data collection (fallback용)
|
||
|
|
- $document: Document model
|
||
|
|
--}}
|
||
|
|
|
||
|
|
@php
|
||
|
|
// inspection_data 스냅샷에서 제품 목록 로드
|
||
|
|
$products = $inspectionData['products'] ?? [];
|
||
|
|
$snapshotJudgment = $inspectionData['judgment'] ?? null;
|
||
|
|
$inadequateContent = $inspectionData['inadequateContent'] ?? '';
|
||
|
|
|
||
|
|
// 스냅샷이 없으면 INITIAL_PRODUCTS 하드코딩 fallback (레거시 호환)
|
||
|
|
if (empty($products)) {
|
||
|
|
$products = [
|
||
|
|
['id' => 'guide-rail-wall', 'category' => 'KWE01', 'productName' => '가이드레일', 'productType' => '벽면형',
|
||
|
|
'lengthDesignValue' => '3000', 'widthDesignValue' => 'N/A', 'bendingStatus' => null, 'lengthMeasured' => '', 'widthMeasured' => '',
|
||
|
|
'gapPoints' => [
|
||
|
|
['point' => '①', 'designValue' => '30', 'measured' => ''],
|
||
|
|
['point' => '②', 'designValue' => '80', 'measured' => ''],
|
||
|
|
['point' => '③', 'designValue' => '45', 'measured' => ''],
|
||
|
|
['point' => '④', 'designValue' => '40', 'measured' => ''],
|
||
|
|
['point' => '⑤', 'designValue' => '34', 'measured' => ''],
|
||
|
|
]],
|
||
|
|
['id' => 'guide-rail-side', 'category' => 'KWE01', 'productName' => '가이드레일', 'productType' => '측면형',
|
||
|
|
'lengthDesignValue' => '3000', 'widthDesignValue' => 'N/A', 'bendingStatus' => null, 'lengthMeasured' => '', 'widthMeasured' => '',
|
||
|
|
'gapPoints' => [
|
||
|
|
['point' => '①', 'designValue' => '28', 'measured' => ''],
|
||
|
|
['point' => '②', 'designValue' => '75', 'measured' => ''],
|
||
|
|
['point' => '③', 'designValue' => '42', 'measured' => ''],
|
||
|
|
['point' => '④', 'designValue' => '38', 'measured' => ''],
|
||
|
|
['point' => '⑤', 'designValue' => '32', 'measured' => ''],
|
||
|
|
]],
|
||
|
|
['id' => 'case', 'category' => 'KWE01', 'productName' => '케이스', 'productType' => '500X380',
|
||
|
|
'lengthDesignValue' => '3000', 'widthDesignValue' => 'N/A', 'bendingStatus' => null, 'lengthMeasured' => '', 'widthMeasured' => '',
|
||
|
|
'gapPoints' => [
|
||
|
|
['point' => '①', 'designValue' => '380', 'measured' => ''],
|
||
|
|
['point' => '②', 'designValue' => '50', 'measured' => ''],
|
||
|
|
['point' => '③', 'designValue' => '240', 'measured' => ''],
|
||
|
|
['point' => '④', 'designValue' => '50', 'measured' => ''],
|
||
|
|
]],
|
||
|
|
['id' => 'bottom-finish', 'category' => 'KWE01', 'productName' => '하단마감재', 'productType' => '60X40',
|
||
|
|
'lengthDesignValue' => '3000', 'widthDesignValue' => 'N/A', 'bendingStatus' => null, 'lengthMeasured' => '', 'widthMeasured' => '',
|
||
|
|
'gapPoints' => [
|
||
|
|
['point' => '①', 'designValue' => '60', 'measured' => ''],
|
||
|
|
['point' => '②', 'designValue' => '64', 'measured' => ''],
|
||
|
|
]],
|
||
|
|
['id' => 'bottom-l-bar', 'category' => 'KWE01', 'productName' => '하단L-BAR', 'productType' => '17X60',
|
||
|
|
'lengthDesignValue' => '3000', 'widthDesignValue' => 'N/A', 'bendingStatus' => null, 'lengthMeasured' => '', 'widthMeasured' => '',
|
||
|
|
'gapPoints' => [
|
||
|
|
['point' => '①', 'designValue' => '17', 'measured' => ''],
|
||
|
|
]],
|
||
|
|
['id' => 'smoke-w50', 'category' => 'KWE01', 'productName' => '연기차단재', 'productType' => "W50\n가이드레일용",
|
||
|
|
'lengthDesignValue' => '3000', 'widthDesignValue' => '', 'bendingStatus' => null, 'lengthMeasured' => '', 'widthMeasured' => '',
|
||
|
|
'gapPoints' => [
|
||
|
|
['point' => '①', 'designValue' => '50', 'measured' => ''],
|
||
|
|
['point' => '②', 'designValue' => '12', 'measured' => ''],
|
||
|
|
]],
|
||
|
|
['id' => 'smoke-w80', 'category' => 'KWE01', 'productName' => '연기차단재', 'productType' => "W80\n케이스용",
|
||
|
|
'lengthDesignValue' => '3000', 'widthDesignValue' => '', 'bendingStatus' => null, 'lengthMeasured' => '', 'widthMeasured' => '',
|
||
|
|
'gapPoints' => [
|
||
|
|
['point' => '①', 'designValue' => '80', 'measured' => ''],
|
||
|
|
['point' => '②', 'designValue' => '12', 'measured' => ''],
|
||
|
|
]],
|
||
|
|
];
|
||
|
|
}
|
||
|
|
|
||
|
|
// 제품 ID → 메타 정보 매핑 (스냅샷에 category/productName/productType가 없을 경우 보완)
|
||
|
|
$productMeta = [
|
||
|
|
'guide-rail-wall' => ['category' => 'KWE01', 'productName' => '가이드레일', 'productType' => '벽면형'],
|
||
|
|
'guide_rail_wall' => ['category' => 'KWE01', 'productName' => '가이드레일', 'productType' => '벽면형'],
|
||
|
|
'guide-rail-side' => ['category' => 'KWE01', 'productName' => '가이드레일', 'productType' => '측면형'],
|
||
|
|
'guide_rail_side' => ['category' => 'KWE01', 'productName' => '가이드레일', 'productType' => '측면형'],
|
||
|
|
'case' => ['category' => 'KWE01', 'productName' => '케이스', 'productType' => '500X380'],
|
||
|
|
'bottom-finish' => ['category' => 'KWE01', 'productName' => '하단마감재', 'productType' => '60X40'],
|
||
|
|
'bottom_finish' => ['category' => 'KWE01', 'productName' => '하단마감재', 'productType' => '60X40'],
|
||
|
|
'bottom-l-bar' => ['category' => 'KWE01', 'productName' => '하단L-BAR', 'productType' => '17X60'],
|
||
|
|
'bottom_l_bar' => ['category' => 'KWE01', 'productName' => '하단L-BAR', 'productType' => '17X60'],
|
||
|
|
'smoke-w50' => ['category' => 'KWE01', 'productName' => '연기차단재', 'productType' => "W50\n가이드레일용"],
|
||
|
|
'smoke_w50' => ['category' => 'KWE01', 'productName' => '연기차단재', 'productType' => "W50\n가이드레일용"],
|
||
|
|
'smoke-w80' => ['category' => 'KWE01', 'productName' => '연기차단재', 'productType' => "W80\n케이스용"],
|
||
|
|
'smoke_w80' => ['category' => 'KWE01', 'productName' => '연기차단재', 'productType' => "W80\n케이스용"],
|
||
|
|
];
|
||
|
|
|
||
|
|
// 종합판정 결정
|
||
|
|
$overallResult = $snapshotJudgment ?? ($docData->where('field_key', 'overall_result')->first()?->field_value ?? '');
|
||
|
|
$isOverallPass = in_array(strtolower($overallResult), ['pass', 'ok', '적합', '합격']);
|
||
|
|
@endphp
|
||
|
|
|
||
|
|
<div class="bg-white rounded-lg shadow-sm border border-gray-200 p-6">
|
||
|
|
<h2 class="text-lg font-semibold text-gray-800 mb-4">■ 중간검사 DATA</h2>
|
||
|
|
|
||
|
|
<div class="overflow-x-auto">
|
||
|
|
<table class="min-w-full border border-gray-300 text-sm">
|
||
|
|
<thead class="bg-gray-50">
|
||
|
|
{{-- 1단 헤더 --}}
|
||
|
|
<tr>
|
||
|
|
<th rowspan="2" class="px-2 py-2 text-center text-xs font-medium text-gray-600 border border-gray-300 w-20">분류</th>
|
||
|
|
<th rowspan="2" class="px-2 py-2 text-center text-xs font-medium text-gray-600 border border-gray-300 w-24">제품명</th>
|
||
|
|
<th rowspan="2" class="px-2 py-2 text-center text-xs font-medium text-gray-600 border border-gray-300 w-24">타입</th>
|
||
|
|
<th rowspan="2" class="px-2 py-2 text-center text-xs font-medium text-gray-600 border border-gray-300 w-24">겉모양/<br>절곡상태</th>
|
||
|
|
<th colspan="2" class="px-2 py-2 text-center text-xs font-medium text-gray-600 border border-gray-300">길이</th>
|
||
|
|
<th colspan="2" class="px-2 py-2 text-center text-xs font-medium text-gray-600 border border-gray-300">너비</th>
|
||
|
|
<th colspan="3" class="px-2 py-2 text-center text-xs font-medium text-gray-600 border border-gray-300">간격</th>
|
||
|
|
<th rowspan="2" class="px-2 py-2 text-center text-xs font-medium text-gray-600 border border-gray-300 w-20">판정</th>
|
||
|
|
</tr>
|
||
|
|
{{-- 2단 헤더 (서브라벨) --}}
|
||
|
|
<tr>
|
||
|
|
<th class="px-2 py-1 text-center text-xs font-medium text-gray-500 border border-gray-300 bg-gray-50">도면치수</th>
|
||
|
|
<th class="px-2 py-1 text-center text-xs font-medium text-gray-500 border border-gray-300 bg-gray-50">측정값</th>
|
||
|
|
<th class="px-2 py-1 text-center text-xs font-medium text-gray-500 border border-gray-300 bg-gray-50">도면치수</th>
|
||
|
|
<th class="px-2 py-1 text-center text-xs font-medium text-gray-500 border border-gray-300 bg-gray-50">측정값</th>
|
||
|
|
<th class="px-2 py-1 text-center text-xs font-medium text-gray-500 border border-gray-300 bg-gray-50">포인트</th>
|
||
|
|
<th class="px-2 py-1 text-center text-xs font-medium text-gray-500 border border-gray-300 bg-gray-50">도면치수</th>
|
||
|
|
<th class="px-2 py-1 text-center text-xs font-medium text-gray-500 border border-gray-300 bg-gray-50">측정값</th>
|
||
|
|
</tr>
|
||
|
|
</thead>
|
||
|
|
<tbody>
|
||
|
|
@foreach($products as $pIdx => $product)
|
||
|
|
@php
|
||
|
|
$gapPoints = $product['gapPoints'] ?? [];
|
||
|
|
$gapCount = count($gapPoints);
|
||
|
|
if ($gapCount === 0) $gapCount = 1;
|
||
|
|
|
||
|
|
$productId = $product['id'] ?? '';
|
||
|
|
$meta = $productMeta[$productId] ?? [];
|
||
|
|
|
||
|
|
$category = $product['category'] ?? ($meta['category'] ?? '');
|
||
|
|
$productName = $product['productName'] ?? ($meta['productName'] ?? $productId);
|
||
|
|
$productType = $product['productType'] ?? ($meta['productType'] ?? '');
|
||
|
|
|
||
|
|
// 스냅샷 필드 (React 저장 형식: lengthDesignValue, lengthMeasured 등)
|
||
|
|
$lengthDesign = $product['lengthDesignValue'] ?? ($product['lengthDesign'] ?? '');
|
||
|
|
$lengthMeasured = $product['lengthMeasured'] ?? '';
|
||
|
|
$widthDesign = $product['widthDesignValue'] ?? ($product['widthDesign'] ?? '');
|
||
|
|
$widthMeasured = $product['widthMeasured'] ?? '';
|
||
|
|
|
||
|
|
// 절곡상태
|
||
|
|
$statusVal = $product['bendingStatus'] ?? null;
|
||
|
|
|
||
|
|
// 판정: 양호→적, 불량→부
|
||
|
|
$judgmentVal = null;
|
||
|
|
if ($statusVal === '양호' || strtolower($statusVal ?? '') === 'pass' || strtolower($statusVal ?? '') === 'ok') {
|
||
|
|
$judgmentVal = '적';
|
||
|
|
} elseif ($statusVal === '불량' || strtolower($statusVal ?? '') === 'fail' || strtolower($statusVal ?? '') === 'ng') {
|
||
|
|
$judgmentVal = '부';
|
||
|
|
}
|
||
|
|
@endphp
|
||
|
|
|
||
|
|
@for($gIdx = 0; $gIdx < max($gapCount, 1); $gIdx++)
|
||
|
|
<tr class="hover:bg-gray-50">
|
||
|
|
@if($gIdx === 0)
|
||
|
|
{{-- 분류 --}}
|
||
|
|
<td rowspan="{{ $gapCount }}" class="px-2 py-2 border border-gray-300 text-center text-xs text-gray-700 align-middle">
|
||
|
|
{{ $category }}
|
||
|
|
</td>
|
||
|
|
{{-- 제품명 --}}
|
||
|
|
<td rowspan="{{ $gapCount }}" class="px-2 py-2 border border-gray-300 text-center text-xs font-medium text-gray-900 align-middle">
|
||
|
|
{{ $productName }}
|
||
|
|
</td>
|
||
|
|
{{-- 타입 --}}
|
||
|
|
<td rowspan="{{ $gapCount }}" class="px-2 py-2 border border-gray-300 text-center text-xs text-gray-700 align-middle whitespace-pre-line">
|
||
|
|
{{ $productType }}
|
||
|
|
</td>
|
||
|
|
{{-- 겉모양/절곡상태 --}}
|
||
|
|
<td rowspan="{{ $gapCount }}" class="px-2 py-2 border border-gray-300 text-center text-sm align-middle">
|
||
|
|
@if($statusVal === '양호' || strtolower($statusVal ?? '') === 'pass' || strtolower($statusVal ?? '') === 'ok')
|
||
|
|
<span class="inline-flex items-center justify-center w-7 h-7 rounded-full bg-green-100 border border-green-300">
|
||
|
|
<svg class="w-5 h-5 text-green-600" fill="none" stroke="currentColor" stroke-width="3" viewBox="0 0 24 24">
|
||
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/>
|
||
|
|
</svg>
|
||
|
|
</span>
|
||
|
|
@elseif($statusVal === '불량' || strtolower($statusVal ?? '') === 'fail' || strtolower($statusVal ?? '') === 'ng')
|
||
|
|
<span class="inline-flex items-center justify-center w-7 h-7 rounded-full bg-red-100 border border-red-300">
|
||
|
|
<svg class="w-5 h-5 text-red-600" fill="none" stroke="currentColor" stroke-width="3" viewBox="0 0 24 24">
|
||
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/>
|
||
|
|
</svg>
|
||
|
|
</span>
|
||
|
|
@else
|
||
|
|
<span class="text-gray-400">-</span>
|
||
|
|
@endif
|
||
|
|
</td>
|
||
|
|
{{-- 길이 도면치수 --}}
|
||
|
|
<td rowspan="{{ $gapCount }}" class="px-2 py-2 border border-gray-300 text-center text-sm text-gray-500 align-middle">
|
||
|
|
{{ $lengthDesign ?: '-' }}
|
||
|
|
</td>
|
||
|
|
{{-- 길이 측정값 --}}
|
||
|
|
<td rowspan="{{ $gapCount }}" class="px-2 py-2 border border-gray-300 text-center text-sm font-mono align-middle">
|
||
|
|
{{ $lengthMeasured ?: '-' }}
|
||
|
|
</td>
|
||
|
|
{{-- 너비 도면치수 --}}
|
||
|
|
<td rowspan="{{ $gapCount }}" class="px-2 py-2 border border-gray-300 text-center text-sm text-gray-500 align-middle">
|
||
|
|
{{ $widthDesign ?: '-' }}
|
||
|
|
</td>
|
||
|
|
{{-- 너비 측정값 --}}
|
||
|
|
<td rowspan="{{ $gapCount }}" class="px-2 py-2 border border-gray-300 text-center text-sm font-mono align-middle">
|
||
|
|
{{ $widthMeasured ?: '-' }}
|
||
|
|
</td>
|
||
|
|
@endif
|
||
|
|
|
||
|
|
{{-- 간격 포인트 --}}
|
||
|
|
@if(!empty($gapPoints))
|
||
|
|
@php $gap = $gapPoints[$gIdx] ?? []; @endphp
|
||
|
|
<td class="px-2 py-1.5 border border-gray-300 text-center text-xs text-gray-500">
|
||
|
|
{{ $gap['point'] ?? '' }}
|
||
|
|
</td>
|
||
|
|
<td class="px-2 py-1.5 border border-gray-300 text-center text-sm text-gray-500">
|
||
|
|
{{ $gap['designValue'] ?? '' }}
|
||
|
|
</td>
|
||
|
|
<td class="px-2 py-1.5 border border-gray-300 text-center text-sm font-mono">
|
||
|
|
{{ ($gap['measured'] ?? '') ?: '-' }}
|
||
|
|
</td>
|
||
|
|
@else
|
||
|
|
<td class="px-2 py-1.5 border border-gray-300 text-center text-gray-400">-</td>
|
||
|
|
<td class="px-2 py-1.5 border border-gray-300 text-center text-gray-400">-</td>
|
||
|
|
<td class="px-2 py-1.5 border border-gray-300 text-center text-gray-400">-</td>
|
||
|
|
@endif
|
||
|
|
|
||
|
|
@if($gIdx === 0)
|
||
|
|
{{-- 판정 --}}
|
||
|
|
<td rowspan="{{ $gapCount }}" class="px-2 py-2 border border-gray-300 text-center text-sm align-middle">
|
||
|
|
@if($judgmentVal === '적')
|
||
|
|
<span class="inline-flex items-center gap-1 px-2 py-1 rounded-md text-xs font-bold bg-green-100 text-green-700 border border-green-300">
|
||
|
|
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" stroke-width="3" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/></svg>
|
||
|
|
적
|
||
|
|
</span>
|
||
|
|
@elseif($judgmentVal === '부')
|
||
|
|
<span class="inline-flex items-center gap-1 px-2 py-1 rounded-md text-xs font-bold bg-red-100 text-red-700 border border-red-300">
|
||
|
|
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" stroke-width="3" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/></svg>
|
||
|
|
부
|
||
|
|
</span>
|
||
|
|
@else
|
||
|
|
<span class="text-gray-400">-</span>
|
||
|
|
@endif
|
||
|
|
</td>
|
||
|
|
@endif
|
||
|
|
</tr>
|
||
|
|
@endfor
|
||
|
|
@endforeach
|
||
|
|
</tbody>
|
||
|
|
</table>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{{-- 종합판정 --}}
|
||
|
|
<div class="mt-4 flex items-center gap-3">
|
||
|
|
<span class="text-sm font-semibold text-gray-700">종합판정:</span>
|
||
|
|
@if($overallResult)
|
||
|
|
@if($isOverallPass)
|
||
|
|
<span class="inline-flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-sm font-bold bg-green-100 text-green-700 border border-green-300">
|
||
|
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="3" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/></svg>
|
||
|
|
적합
|
||
|
|
</span>
|
||
|
|
@else
|
||
|
|
<span class="inline-flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-sm font-bold bg-red-100 text-red-700 border border-red-300">
|
||
|
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="3" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/></svg>
|
||
|
|
부적합
|
||
|
|
</span>
|
||
|
|
@endif
|
||
|
|
@else
|
||
|
|
<span class="text-sm text-gray-400">미판정</span>
|
||
|
|
@endif
|
||
|
|
</div>
|
||
|
|
</div>
|