作者 赵彬吉

rank_data

... ... @@ -2,9 +2,8 @@
namespace App\Console\Commands\RankData;
use App\Helper\Arr;
use App\Helper\QuanqiusouApi;
use App\Models\Project\DeployBuild;
use App\Http\Logic\Bside\RankData\RankDataLogic;
use App\Models\Project\DeployOptimize;
use App\Models\Project\Project;
use App\Models\RankData\RankData as GoogleRankModel;
... ... @@ -39,6 +38,9 @@ class RankData extends BaseCommands
*/
public function do()
{
//所有项目 今日是否达标 重置
Project::where('is_remain_today', 1)->update(['is_remain_today' => 0]);
$error = 0;
$api = new QuanqiusouApi();
//有排名api编号的项目
... ... @@ -50,122 +52,14 @@ class RankData extends BaseCommands
return false;
}
foreach ($list as $item){
$model = GoogleRankModel::where('project_id', $item['project_id'])->where('lang', '')->first();
if (!$model || $model->updated_date != date('Y-m-d')) {
$res = $api->getGoogleRank($item['api_no']);
if(!$res){
$error++;
continue;
}
//收录数
$indexed_pages_num = $site_res[$item['api_no']] ?? 0;
$this->save_rank($item['project_id'], $res, $indexed_pages_num);
}
//有小语种的
$lang_list = $api->getLangList();
if(!empty($lang_list[$item['api_no']])){
$model = GoogleRankModel::where('project_id', $item['project_id'])->where('lang', '<>', '')->first();
if (!$model || $model->updated_date != date('Y-m-d')) {
$res = $api->getGoogleRank($item['api_no'], 1);
if(!$res){
$error++;
continue;
}
$data = [];
//不同的小语种取出来
foreach ($res as $keyword => $v){
$data[Arr::last($v)['lang']][$keyword] = $v;
}
foreach ($data as $lang => $rank){
$this->save_rank($item['project_id'], $rank, 0, $lang);
}
}
try {
(new RankDataLogic())->syncRankData($item['api_no']);
}catch (\Exception $e){
LogUtils::info('rank_data error:' . $e->getMessage());
$error++;
continue;
}
}
return !$error;
}
/**
* @param $project_id
* @param int $indexed_pages_num
* @param $data
* @param string $lang
* @author zbj
* @date 2023/5/8
*/
public function save_rank($project_id, $data, int $indexed_pages_num = 0, string $lang = ''){
$without_project_ids = []; //不用处理排名的项目
$first_num = $first_page_num = $first_three_pages_num = $first_five_pages_num = $first_ten_pages_num = 0;
if(!$lang){
foreach ($data as &$ranks){
ksort($ranks);
foreach ($ranks as &$rank){
//处理排名
if(!in_array($project_id, $without_project_ids)){
if($rank['position'] >= 10){
$rank['position'] -= 5;
}
//todo 需要特殊处理排名的项目
}
}
$last = Arr::last($ranks);
//第一名
if($last['position'] == 1){
$first_num ++;
}
//排名第一页
if($last['position'] > 0 && $last['position'] <= 10){
$first_page_num ++;
}
//排名前三页
if($last['position'] > 0 && $last['position'] <= 30){
$first_three_pages_num ++;
}
//排名前五页
if($last['position'] > 0 && $last['position'] <= 50){
$first_five_pages_num ++;
}
//排名前十页
if($last['position'] > 0 && $last['position'] <= 100){
$first_ten_pages_num ++;
}
}
}
$where = [
'project_id' => $project_id,
'lang' => $lang
];
$model = GoogleRankModel::where($where)->first();
if(!$model){
$model = new GoogleRankModel();
}
//关键词达标天数
$model->is_compliance = 0;
if($model->updated_date != date('Y-m-d')){
//保证关键词数
$keyword_num = DeployBuild::where('project_id', $project_id)->value('keyword_num');
$type = Project::where('id', $project_id)->value('type');
if($keyword_num && $type == 2 && $first_page_num >= $keyword_num){
$model->compliance_day = $model->compliance_day + 1;
$model->is_compliance = 1;
}
}
$model->project_id = $project_id;
$model->first_num = $first_num;
$model->first_page_num = $first_page_num;
$model->first_three_pages_num = $first_three_pages_num;
$model->first_five_pages_num = $first_five_pages_num;
$model->first_ten_pages_num = $first_ten_pages_num;
$model->indexed_pages_num = $indexed_pages_num;
$model->lang = $lang;
$model->data = $data;
$model->updated_date = date('Y-m-d');
@file_put_contents(storage_path('logs/lyh_error.log'), var_export($model, true) . PHP_EOL, FILE_APPEND);
$model->save();
}
}
... ...
<?php
namespace App\Console\Commands\RankData;
use App\Helper\QuanqiusouApi;
use App\Http\Logic\Bside\RankData\RankDataLogic;
use App\Models\Com\NoticeLog;
use App\Models\Project\DeployOptimize;
use App\Models\Project\Project;
use App\Models\RankData\RankData as GoogleRankModel;
use App\Utils\LogUtils;
use Illuminate\Console\Command;
/**
* Class GoogleRank
* @package App\Console\Commands
* @author zbj
* @date 2023/5/6
*/
class RankDataTask extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'rank_data_task';
/**
* The console command description.
* The console command description.
*
* @var string
*/
protected $description = '谷歌排名数据';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* @author zbj
* @date 2023/5/6
*/
public function handle()
{
$list = NoticeLog::where('type', NoticeLog::TYPE_RANK_DATA)->where('status', NoticeLog::STATUS_PENDING)->get();
foreach ($list as $item){
try {
(new RankDataLogic())->syncRankData($item['data']['api_no']);
$item->status = NoticeLog::STATUS_SUCCESS;
$item->save();
}catch (\Exception $e){
errorLog('排名数据更新失败', $item, $e);
$this->retry($item);
}
}
}
/**
* @param NoticeLog $log
*/
public function retry($log){
if($log->retry >= 3){
$log->status = NoticeLog::STATUS_FAIL;
}else{
$log->retry = $log->retry + 1;
}
$log->save();
}
}
... ...
... ... @@ -17,6 +17,7 @@ class Kernel extends ConsoleKernel
{
// $schedule->command('inspire')->hourly();
$schedule->command('remain_day')->dailyAt('03:00')->withoutOverlapping(1); // 项目剩余服务时长
$schedule->command('rank_data_task')->everyMinute()->withoutOverlapping(1); // 排名数据更新任务
$schedule->command('rank_data')->dailyAt('01:00')->withoutOverlapping(1); // 排名数据,每天凌晨执行一次
$schedule->command('rank_data_speed')->weeklyOn(1, '01:00')->withoutOverlapping(1); // 排名数据-测速数据,每周一凌晨执行一次
$schedule->command('rank_data_external_links')->weeklyOn(1, '01:00')->withoutOverlapping(1); // 排名数据-外链,每周一凌晨执行一次
... ...
... ... @@ -17,13 +17,10 @@ class NoticeController extends BaseController
{
/**
* 项目通知
* @return \Illuminate\Http\JsonResponse
* @throws \Psr\Container\ContainerExceptionInterface
* @throws \Psr\Container\NotFoundExceptionInterface
* @author zbj
* @date 2023/6/26
*/
public function project(ProjectLogic $logic)
public function project()
{
//首次 续费
LogUtils::info('notice project', $this->param);
... ... @@ -31,4 +28,18 @@ class NoticeController extends BaseController
$this->response('success');
}
/**
*
* 更新排名数据通知
* @author zbj
* @date 2023/9/20
*/
public function rank_data()
{
LogUtils::info('notice rank_data', $this->param);
NoticeLog::createLog(NoticeLog::TYPE_RANK_DATA, $this->param);
$this->response('success');
}
}
... ...
... ... @@ -2,6 +2,7 @@
namespace App\Http\Logic\Aside\Project;
use App\Models\Com\NoticeLog;
use App\Models\Devops\ServerConfig;
use App\Models\Project\ProjectRenew;
use App\Models\User\ProjectMenu;
... ... @@ -212,6 +213,13 @@ class ProjectLogic extends BaseLogic
if(isset($deploy_optimize['minor_keywords']) && !empty($deploy_optimize['minor_keywords'])){
$deploy_optimize['minor_keywords'] = Arr::a2s($deploy_optimize['minor_keywords']);
}
//是否更新了api_no
$api_no = DeployOptimize::where('id', $deploy_optimize['id'])->value('api_no');
if($api_no != $deploy_optimize['api_no']){
NoticeLog::createLog(NoticeLog::TYPE_RANK_DATA, ['api_no' => $deploy_optimize['api_no']]);
}
$deployOptimizeModel->edit($deploy_optimize,['id'=>$deploy_optimize['id']]);
return $this->success();
}
... ...
... ... @@ -9,6 +9,8 @@ use App\Helper\Translate;
use App\Http\Logic\Aside\Project\DomainInfoLogic;
use App\Http\Logic\Aside\Project\ProjectLogic;
use App\Http\Logic\Bside\BaseLogic;
use App\Models\Project\DeployBuild;
use App\Models\Project\DeployOptimize;
use App\Models\Project\Project;
use App\Models\RankData\ExternalLinks;
use App\Models\RankData\IndexedPages;
... ... @@ -347,4 +349,137 @@ class RankDataLogic extends BaseLogic
}
return $flg_ai;
}
/**
* 同步排名信息
* @throws \Exception
* @author zbj
* @date 2023/9/20
*/
public function syncRankData($api_no){
$project_id = DeployOptimize::where('api_no', $api_no)->value('project_id');
$project = Project::find($project_id);
if(!$project){
throw new \Exception($api_no . '关联的项目不存在');
}
$api = new QuanqiusouApi();
$model = RankData::where('project_id', $project_id)->where('lang', '')->first();
if (!$model || $model->updated_date != date('Y-m-d')) {
$res = $api->getGoogleRank($api_no);
if(!$res){
throw new \Exception('接口数据获取失败');
}
//收录数
$indexed_pages_num = $site_res[$api_no] ?? 0;
$this->save_rank($project_id, $res, $indexed_pages_num);
}
//有小语种的
$lang_list = $api->getLangList();
if(!empty($lang_list[$api_no])){
$model = RankData::where('project_id', $project_id)->where('lang', '<>', '')->first();
if (!$model || $model->updated_date != date('Y-m-d')) {
$res = $api->getGoogleRank($api_no, 1);
if(!$res){
throw new \Exception('接口数据获取失败');
}
$data = [];
//不同的小语种取出来
foreach ($res as $keyword => $v){
$data[Arr::last($v)['lang']][$keyword] = $v;
}
foreach ($data as $lang => $rank){
$this->save_rank($project_id, $rank, 0, $lang);
}
}
}
}
/**
* @param $project_id
* @param int $indexed_pages_num
* @param $data
* @param string $lang
* @author zbj
* @date 2023/5/8
*/
public function save_rank($project_id, $data, int $indexed_pages_num = 0, string $lang = ''){
$without_project_ids = []; //不用处理排名的项目
$first_num = $first_page_num = $first_three_pages_num = $first_five_pages_num = $first_ten_pages_num = 0;
if(!$lang){
foreach ($data as &$ranks){
ksort($ranks);
foreach ($ranks as &$rank){
//处理排名
if(!in_array($project_id, $without_project_ids)){
if($rank['position'] >= 10){
$rank['position'] -= 5;
}
//todo 需要特殊处理排名的项目
}
}
$last = Arr::last($ranks);
//第一名
if($last['position'] == 1){
$first_num ++;
}
//排名第一页
if($last['position'] > 0 && $last['position'] <= 10){
$first_page_num ++;
}
//排名前三页
if($last['position'] > 0 && $last['position'] <= 30){
$first_three_pages_num ++;
}
//排名前五页
if($last['position'] > 0 && $last['position'] <= 50){
$first_five_pages_num ++;
}
//排名前十页
if($last['position'] > 0 && $last['position'] <= 100){
$first_ten_pages_num ++;
}
}
}
$where = [
'project_id' => $project_id,
'lang' => $lang
];
$model = RankData::where($where)->first();
if(!$model){
$model = new RankData();
}
//关键词达标天数
$model->is_compliance = 0;
if($model->updated_date != date('Y-m-d')){
//保证关键词数
$keyword_num = DeployBuild::where('project_id', $project_id)->value('keyword_num');
$type = Project::where('id', $project_id)->value('type');
if($keyword_num && $type == 2 && $first_page_num >= $keyword_num){
$model->compliance_day = $model->compliance_day + 1;
$model->is_compliance = 1;
//项目表更新
Project::where('id', $project_id)->update(['is_remain_today' => 1, 'finish_remain_day' => $model->compliance_day]);
}
}
$model->project_id = $project_id;
$model->first_num = $first_num;
$model->first_page_num = $first_page_num;
$model->first_three_pages_num = $first_three_pages_num;
$model->first_five_pages_num = $first_five_pages_num;
$model->first_ten_pages_num = $first_ten_pages_num;
$model->indexed_pages_num = $indexed_pages_num;
$model->lang = $lang;
$model->data = $data;
$model->updated_date = date('Y-m-d');
@file_put_contents(storage_path('logs/lyh_error.log'), var_export($model, true) . PHP_EOL, FILE_APPEND);
$model->save();
}
}
... ...
... ... @@ -10,6 +10,7 @@ class NoticeLog extends Model
protected $table = 'gl_notice_log';
const TYPE_PROJECT = 'project';
const TYPE_RANK_DATA = 'rank_data';
const STATUS_PENDING = 0;
const STATUS_SUCCESS = 1;
... ...
... ... @@ -322,6 +322,7 @@ Route::group([], function () {
Route::any('/download_images', [\App\Http\Controllers\File\ImageController::class, 'downLoad'])->name('admin.images_downLoad');//导出图片
Route::any('/domain/exportData', [Aside\Domain\DomainInfoController::class, 'exportData'])->name('admin.domain_exportData');//导出数据
Route::any('/notice/project', [Aside\Notice\NoticeController::class, 'project'])->name('admin.notice.project');
Route::any('/notice/rank_data', [Aside\Notice\NoticeController::class, 'rank_data'])->name('admin.notice.rank_data');
Route::any('/sendLoginSms', [Aside\LoginController::class, 'sendLoginSms'])->name('admin.sendLoginSms');//发送验证码
Route::any('/getProjectInService', [Aside\Project\ProjectController::class, 'getProjectInService'])->name('admin.getProjectInService');//获取项目服务状态
Route::any('/getProjectByChannel', [Aside\Project\ProjectController::class, 'getProjectByChannel'])->name('admin.getProjectByChannel');//获取渠道商的项目
... ...