Merge remote-tracking branch 'origin/master' into akun
正在显示
19 个修改的文件
包含
483 行增加
和
105 行删除
| @@ -10,6 +10,7 @@ | @@ -10,6 +10,7 @@ | ||
| 10 | namespace App\Console\Commands\Ai; | 10 | namespace App\Console\Commands\Ai; |
| 11 | 11 | ||
| 12 | use App\Models\Ai\AiVideo; | 12 | use App\Models\Ai\AiVideo; |
| 13 | +use App\Models\AyrShare\AyrShare; | ||
| 13 | use App\Models\Domain\DomainInfo; | 14 | use App\Models\Domain\DomainInfo; |
| 14 | use App\Models\Product\Keyword; | 15 | use App\Models\Product\Keyword; |
| 15 | use App\Models\Product\Product; | 16 | use App\Models\Product\Product; |
| @@ -241,7 +242,15 @@ class AiVideoAutoPublish extends Command | @@ -241,7 +242,15 @@ class AiVideoAutoPublish extends Command | ||
| 241 | $storage = $aiVideoTaskModel->videoSetting()[$video_setting ?? 1]; | 242 | $storage = $aiVideoTaskModel->videoSetting()[$video_setting ?? 1]; |
| 242 | $frequency = $aiVideoTaskModel->videoFrequency()[$frequency_setting ?? 1]; | 243 | $frequency = $aiVideoTaskModel->videoFrequency()[$frequency_setting ?? 1]; |
| 243 | $frequencyArr = explode('-',$frequency); | 244 | $frequencyArr = explode('-',$frequency); |
| 244 | - $result = $aiVideoService->createTask($info['title'],$info['remark'],array_slice($info['images'], 0, 8),[],$storage); | 245 | + if($storage == 'YOUTUBE'){ |
| 246 | + //查看是否有ayr账号 | ||
| 247 | + $ayrModel = new AyrShare(); | ||
| 248 | + $ayrInfo = $ayrModel->read(['project_id'=>$this->param['project_id'],'bind_platforms'=>['like','%"youtube"%'],'profile_key'=>['!=',null]]); | ||
| 249 | + if($ayrInfo !== false){ | ||
| 250 | + $ayrshare_profile_key = $ayrInfo['profile_key']; | ||
| 251 | + } | ||
| 252 | + } | ||
| 253 | + $result = $aiVideoService->createTask($info['title'],$info['remark'],array_slice($info['images'], 0, 8),[],$storage,$ayrshare_profile_key ?? ''); | ||
| 245 | if($result['status'] == 200){ | 254 | if($result['status'] == 200){ |
| 246 | $next_auto_date = date('Y-m-d', strtotime('+' . mt_rand($frequencyArr[0] ?? 5,$frequencyArr[1] ?? 7) . 'days')); //每5-7天自动发布 | 255 | $next_auto_date = date('Y-m-d', strtotime('+' . mt_rand($frequencyArr[0] ?? 5,$frequencyArr[1] ?? 7) . 'days')); //每5-7天自动发布 |
| 247 | $aiVideoTaskModel->addReturnId(['next_auto_date'=>$next_auto_date,'task_id'=>$result['data']['task_id'],'project_id'=>$info['project_id'],'storage'=>$storage]); | 256 | $aiVideoTaskModel->addReturnId(['next_auto_date'=>$next_auto_date,'task_id'=>$result['data']['task_id'],'project_id'=>$info['project_id'],'storage'=>$storage]); |
app/Console/Commands/Geo/GeoCount.php
0 → 100644
| 1 | +<?php | ||
| 2 | +/** | ||
| 3 | + * @remark : | ||
| 4 | + * @name :GeoCount.php | ||
| 5 | + * @author :lyh | ||
| 6 | + * @method :post | ||
| 7 | + * @time :2025/10/13 16:05 | ||
| 8 | + */ | ||
| 9 | + | ||
| 10 | +namespace App\Console\Commands\Geo; | ||
| 11 | + | ||
| 12 | +use App\Models\Geo\GeoQuestionLog; | ||
| 13 | +use App\Models\Geo\GeoQuestionResult; | ||
| 14 | +use Illuminate\Console\Command; | ||
| 15 | +use Illuminate\Support\Carbon; | ||
| 16 | +use App\Models\Geo\GeoCount as GeoCountModel; | ||
| 17 | + | ||
| 18 | +class GeoCount extends Command | ||
| 19 | +{ | ||
| 20 | + /** | ||
| 21 | + * The name and signature of the console command. | ||
| 22 | + * | ||
| 23 | + * @var string | ||
| 24 | + */ | ||
| 25 | + protected $signature = 'geo_count'; | ||
| 26 | + | ||
| 27 | + public $porject_id;//记录当时执行的project_id | ||
| 28 | + | ||
| 29 | + /** | ||
| 30 | + * The console command description. | ||
| 31 | + * | ||
| 32 | + * @var string | ||
| 33 | + */ | ||
| 34 | + protected $description = 'geo统计数据'; | ||
| 35 | + | ||
| 36 | + | ||
| 37 | + | ||
| 38 | + public function handle(){ | ||
| 39 | + $this->output('start'); | ||
| 40 | + $this->_action(); | ||
| 41 | + $this->output('end'); | ||
| 42 | + return true; | ||
| 43 | + } | ||
| 44 | + | ||
| 45 | + /** | ||
| 46 | + * @remark :方法 | ||
| 47 | + * @name :_action | ||
| 48 | + * @author :lyh | ||
| 49 | + * @method :post | ||
| 50 | + * @time :2025/10/13 16:20 | ||
| 51 | + */ | ||
| 52 | + public function _action() | ||
| 53 | + { | ||
| 54 | + $geoCountModel = new GeoCountModel(); | ||
| 55 | + //获取前一天的项目id | ||
| 56 | + $date = Carbon::yesterday()->format('Y-m-d'); | ||
| 57 | + $start = $date.' 00:00:00'; | ||
| 58 | + $end = $date.' 23:59:59'; | ||
| 59 | + $geoLogModel = new GeoQuestionLog(); | ||
| 60 | + $project_id = $geoLogModel->formatQuery(['created_at' => ['between',[$start,$end]]])->distinct()->pluck('project_id'); | ||
| 61 | + if(empty($project_id)){ | ||
| 62 | + return true; | ||
| 63 | + } | ||
| 64 | + $geoQuestionResModel = new GeoQuestionResult(); | ||
| 65 | + $platforms = ['gemini','openai','deepseek','poe','perplexity','google_ai_overview','openai-not-network','claude']; | ||
| 66 | + foreach ($project_id as $item){ | ||
| 67 | + $this->output('执行的项目ID----'.$item); | ||
| 68 | + //收录总数 | ||
| 69 | + $total = $geoQuestionResModel->counts(['project_id' => $item,'hit'=>['!=',0],'created_at' => ['between',[$start,$end]]]); | ||
| 70 | + $data = [ | ||
| 71 | + 'project_id' => $item, | ||
| 72 | + 'date' => $date, | ||
| 73 | + 'created_at' => Carbon::now()->format('Y-m-d H:i:s'), | ||
| 74 | + 'updated_at' => Carbon::now()->format('Y-m-d H:i:s'), | ||
| 75 | + 'total'=>$total,//收录总数 | ||
| 76 | + ]; | ||
| 77 | + foreach ($platforms as $platform){ | ||
| 78 | + if($platform == 'openai-not-network'){ | ||
| 79 | + $data['openai_not_network'] = $geoQuestionResModel->counts(['project_id' => $item,'hit'=>['!=',0],'platform'=>$platform,'created_at' => ['between',[$start,$end]]]); | ||
| 80 | + }else{ | ||
| 81 | + $data[$platform] = $geoQuestionResModel->counts(['project_id' => $item,'hit'=>['!=',0],'platform'=>$platform,'created_at' => ['between',[$start,$end]]]); | ||
| 82 | + } | ||
| 83 | + } | ||
| 84 | + //新增一条数据 | ||
| 85 | + $geoCountModel->addReturnId($data); | ||
| 86 | + } | ||
| 87 | + return true; | ||
| 88 | + } | ||
| 89 | + | ||
| 90 | + /** | ||
| 91 | + * 输出日志 | ||
| 92 | + * @param $message | ||
| 93 | + * @return bool | ||
| 94 | + */ | ||
| 95 | + public function output($message) | ||
| 96 | + { | ||
| 97 | + echo date('Y-m-d H:i:s') . ' ' . $message . PHP_EOL; | ||
| 98 | + return true; | ||
| 99 | + } | ||
| 100 | +} |
app/Console/Commands/Geo/GeoCountAll.php
0 → 100644
| 1 | +<?php | ||
| 2 | +/** | ||
| 3 | + * @remark : | ||
| 4 | + * @name :GeoCount.php | ||
| 5 | + * @author :lyh | ||
| 6 | + * @method :post | ||
| 7 | + * @time :2025/10/13 16:05 | ||
| 8 | + */ | ||
| 9 | + | ||
| 10 | +namespace App\Console\Commands\Geo; | ||
| 11 | + | ||
| 12 | +use App\Models\Geo\GeoQuestionLog; | ||
| 13 | +use App\Models\Geo\GeoQuestionResult; | ||
| 14 | +use Illuminate\Console\Command; | ||
| 15 | +use Illuminate\Support\Carbon; | ||
| 16 | +use App\Models\Geo\GeoCount as GeoCountModel; | ||
| 17 | + | ||
| 18 | +class GeoCountAll extends Command | ||
| 19 | +{ | ||
| 20 | + /** | ||
| 21 | + * The name and signature of the console command. | ||
| 22 | + * | ||
| 23 | + * @var string | ||
| 24 | + */ | ||
| 25 | + protected $signature = 'geo_count_all'; | ||
| 26 | + | ||
| 27 | + public $porject_id;//记录当时执行的project_id | ||
| 28 | + | ||
| 29 | + /** | ||
| 30 | + * The console command description. | ||
| 31 | + * | ||
| 32 | + * @var string | ||
| 33 | + */ | ||
| 34 | + protected $description = 'geo统计数据'; | ||
| 35 | + | ||
| 36 | + | ||
| 37 | + | ||
| 38 | + public function handle(){ | ||
| 39 | + $this->output('start'); | ||
| 40 | + $this->_action(); | ||
| 41 | + $this->output('end'); | ||
| 42 | + return true; | ||
| 43 | + } | ||
| 44 | + | ||
| 45 | + /** | ||
| 46 | + * @remark :方法 | ||
| 47 | + * @name :_action | ||
| 48 | + * @author :lyh | ||
| 49 | + * @method :post | ||
| 50 | + * @time :2025/10/13 16:20 | ||
| 51 | + */ | ||
| 52 | + public function _action() | ||
| 53 | + { | ||
| 54 | + $geoCountModel = new GeoCountModel(); | ||
| 55 | + //获取前一天的项目id | ||
| 56 | + $dates = []; | ||
| 57 | + for ($i = 0; $i < 100; $i++) { | ||
| 58 | + $dates[] = date('Y-m-d', strtotime("-{$i} days")); | ||
| 59 | + } | ||
| 60 | + foreach ($dates as $date) { | ||
| 61 | + $start = $date.' 00:00:00'; | ||
| 62 | + $end = $date.' 23:59:59'; | ||
| 63 | + $geoLogModel = new GeoQuestionLog(); | ||
| 64 | + $project_id = $geoLogModel->formatQuery(['created_at' => ['between',[$start,$end]]])->distinct()->pluck('project_id'); | ||
| 65 | + if(empty($project_id)){ | ||
| 66 | + return true; | ||
| 67 | + } | ||
| 68 | + $geoQuestionResModel = new GeoQuestionLog(); | ||
| 69 | + $platforms = ['gemini','openai','deepseek','poe','perplexity','google_ai_overview','openai-not-network','claude']; | ||
| 70 | + foreach ($project_id as $item){ | ||
| 71 | + $this->output('执行的项目ID----'.$item); | ||
| 72 | + //收录总数 | ||
| 73 | + $total = $geoQuestionResModel->counts(['project_id' => $item,'hit'=>['!=',0],'created_at' => ['between',[$start,$end]]]); | ||
| 74 | + $data = [ | ||
| 75 | + 'project_id' => $item, | ||
| 76 | + 'date' => $date, | ||
| 77 | + 'created_at' => Carbon::now()->format('Y-m-d H:i:s'), | ||
| 78 | + 'updated_at' => Carbon::now()->format('Y-m-d H:i:s'), | ||
| 79 | + 'total'=>$total,//收录总数 | ||
| 80 | + ]; | ||
| 81 | + foreach ($platforms as $platform){ | ||
| 82 | + if($platform == 'openai-not-network'){ | ||
| 83 | + $data['openai_not_network'] = $geoQuestionResModel->counts(['project_id' => $item,'hit'=>['!=',0],'platform'=>$platform,'created_at' => ['between',[$start,$end]]]); | ||
| 84 | + }else{ | ||
| 85 | + $data[$platform] = $geoQuestionResModel->counts(['project_id' => $item,'hit'=>['!=',0],'platform'=>$platform,'created_at' => ['between',[$start,$end]]]); | ||
| 86 | + } | ||
| 87 | + } | ||
| 88 | + $info = $geoCountModel->read(['project_id' => $item,'date'=>$date]); | ||
| 89 | + if($info === false){ | ||
| 90 | + //新增一条数据 | ||
| 91 | + $geoCountModel->addReturnId($data); | ||
| 92 | + }else{ | ||
| 93 | + $geoCountModel->edit($data,['id'=>$info['id']]); | ||
| 94 | + } | ||
| 95 | + } | ||
| 96 | + } | ||
| 97 | + | ||
| 98 | + return true; | ||
| 99 | + } | ||
| 100 | + | ||
| 101 | + /** | ||
| 102 | + * 输出日志 | ||
| 103 | + * @param $message | ||
| 104 | + * @return bool | ||
| 105 | + */ | ||
| 106 | + public function output($message) | ||
| 107 | + { | ||
| 108 | + echo date('Y-m-d H:i:s') . ' ' . $message . PHP_EOL; | ||
| 109 | + return true; | ||
| 110 | + } | ||
| 111 | +} |
| @@ -30,6 +30,8 @@ class GeoQuestionRes extends Command | @@ -30,6 +30,8 @@ class GeoQuestionRes extends Command | ||
| 30 | */ | 30 | */ |
| 31 | protected $signature = 'geo_question_result'; | 31 | protected $signature = 'geo_question_result'; |
| 32 | 32 | ||
| 33 | + public $porject_id;//记录当时执行的project_id | ||
| 34 | + | ||
| 33 | /** | 35 | /** |
| 34 | * The console command description. | 36 | * The console command description. |
| 35 | * | 37 | * |
| @@ -337,15 +339,18 @@ class GeoQuestionRes extends Command | @@ -337,15 +339,18 @@ class GeoQuestionRes extends Command | ||
| 337 | $key = 'geo_task_list'; | 339 | $key = 'geo_task_list'; |
| 338 | $task_id = Redis::rpop($key); | 340 | $task_id = Redis::rpop($key); |
| 339 | if(empty($task_id)){ | 341 | if(empty($task_id)){ |
| 342 | + //todo::这里需要执行统计一次,统计当前项目当前日期的统计 | ||
| 343 | + | ||
| 340 | # TODO 按照项目进行获取, 一个项目当天需要将所有跑完 | 344 | # TODO 按照项目进行获取, 一个项目当天需要将所有跑完 |
| 341 | $project_id = GeoQuestion::where('status', GeoQuestion::STATUS_OPEN)->where('next_time', '<=', date('Y-m-d'))->value('project_id'); | 345 | $project_id = GeoQuestion::where('status', GeoQuestion::STATUS_OPEN)->where('next_time', '<=', date('Y-m-d'))->value('project_id'); |
| 342 | - if (empty($project_id)) | ||
| 343 | - return $task_id; | ||
| 344 | - $ids = GeoQuestion::where(['project_id' => $project_id, 'status' => GeoQuestion::STATUS_OPEN])->where('current_time', '<>', date('Y-m-d'))->pluck('id'); | ||
| 345 | - foreach ($ids as $id) { | ||
| 346 | - Redis::lpush($key, $id); | 346 | + if (!empty($project_id)){ |
| 347 | + $this->project_id = $project_id; | ||
| 348 | + $ids = GeoQuestion::where(['project_id' => $project_id, 'status' => GeoQuestion::STATUS_OPEN])->where('current_time', '<>', date('Y-m-d'))->pluck('id'); | ||
| 349 | + foreach ($ids as $id) { | ||
| 350 | + Redis::lpush($key, $id); | ||
| 351 | + } | ||
| 352 | + $task_id = Redis::rpop($key); | ||
| 347 | } | 353 | } |
| 348 | - $task_id = Redis::rpop($key); | ||
| 349 | } | 354 | } |
| 350 | return $task_id; | 355 | return $task_id; |
| 351 | } | 356 | } |
| @@ -979,14 +979,13 @@ class RelayInquiry extends Command | @@ -979,14 +979,13 @@ class RelayInquiry extends Command | ||
| 979 | */ | 979 | */ |
| 980 | public function delay_seconds($inquiry_date, $domain, $task) | 980 | public function delay_seconds($inquiry_date, $domain, $task) |
| 981 | { | 981 | { |
| 982 | - $inquiry_date = Carbon::make($inquiry_date); | ||
| 983 | //当天的 | 982 | //当天的 |
| 984 | - if($inquiry_date->isToday()){ | 983 | + if(date('Y-m-d', strtotime($inquiry_date)) == date('Y-m-d')){ |
| 985 | //广告投放日(周一、二、三、四) 第一封询盘100%及时推送 | 984 | //广告投放日(周一、二、三、四) 第一封询盘100%及时推送 |
| 986 | $is_timely = true; //是否及时推送 | 985 | $is_timely = true; //是否及时推送 |
| 987 | - if(in_array($inquiry_date->weekday(), [1,2,3,4])) { | 986 | + if(in_array(date('w'), [1,2,3,4])) { |
| 988 | //是否今天的第一封询盘 | 987 | //是否今天的第一封询盘 |
| 989 | - $detail = ReInquiryDetail::where('re_website', $domain)->where('start_at', '>=', $inquiry_date->startOfDay()->toDatetimeString())->first(); | 988 | + $detail = ReInquiryDetail::where('re_website', $domain)->where('start_at', '>=', date('Y-m-d 00:00:00'))->first(); |
| 990 | if($detail){ | 989 | if($detail){ |
| 991 | $is_timely = false; //只有周一到周四的非第一封询盘 根据概率及时推送 | 990 | $is_timely = false; //只有周一到周四的非第一封询盘 根据概率及时推送 |
| 992 | } | 991 | } |
| @@ -997,15 +996,17 @@ class RelayInquiry extends Command | @@ -997,15 +996,17 @@ class RelayInquiry extends Command | ||
| 997 | $res = $this->get_rand([$task->second_push_rate, 100 - $task->second_push_rate]); | 996 | $res = $this->get_rand([$task->second_push_rate, 100 - $task->second_push_rate]); |
| 998 | if($res == 1){ | 997 | if($res == 1){ |
| 999 | //随机分配到未投放广告日期 | 998 | //随机分配到未投放广告日期 |
| 1000 | - $now = Carbon::now(); | 999 | + $now = time(); |
| 1001 | // 随机开始时间(本周四或现在) | 1000 | // 随机开始时间(本周四或现在) |
| 1002 | - $startTime = max($now->timestamp, $now->startOfWeek(4)->timestamp); | 1001 | + $startTime = max($now, strtotime('this thursday')); |
| 1003 | 1002 | ||
| 1004 | - $random = mt_rand($startTime, $now->endOfWeek()->timestamp); | 1003 | + $random = mt_rand($startTime, strtotime('next monday')); |
| 1005 | 1004 | ||
| 1006 | - $delay = $random - time(); | 1005 | + $delay = $random - $now; |
| 1007 | $this->output('非广告投放日第一封询盘 概率' . (100 - $task->second_push_rate) . '%延迟推送' . $delay); | 1006 | $this->output('非广告投放日第一封询盘 概率' . (100 - $task->second_push_rate) . '%延迟推送' . $delay); |
| 1008 | return $delay; | 1007 | return $delay; |
| 1008 | + }else{ | ||
| 1009 | + $this->output('非广告投放日第一封询盘 概率' . $task->second_push_rate . '%即时推送'); | ||
| 1009 | } | 1010 | } |
| 1010 | } | 1011 | } |
| 1011 | } | 1012 | } |
| @@ -64,50 +64,74 @@ class CopyOldProject extends Command | @@ -64,50 +64,74 @@ class CopyOldProject extends Command | ||
| 64 | { | 64 | { |
| 65 | // 设置源数据库 | 65 | // 设置源数据库 |
| 66 | config(['database.connections.custom_tmp_mysql_copy.database' => 'gl_data_' . $project_id]); | 66 | config(['database.connections.custom_tmp_mysql_copy.database' => 'gl_data_' . $project_id]); |
| 67 | + DB::purge('custom_tmp_mysql_copy'); | ||
| 68 | + DB::reconnect('custom_tmp_mysql_copy'); | ||
| 67 | $database_name = DB::connection('custom_tmp_mysql_copy')->getDatabaseName(); | 69 | $database_name = DB::connection('custom_tmp_mysql_copy')->getDatabaseName(); |
| 68 | // 获取源数据库的所有表 | 70 | // 获取源数据库的所有表 |
| 69 | $tables = Schema::connection('custom_tmp_mysql_copy')->getAllTables(); | 71 | $tables = Schema::connection('custom_tmp_mysql_copy')->getAllTables(); |
| 70 | $tables = array_column($tables, 'Tables_in_' . $database_name); | 72 | $tables = array_column($tables, 'Tables_in_' . $database_name); |
| 71 | foreach ($tables as $table) { | 73 | foreach ($tables as $table) { |
| 72 | - // 目标数据库是否存在该表 | ||
| 73 | - $has_table = Schema::connection('custom_mysql')->hasTable($table); | ||
| 74 | - if ($has_table) { | ||
| 75 | - // 1. 删除目标数据库中的表 | ||
| 76 | - DB::connection('custom_mysql')->statement("DROP TABLE IF EXISTS {$table}"); | ||
| 77 | - } | ||
| 78 | - // 2. 重新创建表 | ||
| 79 | - $sql = DB::connection('custom_tmp_mysql_copy')->select("SHOW CREATE TABLE {$table}"); | ||
| 80 | - DB::connection('custom_mysql')->statement(get_object_vars($sql[0])['Create Table']); | ||
| 81 | - // 3. 跳过指定的表 | ||
| 82 | - if (in_array($table, [ | ||
| 83 | - 'gl_customer_visit', | ||
| 84 | - 'gl_customer_visit_item', | ||
| 85 | - 'gl_inquiry_other', | ||
| 86 | - 'gl_inquiry_form_data', | ||
| 87 | - 'gl_inquiry_form', | ||
| 88 | - 'gl_ai_blog', | ||
| 89 | - 'gl_ai_blog_author', | ||
| 90 | - 'gl_ai_blog_list', | ||
| 91 | - 'gl_ai_blog_log', | ||
| 92 | - ])) { | ||
| 93 | - continue; | ||
| 94 | - } | ||
| 95 | - // 4. 重新插入数据 | ||
| 96 | - DB::connection('custom_mysql')->table($table)->insertUsing( | ||
| 97 | - [], // 插入所有列 | ||
| 98 | - function ($query) use ($table, $project_id) { | ||
| 99 | - $name = 'gl_data_' . $project_id . '.' . $table; | ||
| 100 | - $query->select('*')->from("{$name}"); | 74 | + try { |
| 75 | + // 1. 检查源表是否存在(防止 gl_data_{$project_id} 下缺表) | ||
| 76 | + $exists = Schema::connection('custom_tmp_mysql_copy')->hasTable($table); | ||
| 77 | + if (!$exists) { | ||
| 78 | + @file_put_contents( | ||
| 79 | + storage_path('logs/copy_mysql_error.log'), | ||
| 80 | + "源库中不存在表:{$table}" . PHP_EOL, | ||
| 81 | + FILE_APPEND | ||
| 82 | + ); | ||
| 83 | + continue; | ||
| 84 | + } | ||
| 85 | + // 2. 删除目标数据库中的表 | ||
| 86 | + $result = DB::connection('custom_mysql')->statement("DROP TABLE IF EXISTS `{$table}`"); | ||
| 87 | + @file_put_contents(storage_path('logs/copy_mysql_error.log'), "删除旧表:{$table} => {$result}" . PHP_EOL, FILE_APPEND); | ||
| 88 | + // 3. 复制建表 SQL | ||
| 89 | + $sql = DB::connection('custom_tmp_mysql_copy')->select("SHOW CREATE TABLE `{$table}`"); | ||
| 90 | + $createSql = get_object_vars($sql[0])['Create Table']; | ||
| 91 | + $result1 = DB::connection('custom_mysql')->statement($createSql); | ||
| 92 | + @file_put_contents(storage_path('logs/copy_mysql_error.log'), "创建表:{$table} => {$result1}" . PHP_EOL, FILE_APPEND); | ||
| 93 | + // 4. 跳过指定表 | ||
| 94 | + if (in_array($table, [ | ||
| 95 | + 'gl_customer_visit', 'gl_customer_visit_item', | ||
| 96 | + 'gl_inquiry_other', 'gl_inquiry_form_data', 'gl_inquiry_form', | ||
| 97 | + 'gl_ai_blog', 'gl_ai_blog_author', 'gl_ai_blog_list', 'gl_ai_blog_log' | ||
| 98 | + ])) { | ||
| 99 | + continue; | ||
| 100 | + } | ||
| 101 | + // 5. 插入数据前,再次确认源表存在(双保险) | ||
| 102 | + if (!Schema::connection('custom_tmp_mysql_copy')->hasTable($table)) { | ||
| 103 | + @file_put_contents(storage_path('logs/copy_mysql_error.log'), "插入数据前发现表不存在:{$table}" . PHP_EOL, FILE_APPEND); | ||
| 104 | + continue; | ||
| 101 | } | 105 | } |
| 102 | - ); | ||
| 103 | - // 5. 更新 project_id(如果存在) | ||
| 104 | - if (Schema::connection('custom_mysql')->hasColumn($table, 'project_id')) { | ||
| 105 | - DB::connection('custom_mysql')->table($table)->update(['project_id' => $news_project_id]); | 106 | + // 6. 原生 SQL 插入数据(完全复制) |
| 107 | + $insert_sql = "INSERT INTO `{$table}` SELECT * FROM `gl_data_{$project_id}`.`{$table}`"; | ||
| 108 | + try { | ||
| 109 | + $result2 = DB::connection('custom_mysql')->statement($insert_sql); | ||
| 110 | + @file_put_contents(storage_path('logs/copy_mysql_error.log'), "插入数据成功:{$table} => {$result2}" . PHP_EOL, FILE_APPEND); | ||
| 111 | + } catch (\Exception $e) { | ||
| 112 | + @file_put_contents(storage_path('logs/copy_mysql_error.log'), | ||
| 113 | + "插入数据失败:{$table} => " . $e->getMessage() . PHP_EOL, | ||
| 114 | + FILE_APPEND | ||
| 115 | + ); | ||
| 116 | + continue; // 跳过这个表,不中断整个流程 | ||
| 117 | + } | ||
| 118 | + // 7. 更新 project_id(如果存在) | ||
| 119 | + if (Schema::connection('custom_mysql')->hasColumn($table, 'project_id')) { | ||
| 120 | + DB::connection('custom_mysql')->table($table)->update(['project_id' => $news_project_id]); | ||
| 121 | + } | ||
| 122 | + } catch (\Exception $e) { | ||
| 123 | + @file_put_contents( | ||
| 124 | + storage_path('logs/copy_mysql_error.log'), | ||
| 125 | + "处理表 {$table} 出错:" . $e->getMessage() . PHP_EOL, | ||
| 126 | + FILE_APPEND | ||
| 127 | + ); | ||
| 128 | + continue; | ||
| 106 | } | 129 | } |
| 107 | } | 130 | } |
| 108 | return true; | 131 | return true; |
| 109 | } | 132 | } |
| 110 | 133 | ||
| 134 | + | ||
| 111 | /** | 135 | /** |
| 112 | * @param $message | 136 | * @param $message |
| 113 | * @return bool | 137 | * @return bool |
| @@ -234,33 +234,75 @@ class CopyProject extends Command | @@ -234,33 +234,75 @@ class CopyProject extends Command | ||
| 234 | { | 234 | { |
| 235 | // 设置源数据库 | 235 | // 设置源数据库 |
| 236 | config(['database.connections.custom_tmp_mysql_copy.database' => 'gl_data_' . $project_id]); | 236 | config(['database.connections.custom_tmp_mysql_copy.database' => 'gl_data_' . $project_id]); |
| 237 | + DB::purge('custom_tmp_mysql_copy'); | ||
| 238 | + DB::reconnect('custom_tmp_mysql_copy'); | ||
| 237 | $database_name = DB::connection('custom_tmp_mysql_copy')->getDatabaseName(); | 239 | $database_name = DB::connection('custom_tmp_mysql_copy')->getDatabaseName(); |
| 238 | // 获取源数据库的所有表 | 240 | // 获取源数据库的所有表 |
| 239 | $tables = Schema::connection('custom_tmp_mysql_copy')->getAllTables(); | 241 | $tables = Schema::connection('custom_tmp_mysql_copy')->getAllTables(); |
| 240 | $tables = array_column($tables, 'Tables_in_' . $database_name); | 242 | $tables = array_column($tables, 'Tables_in_' . $database_name); |
| 241 | foreach ($tables as $table) { | 243 | foreach ($tables as $table) { |
| 242 | - // 1. 删除目标数据库中的表 | ||
| 243 | - $result = DB::connection('custom_mysql')->statement("DROP TABLE IF EXISTS {$table}"); | ||
| 244 | - @file_put_contents(storage_path('logs/copy_mysql_error.log'), var_export('先删除对应数据库的对应表返回结果:'.$result, true) . PHP_EOL, FILE_APPEND); | ||
| 245 | - // 2. 复制建表 SQL | ||
| 246 | - $sql = DB::connection('custom_tmp_mysql_copy')->select("SHOW CREATE TABLE `{$table}`"); | ||
| 247 | - $result1 = DB::connection('custom_mysql')->statement(get_object_vars($sql[0])['Create Table']); | ||
| 248 | - @file_put_contents(storage_path('logs/copy_mysql_error.log'), var_export('创建对应表数据:'.$result1, true) . PHP_EOL, FILE_APPEND); | ||
| 249 | - // 3. 跳过指定的表 | ||
| 250 | - if (in_array($table, ['gl_customer_visit', 'gl_customer_visit_item', 'gl_inquiry_other', 'gl_inquiry_form_data', 'gl_inquiry_form','gl_ai_blog', 'gl_ai_blog_author', 'gl_ai_blog_list','gl_ai_blog_log'])) { | 244 | + try { |
| 245 | + // 1. 检查源表是否存在(防止 gl_data_{$project_id} 下缺表) | ||
| 246 | + $exists = Schema::connection('custom_tmp_mysql_copy')->hasTable($table); | ||
| 247 | + if (!$exists) { | ||
| 248 | + @file_put_contents( | ||
| 249 | + storage_path('logs/copy_mysql_error.log'), | ||
| 250 | + "源库中不存在表:{$table}" . PHP_EOL, | ||
| 251 | + FILE_APPEND | ||
| 252 | + ); | ||
| 253 | + continue; | ||
| 254 | + } | ||
| 255 | + // 2. 删除目标数据库中的表 | ||
| 256 | + $result = DB::connection('custom_mysql')->statement("DROP TABLE IF EXISTS `{$table}`"); | ||
| 257 | + @file_put_contents(storage_path('logs/copy_mysql_error.log'), "删除旧表:{$table} => {$result}" . PHP_EOL, FILE_APPEND); | ||
| 258 | + // 3. 复制建表 SQL | ||
| 259 | + $sql = DB::connection('custom_tmp_mysql_copy')->select("SHOW CREATE TABLE `{$table}`"); | ||
| 260 | + $createSql = get_object_vars($sql[0])['Create Table']; | ||
| 261 | + $result1 = DB::connection('custom_mysql')->statement($createSql); | ||
| 262 | + @file_put_contents(storage_path('logs/copy_mysql_error.log'), "创建表:{$table} => {$result1}" . PHP_EOL, FILE_APPEND); | ||
| 263 | + | ||
| 264 | + // 4. 跳过指定表 | ||
| 265 | + if (in_array($table, [ | ||
| 266 | + 'gl_customer_visit', 'gl_customer_visit_item', | ||
| 267 | + 'gl_inquiry_other', 'gl_inquiry_form_data', 'gl_inquiry_form', | ||
| 268 | + 'gl_ai_blog', 'gl_ai_blog_author', 'gl_ai_blog_list', 'gl_ai_blog_log' | ||
| 269 | + ])) { | ||
| 270 | + continue; | ||
| 271 | + } | ||
| 272 | + // 5. 插入数据前,再次确认源表存在(双保险) | ||
| 273 | + if (!Schema::connection('custom_tmp_mysql_copy')->hasTable($table)) { | ||
| 274 | + @file_put_contents(storage_path('logs/copy_mysql_error.log'), "插入数据前发现表不存在:{$table}" . PHP_EOL, FILE_APPEND); | ||
| 275 | + continue; | ||
| 276 | + } | ||
| 277 | + // 6. 原生 SQL 插入数据(完全复制) | ||
| 278 | + $insert_sql = "INSERT INTO `{$table}` SELECT * FROM `gl_data_{$project_id}`.`{$table}`"; | ||
| 279 | + try { | ||
| 280 | + $result2 = DB::connection('custom_mysql')->statement($insert_sql); | ||
| 281 | + @file_put_contents(storage_path('logs/copy_mysql_error.log'), "插入数据成功:{$table} => {$result2}" . PHP_EOL, FILE_APPEND); | ||
| 282 | + } catch (\Exception $e) { | ||
| 283 | + @file_put_contents(storage_path('logs/copy_mysql_error.log'), | ||
| 284 | + "插入数据失败:{$table} => " . $e->getMessage() . PHP_EOL, | ||
| 285 | + FILE_APPEND | ||
| 286 | + ); | ||
| 287 | + continue; // 跳过这个表,不中断整个流程 | ||
| 288 | + } | ||
| 289 | + // 7. 更新 project_id(如果存在) | ||
| 290 | + if (Schema::connection('custom_mysql')->hasColumn($table, 'project_id')) { | ||
| 291 | + DB::connection('custom_mysql')->table($table)->update(['project_id' => $news_project_id]); | ||
| 292 | + } | ||
| 293 | + } catch (\Exception $e) { | ||
| 294 | + @file_put_contents( | ||
| 295 | + storage_path('logs/copy_mysql_error.log'), | ||
| 296 | + "处理表 {$table} 出错:" . $e->getMessage() . PHP_EOL, | ||
| 297 | + FILE_APPEND | ||
| 298 | + ); | ||
| 251 | continue; | 299 | continue; |
| 252 | } | 300 | } |
| 253 | - // 4. 原生 SQL 插入数据(完全复制) | ||
| 254 | - $insert_sql = "INSERT INTO `{$table}` SELECT * FROM `gl_data_{$project_id}`.`{$table}`"; | ||
| 255 | - $result2 = DB::connection('custom_mysql')->statement($insert_sql); | ||
| 256 | - @file_put_contents(storage_path('logs/copy_mysql_error.log'), var_export('对应表插入数据:'.$result2, true) . PHP_EOL, FILE_APPEND); | ||
| 257 | - // 5. 更新 project_id(如果存在) | ||
| 258 | - if (Schema::connection('custom_mysql')->hasColumn($table, 'project_id')) { | ||
| 259 | - DB::connection('custom_mysql')->table($table)->update(['project_id' => $news_project_id]); | ||
| 260 | - } | ||
| 261 | } | 301 | } |
| 302 | + | ||
| 262 | return true; | 303 | return true; |
| 263 | } | 304 | } |
| 305 | + | ||
| 264 | /** | 306 | /** |
| 265 | * @param $message | 307 | * @param $message |
| 266 | * @return bool | 308 | * @return bool |
| @@ -166,11 +166,8 @@ class SyncProject extends Command | @@ -166,11 +166,8 @@ class SyncProject extends Command | ||
| 166 | ]; | 166 | ]; |
| 167 | $data['deploy_build']['plan'] = $this->versionData($param['plan_marketing'] ?? ''); | 167 | $data['deploy_build']['plan'] = $this->versionData($param['plan_marketing'] ?? ''); |
| 168 | $data['deploy_build']['seo_plan'] = $this->versionSeoData($param['geo_plan'] ?? ''); | 168 | $data['deploy_build']['seo_plan'] = $this->versionSeoData($param['geo_plan'] ?? ''); |
| 169 | - if(!empty($data['deploy_build']['plan'])){ | ||
| 170 | - $data['deploy_build']['service_duration'] = $param['years'] ?? 0; | ||
| 171 | - }else{ | ||
| 172 | - $data['deploy_build']['seo_service_duration'] = $param['years'] ?? 0; | ||
| 173 | - } | 169 | + $data['deploy_build']['service_duration'] = $param['years'] ?? 0; |
| 170 | + $data['deploy_build']['seo_service_duration'] = $param['geo_plan_day'] ?? 0; | ||
| 174 | $renewModel = new ProjectRenew(); | 171 | $renewModel = new ProjectRenew(); |
| 175 | $rs = $renewModel->add($data); | 172 | $rs = $renewModel->add($data); |
| 176 | if($rs === false){ | 173 | if($rs === false){ |
| @@ -256,11 +253,8 @@ class SyncProject extends Command | @@ -256,11 +253,8 @@ class SyncProject extends Command | ||
| 256 | ]; | 253 | ]; |
| 257 | $data['deploy_build']['plan'] = $this->versionData($param['plan_marketing'] ?? ''); | 254 | $data['deploy_build']['plan'] = $this->versionData($param['plan_marketing'] ?? ''); |
| 258 | $data['deploy_build']['seo_plan'] = $this->versionSeoData($param['geo_plan'] ?? ''); | 255 | $data['deploy_build']['seo_plan'] = $this->versionSeoData($param['geo_plan'] ?? ''); |
| 259 | - if(!empty($data['deploy_build']['plan'])){ | ||
| 260 | - $data['deploy_build']['service_duration'] = $param['years'] ?? 0; | ||
| 261 | - }else{ | ||
| 262 | - $data['deploy_build']['seo_service_duration'] = $param['years'] ?? 0; | ||
| 263 | - } | 256 | + $data['deploy_build']['service_duration'] = $param['years'] ?? 0; |
| 257 | + $data['deploy_build']['seo_service_duration'] = $param['geo_plan_day'] ?? 0; | ||
| 264 | DB::beginTransaction(); | 258 | DB::beginTransaction(); |
| 265 | try { | 259 | try { |
| 266 | if(isset($data['deploy_build']['plan']) && in_array($data['deploy_build']['plan'],[4,5,15,16,17])){ | 260 | if(isset($data['deploy_build']['plan']) && in_array($data['deploy_build']['plan'],[4,5,15,16,17])){ |
| @@ -374,7 +374,7 @@ class UpdateSeoTdk extends Command | @@ -374,7 +374,7 @@ class UpdateSeoTdk extends Command | ||
| 374 | $seo_title = $v[$this->topic_fields[$table]];; | 374 | $seo_title = $v[$this->topic_fields[$table]];; |
| 375 | //只有推广项目 才加 前后缀 | 375 | //只有推广项目 才加 前后缀 |
| 376 | if($project->type == Project::TYPE_TWO) { | 376 | if($project->type == Project::TYPE_TWO) { |
| 377 | - $prefix = $this->getPrefixKeyword($project_id, 'prefix', 1, $seo_title); | 377 | + $prefix = $this->getPrefixKeyword($project_id, 'prefix', 2, $seo_title); |
| 378 | $suffix = $this->getPrefixKeyword($project_id, 'suffix', 2, trim($prefix . ' ' . $seo_title)); | 378 | $suffix = $this->getPrefixKeyword($project_id, 'suffix', 2, trim($prefix . ' ' . $seo_title)); |
| 379 | if(Str::startsWith($suffix, ', ')){ | 379 | if(Str::startsWith($suffix, ', ')){ |
| 380 | $seo_title = $prefix . ' ' . $seo_title . $suffix; | 380 | $seo_title = $prefix . ' ' . $seo_title . $suffix; |
| @@ -574,7 +574,7 @@ class UpdateSeoTdk extends Command | @@ -574,7 +574,7 @@ class UpdateSeoTdk extends Command | ||
| 574 | return $str; | 574 | return $str; |
| 575 | } | 575 | } |
| 576 | 576 | ||
| 577 | - //前后缀(包括自定义前后缀)如果已经存在,就不在拼接当前类型 后缀只包含了一个,要再拼一个(需去重) | 577 | + //前后缀(包括自定义前后缀)如果已经存在,就不在拼接当前类型 前、后缀只包含了一个,要再拼一个(需去重) |
| 578 | $all_prefixes = $this->getAllPrefix(1, $project_id); | 578 | $all_prefixes = $this->getAllPrefix(1, $project_id); |
| 579 | $all_prefixes = array_map('strtolower', $all_prefixes); | 579 | $all_prefixes = array_map('strtolower', $all_prefixes); |
| 580 | 580 | ||
| @@ -595,8 +595,14 @@ class UpdateSeoTdk extends Command | @@ -595,8 +595,14 @@ class UpdateSeoTdk extends Command | ||
| 595 | $i= 0; | 595 | $i= 0; |
| 596 | foreach ($topic_words as $topic_word){ | 596 | foreach ($topic_words as $topic_word){ |
| 597 | //关键词本身包含了前缀就不拼前缀,只拼后缀 | 597 | //关键词本身包含了前缀就不拼前缀,只拼后缀 |
| 598 | + //关键词本身包含了前缀,可拼后缀,也可以再拼一个不重复的前缀,包含两个前缀就不拼前缀了 2025-10-14 zhl | ||
| 598 | if(in_array($topic_word, $all_prefixes) && $type == 'prefix'){ | 599 | if(in_array($topic_word, $all_prefixes) && $type == 'prefix'){ |
| 599 | - return $str; | 600 | + if($i == $num - 1){ |
| 601 | + return $str; | ||
| 602 | + } | ||
| 603 | + $ban[] = $topic_word; | ||
| 604 | + $i++; | ||
| 605 | + $num--; | ||
| 600 | } | 606 | } |
| 601 | //关键词本身包含了后缀,可拼前缀,也可以再拼一个不重复的后缀,包含两个后缀就不拼后缀了 | 607 | //关键词本身包含了后缀,可拼前缀,也可以再拼一个不重复的后缀,包含两个后缀就不拼后缀了 |
| 602 | if(in_array($topic_word, $all_suffixes) && $type == 'suffix'){ | 608 | if(in_array($topic_word, $all_suffixes) && $type == 'suffix'){ |
| @@ -683,6 +689,11 @@ class UpdateSeoTdk extends Command | @@ -683,6 +689,11 @@ class UpdateSeoTdk extends Command | ||
| 683 | if ($type == 'suffix' && count($keywords) == 1 && in_array(Arr::last($topic_words), $all_suffixes)) { | 689 | if ($type == 'suffix' && count($keywords) == 1 && in_array(Arr::last($topic_words), $all_suffixes)) { |
| 684 | return ', ' . $keywords[0]; | 690 | return ', ' . $keywords[0]; |
| 685 | } | 691 | } |
| 692 | + | ||
| 693 | + //前缀空格隔开 | ||
| 694 | + if($type == 'prefix'){ | ||
| 695 | + return implode(' ', $keywords); | ||
| 696 | + } | ||
| 686 | return implode(', ', $keywords); | 697 | return implode(', ', $keywords); |
| 687 | } | 698 | } |
| 688 | 699 |
| @@ -190,9 +190,9 @@ class WorkOrderDing extends Command | @@ -190,9 +190,9 @@ class WorkOrderDing extends Command | ||
| 190 | } | 190 | } |
| 191 | }catch (\Exception $exception){ | 191 | }catch (\Exception $exception){ |
| 192 | echo now() . " | ERROR | gl_ticket_dings ID {$tickDing->id} {$exception->getMessage()} {$exception->getTraceAsString()} \n"; | 192 | echo now() . " | ERROR | gl_ticket_dings ID {$tickDing->id} {$exception->getMessage()} {$exception->getTraceAsString()} \n"; |
| 193 | - $ding->status = 2; // 标记为失败 | ||
| 194 | - $ding->errorMsg = $exception->getMessage(); | ||
| 195 | - $ding->save(); | 193 | + $tickDing->status = 2; // 标记为失败 |
| 194 | + $tickDing->errorMsg = $exception->getMessage(); | ||
| 195 | + $tickDing->save(); | ||
| 196 | } | 196 | } |
| 197 | } | 197 | } |
| 198 | } | 198 | } |
| @@ -93,8 +93,9 @@ class AsideTicketLogController extends BaseController | @@ -93,8 +93,9 @@ class AsideTicketLogController extends BaseController | ||
| 93 | $ticket->end_at = now(); | 93 | $ticket->end_at = now(); |
| 94 | $ticket->end_time = diffInHours($ticket->created_at,$ticket->end_at); | 94 | $ticket->end_time = diffInHours($ticket->created_at,$ticket->end_at); |
| 95 | $project = $ticket->project; | 95 | $project = $ticket->project; |
| 96 | - if ($project->wechat_switch && !$ticket->close_wechat) | 96 | + if ($project->wechat_switch && !$ticket->close_wechat){ |
| 97 | $project->pushWechatGroupMsg("工单(ID:{$ticket->id})已全部完成,请访问查看详情!"); | 97 | $project->pushWechatGroupMsg("工单(ID:{$ticket->id})已全部完成,请访问查看详情!"); |
| 98 | + } | ||
| 98 | $ticket->pushDing('finish'); | 99 | $ticket->pushDing('finish'); |
| 99 | }else{ | 100 | }else{ |
| 100 | $ticket->status = Tickets::STATUS_YANSHOU; | 101 | $ticket->status = Tickets::STATUS_YANSHOU; |
| @@ -77,7 +77,7 @@ class GeoQuestionResController extends BaseController | @@ -77,7 +77,7 @@ class GeoQuestionResController extends BaseController | ||
| 77 | } | 77 | } |
| 78 | 78 | ||
| 79 | /** | 79 | /** |
| 80 | - * @remark : | 80 | + * @remark :获取详情 |
| 81 | * @name :getInfo | 81 | * @name :getInfo |
| 82 | * @author :lyh | 82 | * @author :lyh |
| 83 | * @method :post | 83 | * @method :post |
| @@ -129,4 +129,16 @@ class GeoQuestionResController extends BaseController | @@ -129,4 +129,16 @@ class GeoQuestionResController extends BaseController | ||
| 129 | $data = $this->logic->getLabelData(); | 129 | $data = $this->logic->getLabelData(); |
| 130 | $this->response('success',Code::SUCCESS,$data); | 130 | $this->response('success',Code::SUCCESS,$data); |
| 131 | } | 131 | } |
| 132 | + | ||
| 133 | + /** | ||
| 134 | + * @remark :根据项目获取 | ||
| 135 | + * @name :getPlatformCount | ||
| 136 | + * @author :lyh | ||
| 137 | + * @method :post | ||
| 138 | + * @time :2025/10/14 10:43 | ||
| 139 | + */ | ||
| 140 | + public function getPlatformCount(){ | ||
| 141 | + $data = $this->logic->getPlatformCount(); | ||
| 142 | + $this->response('success',Code::SUCCESS,$data); | ||
| 143 | + } | ||
| 132 | } | 144 | } |
| @@ -177,7 +177,7 @@ class LoginController extends BaseController | @@ -177,7 +177,7 @@ class LoginController extends BaseController | ||
| 177 | } | 177 | } |
| 178 | $wechat = new Wechat(); | 178 | $wechat = new Wechat(); |
| 179 | $accessToken = $wechat->getAccessToken(); | 179 | $accessToken = $wechat->getAccessToken(); |
| 180 | - $data = $wechat->setQrcode('global-v6_'.$this->param['type'].'_'.$this->param['id'],$accessToken); | 180 | + $data = $wechat->setQrcode('global-v6_'.$this->param['type'].'_'.$this->param['id'].'_'.($this->param['project_id'] ?? 0),$accessToken); |
| 181 | if(!empty($data) && isset($data['ticket'])){ | 181 | if(!empty($data) && isset($data['ticket'])){ |
| 182 | $data['url'] = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=".$data['ticket']; | 182 | $data['url'] = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=".$data['ticket']; |
| 183 | } | 183 | } |
| @@ -313,7 +313,7 @@ class LoginController extends BaseController | @@ -313,7 +313,7 @@ class LoginController extends BaseController | ||
| 313 | if($key[1] == 'login'){ | 313 | if($key[1] == 'login'){ |
| 314 | $data = $userLoginLogic->wechatLogin($wechat); | 314 | $data = $userLoginLogic->wechatLogin($wechat); |
| 315 | }elseif($key[1] == 'bind'){ | 315 | }elseif($key[1] == 'bind'){ |
| 316 | - $data = $userLoginLogic->wechatBind($wechat,$key[2]); | 316 | + $data = $userLoginLogic->wechatBind($wechat,$key[2],$key[3] ?? 0); |
| 317 | }else{ | 317 | }else{ |
| 318 | $data = [ | 318 | $data = [ |
| 319 | 'code'=>0, | 319 | 'code'=>0, |
| @@ -6,6 +6,7 @@ use App\Helper\Translate; | @@ -6,6 +6,7 @@ use App\Helper\Translate; | ||
| 6 | use App\Http\Logic\Bside\BaseLogic; | 6 | use App\Http\Logic\Bside\BaseLogic; |
| 7 | use App\Models\Ai\AiBlogAuthor; | 7 | use App\Models\Ai\AiBlogAuthor; |
| 8 | use App\Models\Ai\AiVideo; | 8 | use App\Models\Ai\AiVideo; |
| 9 | +use App\Models\AyrShare\AyrShare; | ||
| 9 | use App\Models\Project\AiBlogTask; | 10 | use App\Models\Project\AiBlogTask; |
| 10 | use App\Models\Project\AiVideoTask; | 11 | use App\Models\Project\AiVideoTask; |
| 11 | use App\Models\Project\ProjectAiSetting; | 12 | use App\Models\Project\ProjectAiSetting; |
| @@ -66,8 +67,16 @@ class AiVideoLogic extends BaseLogic | @@ -66,8 +67,16 @@ class AiVideoLogic extends BaseLogic | ||
| 66 | $aiVideoTaskModel = new AiVideoTask(); | 67 | $aiVideoTaskModel = new AiVideoTask(); |
| 67 | $aiVideoService = new AiVideoService($this->user['project_id']); | 68 | $aiVideoService = new AiVideoService($this->user['project_id']); |
| 68 | $storage = $aiVideoTaskModel->videoSetting()[$this->user['video_setting'] ?? 1]; | 69 | $storage = $aiVideoTaskModel->videoSetting()[$this->user['video_setting'] ?? 1]; |
| 70 | + if($storage == 'YOUTUBE'){ | ||
| 71 | + //查看是否有ayr账号 | ||
| 72 | + $ayrModel = new AyrShare(); | ||
| 73 | + $ayrInfo = $ayrModel->read(['project_id'=>$this->param['project_id'],'bind_platforms'=>['like','%"youtube"%'],'profile_key'=>['!=',null]]); | ||
| 74 | + if($ayrInfo !== false){ | ||
| 75 | + $ayrshare_profile_key = $ayrInfo['profile_key']; | ||
| 76 | + } | ||
| 77 | + } | ||
| 69 | //todo::获取ayr的key | 78 | //todo::获取ayr的key |
| 70 | - $result = $aiVideoService->createTask($this->param['title'],$this->param['description'],$this->param['images'],$this->param['anchor'] ?? [],$storage); | 79 | + $result = $aiVideoService->createTask($this->param['title'],$this->param['description'],$this->param['images'],$this->param['anchor'] ?? [],$storage,$ayrshare_profile_key ?? ''); |
| 71 | if($result['status'] == 200){ | 80 | if($result['status'] == 200){ |
| 72 | $aiVideoTaskModel->addReturnId(['task_id'=>$result['data']['task_id'],'project_id'=>$this->user['project_id'],'storage'=>$storage]); | 81 | $aiVideoTaskModel->addReturnId(['task_id'=>$result['data']['task_id'],'project_id'=>$this->user['project_id'],'storage'=>$storage]); |
| 73 | $id = $this->model->addReturnId(['title'=>$this->param['title'],'task_id'=>$result['data']['task_id'],'description'=>$this->param['description'],'project_id'=>$this->user['project_id'],'images'=>json_encode($this->param['images'],true),'anchor'=>json_encode($this->param['anchor'] ?? [],true)]); | 82 | $id = $this->model->addReturnId(['title'=>$this->param['title'],'task_id'=>$result['data']['task_id'],'description'=>$this->param['description'],'project_id'=>$this->user['project_id'],'images'=>json_encode($this->param['images'],true),'anchor'=>json_encode($this->param['anchor'] ?? [],true)]); |
| @@ -10,6 +10,7 @@ | @@ -10,6 +10,7 @@ | ||
| 10 | namespace App\Http\Logic\Bside\Geo; | 10 | namespace App\Http\Logic\Bside\Geo; |
| 11 | 11 | ||
| 12 | use App\Http\Logic\Bside\BaseLogic; | 12 | use App\Http\Logic\Bside\BaseLogic; |
| 13 | +use App\Models\Geo\GeoCount; | ||
| 13 | use App\Models\Geo\GeoPlatform; | 14 | use App\Models\Geo\GeoPlatform; |
| 14 | use App\Models\Geo\GeoQuestion; | 15 | use App\Models\Geo\GeoQuestion; |
| 15 | use App\Models\Geo\GeoQuestionLog; | 16 | use App\Models\Geo\GeoQuestionLog; |
| @@ -98,7 +99,7 @@ class GeoQuestionResLogic extends BaseLogic | @@ -98,7 +99,7 @@ class GeoQuestionResLogic extends BaseLogic | ||
| 98 | $list = $questionModel->list(['project_id'=>$this->user['project_id']],['question','keywords','url']); | 99 | $list = $questionModel->list(['project_id'=>$this->user['project_id']],['question','keywords','url']); |
| 99 | $core_question_count = $questionTotalCount = $urlTotalCount = $keywordsTotalCount = 0; | 100 | $core_question_count = $questionTotalCount = $urlTotalCount = $keywordsTotalCount = 0; |
| 100 | $keywordArr = []; | 101 | $keywordArr = []; |
| 101 | - $questionLogModel = new GeoQuestionLog(); | 102 | + $questionLogModel = new GeoQuestionResult(); |
| 102 | if($this->user['project_id'] == 4533){ | 103 | if($this->user['project_id'] == 4533){ |
| 103 | $keywordUrlCount = $questionLogModel->counts(['project_id'=>$this->user['project_id'],'is_match'=>1,'hit'=>['!=',0]]); | 104 | $keywordUrlCount = $questionLogModel->counts(['project_id'=>$this->user['project_id'],'is_match'=>1,'hit'=>['!=',0]]); |
| 104 | foreach ($list as $item){ | 105 | foreach ($list as $item){ |
| @@ -119,9 +120,8 @@ class GeoQuestionResLogic extends BaseLogic | @@ -119,9 +120,8 @@ class GeoQuestionResLogic extends BaseLogic | ||
| 119 | 'core_question_count'=>$core_question_count,//核心问题总数 | 120 | 'core_question_count'=>$core_question_count,//核心问题总数 |
| 120 | 'keywords_url_count'=>$keywordUrlCount, | 121 | 'keywords_url_count'=>$keywordUrlCount, |
| 121 | 'keywords_arr' => $keywordArr, | 122 | 'keywords_arr' => $keywordArr, |
| 122 | - 'core_keyword_url_count'=>$coreKeywordUrlCount ?? 0 | 123 | + 'core_keyword_url_count'=>$coreKeywordUrlCount ?? 0, |
| 123 | ]; | 124 | ]; |
| 124 | - return $this->success($data); | ||
| 125 | }else{ | 125 | }else{ |
| 126 | $keywordUrlCount = $questionLogModel->counts(['project_id'=>$this->user['project_id'],'hit'=>['!=',0]]); | 126 | $keywordUrlCount = $questionLogModel->counts(['project_id'=>$this->user['project_id'],'hit'=>['!=',0]]); |
| 127 | foreach ($list as $item){ | 127 | foreach ($list as $item){ |
| @@ -141,8 +141,18 @@ class GeoQuestionResLogic extends BaseLogic | @@ -141,8 +141,18 @@ class GeoQuestionResLogic extends BaseLogic | ||
| 141 | 'keywords_url_count'=>$keywordUrlCount, | 141 | 'keywords_url_count'=>$keywordUrlCount, |
| 142 | 'keywords_arr' => $keywordArr, | 142 | 'keywords_arr' => $keywordArr, |
| 143 | ]; | 143 | ]; |
| 144 | - return $this->success($data); | ||
| 145 | } | 144 | } |
| 145 | + //问题达标数据 | ||
| 146 | + $data['question_qualify_count'] = $questionLogModel->where('project_id', $this->user['project_id']) | ||
| 147 | + ->where('hit','!=',0)->whereIn('platform',['openai', 'gemini','google_ai_overview']) | ||
| 148 | + ->select(DB::raw('COUNT(DISTINCT question) as total')) | ||
| 149 | + ->value('total'); | ||
| 150 | + $latestCreatedAt = $questionLogModel | ||
| 151 | + ->where('project_id', $this->user['project_id']) | ||
| 152 | + ->orderBy('id', 'desc') | ||
| 153 | + ->value('created_at'); | ||
| 154 | + $data['date'] = $latestCreatedAt ? date('Y-m-d', strtotime($latestCreatedAt)) : null; | ||
| 155 | + return $this->success($data); | ||
| 146 | } | 156 | } |
| 147 | 157 | ||
| 148 | /** | 158 | /** |
| @@ -156,7 +166,7 @@ class GeoQuestionResLogic extends BaseLogic | @@ -156,7 +166,7 @@ class GeoQuestionResLogic extends BaseLogic | ||
| 156 | $data = []; | 166 | $data = []; |
| 157 | $platformModel = new GeoPlatform(); | 167 | $platformModel = new GeoPlatform(); |
| 158 | $list = $platformModel->list(['status'=>1],'id',['name','en_name']); | 168 | $list = $platformModel->list(['status'=>1],'id',['name','en_name']); |
| 159 | - $questionResModel = new GeoQuestionLog(); | 169 | + $questionResModel = new GeoQuestionResult(); |
| 160 | foreach ($list as $item){ | 170 | foreach ($list as $item){ |
| 161 | if($this->user['project_id'] == 4533){ | 171 | if($this->user['project_id'] == 4533){ |
| 162 | $data[$item['name']] = $questionResModel->counts(['project_id'=>$this->user['project_id'],'is_match'=>1,'hit'=>['!=',0],'platform'=>$item['en_name']]); | 172 | $data[$item['name']] = $questionResModel->counts(['project_id'=>$this->user['project_id'],'is_match'=>1,'hit'=>['!=',0],'platform'=>$item['en_name']]); |
| @@ -196,4 +206,18 @@ class GeoQuestionResLogic extends BaseLogic | @@ -196,4 +206,18 @@ class GeoQuestionResLogic extends BaseLogic | ||
| 196 | } | 206 | } |
| 197 | return $this->success($data); | 207 | return $this->success($data); |
| 198 | } | 208 | } |
| 209 | + | ||
| 210 | + /** | ||
| 211 | + * @remark :获取图标数据 | ||
| 212 | + * @name :getPlatformCount | ||
| 213 | + * @author :lyh | ||
| 214 | + * @method :post | ||
| 215 | + * @time :2025/10/14 10:45 | ||
| 216 | + */ | ||
| 217 | + public function getPlatformCount() | ||
| 218 | + { | ||
| 219 | + $geoCountModel = new GeoCount(); | ||
| 220 | + $lists = $geoCountModel->list(['project_id'=>$this->user['project_id']],'date',['*'],'desc',30); | ||
| 221 | + return $this->success($lists); | ||
| 222 | + } | ||
| 199 | } | 223 | } |
| @@ -394,7 +394,7 @@ class UserLoginLogic | @@ -394,7 +394,7 @@ class UserLoginLogic | ||
| 394 | * @method :post | 394 | * @method :post |
| 395 | * @time :2023/9/1 11:43 | 395 | * @time :2023/9/1 11:43 |
| 396 | */ | 396 | */ |
| 397 | - public function wechatBind($wechat,$id){ | 397 | + public function wechatBind($wechat,$id,$project_id = 0){ |
| 398 | $info = $this->model->read(['wechat'=>$wechat]); | 398 | $info = $this->model->read(['wechat'=>$wechat]); |
| 399 | if($info !== false){ | 399 | if($info !== false){ |
| 400 | $data = [ | 400 | $data = [ |
app/Models/Geo/GeoCount.php
0 → 100644
| @@ -453,33 +453,50 @@ class SyncSubmitTaskService | @@ -453,33 +453,50 @@ class SyncSubmitTaskService | ||
| 453 | 453 | ||
| 454 | //关杰 全局过滤 满足 name、message 8-16 纯字母不含空格 ip 荷兰 mobile 10位纯数字 过滤 | 454 | //关杰 全局过滤 满足 name、message 8-16 纯字母不含空格 ip 荷兰 mobile 10位纯数字 过滤 |
| 455 | if( | 455 | if( |
| 456 | - strlen($data['data']['name']) <= 16 && strlen($data['data']['name']) >= 8 && | ||
| 457 | - strlen($data['data']['message']) <= 16 && strlen($data['data']['message']) >= 8 && | ||
| 458 | - preg_match('/^[a-zA-Z]+$/', $data['data']['name']) && | ||
| 459 | - preg_match('/^[a-zA-Z]+$/', $data['data']['message']) && | ||
| 460 | - preg_match('/^\d+$/', $data['data']['phone']) && | ||
| 461 | - strlen($data['data']['phone']) == 10 && | ||
| 462 | - in_array($data['country'], ['荷兰', '俄罗斯']) | 456 | + strlen($data['data']['name']??'') <= 16 && strlen($data['data']['name']??'') >= 8 && |
| 457 | + strlen($data['data']['message']??'') <= 16 && strlen($data['data']['message']??'') >= 8 && | ||
| 458 | + preg_match('/^[a-zA-Z]+$/', $data['data']['name']??'') && | ||
| 459 | + preg_match('/^[a-zA-Z]+$/', $data['data']['message']??'') && | ||
| 460 | + preg_match('/^\d+$/', $data['data']['phone']??'') && | ||
| 461 | + strlen($data['data']['phone']??'') == 10 && | ||
| 462 | + in_array($data['country']??'', ['荷兰', '俄罗斯']) | ||
| 463 | + ){ | ||
| 464 | + throw new InquiryFilterException( '全局过滤'); | ||
| 465 | + } | ||
| 466 | + if( | ||
| 467 | + strlen($data['data']['name']??'') <= 16 && strlen($data['data']['name']??'') >= 8 && | ||
| 468 | + strlen($data['data']['message']??'') <= 16 && strlen($data['data']['message']??'') >= 8 && | ||
| 469 | + preg_match('/^[a-zA-Z]+$/', $data['data']['name']??'') && | ||
| 470 | + preg_match('/^[a-zA-Z]+$/', $data['data']['message']??'') && | ||
| 471 | + in_array($data['country']??'', ['荷兰', '俄罗斯']) | ||
| 463 | ){ | 472 | ){ |
| 464 | throw new InquiryFilterException( '全局过滤'); | 473 | throw new InquiryFilterException( '全局过滤'); |
| 465 | } | 474 | } |
| 466 | //全局过滤 ip 荷兰 有name、phone、email字段,但都是空 | 475 | //全局过滤 ip 荷兰 有name、phone、email字段,但都是空 |
| 467 | if( | 476 | if( |
| 468 | - in_array($data['country'], ['荷兰', '俄罗斯']) && | ||
| 469 | - isset($data['data']['name']) && | ||
| 470 | - isset($data['data']['phone']) && | ||
| 471 | - isset($data['data']['email']) && | 477 | + in_array($data['country']??'', ['荷兰', '俄罗斯']) && |
| 478 | + array_key_exists('name', $data['data']) && | ||
| 479 | + array_key_exists('phone', $data['data']) && | ||
| 480 | + array_key_exists('email', $data['data']) && | ||
| 472 | empty($data['data']['name']) && | 481 | empty($data['data']['name']) && |
| 473 | empty($data['data']['phone']) && | 482 | empty($data['data']['phone']) && |
| 474 | empty($data['data']['email']) | 483 | empty($data['data']['email']) |
| 475 | ){ | 484 | ){ |
| 476 | - throw new InquiryFilterException( '全局过滤'); | 485 | + throw new InquiryFilterException( '全局过滤2'); |
| 486 | + } | ||
| 487 | + | ||
| 488 | + //1913宁波市鄞州永鑫 ip荷兰 message 8-16 纯字母不含空格 | ||
| 489 | + if($project_id == 1913 && in_array($data['country']??'', ['荷兰', '俄罗斯']) | ||
| 490 | + && strlen($data['data']['message']??'') <= 16 && strlen($data['data']['message']??"") >= 8 | ||
| 491 | + && preg_match('/^[a-zA-Z]+$/', $data['data']['message']??'') | ||
| 492 | + ){ | ||
| 493 | + throw new InquiryFilterException( '被刷数据'); | ||
| 477 | } | 494 | } |
| 478 | 495 | ||
| 479 | //数据都是空的 | 496 | //数据都是空的 |
| 480 | $is_all_empty = true; | 497 | $is_all_empty = true; |
| 481 | foreach ($data['data'] as $item){ | 498 | foreach ($data['data'] as $item){ |
| 482 | - if(Str::startsWith(strtolower($item),'globalso-')){ | 499 | + if(is_string($item) && Str::startsWith(strtolower($item),'globalso-')){ |
| 483 | continue; | 500 | continue; |
| 484 | } | 501 | } |
| 485 | if(!empty($item)){ | 502 | if(!empty($item)){ |
| @@ -766,6 +766,7 @@ Route::middleware(['bloginauth'])->group(function () { | @@ -766,6 +766,7 @@ Route::middleware(['bloginauth'])->group(function () { | ||
| 766 | Route::any('/getCount', [\App\Http\Controllers\Bside\Geo\GeoQuestionResController::class, 'getCount'])->name('geo_result_getCount');//geo设置类型统计数量 | 766 | Route::any('/getCount', [\App\Http\Controllers\Bside\Geo\GeoQuestionResController::class, 'getCount'])->name('geo_result_getCount');//geo设置类型统计数量 |
| 767 | Route::any('/countQuantity', [\App\Http\Controllers\Bside\Geo\GeoQuestionResController::class, 'countQuantity'])->name('geo_result_countQuantity');//geo统计 | 767 | Route::any('/countQuantity', [\App\Http\Controllers\Bside\Geo\GeoQuestionResController::class, 'countQuantity'])->name('geo_result_countQuantity');//geo统计 |
| 768 | Route::any('/getSearchDate', [\App\Http\Controllers\Bside\Geo\GeoQuestionResController::class, 'getSearchDate'])->name('geo_result_getSearchDate');//搜索记录时间 | 768 | Route::any('/getSearchDate', [\App\Http\Controllers\Bside\Geo\GeoQuestionResController::class, 'getSearchDate'])->name('geo_result_getSearchDate');//搜索记录时间 |
| 769 | + Route::any('/getPlatformCount', [\App\Http\Controllers\Bside\Geo\GeoQuestionResController::class, 'getPlatformCount'])->name('geo_result_getPlatformCount');//搜索记录时间 | ||
| 769 | }); | 770 | }); |
| 770 | }); | 771 | }); |
| 771 | //无需登录验证的路由组 | 772 | //无需登录验证的路由组 |
-
请 注册 或 登录 后发表评论