diff --git a/app/Http/Controllers/Api/Admin/EquipmentInspectionController.php b/app/Http/Controllers/Api/Admin/EquipmentInspectionController.php index c2026c80..06960b37 100644 --- a/app/Http/Controllers/Api/Admin/EquipmentInspectionController.php +++ b/app/Http/Controllers/Api/Admin/EquipmentInspectionController.php @@ -79,6 +79,39 @@ public function toggleDetail(Request $request): JsonResponse } } + public function setResult(Request $request): JsonResponse + { + $request->validate([ + 'equipment_id' => 'required|integer', + 'template_item_id' => 'required|integer', + 'check_date' => 'required|date', + 'cycle' => 'nullable|string', + 'result' => 'nullable|in:good,bad,repaired', + ]); + + try { + $result = $this->inspectionService->setResult( + $request->input('equipment_id'), + $request->input('template_item_id'), + $request->input('check_date'), + $request->input('cycle', InspectionCycle::DAILY), + $request->input('result') + ); + + return response()->json([ + 'success' => true, + 'data' => $result, + ]); + } catch (\Exception $e) { + $status = $e->getMessage() === '점검 권한이 없습니다.' ? 403 : 400; + + return response()->json([ + 'success' => false, + 'message' => $e->getMessage(), + ], $status); + } + } + public function updateNotes(Request $request): JsonResponse { $request->validate([ diff --git a/app/Http/Controllers/Mobile/MobileInspectionController.php b/app/Http/Controllers/Mobile/MobileInspectionController.php new file mode 100644 index 00000000..d398600d --- /dev/null +++ b/app/Http/Controllers/Mobile/MobileInspectionController.php @@ -0,0 +1,62 @@ +findOrFail($id); + + $cycle = $request->input('cycle', InspectionCycle::DAILY); + $today = now()->format('Y-m-d'); + $period = InspectionCycle::resolvePeriod($cycle, $today); + + $activeCycles = EquipmentInspectionTemplate::where('equipment_id', $equipment->id) + ->where('is_active', true) + ->distinct() + ->pluck('inspection_cycle') + ->toArray(); + + $templates = EquipmentInspectionTemplate::where('equipment_id', $equipment->id) + ->where('inspection_cycle', $cycle) + ->where('is_active', true) + ->orderBy('sort_order') + ->get(); + + $inspection = EquipmentInspection::where('equipment_id', $equipment->id) + ->where('inspection_cycle', $cycle) + ->where('year_month', $period) + ->first(); + + $details = collect(); + if ($inspection) { + $details = EquipmentInspectionDetail::where('inspection_id', $inspection->id) + ->where('check_date', $today) + ->get() + ->keyBy('template_item_id'); + } + + $canInspect = $equipment->canInspect(); + + return view('mobile.inspection.show', compact( + 'equipment', + 'cycle', + 'today', + 'period', + 'activeCycles', + 'templates', + 'details', + 'canInspect', + )); + } +} diff --git a/app/Services/EquipmentInspectionService.php b/app/Services/EquipmentInspectionService.php index 72cd30ed..9fc1c76b 100644 --- a/app/Services/EquipmentInspectionService.php +++ b/app/Services/EquipmentInspectionService.php @@ -137,6 +137,62 @@ public function toggleDetail(int $equipmentId, int $templateItemId, string $chec ]; } + /** + * 점검 결과 직접 설정 (모바일용) + */ + public function setResult(int $equipmentId, int $templateItemId, string $checkDate, string $cycle, ?string $result): array + { + $equipment = Equipment::findOrFail($equipmentId); + if (! $equipment->canInspect()) { + throw new \Exception('점검 권한이 없습니다.'); + } + + $tenantId = session('selected_tenant_id', 1); + $period = InspectionCycle::resolvePeriod($cycle, $checkDate); + + $inspection = EquipmentInspection::firstOrCreate( + [ + 'tenant_id' => $tenantId, + 'equipment_id' => $equipmentId, + 'inspection_cycle' => $cycle, + 'year_month' => $period, + ], + [ + 'created_by' => auth()->id(), + ] + ); + + $detail = EquipmentInspectionDetail::where('inspection_id', $inspection->id) + ->where('template_item_id', $templateItemId) + ->where('check_date', $checkDate) + ->first(); + + if ($result === null) { + if ($detail) { + $detail->delete(); + } + + return ['result' => null, 'symbol' => '', 'color' => 'text-gray-400']; + } + + if ($detail) { + $detail->update(['result' => $result]); + } else { + $detail = EquipmentInspectionDetail::create([ + 'inspection_id' => $inspection->id, + 'template_item_id' => $templateItemId, + 'check_date' => $checkDate, + 'result' => $result, + ]); + } + + return [ + 'result' => $result, + 'symbol' => $detail->fresh()->result_symbol, + 'color' => $detail->fresh()->result_color, + ]; + } + public function updateInspectionNotes(int $equipmentId, string $yearMonth, array $data, string $cycle = 'daily'): EquipmentInspection { $tenantId = session('selected_tenant_id', 1); diff --git a/app/Services/QrCodeService.php b/app/Services/QrCodeService.php new file mode 100644 index 00000000..a32ea9d0 --- /dev/null +++ b/app/Services/QrCodeService.php @@ -0,0 +1,16 @@ + +

QR 코드 (모바일 점검)

+
+
+
+
+
+

{{ $equipment->equipment_code }}

+

{{ $equipment->name }}

+

+
+ + +
+
+
+ + + + diff --git a/resources/views/equipment/partials/tabs/basic-info.blade.php b/resources/views/equipment/partials/tabs/basic-info.blade.php index eef49776..3e09781a 100644 --- a/resources/views/equipment/partials/tabs/basic-info.blade.php +++ b/resources/views/equipment/partials/tabs/basic-info.blade.php @@ -145,6 +145,8 @@ function closePhotoModal(e) { @endif +@include('equipment.partials.qr-code', ['equipment' => $equipment]) + @if($equipment->processes->isNotEmpty())

연결된 공정

diff --git a/resources/views/layouts/mobile.blade.php b/resources/views/layouts/mobile.blade.php new file mode 100644 index 00000000..b09d2a35 --- /dev/null +++ b/resources/views/layouts/mobile.blade.php @@ -0,0 +1,29 @@ + + + + + + + @yield('title', '점검') - SAM + @vite(['resources/css/app.css', 'resources/js/app.js']) + + + + {{-- 최소 헤더 --}} +
+ SAM + {{ auth()->user()->name }} 님 +
+ +
+ @yield('content') +
+ + + @stack('scripts') + + diff --git a/resources/views/mobile/inspection/show.blade.php b/resources/views/mobile/inspection/show.blade.php new file mode 100644 index 00000000..47d27b3f --- /dev/null +++ b/resources/views/mobile/inspection/show.blade.php @@ -0,0 +1,223 @@ +@extends('layouts.mobile') + +@section('title', $equipment->name . ' 점검') + +@section('content') +
+ {{-- 설비 정보 --}} +
+
+
+

{{ $equipment->equipment_code }}

+

{{ $equipment->name }}

+
+ + {{ $equipment->status_label }} + +
+
+ @if($equipment->production_line) + {{ $equipment->production_line }} + @endif + @if($equipment->manager) + 담당: {{ $equipment->manager->name }} + @endif +
+
+ + {{-- 날짜 및 주기 탭 --}} +
+
+

+ {{ \Carbon\Carbon::parse($today)->format('Y-m-d') }} + {{ \App\Enums\InspectionCycle::label($cycle) }} 점검 +

+
+ + @if(count($activeCycles) > 1) +
+ @foreach($activeCycles as $c) + + {{ \App\Enums\InspectionCycle::label($c) }} + + @endforeach +
+ @endif +
+ + @if($templates->isEmpty()) +
+

이 주기에 등록된 점검항목이 없습니다.

+
+ @else + {{-- 점검 항목 리스트 --}} +
+ @foreach($templates as $idx => $template) + @php + $detail = $details->get($template->id); + $currentResult = $detail?->result; + @endphp +
+
+
+

+ {{ $idx + 1 }}. {{ $template->check_point }} + - {{ $template->check_item }} +

+ @if($template->check_method) +

{{ $template->check_method }}

+ @endif +
+
+ + {{-- 결과 버튼 --}} +
+ + + + +
+
+ @endforeach +
+ + {{-- 요약 + 전체 양호 --}} +
+
+

+ 전체 {{ $templates->count() }}항목 | + 점검 {{ $details->count() }} | + 미점검 {{ $templates->count() - $details->count() }} +

+ @if($canInspect) + + @endif +
+
+ @endif +
+@endsection + +@push('scripts') + +@endpush diff --git a/routes/api.php b/routes/api.php index ac51f3d0..ffc7814f 100644 --- a/routes/api.php +++ b/routes/api.php @@ -1029,6 +1029,7 @@ Route::get('/inspections', [\App\Http\Controllers\Api\Admin\EquipmentInspectionController::class, 'index'])->name('inspections.index'); Route::patch('/inspections/detail', [\App\Http\Controllers\Api\Admin\EquipmentInspectionController::class, 'toggleDetail'])->name('inspections.toggle'); Route::patch('/inspections/notes', [\App\Http\Controllers\Api\Admin\EquipmentInspectionController::class, 'updateNotes'])->name('inspections.notes'); + Route::patch('/inspections/set-result', [\App\Http\Controllers\Api\Admin\EquipmentInspectionController::class, 'setResult'])->name('inspections.set-result'); // 수리이력 Route::get('/repairs', [\App\Http\Controllers\Api\Admin\EquipmentRepairController::class, 'index'])->name('repairs.index'); diff --git a/routes/web.php b/routes/web.php index c9f4ff8d..c7ee3df0 100644 --- a/routes/web.php +++ b/routes/web.php @@ -1667,6 +1667,15 @@ Route::delete('/history', [\App\Http\Controllers\Video\TutorialVideoController::class, 'destroy'])->name('destroy'); }); +/* +|-------------------------------------------------------------------------- +| 모바일 점검 (QR 코드 → 모바일 점검) +|-------------------------------------------------------------------------- +*/ +Route::middleware(['auth', 'hq.member'])->group(function () { + Route::get('/m/inspect/{id}', [\App\Http\Controllers\Mobile\MobileInspectionController::class, 'show'])->whereNumber('id')->name('mobile.inspect'); +}); + /* |-------------------------------------------------------------------------- | 설비관리 (Equipment Management)