$p !== '')); $days = null; $channelId = ''; if (isset($parts[0]) && in_array($parts[0], ['1', '7', '30'], true)) { $days = $parts[0]; $channelId = $parts[1] ?? ''; } elseif (isset($parts[0])) { if (preg_match('/^[0-9a-f]{32}$/i', $parts[0])) { $channelId = $parts[0]; } else { $bot->sendMessage( "Usage: /data [1|7|30] [channelId]\n" ."Omit days for today. Omit channelId for all channels." ); return; } } if ($channelId !== '' && ! preg_match('/^[0-9a-f]{32}$/i', $channelId)) { $bot->sendMessage('channelId must be a 32-char hex string.'); return; } $channelId = strtolower($channelId); $agent = $this->context->agent(); if ($agent !== null && $channelId !== '') { $owned = Channel::query() ->where('user_id', $agent->id) ->where('channel_id', $channelId) ->exists(); if (! $owned) { $bot->sendMessage('⛔ 无权查看该渠道'); return; } } try { $range = $this->stats->rangeFromDays($days); } catch (\InvalidArgumentException $e) { $bot->sendMessage($e->getMessage()); return; } $data = $this->stats->collect([ 'range' => $range, 'channel_id' => $channelId, 'channel_exact' => $channelId !== '', 'agent' => $agent, ]); $lines = [ '📊 访问统计', '区间: '.$data['from'].' ~ '.$data['to'], '渠道: '.($channelId !== '' ? $channelId : ($agent ? '本代理全部' : '全部')), '', '总设备: '.$data['total'], '新增设备: '.$data['new_count'], '活跃设备: '.$data['active_count'], '页面 PV: '.$data['effective_pv'].' / '.$data['pv'].' (有效/全部)', '页面 UV: '.$data['effective_uv'].' / '.$data['uv'].' (有效/全部)', '有效口径: iOS<17 + Safari', '', '按系统:', ]; foreach ($data['by_os'] as $row) { $lines[] = sprintf('• %s PV %d UV %d %s%%', $row['label'], $row['pv'], $row['uv'], $row['pct']); } $lines[] = ''; $lines[] = '按 iOS 版本:'; if ($data['by_ios_version'] === []) { $lines[] = '• 暂无'; } else { foreach ($data['by_ios_version'] as $row) { $lines[] = sprintf('• %s PV %d UV %d %s%%', $row['label'], $row['pv'], $row['uv'], $row['pct']); } } $bot->sendMessage(implode("\n", $lines)); } }