Files
boursecu_server/app/Services/AppNotificationUnreadService.php
T

81 lines
2.4 KiB
PHP
Raw Normal View History

2026-07-29 17:00:51 +03:30
<?php
namespace App\Services;
use App\Models\AppNotification;
use App\Models\AppNotificationRead;
use Illuminate\Database\Eloquent\Builder;
/**
* تعداد خوانده‌نشده + پخش SSE رویداد unread-count برای اپ کاربر.
*/
class AppNotificationUnreadService
{
public function __construct(
private readonly ConfigService $config,
private readonly PriceStreamService $stream,
) {
}
public function featureEnabled(): bool
{
return $this->config->getBool('has_page_notification', true);
}
public 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 countForCustomer(int $customerId): int
{
if ($customerId <= 0 || ! $this->featureEnabled()) {
return 0;
}
$visibleIds = $this->visibleQuery($customerId)->select('id');
$total = (clone $visibleIds)->count();
$read = AppNotificationRead::query()
->where('customer_id', $customerId)
->whereIn('notification_id', $visibleIds)
->count();
return max(0, $total - $read);
}
/**
* @return array{unread_count: int}
*/
public function payloadForCustomer(int $customerId): array
{
return [
'unread_count' => $this->countForCustomer($customerId),
];
}
public function publishForCustomer(int $customerId): void
{
if ($customerId <= 0 || ! $this->featureEnabled() || ! $this->stream->isEnabled()) {
return;
}
$this->stream->publishForCustomer(
$customerId,
'unread-count',
$this->payloadForCustomer($customerId)
);
}
}