RankDataLogic.php 12.4 KB
<?php

namespace App\Http\Logic\Bside;


use App\Helper\Arr;
use App\Helper\QuanqiusouApi;
use App\Helper\Translate;
use App\Http\Logic\Aside\Project\DomainInfoLogic;
use App\Http\Logic\Aside\Project\ProjectLogic;
use App\Models\RankData\ExternalLinks;
use App\Models\RankData\IndexedPages;
use App\Models\RankData\RankData;
use App\Models\RankData\RankWeek;
use App\Models\RankData\RecommDomain;
use App\Models\RankData\Speed;
use App\Utils\HttpUtils;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Str;

class RankDataLogic extends BaseLogic
{

    /**
     * 统计数据
     * @author zbj
     * @date 2023/5/11
     */
    public function index()
    {
        $project_id = $this->user['project_id'];

        //查数据
        $project = app(ProjectLogic::class)->getInfo($project_id);
        $domain_info = app(DomainInfoLogic::class)->getDomainInfo($project_id);
        $rank = RankData::where('project_id', $project_id)->first();
        $rank_week = RankWeek::where('project_id', $project_id)->first();
        $recomm_domain = RecommDomain::where('project_id', $project_id)->first();
        $external_links = ExternalLinks::where('project_id', $project_id)->first();
        $indexed_pages = IndexedPages::where('project_id', $project_id)->first();
        $speed = Speed::where('project_id', $project_id)->first();
        $api_no = $project['deploy_optimize']['api_no'] ?? '';
        //排名数据
        $data = [
            'first_num' => $rank['first_num'] ?? 0,
            'first_page_num' => $rank['first_page_num'] ?? 0,
            'first_three_pages_num' => $rank['first_three_pages_num'] ?? 0,
            'first_five_pages_num' => $rank['first_five_pages_num'] ?? 0,
            'first_ten_pages_num' => $rank['first_ten_pages_num'] ?? 0,
            'indexed_pages_num' => $rank['indexed_pages_num'] ?? 0,
            'external_links_num' => $external_links['total'] ?? 0,
        ];

        //项目信息
        $data['project'] = [
            'company' => $project['company'],
            'domain' => $project['deploy_optimize']['domain'],
            'domain_info' => ($domain_info['domain_info']['creation_date'] ?? '') . ' - ' . ($domain_info['domain_info']['expiration_date'] ?? ''),
            'cert_info' => ($domain_info['ssl']['start_time'] ?? '') . ' - ' . ($domain_info['ssl']['end_time'] ?? ''),
            'plan' => str_replace('营销大师-', '全球搜-', $project['deploy_build']['plan'][0]),
            'keyword_num' => $project['deploy_build']['keyword_num'],
            'compliance_day' => $rank['compliance_day'] ?? 0,
            'remain_day' => $project['deploy_build']['service_duration'] - ($rank['compliance_day'] ?? 0),
        ];

        //小语种列表
        $quanqiusou_api = new QuanqiusouApi();
        $lang_data = $quanqiusou_api->getLangRankData($api_no);
        $lang_data = Arr::setValueToKey($lang_data, 'language');

        foreach($project['deploy_optimize']['minor_languages'] as $lang){
            $remain_day = $lang_data[$lang['tl']]['dabiao_day'] ?? 0;
            $data['langs'][$lang['tl'] ?? ''] = [
                'lang_text' => Translate::getTls($lang['tl'] ?? ''),
                'keyword_num' => $lang['keywords'] ?? 0,
                'reach_day' => $lang_data[$lang['tl']]['dabiao_day'] ?? 0,
                'remain_day' => ($lang['type']??0) == 1 ? $data['project']['remain_day'] : $lang['service_day'] - $remain_day,
                'type' => $lang['type'] ?? 0, //1 项目关键词 项目天数  2 保证首页关键词 项目达标天数
            ];
        }


        //测速
        $data['speed'] = $speed['data'] ?? [];

        //seo基础设置
        $data['seo'] = [
            'H1,H2,H3标签',
            'TDK设置(Title, Description, Keywords)',
            'Google 收录提交',
            'Sitemap.xml Google站长地图',
            'Robots.txt文件优化',
            'Google站长工具优化设置'
        ];

        //外链引荐域名
        $data['external_links_domain_chat'] = [
            'labels' => array_map(function ($item) {
                return Str::substrReplace($item, '***', 2, 3);
            }, Arr::pluck($recomm_domain['data'] ?? [], 'domain')),
            'data' => Arr::pluck($recomm_domain['data'] ?? [], 'backlinks_num'),
            'list_date' => $recomm_domain['updated_at'] ?? '',
        ];
        //SEO数据周期分析图 外链数
        $data['external_links_chat'] = [
            'labels' => array_keys($external_links['data'] ?? []),
            'data' => array_values($external_links['data'] ?? []),
        ];
        //SEO数据周期分析图 收录数
        $data['indexed_pages_chat'] = [
            'labels' => array_keys($indexed_pages['data'] ?? []),
            'data' => array_values($indexed_pages['data'] ?? []),
        ];
        //收录数加上当日数据
        if ((Arr::last($data['indexed_pages_chat']['labels'])) != date('Y-m-d')) {
            $data['indexed_pages_chat']['labels'][] = date('Y-m-d');
            $data['indexed_pages_chat']['data'][] = $data['indexed_pages_num'];
        }
        //关键词排名分析图
        $data['rank_chat'] = [
            'data' => $rank_week['data'],
            'labels' => $rank_week['date'],
        ];

        return $data;
    }

