<?php
 namespace Module\ShortLink\Util; use ModStart\Core\Dao\ModelUtil; use ModStart\Core\Util\ArrayUtil; use ModStart\Core\Util\TimeUtil; class LinkReportUtil { public static function get($linkId, $fromDay = null, $toDay = null) { if (TimeUtil::isDateEmpty($fromDay)) { $fromDay = date('Y-m-d', time()); } if (TimeUtil::isDateEmpty($toDay)) { $toDay = date('Y-m-d', time()); } $fromTs = strtotime($fromDay); $toTs = strtotime($toDay); if ($toTs > time()) { $toDay = date('Y-m-d', time()); $toTs = strtotime($toDay); } if ($toTs - $fromTs > TimeUtil::PERIOD_DAY) { $toTs = $fromTs + TimeUtil::PERIOD_DAY; $toDay = date('Y-m-d', $toTs); } if ($toDay > $fromDay) { $toDay = $fromDay; } $fromDay = $fromDay . ' 00:00:00'; $toDay = $toDay . ' 23:59:59'; $fromTs = strtotime($fromDay); $toTs = strtotime($toDay); $reports = []; for ($ts = $fromTs; $ts <= $toTs; $ts += TimeUtil::PERIOD_HOUR) { $reports[date('Y-m-d H:i:s', $ts)] = null; } $histories = ModelUtil::model('link_visit_hourly_report') ->where('linkId', $linkId) ->where('time', '>=', $fromDay) ->where('time', '<', $toDay) ->get(); foreach ($histories as $history) { $reports[$history['time']] = [ 'pv' => $history->pv, 'ipCount' => $history->ipCount, 'osCountInfo' => @json_decode($history->osCountInfo, true), 'browserCountInfo' => @json_decode($history->browserCountInfo, true), 'locationCountInfo' => @json_decode($history->locationCountInfo, true), 'ipCountInfo' => @json_decode($history->ipCountInfo, true), ]; } foreach ($reports as $reportTime => $report) { if (null === $report) { $reports[$reportTime] = self::calcReport($linkId, $reportTime); } } $reportList = []; foreach ($reports as $reportTime => $report) { $report['time'] = $reportTime; $reportList[] = $report; } return [ 'from' => $fromDay, 'to' => $toDay, 'reports' => $reportList, ]; } private static function calcReport($linkId, $reportTime) { $data = [ 'pv' => 0, 'ipCount' => 0, 'osCountInfo' => [], 'browserCountInfo' => [], 'locationCountInfo' => [], 'ipCountInfo' => [], ]; $ts = strtotime($reportTime); if ($ts > time()) { return $data; } $records = ModelUtil::model('link_visit')->where('linkId', $linkId) ->where('created_at', '>=', $reportTime) ->where('created_at', '<=', TimeUtil::format($ts + 3600 - 1)) ->get(['linkId', 'ip', 'ipCountry', 'ipProvince', 'os', 'browser']); $ips = []; foreach ($records as $record) { $data['pv']++; if (empty($ips[$record['ip']])) { $ips[$record['ip']] = true; $data['ipCount']++; } if (empty($data['osCountInfo'][$record['os']])) { $data['osCountInfo'][$record['os']] = 1; } else { $data['osCountInfo'][$record['os']]++; } if (empty($data['browserCountInfo'][$record['browser']])) { $data['browserCountInfo'][$record['browser']] = 1; } else { $data['browserCountInfo'][$record['browser']]++; } $location = []; if ($record['ipCountry']) { $location[] = $record['ipCountry']; } if ($record['ipProvince']) { $location[] = $record['ipProvince']; } $location = join(',', $location); if (empty($location)) { $location = '其他'; } if (empty($data['locationCountInfo'][$location])) { $data['locationCountInfo'][$location] = 1; } else { $data['locationCountInfo'][$location]++; } if (empty($data['ipCountInfo'][$record['ip']])) { $data['ipCountInfo'][$record['ip']] = 1; } else { $data['ipCountInfo'][$record['ip']]++; } } foreach (['osCountInfo', 'browserCountInfo', 'locationCountInfo', 'ipCountInfo'] as $k) { arsort($data[$k]); $data[$k] = ArrayUtil::keep($data[$k], 10); } if ($ts < time() - TimeUtil::PERIOD_HOUR * 1.5) { $insert = array_merge([ 'linkId' => $linkId, 'time' => $reportTime, ], $data); ModelUtil::encodeRecordJson($insert, ['osCountInfo', 'browserCountInfo', 'locationCountInfo', 'ipCountInfo']); ModelUtil::insert('link_visit_hourly_report', $insert); } return $data; } }