From 0c5ecababa05c34cfb3660b9c5ee2ed41a4575db Mon Sep 17 00:00:00 2001 From: LL Date: Wed, 19 Nov 2025 09:31:41 +0800 Subject: [PATCH] =?UTF-8?q?=E6=95=B0=E6=8D=AE=E7=94=B1=E5=B1=95=E7=A4=BA?= =?UTF-8?q?=E6=AF=8F=E5=A4=A9=E7=9A=84=E6=94=B9=E4=B8=BA=E7=B4=AF=E8=AE=A1?= =?UTF-8?q?=E7=9A=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/stats.php | 62 ++++++++++++++++++++++++++++++++++++++++++++++-- assets/script.js | 7 ++++-- 2 files changed, 65 insertions(+), 4 deletions(-) diff --git a/api/stats.php b/api/stats.php index ad07684..d5209ce 100644 --- a/api/stats.php +++ b/api/stats.php @@ -24,7 +24,32 @@ if ($method === 'GET') { $out = []; foreach ($last7 as $k) { $out[$k] = $daily[$k]; } $todayData = $daily[$today] ?? ['visits' => 0, 'video_plays' => 0, 'picture_shows' => 0, 'uv' => 0, 'bandwidth_in' => 0, 'bandwidth_out' => 0]; - echo json_encode(['success' => true, 'today' => $todayData, 'daily' => $out], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); + $total = ['visits' => 0, 'video_plays' => 0, 'picture_shows' => 0, 'uv' => 0, 'bandwidth_in' => 0, 'bandwidth_out' => 0]; + foreach ($daily as $d) { + if (!is_array($d)) continue; + $total['visits'] += intval($d['visits'] ?? 0); + $total['video_plays'] += intval($d['video_plays'] ?? 0); + $total['picture_shows'] += intval($d['picture_shows'] ?? 0); + $total['bandwidth_in'] += intval($d['bandwidth_in'] ?? 0); + $total['bandwidth_out'] += intval($d['bandwidth_out'] ?? 0); + } + // 累计唯一访客:合并所有 uv/.json 的 IP + $ips = []; + if (is_dir($uvRoot)) { + $list = @scandir($uvRoot) ?: []; + foreach ($list as $f) { + if ($f === '.' || $f === '..') continue; + $p = $uvRoot . DIRECTORY_SEPARATOR . $f; + if (!is_file($p)) continue; + $rawIps = @file_get_contents($p); + $decodedIps = json_decode($rawIps, true); + if (is_array($decodedIps)) { + foreach ($decodedIps as $ip) { if (is_string($ip)) { $ips[$ip] = true; } } + } + } + } + $total['uv'] = count($ips); + echo json_encode(['success' => true, 'today' => $todayData, 'total' => $total, 'daily' => $out], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); exit; } @@ -90,7 +115,40 @@ $events[] = [ ]; @file_put_contents($eventsPath, json_encode($events, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT), LOCK_EX); -echo json_encode(['success' => true, 'today' => $daily[$today]], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); +// 计算累计总数并返回 +$total = ['visits' => 0, 'video_plays' => 0, 'picture_shows' => 0, 'uv' => 0, 'bandwidth_in' => 0, 'bandwidth_out' => 0]; +if (file_exists($dailyPath)) { + $rawDaily = @file_get_contents($dailyPath); + $decoded = json_decode($rawDaily, true); + if (is_array($decoded)) { + foreach ($decoded as $d) { + if (!is_array($d)) continue; + $total['visits'] += intval($d['visits'] ?? 0); + $total['video_plays'] += intval($d['video_plays'] ?? 0); + $total['picture_shows'] += intval($d['picture_shows'] ?? 0); + $total['bandwidth_in'] += intval($d['bandwidth_in'] ?? 0); + $total['bandwidth_out'] += intval($d['bandwidth_out'] ?? 0); + } + } +} +// 累计 UV +$ips = []; +if (is_dir($uvRoot)) { + $list = @scandir($uvRoot) ?: []; + foreach ($list as $f) { + if ($f === '.' || $f === '..') continue; + $p = $uvRoot . DIRECTORY_SEPARATOR . $f; + if (!is_file($p)) continue; + $rawIps = @file_get_contents($p); + $decodedIps = json_decode($rawIps, true); + if (is_array($decodedIps)) { + foreach ($decodedIps as $ip) { if (is_string($ip)) { $ips[$ip] = true; } } + } + } +} +$total['uv'] = count($ips); + +echo json_encode(['success' => true, 'today' => $daily[$today], 'total' => $total], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); $direction = isset($data['direction']) ? (string)$data['direction'] : ''; $bytes = isset($data['bytes']) ? intval($data['bytes']) : 0; if ($event === 'bandwidth' && $bytes > 0) { diff --git a/assets/script.js b/assets/script.js index acacfa8..6d08028 100644 --- a/assets/script.js +++ b/assets/script.js @@ -47,10 +47,13 @@ document.addEventListener('DOMContentLoaded', () => { body: JSON.stringify(payload) }); const j = await r.json(); - if (j && j.success && j.today) updateStatsUI(j.today); + if (j && j.success) { + const t = j.total || j.today; + updateStatsUI(t); + } } catch {} }; - (async () => { try { const r = await fetch('api/stats.php'); const j = await r.json(); if (j && j.success && j.today) updateStatsUI(j.today); } catch {} })(); + (async () => { try { const r = await fetch('api/stats.php'); const j = await r.json(); if (j && j.success) updateStatsUI(j.total || j.today); } catch {} })(); track({ event: 'visit', page: location.pathname }); // 底部工具栏与标题已移除,无需获取相关元素