    /**
     * 关键词排名
     * @author zbj
     * @date 2023/5/12
     */
    public function keywords_rank_list($export = false)
    {
        $page = intval($this->request['page'] ?: 1);
        $lang = $this->request['lang'] ?: '';
        $project_id = $this->user['project_id'];
        $project = app(ProjectLogic::class)->getInfo($project_id);
        $api_no = $project['deploy_optimize']['api_no'] ?? '';
        $domain = $project['deploy_optimize']['domain'] ?? '';
        $domain_arr = parse_url($domain);
        $domain = $domain_arr['host'] ?? $domain_arr['path'];

        //复制站点域名
        $ext_projects = $this->getExtendProjects();
        $flg_ext = $this->getExtFlag($ext_projects, $domain, $api_no);
        $ext_domain = str_replace('www.', '', $this->getExtendProjects($api_no)['ext'] ?? '');
        //AI站点域名
        $ai_projects = $this->getAiProjects()['data'] ?? [];
        $flg_ai = $this->getAiFlag($ai_projects, $domain);
        $ai_domain = str_replace('www.', '', $this->getAiProjects($domain)['domain'] ?? '');


        $list = RankData::where('project_id', $project_id)->where('lang', $lang)->value('data');
        $list30 = []; //排名前三十的
        $list30_0 = []; //排名前三十且近三天没有排名的
        $list100 = []; //排名前100的
        $list0 = [];//排名为0的
        foreach ($list as $key => $v) {
            $last = Arr::last($v);
            $data = [];

            //处理日期
            foreach ($v as $date => $position) {
                $data[date('m-d', strtotime($date . '+ 1 day'))] = $position['position'];
            }

            //域名类型
            $domain_text = '主域名:' . str_replace('www.', '', $domain);
            if (!empty($last['r'])) {
                $domain_text = 'AI域名:' . $last['r'];
                if (in_array($flg_ext, [1, 2]) || $flg_ai == 1) {
                    if ($last['r'] == $ai_domain) {
                        $domain_text = '星链域名:' . $ai_domain;
                    } else if ($last['r'] == $ext_domain) {
                        $domain_text = '主域名2:' . $ext_domain;
                    } else {
                        $domain_text = 'AI域名:' . $last['r'];
                    }
                }
            }
            $v = [
                'keyword' => $key,
                'domain' => $domain_text,
                'g' => $last['g'],  //1核心关键词
                'position' => $data
            ];
            if ($last['position'] == 0) {
                $list0[] = $v;
            } elseif ($last['position'] <= 30) {
                if (($v['position'][date('m-d', strtotime('-1day'))] ?? '') == 0 ||
                    ($v['position'][date('m-d', strtotime('-2day'))] ?? '') == 0) {
                    $list30_0[] = $v;
                } else {
                    $list30[] = $v;
                }
            } else {
                $list100[] = $v;
            }
        }
        //排序 排名前30的 按关键词长短排序 最近三天无排名的排后; 后30名的按排名排序
        $list30 = collect($list30)->sortBy(function ($item) {
            return strlen($item['keyword']);
        })->values()->all();
        $list30_0 = collect($list30_0)->sortBy(function ($item) {
            return strlen($item['keyword']);
        })->values()->all();
        $list100 = collect($list100)->sortBy(function ($item) {
            return Arr::last($item['position']);
        })->values()->all();
        $list = collect($list30)->merge($list30_0)->merge($list100)->merge($list0)->filter(function ($item) {
            //搜索
            if ($this->request['search']) {
                return strpos($item['keyword'], $this->request['search']) !== false;
            }
            //前几名
            if ($this->request['first']) {
                $position = Arr::last($item['position']);
                return $position > 0 && $position <= $this->request['first'];
            }
            //核心词
            if ($this->request['g']) {
                return $item['g'] == $this->request['g'];
            }
            return true;
        })->values();

        if($export){
            return $list->toArray();
        }
        $data = [
            "list" => $list->forPage($page, 100)->toArray(),
            "total" => $list->count(),
            "page" => $page,
            "total_page" => ceil($list->count() / 100),
            "size" => 100
        ];
        return $this->success($data);
    }


