CustomerVisit.php 8.3 KB
<?php

namespace App\Models\CustomerVisit;

use App\Models\Base;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Factories\HasFactory;

/**
 * App\Models\CustomerVisit\CustomerVisit
 *
 * @property int $id ID
 * @property string $url 客户访问URL
 * @property string $referrer_url 访问来源
 * @property int $device_port 设备端口 1:PC端,2:移动端
 * @property string $country 国家
 * @property string $city 地区
 * @property string $ip 访问ip
 * @property int $depth 访问深度
 * @property string $domain 域名
 * @property \Illuminate\Support\Carbon $created_at 访问时间
 * @property \Illuminate\Support\Carbon $updated_at 更新时间
 * @property string $updated_date 统计日期
 * @method static \Database\Factories\CustomerVisit\CustomerVisitFactory factory(...$parameters)
 * @method static Builder|CustomerVisit newModelQuery()
 * @method static Builder|CustomerVisit newQuery()
 * @method static Builder|CustomerVisit query()
 * @method static Builder|CustomerVisit whereCity($value)
 * @method static Builder|CustomerVisit whereCountry($value)
 * @method static Builder|CustomerVisit whereCreatedAt($value)
 * @method static Builder|CustomerVisit whereDepth($value)
 * @method static Builder|CustomerVisit whereDevicePort($value)
 * @method static Builder|CustomerVisit whereDomain($value)
 * @method static Builder|CustomerVisit whereId($value)
 * @method static Builder|CustomerVisit whereIp($value)
 * @method static Builder|CustomerVisit whereReferrerUrl($value)
 * @method static Builder|CustomerVisit whereUpdatedAt($value)
 * @method static Builder|CustomerVisit whereUpdatedDate($value)
 * @method static Builder|CustomerVisit whereUrl($value)
 * @mixin \Eloquent
 */
class CustomerVisit extends Base
{
    use HasFactory;
    protected $table = 'gl_customer_visit';
    const LIMIT = 15;

    /** @var int PC端 */
    const TERMINAL_PC = 1;
    /** @var int 移动端 */
    const TERMINAL_MOBILE = 2;

    /**
     * @param string $field 统计字段
     * @param string $action 统计方法 count|sum
     * @param bool $isDay 是否按天查询
     * @param string|null $date 日期 格式:Y-m-d
     * @return int
     */
    public function queryField(string $field, string $action = 'count', bool $isDay = false, string $date = null)
    {
        $query = $this->query()->selectRaw("{$action}({$field}) as count");
        if ($date) {
            $dd    = explode('-', $date);
            $year  = $dd[0] ?? null;
            $month = $dd[1] ?? null;
            $day   = $dd[2] ?? null;
            if (!is_null($year)) {
                $query->whereYear('updated_date', '=', $year);
            }
            if (!is_null($month)) {
                $query->whereMonth('updated_date', '=', $month);
            }
            if (!is_null($day)) {
                $query->whereDay('updated_date', '=', $day);
            }
        } else {
            $query->whereYear('updated_date', '=', date("Y"))
                ->whereMonth('updated_date', '=', date("m"));
            if ($isDay) {
                $query->whereDay('updated_date', '=', date("d"));
            }
        }

        return (int)$query->value('count') ?? 0;
    }


    /**
     * @param string $field 统计字段
     * @param int $action 终端类型
     * @param string|null $date 日期 格式:Y-m
     * @return int
     */
    public function queryTerminal(string $field, string $date = null, int $action = self::TERMINAL_PC)
    {
        $query = $this->query()
            ->selectRaw("count(*) as count")
            ->where($field, '=', $action);
        $this->extracted($date, $query);
        return (int)$query->value('count') ?? 0;
    }

    /**
     * @param string $field 查询字段
     * @param string|null $date 日期 格式:Y-m-d
     * @param int $limit 查询条数
     * @return Builder[]|Collection|\Illuminate\Support\Collection
     */
    public function getRankingData(string $field, string $date = null, int $limit = self::LIMIT)
    {
        $query = $this->query()
            ->selectRaw('count(*) as count, ' . $field . ' as request');
        $this->extracted($date, $query);
        return $query->groupBy($field)
            ->orderBy('count', 'desc')
            ->limit($limit)
            ->get();
    }

