giftcon_dev/app/Repositories/Admin/Log/AdminAuditLogRepository.php
2026-03-03 15:13:16 +09:00

100 lines
3.0 KiB
PHP

<?php
namespace App\Repositories\Admin\Log;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;
final class AdminAuditLogRepository
{
private const TABLE = 'admin_audit_logs';
public function paginate(array $filters, int $perPage = 30): LengthAwarePaginator
{
$q = DB::table(self::TABLE . ' as l')
->leftJoin('admin_users as au', 'au.id', '=', 'l.actor_admin_user_id')
->select([
'l.id',
'l.actor_admin_user_id',
'l.action',
'l.target_type',
'l.target_id',
'l.ip',
'l.created_at',
'au.email as actor_email',
'au.name as actor_name',
]);
// 기간
if (!empty($filters['date_from'])) {
$q->where('l.created_at', '>=', $filters['date_from'] . ' 00:00:00');
}
if (!empty($filters['date_to'])) {
$q->where('l.created_at', '<=', $filters['date_to'] . ' 23:59:59');
}
// actor 검색 (email/name)
$actorQ = trim((string)($filters['actor_q'] ?? ''));
if ($actorQ !== '') {
$like = '%' . $this->escapeLike($actorQ) . '%';
$q->where(function ($qq) use ($like) {
$qq->where('au.email', 'like', $like)
->orWhere('au.name', 'like', $like);
});
}
// action (prefix match)
$action = trim((string)($filters['action'] ?? ''));
if ($action !== '') {
$q->where('l.action', 'like', $this->escapeLike($action) . '%');
}
// target_type (prefix match)
$tt = trim((string)($filters['target_type'] ?? ''));
if ($tt !== '') {
$q->where('l.target_type', 'like', $this->escapeLike($tt) . '%');
}
// ip (prefix match)
$ip = trim((string)($filters['ip'] ?? ''));
if ($ip !== '') {
$q->where('l.ip', 'like', $this->escapeLike($ip) . '%');
}
// 최신순
$q->orderByDesc('l.created_at')->orderByDesc('l.id');
return $q->paginate($perPage)->withQueryString();
}
public function findOne(int $id): ?array
{
$row = DB::table(self::TABLE . ' as l')
->leftJoin('admin_users as au', 'au.id', '=', 'l.actor_admin_user_id')
->select([
'l.id',
'l.actor_admin_user_id',
'l.action',
'l.target_type',
'l.target_id',
'l.before_json',
'l.after_json',
'l.ip',
'l.user_agent',
'l.created_at',
'au.email as actor_email',
'au.name as actor_name',
])
->where('l.id', $id)
->first();
return $row ? (array)$row : null;
}
private function escapeLike(string $s): string
{
// MySQL LIKE escape (%, _)
return str_replace(['\\', '%', '_'], ['\\\\', '\%', '\_'], $s);
}
}