作者 lyh

gx

... ... @@ -11,6 +11,8 @@ use App\Enums\Common\Code;
use App\Http\Controllers\Controller;
use Illuminate\Http\Exceptions\HttpResponseException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
/**
* Class BaseController
... ... @@ -18,6 +20,12 @@ use Illuminate\Http\JsonResponse;
*/
class BaseController extends Controller
{
public $param;
public function __construct(Request $request)
{
$this->request = $request;
$this->param = $this->request->all();
}
/**
* @param array $data
* @param string $message
... ...
<?php
/**
* @remark :
* @name :OptimizationReportController.php
* @author :lyh
* @method :post
* @time :2024/3/7 15:57
*/
namespace App\Http\Controllers\Api;
use App\Enums\Common\Code;
use App\Helper\Arr;
use App\Helper\FormGlobalsoApi;
use App\Http\Logic\Aside\Project\DomainInfoLogic;
use App\Http\Logic\Aside\Project\ProjectLogic;
use App\Models\Domain\DomainInfo;
use App\Models\HomeCount\Count;
use App\Models\Inquiry\InquiryForm;
use App\Models\Inquiry\InquiryFormData;
use App\Models\Inquiry\InquiryOther;
use App\Models\Project\Project;
use App\Models\RankData\ExternalLinks;
use App\Models\RankData\IndexedPages;
use App\Models\RankData\RankData;
use App\Models\RankData\RankWeek;
use App\Models\RankData\Speed;
use App\Models\Visit\Visit;
use App\Models\Visit\VisitItem;
use App\Services\ProjectServer;
use App\Utils\HttpUtils;
use Carbon\Carbon;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
class OptimizationReportController extends BaseController
{
/**
* @remark :优化报告
* @name :getOptimizationReport
* @author :lyh
* @method :post
* @time :2024/3/7 15:54
*/
public function getOptimizationReport(){
ProjectServer::useProject($this->param['project_id']);
$data = [];
$projectModel = new Project();
$projectInfo = $projectModel->with('payment')->with('deploy_build')
->with('deploy_optimize')->with('online_check')->where(['id'=>$this->param['project_id']])->first();
$domainModel = new DomainInfo();
$domain_info = $domainModel->where('project_id', $this->param['project_id'])->first();
if(!$domain_info){
return [];
}else{
$domain_info = [
'domain' => 'https://'.$domain_info['domain'].'/',
'domain_info' => date('Y-m-d', strtotime($domain_info['domain_start_time'])) . ' - ' .date('Y-m-d', strtotime($domain_info['domain_end_time'])),
'cert_info' => date('Y-m-d', strtotime($domain_info['certificate_start_time'])) . ' - ' .date('Y-m-d', strtotime($domain_info['certificate_end_time'])),
];
}
//方案信息
$data['plan_information'] = $this->plan_information($projectInfo);
//排名数据
$data['first_total'] = $this->first_total();
//关键词排名分析图
$data['rank_chat'] = $this->rank_chat();
//关键词排名明细
$data['keywords_rank_list'] = $this->keywords_rank_list($this->param['project_id'],$projectInfo);
//pv_ip统计
$data['pv_ip'] = $this->pv_ip($domain_info['domain']);
//30天统计
$data['count_30'] = $this->count_30_total();
//访问国家前10
$data['access_country_count'] = $this->access_country_count();
//外链周期分析
$external_links = ExternalLinks::where('project_id', $this->param['project_id'])->first();
//SEO数据周期分析图 外链数
$data['external_links_chat'] = [
'labels' => array_keys($external_links['data'] ?? []),
'data' => array_values($external_links['data'] ?? []),
];
$indexed_pages = IndexedPages::where('project_id', $this->param['project_id'])->first();
//SEO数据周期分析图 收录数
$data['indexed_pages_chat'] = [
'labels' => array_keys($indexed_pages['data'] ?? []),
'data' => array_values($indexed_pages['data'] ?? []),
];
//月统计报告
$data['month_count'] = $this->currentMonthCount();
//测速
$speed = Speed::where('project_id', $this->param['project_id'])->first();
$data['speed'] = $speed['data'] ?? [];
//询盘
$data['inquiry'] = $this->getApiList($projectInfo);
DB::disconnect('custom_mysql');
$this->response('success',Code::SUCCESS,$data);
}
/**
* @remark :获取当前月数据统计
* @name :currentMonth
* @author :lyh
* @method :post
* @time :2023/7/3 9:55
*/
public function currentMonthCount(){
// 获取当前月的开始时间
$startTime = date('Y-m-01 00:00:00', strtotime('2024-01'));
// 获取当前月的结束时间
$endTime = date('Y-m-t 23:59:59', strtotime('2024-01'));
$arr = [];
$arr = $this->inquiryCount($arr,$startTime,$endTime,$this->user['domain']);
$arr = $this->flowCount($arr,$startTime,$endTime,$this->user['project_id']);
$arr = $this->sourceCount($arr,$startTime,$endTime,$this->user['domain']);
$arr['month'] = date('Y-m',time());
return $arr;
}
/**
* @param $domain
* @param $project_id
* @remark :询盘按月统计
* @name :inquiryCount
* @author :lyh
* @method :post
* @time :2023/6/30 14:29
*/
public function inquiryCount(&$arr,&$startTime,&$endTime,$domain){
$inquiry_list = (new FormGlobalsoApi())->getInquiryList($domain,'',1,100000000);
if(!empty($inquiry_list)){
//总数
$arr['total'] = $inquiry_list['data']['total'] ?? 0;
//数据详情
$data = $inquiry_list['data']['data'] ?? '';
$arr['month_total'] = 0;
$countryArr = [];
if(isset($data) && !empty($data)){
foreach ($data as $v){
if(($startTime.' 00:00:00' <= $v['submit_time']) && $v['submit_time'] <= $endTime.' 23:59:59'){
$arr['month_total']++;
if(isset($countryArr[$v['country']])){
$countryArr[$v['country']]++;
}else{
$countryArr[$v['country']] = 1;
}
}
}
}
}
//加上其他询盘
$arr['total'] += InquiryFormData::getCount();
$arr['month_total'] += InquiryFormData::getCount([$startTime, $endTime]);
$countryData = InquiryFormData::getCountryCount([$startTime, $endTime]);
foreach ($countryData as $v1){
if(isset($countryArr[$v1['country']])){
$countryArr[$v1['country']] += $v1['count'];
}else{
$countryArr[$v1['country']] = $v1['count'];
}
}
arsort($countryArr);
$top20 = array_slice($countryArr, 0, 15, true);
$arr['country'] = $top20;
return $arr;
}
/**
* @remark :流量统计
* @name :flowCount
* @author :lyh
* @method :post
* @time :2023/6/30 14:31
*/
public function flowCount(&$arr,&$startTime,&$endTime,$project_id){
$pv_ip = DB::table('gl_count')
->where(['project_id'=>$project_id])
->whereBetween('date', [$startTime,$endTime])
->select(DB::raw('SUM(pv_num) as pv_num'), DB::raw('SUM(ip_num) as ip_num'))
->orderBy('id','desc')
->first();
$arr['pv'] = $pv_ip->pv_num;
$arr['ip'] = $pv_ip->ip_num;
$arr['rate'] = 0;
if($arr['ip'] != 0){
$arr['rate'] = round(($arr['month_total'] / $arr['ip']) * 100,2);
}
return $arr;
}
/**
* @remark :来源访问前8
* @name :sourceCount
* @author :lyh
* @method :post
* @time :2023/6/30 16:14
*/
public function sourceCount(&$arr,$startTime,$endTime,$domain){
//访问来源前10
$source = DB::connection('custom_mysql')->table('gl_customer_visit')
->select('referrer_url', DB::raw('COUNT(*) as count'))
->groupBy('referrer_url')
->where('referrer_url','!=','')
->whereBetween('updated_date', [$startTime,$endTime])
->orderByDesc('count')->limit(10)->get()->toArray();
$arr['source'] = $source;
//访问国家前15
$query = DB::connection('custom_mysql')->table('gl_customer_visit')
->select('country',DB::raw('COUNT(*) as ip'),DB::raw('SUM(depth) as pv'))
->groupBy('country');
if(isset($this->project['is_record_china_visit']) && ($this->project['is_record_china_visit'] == 0)){
$query->where('country','<>','中国');
}
$source_country = $query->whereBetween('updated_date', [$startTime,$endTime])
->orderBy('ip','desc')->limit(15)->get()->toArray();
$arr['source_country'] = $source_country;
//受访界面前15
$referrer_url = DB::connection('custom_mysql')->table('gl_customer_visit')
->select('url',DB::raw('COUNT(*) as num'))
->orderBy('num','desc')
->whereBetween('updated_date', [$startTime,$endTime])
->groupBy('url')
->limit(15)->get()->toArray();
$arr['referrer_url'] = $referrer_url;
//访问断后
$referrer_port = DB::connection('custom_mysql')->table('gl_customer_visit')
->select('device_port',DB::raw('COUNT(*) as num'))
->orderBy('num','desc')
->whereBetween('updated_date', [$startTime,$endTime])
->groupBy('device_port')
->limit(15)->get()->toArray();
$arr['referrer_port'] = $referrer_port;
return $arr;
}
public function getApiList($projectInfo,$export = false)
{
$this->form_globalso_api = new FormGlobalsoApi();
if(isset($this->request['row'])){
$page_size = $this->request['row'];
}else{
$page_size = $export ? 1000 : 20;
}
$search = $this->request['search'] ?: '';
$page = $this->request['page'] ?: 1;
$domain = (!empty($projectInfo['deploy_optimize']['domain']) ? ((new DomainInfo())->getDomain($projectInfo['deploy_optimize']['domain'])) : '');
$list = $this->form_globalso_api->getInquiryList($domain, $search, $page, $page_size);
//处理格式 免得前端又改
$data = [
"list" => [],
"total" => 0,
"page" => $page,
"total_page" => 1,
"size" => $page_size
];
if (!empty($list['status']) && $list['status'] == 200) {
foreach ($list['data']['data'] as $item) {
$data['list'][] = $item;
}
$data['total'] = $list['data']['total'];
$data['total_page'] = $list['data']['last_page'];
}
return $data;
}
/**
* @remark :方案信息
* @name :plan_information
* @author :lyh
* @method :post
* @time :2024/3/7 17:00
*/
public function plan_information($projectInfo){
return [
'company' => $projectInfo['company'],
'domain' => $domain_info['domain'] ?? '',
'domain_info' => $domain_info['domain_info'] ?? '',
'cert_info' => $domain_info['cert_info'] ?? '',
'plan' => Project::planMap()[$projectInfo['deploy_build']['plan']],
'keyword_num' => $projectInfo['deploy_build']['keyword_num'],
'compliance_day' => $projectInfo['finish_remain_day'] ?? 0,
'start_time' => $projectInfo['deploy_optimize']['start_date'] ?? '',
'remain_day' => $projectInfo['deploy_build']['service_duration'] - ($projectInfo['finish_remain_day'] ?? 0),
];
}
/**
* @remark :排名数据
* @name :ce
* @author :lyh
* @method :post
* @time :2024/3/7 16:58
*/
public function first_total(){
$rank = RankData::where('project_id', $this->param['project_id'])->first();
return [
'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,
];
}
/**
* @remark :关键词排名分析图
* @name :ceshi
* @author :lyh
* @method :post
* @time :2024/3/7 17:39
*/
public function rank_chat(){
//关键词排名分析图
$rank_week = RankWeek::where('project_id', $this->param['project_id'])->first();
return [
'data' => $rank_week['data'] ?? [],
'labels' => $rank_week['date'] ?? [],
];
}
/**
* @remark :30天统计
* @name :count_30_total
* @author :lyh
* @method :post
* @time :2024/3/7 16:56
*/
public function count_30_total(){
$count_param = [
'date' => ['between',[now()->subDays(30)->startOfDay()->toDateString(),now()->startOfDay()->toDateString()]],
'project_id' => $this->user['project_id']
];
return (new Count())->list($count_param,'date',['id','pv_num','ip_num','date']);
}
/**
* @remark :pv_ip
* @name :visit_data
* @author :lyh
* @method :post
* @time :2024/3/7 16:53
*/
public function pv_ip($domain){
$pv = (new VisitItem())->count();
$ip = (new Visit())->count();
$inquiry_list = (new FormGlobalsoApi())->getInquiryList($domain,'',1,100000000);
if(!empty($inquiry_list)){
$total = $inquiry_list['data']['total'] ?? 0;
}
return [
'total_pv'=>$pv,
'total_ip'=>$ip,
'conversion_rate' => (isset($total) && !empty($total) && ($ip != 0)) ? round(($total / $ip) * 10,2) : 0,
];
}
/**
* @name :(访问国家统计)access_country_count
* @author :lyh
* @method :post
* @time :2023/5/24 15:56
*/
public function access_country_count(){
$customerVisitModel = new Visit();
$data = $customerVisitModel->select('country',DB::raw('COUNT(*) as ip'),DB::raw('SUM(depth) as pv'))
->groupBy('country')
->orderBy('ip','desc')->limit(11)->get()->toArray();
$result =array();
if(!empty($data)){
foreach ($data as $k => $v){
if(($this->project['is_record_china_visit'] != 1) && ($v['country'] == '中国')){
continue;
}else{
$v['pv'] = (int)$v['pv'];
$result[] = $v;
}
}
}
return $result;
}
public function keywords_rank_list($project_id,$projectInfo,$export = false)
{
$page = 1;
$lang = $this->request['lang'] ?: '';
$api_no = $projectInfo['deploy_optimize']['api_no'] ?? '';
$domain = (!empty($projectInfo['deploy_optimize']['domain']) ? ((new DomainInfo())->getDomain($projectInfo['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'];
}
}
}
$domain_arr = explode(':', $domain_text);
$v = [
'keyword' => $key,
'domain_type' => $domain_arr[0],
'domain' => $domain_arr[1],
'domain_text' => $domain_text,
'g' => $last['g'], //1核心关键词
'position' => $data,
];
//图片排名
if(isset($last['p_img'])){
$v['img_position'] = $last['p_img'];
}
//视频排名
if(isset($last['p_vid'])){
$v['video_position'] = $last['p_vid'];
}
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 $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;
}
}
... ...
... ... @@ -6,6 +6,7 @@ use App\Enums\Common\Code;
use App\Helper\Arr;
use App\Helper\Common;
use App\Http\Controllers\Bside\BaseController;
use App\Http\Logic\Aside\Project\ProjectLogic;
use App\Http\Logic\Bside\User\UserLogic;
use App\Jobs\PurchaserJob;
use App\Models\Com\Purchaser;
... ... @@ -328,5 +329,4 @@ class ComController extends BaseController
$this->response('success',Code::SUCCESS,$data);
}
}
... ...
... ... @@ -58,7 +58,7 @@ class InquiryLogic extends BaseLogic
$data['total'] = $list['data']['total'];
$data['total_page'] = $list['data']['last_page'];
}
return $this->success($data);
return $data;
}
public function getOtherList($export = false){
... ...