Files
sam-manage/resources/views/audit-logs/show.blade.php
권혁성 0eee22e0f5 feat:감사 로그 뷰어 추가 (시스템 설정 > 감사 로그)
- AuditLogController: 목록/상세 조회, 필터링(액션/테넌트/날짜/검색)
- AuditLog 모델: 재고 변동 액션 및 참조 타입 상수 정의
- Blade 뷰: 통계 카드, 필터, 아코디언(Before/After JSON), 상세 페이지
- 메뉴 DB 등록: 시스템 설정 하위에 감사 로그, 삭제된 데이터 백업 추가

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 12:41:00 +09:00

193 lines
8.1 KiB
PHP

@extends('layouts.app')
@section('title', '감사 로그 상세')
@section('content')
<!-- 페이지 헤더 -->
<div class="flex justify-between items-center mb-6">
<div class="flex items-center gap-4">
<a href="{{ route('audit-logs.index') }}" class="p-2 text-gray-600 hover:text-gray-800 hover:bg-gray-100 rounded-lg">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"/>
</svg>
</a>
<h1 class="text-2xl font-bold text-gray-800">감사 로그 상세 #{{ $log->id }}</h1>
</div>
<div class="text-sm text-gray-500">
{{ $log->created_at->format('Y-m-d H:i:s') }}
</div>
</div>
<!-- 기본 정보 카드 -->
<div class="bg-white rounded-lg shadow-sm p-6 mb-6">
<h2 class="text-lg font-semibold text-gray-800 mb-4">기본 정보</h2>
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
<!-- 액션 -->
<div>
<label class="block text-sm text-gray-500 mb-1">액션</label>
@php
$actionColors = [
'stock_increase' => 'bg-green-100 text-green-800',
'stock_decrease' => 'bg-red-100 text-red-800',
'stock_reserve' => 'bg-yellow-100 text-yellow-800',
'stock_release' => 'bg-blue-100 text-blue-800',
];
@endphp
<span class="px-3 py-1 text-sm font-medium rounded {{ $actionColors[$log->action] ?? 'bg-gray-100 text-gray-800' }}">
{{ $log->action_label }}
</span>
</div>
<!-- 대상 타입 -->
<div>
<label class="block text-sm text-gray-500 mb-1">대상 타입</label>
<p class="text-gray-900 font-medium">{{ $log->target_type }}</p>
</div>
<!-- 대상 ID -->
<div>
<label class="block text-sm text-gray-500 mb-1">대상 ID</label>
<p class="text-gray-900 font-medium">#{{ $log->target_id }}</p>
</div>
<!-- 테넌트 -->
<div>
<label class="block text-sm text-gray-500 mb-1">테넌트</label>
<p class="text-gray-900 font-medium">{{ $log->tenant?->company_name ?? '-' }}</p>
</div>
<!-- LOT 번호 -->
<div>
<label class="block text-sm text-gray-500 mb-1">LOT 번호</label>
<p class="text-gray-900 font-mono">{{ $log->lot_no ?? '-' }}</p>
</div>
<!-- 수량 변화 -->
<div>
<label class="block text-sm text-gray-500 mb-1">수량 변화</label>
<p class="font-medium {{ $log->qty_change > 0 ? 'text-green-600' : ($log->qty_change < 0 ? 'text-red-600' : 'text-gray-500') }}">
@if($log->qty_change > 0)
+{{ number_format($log->qty_change, 2) }}
@elseif($log->qty_change < 0)
{{ number_format($log->qty_change, 2) }}
@else
-
@endif
</p>
</div>
<!-- 사유 -->
<div>
<label class="block text-sm text-gray-500 mb-1">사유</label>
<p class="text-gray-900 font-medium">{{ $log->reason_label ?? '-' }}</p>
</div>
<!-- 참조 ID -->
<div>
<label class="block text-sm text-gray-500 mb-1">참조 ID</label>
<p class="text-gray-900">
@if($log->reference_id)
<span class="text-blue-600">#{{ $log->reference_id }}</span>
@if($log->reference_type)
<span class="text-gray-500 text-sm">({{ $log->reference_type }})</span>
@endif
@else
-
@endif
</p>
</div>
</div>
</div>
<!-- 수행자 정보 -->
<div class="bg-white rounded-lg shadow-sm p-6 mb-6">
<h2 class="text-lg font-semibold text-gray-800 mb-4">수행자 정보</h2>
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
<div>
<label class="block text-sm text-gray-500 mb-1">수행자</label>
<p class="text-gray-900 font-medium">{{ $log->actor?->name ?? '시스템' }}</p>
</div>
<div>
<label class="block text-sm text-gray-500 mb-1">이메일</label>
<p class="text-gray-900">{{ $log->actor?->email ?? '-' }}</p>
</div>
<div>
<label class="block text-sm text-gray-500 mb-1">IP 주소</label>
<p class="text-gray-900 font-mono">{{ $log->ip ?? '-' }}</p>
</div>
<div>
<label class="block text-sm text-gray-500 mb-1">User Agent</label>
<p class="text-gray-900 text-sm truncate" title="{{ $log->ua }}">{{ Str::limit($log->ua, 50) ?? '-' }}</p>
</div>
</div>
</div>
<!-- 데이터 비교 -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-6">
<!-- Before -->
<div class="bg-white rounded-lg shadow-sm p-6">
<h2 class="text-lg font-semibold text-gray-800 mb-4">변경 (Before)</h2>
<div class="bg-gray-900 rounded-lg p-4 overflow-x-auto max-h-96">
<pre class="text-yellow-400 text-sm font-mono whitespace-pre-wrap">{{ json_encode($log->before, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) ?: '(데이터 없음)' }}</pre>
</div>
</div>
<!-- After -->
<div class="bg-white rounded-lg shadow-sm p-6">
<h2 class="text-lg font-semibold text-gray-800 mb-4">변경 (After)</h2>
<div class="bg-gray-900 rounded-lg p-4 overflow-x-auto max-h-96">
<pre class="text-green-400 text-sm font-mono whitespace-pre-wrap">{{ json_encode($log->after, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) ?: '(데이터 없음)' }}</pre>
</div>
</div>
</div>
<!-- 변경 내용 하이라이트 -->
@if($log->before && $log->after)
<div class="bg-white rounded-lg shadow-sm p-6">
<h2 class="text-lg font-semibold text-gray-800 mb-4">변경 내용 요약</h2>
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-50">
<tr>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase">필드</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase">변경 </th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase">변경 </th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
@php
$allKeys = array_unique(array_merge(array_keys($log->before ?? []), array_keys($log->after ?? [])));
@endphp
@foreach($allKeys as $key)
@php
$beforeVal = $log->before[$key] ?? null;
$afterVal = $log->after[$key] ?? null;
$changed = $beforeVal !== $afterVal;
@endphp
<tr class="{{ $changed ? 'bg-yellow-50' : '' }}">
<td class="px-4 py-2 text-sm font-medium text-gray-900">{{ $key }}</td>
<td class="px-4 py-2 text-sm text-gray-500 font-mono">
@if(is_array($beforeVal))
{{ json_encode($beforeVal, JSON_UNESCAPED_UNICODE) }}
@else
{{ $beforeVal ?? '-' }}
@endif
</td>
<td class="px-4 py-2 text-sm font-mono {{ $changed ? 'text-green-600 font-medium' : 'text-gray-500' }}">
@if(is_array($afterVal))
{{ json_encode($afterVal, JSON_UNESCAPED_UNICODE) }}
@else
{{ $afterVal ?? '-' }}
@endif
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
@endif
@endsection