getBool('has_page_notification', true)) { throw new NotFoundHttpException('اعلان داخل اپ غیرفعال است.'); } } private function visibleQuery(int $customerId): Builder { return AppNotification::query() ->where('is_active', true) ->where(function (Builder $q) use ($customerId) { $q->where('audience_type', AppNotificationAudienceService::TYPE_ALL) ->orWhere(function (Builder $inner) use ($customerId) { $inner->whereIn('audience_type', [ AppNotificationAudienceService::TYPE_SEGMENT, AppNotificationAudienceService::TYPE_CUSTOMERS, ])->whereHas('recipients', function (Builder $r) use ($customerId) { $r->where('customer_id', $customerId); }); }); }); } public function index() { $this->assertFeatureEnabled(); $customerId = (int) auth()->id(); $rows = $this->visibleQuery($customerId) ->orderByDesc('id') ->limit(100) ->get(['id', 'title', 'body', 'severity', 'created_at']); $readIds = AppNotificationRead::query() ->where('customer_id', $customerId) ->whereIn('notification_id', $rows->pluck('id')) ->pluck('notification_id') ->all(); $readSet = array_fill_keys($readIds, true); $payload = $rows->map(function (AppNotification $row) use ($readSet) { return [ 'id' => $row->id, 'title' => $row->title, 'body' => $row->body, 'severity' => $row->severity, 'created_at' => $row->created_at, 'is_read' => isset($readSet[$row->id]), ]; }); return response()->json($payload); } public function unreadCount() { $this->assertFeatureEnabled(); $customerId = (int) auth()->id(); $visibleIds = $this->visibleQuery($customerId)->select('id'); $total = (clone $visibleIds)->count(); $read = AppNotificationRead::query() ->where('customer_id', $customerId) ->whereIn('notification_id', $visibleIds) ->count(); return response()->json([ 'unread_count' => max(0, $total - $read), ]); } public function markRead(Request $request, int $id) { $this->assertFeatureEnabled(); $customerId = (int) auth()->id(); $exists = $this->visibleQuery($customerId)->where('id', $id)->exists(); if (! $exists) { throw new NotFoundHttpException('اعلان یافت نشد.'); } AppNotificationRead::query()->updateOrCreate( [ 'notification_id' => $id, 'customer_id' => $customerId, ], [ 'read_at' => now(), ] ); return response()->json(true); } public function markAllRead() { $this->assertFeatureEnabled(); $customerId = (int) auth()->id(); $ids = $this->visibleQuery($customerId)->pluck('id'); $now = now(); foreach ($ids as $notificationId) { AppNotificationRead::query()->updateOrCreate( [ 'notification_id' => $notificationId, 'customer_id' => $customerId, ], [ 'read_at' => $now, ] ); } return response()->json(true); } }