    /**
     * 获取复制站点项目
     * @author zbj
     * @date 2023/5/12
     */
    public function getExtendProjects($api_no = null)
    {
        $key = 'extend_projects_list';
        $data = Cache::get($key);
        if (!$data) {
            $api_url = 'http://api.quanqiusou.cn/google-rank/api/extend_projects.php';
            try {
                $data = HttpUtils::get($api_url, []);
                if ($data) {
                    $data = Arr::s2a($data);
                    Cache::put($key, $data, 4 * 3600);
                }
            } catch (\Exception | GuzzleException $e) {
                errorLog('复制站点项目获取失败', [], $e);
                return false;
            }
        }
        if ($api_no !== null) {
            $data = collect($data)->where('apino', $api_no)->first();
            return $data ?: [];
        }
        return $data;
    }

    /**
     * 获取AI站点项目
     * @author zbj
     * @date 2023/5/12
     */
    public function getAiProjects($domain = null)
    {
        $key = 'ai_projects_list';
        $data = Cache::get($key);
        if (!$data) {
            $api_url = 'https://demosite5.globalso.com/api/domain';
            try {
                $data = HttpUtils::get($api_url, []);
                if ($data) {
                    $data = Arr::s2a($data);
                    Cache::put($key, $data, 4 * 3600);
                }
            } catch (\Exception | GuzzleException $e) {
                errorLog('AI站点项目获取失败', [], $e);
                return false;
            }
        }
        if ($domain !== null) {
            $domain = parse_url($domain);
            $data = collect($data['data'])->where('bind_domain', $domain['host'] ?? $domain['path'])->first();
            return $data ?: [];
        }
        return $data;
    }

    /**
     * 获取复制项目标识
     * @author zbj
     * @date 2023/5/15
     */
    protected function getExtFlag($ext_projects, $domain, $api_no)
    {
        //复制站点标识
        $flg_ext = 0;
        if ($ext_projects) {
            $ext_urls = array_column($ext_projects, 'ext');
            $api_nos = array_column($ext_projects, 'apino');
            if (in_array($api_no, $api_nos)) {
                $flg_ext = 1;
            }
            if (in_array($domain, $ext_urls)) {
                $flg_ext = 2;
            }
        }
        return $flg_ext;
    }

    /**
     * 获取AI项目标识
     * @author zbj
     * @date 2023/5/15
     */
    protected function getAiFlag($ai_projects, $domain)
    {
        $flg_ai = 0;
        foreach ($ai_projects as $ai_project) {
            if ($ai_project['bind_domain'] == $domain) {
                $flg_ai = 1;
            }
        }
        return $flg_ai;
    }
}