StatisticsLogic.php 8.1 KB
<?php

namespace App\Http\Logic\Bside\Statistics;

use App\Http\Logic\Bside\BaseLogic;
use App\Models\Bside\Statistics\TrafficStatistics;
use App\Models\CustomerVisit\CustomerVisit;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Contracts\Cache\Repository;
use Illuminate\Support\Facades\DB;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Throwable;

class StatisticsLogic extends BaseLogic
{
    public $trafficStatistics;

    private $customerVisit;

    public $date;

    public $time = 60 * 60 * 2;

    public function __construct()
    {
        parent::__construct();
        $this->customerVisit     = new CustomerVisit();
        $this->trafficStatistics = new TrafficStatistics();
        try {
            $this->date = request()->get('date') ?? null;
            // 判断传入日期是否大于当月
            if ($this->checkIsGreaterMonth($this->date)) {
                $this->date = null;
            }
            // 判断传入日期是否是当月
            if ($this->checkIsMonth($this->date)) {
                $this->date = null;
            }
        } catch (NotFoundExceptionInterface|ContainerExceptionInterface $e) {
            $this->date = null;
        }
    }

    /**
     * @param $type
     * @return array|Repository|mixed
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface|Throwable
     */
    public function getStatisticsData($type)
    {
        $function = debug_backtrace()[1]['function'];
        // 判断是否查询当月数据
        if (!is_null($this->date)) {
            // 获取缓存名
            $key      = $this->cacheName($type, $this->date);
            $response = cache()->get($key);
            if (empty($response)) {
                $dd    = explode('-', $this->date);
                $year  = $dd[0] ?? null;
                $month = str_pad($dd[1], 2, '0', STR_PAD_LEFT) ?? null;
                // 获取当前数据是否存在
                $data = $this->trafficStatistics->getData($type, $year, $month);
                if (is_null($data)) {
                    $response = $this->$function();
                    // 存在则直接返回
                    $response_data = array_filter($response);
                    if ($response_data) {
                        // 不存在则请求接口获取数据并保存
                        $this->create($response_data);
                    }
                } else {
                    $response = $data->toArray();
                }
                // 缓存数据
                cache()->put($key, $response, $this->time);
            }
        } else {
            $response = $this->$function();
        }
        return $response;
    }

    /**
     * @param $response
     * @return bool
     * @throws Throwable
     */
    public function create($response)
    {
        DB::beginTransaction();
        $keys = array_flip($this->trafficStatistics::KEY_VALUE);
        foreach ($response as $k => $v) {
            if (is_array($v)) {
                $v = json_encode($v);
            }
            $field                           = $keys[$k];
            $this->trafficStatistics->$field = $v;
        }
        $isRes = $this->trafficStatistics->save();
        if (!$isRes) {
            DB::rollBack();
            return false;
        }
        DB::commit();
        return true;
    }

    /**
     * 访问来源
     * @return array
     */
    public function source()
    {
        $response          = $this->getPvIp();
        $response['lists'] = $this->customerVisit->getUrlCount();
        return $response;
    }

    public function getPvIp()
    {
        $response['pv_count'] = $this->customerVisit->getMonthPVCount();
        $response['ip_count'] = $this->customerVisit->getMonthIPCount();
        return $response;
    }

    /**
     * 地域分布
     * @return array
     */
    public function distribution()
    {
        $response          = $this->getPvIp();
        $response['lists'] = $this->customerVisit->getCountryCount();
        return $response;
    }

    /**
     * 流量趋势
     * @return array
     * @throws ContainerExceptionInterface
     * @throws GuzzleException
     * @throws NotFoundExceptionInterface
     */
    public function trend()
    {
        $response             = $this->getPvIp();
        $inquiry              = $this->getCache('inquiry_information', $this->date);
        $response['in_count'] = $inquiry['count'] ?? 0;
        $response['lists']    = $inquiry['lists'] ?? [];
        return $response;
    }

    /**
     * 访问终端
     * @return array
     */
    public function terminal()
    {
        $response                 = $this->getPvIp();
        $response['pc_count']     = $this->customerVisit->getTerminalPcCount();
        $response['mobile_count'] = $this->customerVisit->getTerminalMobileCount();
        $response['lists']        = $this->customerVisit->getCountryCount();
        return $response;
    }

    /**
     * 受访页面
     * @return array
     */
    public function page()
    {
        $response          = $this->getPvIp();
        $response['lists'] = $this->customerVisit->getPageCount();
        return $response;
    }

    /**
     * 获取缓存
     * @param string $key 缓存键名
     * @param string|null $date 日期 格式:Y-m
     * @param float|int $time 缓存时间,默认2小时
     * @return mixed
     * @throws ContainerExceptionInterface
     * @throws GuzzleException
     * @throws NotFoundExceptionInterface
     */
    public function getCache(string $key, string $date = null, $time = 60 * 60 * 2)
    {
        $domain   = request()->getHttpHost(); //'www.wowstainless.com';
        $sta_date = !is_null($date) ? $date . '-01' : date('Y-m-01');
        $key      = $key . '_' . stringUnderlineLowercase($domain) . '_' . str_replace('-', '_', $sta_date);
        $value    = cache()->get($key);
        if (!$value) {
            $value = getInquiryInformation($domain, $sta_date);
            cache()->put($key, $value, $time);
        }
        return $value;
    }

    /**
     * @param int $type
     * @param string|null $date 日期 格式:Y-m-d
     * @return string
     */
    public function cacheName(int $type = TrafficStatistics::TYPE_SOURCE, string $date = null)
    {
        return 'statistics_' . $type . '_' . str_replace('-', '_', $date);
    }

    /**
     * 判断传入日期是否是当日
     * @param $date
     * @return bool
     */
    public function checkIsDay($date)
    {
        // 传入日期的时间戳
        $timestamp = strtotime($date);
        // 当日的日期格式,如:2021-10-13
        $today = date('Y-m-d');
        // 传入日期的日期格式,如:2021-10-12
        $date = date('Y-m-d', $timestamp);
        // 判断传入日期是否是当日
        return $date == $today;
    }

    /**
     * 判断传入日期是否大于当日
     * @param $date
     * @return bool
     */
    public function checkIsGreaterDay($date)
    {
        // 传入日期的时间戳
        $timestamp = strtotime($date);
        // 当前日期的时间戳
        $now = strtotime(date('Y-m-d'));
        // 判断传入日期是否大于当前日期
        return $timestamp > $now;
    }

    /**
     * 判断传入日期是否大于当月
     * @param $date
     * @return bool
     */
    public function checkIsGreaterMonth($date)
    {
        // 传入日期的时间戳
        $timestamp = strtotime($date);
        // 当前月份的时间戳
        $nowMonth = strtotime(date('Y-m'));
        // 判断传入日期是否大于当前月份
        return $timestamp > $nowMonth;
    }

    /**
     * 判断传入日期是否是当月
     * @param $date
     * @return bool
     */
    public function checkIsMonth($date)
    {
        // 获取当前时间戳
        $now = time();
        // 获取当月的起始时间戳和结束时间戳
        $firstDay = strtotime(date('Y-m-01', $now));
        $lastDay  = strtotime(date('Y-m-t', $now));
        // 传入日期的时间戳
        $timestamp = strtotime($date);
        // 判断传入日期是否在当月范围内
        return $timestamp >= $firstDay && $timestamp <= $lastDay;
    }
}