    /**
     * 获取相加总数
     * @param string $field
     * @param string|null $date 日期 格式:Y-m-d
     * @return int
     */
    public function getSum(string $field, string $date = null)
    {
        return $this->queryField($field, 'sum', false, $date);
    }

    /**
     * 获取总数
     * @param string $field
     * @param string|null $date 日期 格式:Y-m-d
     * @return int
     */
    public function getCount(string $field, string $date = null)
    {
        return $this->queryField($field, 'count', false, $date);
    }

    /**
     * 获取列表和总数
     * @param Collection $data
     * @param int $limit
     * @return array
     */
    public function returnLists(Collection $data, int $limit = self::LIMIT)
    {
        $lists = $data->toArray();
        $lists = $lists ? array_slice($lists, 0, $limit) : [];
        $count = $data->count();
        return compact('lists', 'count');
    }

    /**
     * 查询当月流量的浏览量
     * @param string|null $data 日期 格式:Y-m-d
     * @return int
     */
    public function getMonthPVCount(string $data = null)
    {
        return $this->getSum('depth', $data);
    }

    /**
     * 查询当月流量的访客量
     * @param string|null $data 日期 格式:Y-m-d
     * @return int
     */
    public function getMonthIPCount(string $data = null)
    {
        return $this->getCount('ip', $data);
    }

    /**
     * 查询当月TOP15访问来源
     * @param string|null $date 日期 格式:Y-m-d
     * @param int $limit 查询条数
     * @return array
     */
    public function getUrlCount(string $date = null, int $limit = self::LIMIT)
    {
        return $this->getRankingData('referrer_url', $date, $limit);
    }

    /**
     * 查询当月TOP15访问国家来源
     * @param string|null $date 日期 格式:Y-m
     * @param int $limit
     * @return array
     */
    public function getCountryCount(string $date = null, int $limit = self::LIMIT)
    {
        return $this->getRankingData('country', $date, $limit);
    }

    /**
     * 查询当月TOP15受访页面
     * @param string|null $date 日期 格式:Y-m
     * @param int $limit
     * @return array
     */
    public function getPageCount(string $date = null, int $limit = self::LIMIT)
    {
        return $this->getRankingData('url', $date, $limit);
    }

    /**
     * 查询当月TOP15访问终端
     * @param string|null $date 日期 格式:Y-m-d
     * @return int
     */
    public function getTerminalPcCount(string $date = null)
    {
        return $this->queryTerminal('device_port', $date);
    }

    /**
     * 查询当月TOP15访问终端
     * @param string|null $date 日期 格式:Y-m-d
     * @return int
     */
    public function getTerminalMobileCount(string $date = null)
    {
        return $this->queryTerminal('device_port', $date, self::TERMINAL_MOBILE);
    }

    /**
     * 查询当日流量的浏览量
     * @param string|null $date 日期 格式:Y-m-d
     * @return int
     */
    public function getDayPVCount(string $date = null)
    {
        return $this->queryField('depth', 'sum', true, $date);
    }

    /**
     * 查询当日流量的访客量
     * @param string|null $date 日期 格式:Y-m-d
     * @return int
     */
    public function getDayIPCount(string $date = null)
    {
        return $this->queryField('ip', 'count', true, $date);
    }

    /**
     * @param $date
     * @param $query
     * @return void
     */
    public function extracted($date, $query)
    {
        if (!is_null($date)) {
            $dd    = explode('-', $date);
            $year  = $dd[0] ?? null;
            $month = $dd[1] ?? null;
            if (!is_null($year)) {
                $query->whereYear('updated_date', '=', $year);
            }
            if (!is_null($month)) {
                $query->whereMonth('updated_date', '=', $month);
            }
        } else {
            $query->whereYear('updated_date', '=', date("Y"))
                ->whereMonth('updated_date', '=', date("m"));
        }
    }
}