'today', 'date' => $day]; } else { $bucketExpr = "DATE_FORMAT(created_at, '%Y-%m-%d')"; $times = []; $cursor = strtotime($startDate); $endTs = strtotime($endDate); while ($cursor <= $endTs) { $times[] = date('Y-m-d', $cursor); $cursor = strtotime('+1 day', $cursor); } $rangeStart = $startDate . ' 00:00:00'; $rangeEnd = $endDate . ' 23:59:59'; $meta = [ 'type' => 'all', 'start_time' => $startDate, 'end_time' => $endDate, ]; } $rows = User::query() ->selectRaw("{$bucketExpr} as time_key, `from` as user_from, COUNT(*) as cnt") ->whereBetween('created_at', [$rangeStart, $rangeEnd]) ->groupByRaw("{$bucketExpr}, `from`") ->get(); $memberMap = array_fill_keys($times, 0); $virtualMap = array_fill_keys($times, 0); foreach ($rows as $row) { $key = (string)$row->time_key; if (!array_key_exists($key, $memberMap)) { continue; } if ((string)$row->user_from === '2') { $virtualMap[$key] += (int)$row->cnt; } else { $memberMap[$key] += (int)$row->cnt; } } return array_merge($meta, [ 'times' => $times, 'member' => array_values($memberMap), 'virtual' => array_values($virtualMap), 'member_total' => array_sum($memberMap), 'virtual_total' => array_sum($virtualMap), ]); } /** * 域名统计(SQL 分页) * * @return array{total:int,data:list} */ public static function domain(?string $startDate, ?string $endDate, int $page, int $limit): array { $domainExpr = "IF(register_domain = '' OR register_domain IS NULL, '未知', register_domain)"; $base = User::query(); if ($startDate) { $base->where('created_at', '>=', $startDate . ' 00:00:00'); } if ($endDate) { $base->where('created_at', '<=', $endDate . ' 23:59:59'); } $grouped = (clone $base) ->selectRaw("{$domainExpr} as register_url, COUNT(*) as register_count") ->groupByRaw($domainExpr); $total = (int)DB::query()->fromSub( (clone $grouped), 'domain_groups' )->count(); $offset = max(0, ($page - 1) * $limit); $rows = (clone $grouped) ->orderByDesc(DB::raw('register_count')) ->offset($offset) ->limit($limit) ->get(); $data = $rows->map(fn ($row) => [ 'register_url' => (string)$row->register_url, 'register_count' => (int)$row->register_count, ])->values()->all(); return ['total' => $total, 'data' => $data]; } }