Files
animexe/app/Http/Controllers/Admin/UserAnalyticsController.php
T
2026-07-14 00:01:48 +03:00

141 lines
7.1 KiB
PHP

<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\User;
use App\Models\UserActivityLog;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class UserAnalyticsController extends Controller
{
public function index(Request $request)
{
$tab = $request->input('tab', 'overview'); // overview | bots | activity | country
$country = $request->input('country');
$period = (int) $request->input('period', 30); // days
$from = now()->subDays($period);
// ── Overview stats ────────────────────────────────────────────────────
$totalReal = User::where('role', '!=', 'admin')->count();
$newReal = User::where('role', '!=', 'admin')->where('created_at', '>=', $from)->count();
$active30 = DB::table('analytics_pageviews')
->where('is_bot', 0)->where('created_at', '>=', $from)
->distinct('user_id')->whereNotNull('user_id')->count('user_id');
$botViews = DB::table('analytics_pageviews')
->where('is_bot', 1)->where('created_at', '>=', $from)->count();
$realViews = DB::table('analytics_pageviews')
->where('is_bot', 0)->where('created_at', '>=', $from)->count();
// ── Daily new users (chart) ───────────────────────────────────────────
$dailyNew = DB::table('users')
->selectRaw('DATE(created_at) as day, COUNT(*) as cnt')
->where('role', '!=', 'admin')
->where('created_at', '>=', $from)
->groupBy('day')->orderBy('day')
->pluck('cnt', 'day');
// ── Country breakdown ─────────────────────────────────────────────────
$countriesQuery = DB::table('analytics_pageviews')
->selectRaw('country, COUNT(*) as views, COUNT(DISTINCT user_id) as users')
->where('is_bot', 0)
->where('created_at', '>=', $from)
->whereNotNull('country')
->groupBy('country')
->orderByDesc('views');
if ($country) $countriesQuery->where('country', $country);
$countries = $countriesQuery->limit(50)->get();
// ── Bot analysis ──────────────────────────────────────────────────────
$botStats = DB::table('analytics_bot_logs')
->selectRaw('bot_name, action, COUNT(*) as cnt')
->where('created_at', '>=', $from)
->groupBy('bot_name', 'action')
->orderByDesc('cnt')
->limit(30)->get();
$topBotIps = DB::table('analytics_bot_logs')
->selectRaw('ip, COUNT(*) as cnt')
->where('created_at', '>=', $from)
->groupBy('ip')
->orderByDesc('cnt')
->limit(20)->get();
$blockedIps = DB::table('blocked_ips')
->orderByDesc('blocked_at')
->limit(30)->get();
// ── User activity log ─────────────────────────────────────────────────
$actQuery = UserActivityLog::with('user:id,name,username,avatar')
->where('created_at', '>=', $from);
if ($country) $actQuery->where('country', $country);
if ($request->input('user_id')) $actQuery->where('user_id', $request->input('user_id'));
if ($request->input('action')) $actQuery->where('action', $request->input('action'));
$actQuery->orderByDesc('created_at');
$actLogs = $actQuery->paginate(50)->withQueryString();
// ── Top active users ──────────────────────────────────────────────────
$topUsers = DB::table('user_activity_logs')
->selectRaw('user_id, COUNT(*) as actions')
->where('is_bot', 0)->whereNotNull('user_id')
->where('created_at', '>=', $from)
->groupBy('user_id')->orderByDesc('actions')
->limit(10)->get();
$topUserIds = $topUsers->pluck('user_id');
$topUserMap = User::whereIn('id', $topUserIds)->get()->keyBy('id');
// ── Action breakdown ──────────────────────────────────────────────────
$actionBreakdown = DB::table('user_activity_logs')
->selectRaw('action, COUNT(*) as cnt')
->where('is_bot', 0)
->where('created_at', '>=', $from)
->groupBy('action')->orderByDesc('cnt')
->get();
// ── Device breakdown ──────────────────────────────────────────────────
$deviceBreakdown = DB::table('analytics_pageviews')
->selectRaw('device, COUNT(*) as cnt')
->where('is_bot', 0)->where('created_at', '>=', $from)
->groupBy('device')->orderByDesc('cnt')->get();
return view('admin.analytics.users', compact(
'tab', 'period', 'country',
'totalReal', 'newReal', 'active30', 'botViews', 'realViews',
'dailyNew', 'countries', 'botStats', 'topBotIps', 'blockedIps',
'actLogs', 'topUsers', 'topUserMap', 'actionBreakdown', 'deviceBreakdown'
));
}
public function userDetail(Request $request, User $user)
{
$period = (int) $request->input('period', 30);
$from = now()->subDays($period);
$logs = UserActivityLog::where('user_id', $user->id)
->where('created_at', '>=', $from)
->orderByDesc('created_at')
->paginate(50)->withQueryString();
$actBreakdown = DB::table('user_activity_logs')
->selectRaw('action, COUNT(*) as cnt')
->where('user_id', $user->id)->where('created_at', '>=', $from)
->groupBy('action')->orderByDesc('cnt')->get();
$pageviews = DB::table('analytics_pageviews')
->where('user_id', $user->id)->where('created_at', '>=', $from)
->orderByDesc('created_at')->limit(100)->get();
$watchEvents = DB::table('analytics_watch_events as we')
->join('episodes as e', 'e.id', '=', 'we.episode_id')
->join('animes as a', 'a.id', '=', 'we.anime_id')
->selectRaw('we.created_at, a.title as anime_title, e.episode_number, we.percent_complete, we.seconds_watched')
->where('we.user_id', $user->id)->where('we.created_at', '>=', $from)
->orderByDesc('we.created_at')->limit(50)->get();
return view('admin.analytics.user-detail', compact(
'user', 'logs', 'actBreakdown', 'pageviews', 'watchEvents', 'period'
));
}
}