- AuditLogController: 목록/상세 조회, 필터링(액션/테넌트/날짜/검색) - AuditLog 모델: 재고 변동 액션 및 참조 타입 상수 정의 - Blade 뷰: 통계 카드, 필터, 아코디언(Before/After JSON), 상세 페이지 - 메뉴 DB 등록: 시스템 설정 하위에 감사 로그, 삭제된 데이터 백업 추가 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
110 lines
2.9 KiB
PHP
110 lines
2.9 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\Audit\AuditLog;
|
|
use App\Models\Tenants\Tenant;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\View\View;
|
|
|
|
class AuditLogController extends Controller
|
|
{
|
|
/**
|
|
* 감사 로그 목록
|
|
*/
|
|
public function index(Request $request): View
|
|
{
|
|
$query = AuditLog::query()
|
|
->with(['tenant', 'actor'])
|
|
->orderByDesc('created_at');
|
|
|
|
// 대상 타입 필터 (기본: Stock)
|
|
$targetType = $request->input('target_type', 'Stock');
|
|
if ($targetType) {
|
|
$query->where('target_type', $targetType);
|
|
}
|
|
|
|
// 액션 필터
|
|
if ($request->filled('action')) {
|
|
$query->where('action', $request->action);
|
|
}
|
|
|
|
// 테넌트 필터
|
|
if ($request->filled('tenant_id')) {
|
|
$query->where('tenant_id', $request->tenant_id);
|
|
}
|
|
|
|
// 날짜 범위 필터
|
|
if ($request->filled('from')) {
|
|
$query->where('created_at', '>=', $request->from.' 00:00:00');
|
|
}
|
|
if ($request->filled('to')) {
|
|
$query->where('created_at', '<=', $request->to.' 23:59:59');
|
|
}
|
|
|
|
// 검색 (LOT 번호, 참조 ID)
|
|
if ($request->filled('search')) {
|
|
$search = $request->search;
|
|
$query->where(function ($q) use ($search) {
|
|
$q->whereRaw("JSON_EXTRACT(after, '$.lot_no') LIKE ?", ["%{$search}%"])
|
|
->orWhereRaw("JSON_EXTRACT(after, '$.reference_id') = ?", [$search]);
|
|
});
|
|
}
|
|
|
|
// 통계
|
|
$stats = $this->getStats($targetType);
|
|
|
|
// 페이지네이션
|
|
$logs = $query->paginate(50)->withQueryString();
|
|
|
|
// 테넌트 목록 (필터용)
|
|
$tenants = Tenant::orderBy('company_name')->get(['id', 'company_name as name']);
|
|
|
|
// 액션 목록
|
|
$actions = AuditLog::STOCK_ACTIONS;
|
|
|
|
return view('audit-logs.index', compact('logs', 'stats', 'tenants', 'actions', 'targetType'));
|
|
}
|
|
|
|
/**
|
|
* 감사 로그 상세
|
|
*/
|
|
public function show(int $id): View
|
|
{
|
|
$log = AuditLog::with(['tenant', 'actor'])->findOrFail($id);
|
|
|
|
return view('audit-logs.show', compact('log'));
|
|
}
|
|
|
|
/**
|
|
* 통계 조회
|
|
*/
|
|
private function getStats(?string $targetType): array
|
|
{
|
|
$baseQuery = AuditLog::query();
|
|
|
|
if ($targetType) {
|
|
$baseQuery->where('target_type', $targetType);
|
|
}
|
|
|
|
$total = (clone $baseQuery)->count();
|
|
|
|
$byAction = (clone $baseQuery)
|
|
->selectRaw('action, COUNT(*) as count')
|
|
->groupBy('action')
|
|
->pluck('count', 'action')
|
|
->toArray();
|
|
|
|
// 오늘 기록 수
|
|
$today = (clone $baseQuery)
|
|
->whereDate('created_at', today())
|
|
->count();
|
|
|
|
return [
|
|
'total' => $total,
|
|
'today' => $today,
|
|
'by_action' => $byAction,
|
|
];
|
|
}
|
|
}
|