<?php
namespace Module\VisitStatistic\Util;
use ModStart\Core\Dao\ModelUtil;
use ModStart\Core\Util\LockUtil;
use ModStart\Core\Util\TimeUtil;
use Module\VisitStatistic\Model\VisitStatisticDailyReport;
use Module\VisitStatistic\Model\VisitStatisticItem;
class VisitStatisticUtil
{
public static function report($startDay = null, $endDay = null)
{
if (TimeUtil::isDateEmpty($startDay)) {
$startDay = date('Y-m-d', time() - 15 * TimeUtil::PERIOD_DAY);
}
if (TimeUtil::isDateEmpty($endDay)) {
$endDay = date('Y-m-d', time());
}
$startTs = strtotime($startDay);
$endTs = strtotime($endDay);
$records = VisitStatisticDailyReport::query()
->where('day', '>=', $startDay)
->where('day', '<=', $endDay)->get();
$recordMap = [];
foreach ($records as $record) {
$recordMap[$record->day] = $record->toArray();
}
$today = strtotime(date('Y-m-d', time()));
for ($t = $startTs; $t <= $endTs; $t += TimeUtil::PERIOD_DAY) {
$day = date('Y-m-d', $t);
if (!isset($recordMap[$day])) {
if ($t <= $today) {
$recordMap[$day] = self::calcReport($day);
if ($t < $today) {
$where = ['day' => $day];
$lockKey = 'VisitStatistic:DailyReport:' . $day;
if (LockUtil::acquire($lockKey)) {
if (!ModelUtil::exists(VisitStatisticDailyReport::class, $where)) {
ModelUtil::insert(VisitStatisticDailyReport::class, $recordMap[$day]);
}
LockUtil::release($lockKey);
}
}
} else {
$recordMap[$day] = [
'day' => $day,
'uv' => 0,
'pv' => 0,
];
}
}
}
return [
'start' => $startDay,
'end' => $endDay,
'time' => array_keys($recordMap),
'pv' => array_column($recordMap, 'pv'),
'uv' => array_column($recordMap, 'uv'),
];
}
private static function calcReport($day)
{
$result = [
'day' => $day,
'uv' => 0,
'pv' => 0,
];
$result['pv'] = VisitStatisticItem::where('created_at', '>=', $day . ' 00:00:00')
->where('created_at', '<=', $day . ' 23:59:59')
->count();
$result['uv'] = VisitStatisticItem::where('created_at', '>=', $day . ' 00:00:00')
->where('created_at', '<=', $day . ' 23:59:59')
->distinct('ip')
->count('ip');
return $result;
}
}