作者 刘锟

Merge remote-tracking branch 'origin/master' into akun

  1 +<?php
  2 +/**
  3 + * @remark :
  4 + * @name :AiBlogTask.php
  5 + * @author :lyh
  6 + * @method :post
  7 + * @time :2025/2/14 11:14
  8 + */
  9 +
  10 +namespace App\Console\Commands\Ai;
  11 +
  12 +use App\Models\Ai\AiBlog;
  13 +use App\Models\Ai\AiBlogAuthor;
  14 +use App\Models\Ai\AiBlogList;
  15 +use App\Models\Domain\DomainInfo;
  16 +use App\Models\Project\Project;
  17 +use App\Models\Project\ProjectAiSetting;
  18 +use App\Models\RouteMap\RouteMap;
  19 +use App\Services\AiBlogService;
  20 +use App\Services\ProjectServer;
  21 +use Illuminate\Console\Command;
  22 +use App\Models\Project\AiBlogTask as AiBlogTaskModel;
  23 +use Illuminate\Support\Facades\Cache;
  24 +use Illuminate\Support\Facades\DB;
  25 +use function Symfony\Component\String\s;
  26 +
  27 +/***
  28 + * @remark :根据项目更新blog列表
  29 + * @name :AiBlogListTask
  30 + * @author :lyh
  31 + * @method :post
  32 + * @time :2025/3/6 9:45
  33 + */
  34 +class AiBlogListAllTask extends Command
  35 +{
  36 + /**
  37 + * The name and signature of the console command.
  38 + *
  39 + * @var string
  40 + */
  41 + protected $signature = 'save_all_ai_blog_list';
  42 +
  43 + /**
  44 + * The console command description.
  45 + *
  46 + * @var string
  47 + */
  48 + protected $description = '生成blog列表';
  49 +
  50 + public function handle(){
  51 + $projectModel = new Project();
  52 + $lists = $projectModel->list(['delete_status' => 0,'project_type'=>0,'extend_type'=>0,'type'=>['in',[2,3,4,6]]], 'id', ['id']);
  53 + foreach ($lists as $item){
  54 + echo '执行的项目的id'.$item['id'].PHP_EOL;
  55 + $project_id = $item['id'];
  56 + ProjectServer::useProject($project_id);
  57 + $projectAiSettingModel = new ProjectAiSetting();
  58 + $aiSettingInfo = $projectAiSettingModel->read(['project_id'=>$project_id]);
  59 + if($aiSettingInfo === false){
  60 + echo '未加载到配置。'.PHP_EOL;
  61 + continue;
  62 + }
  63 + $this->updateBlogList($aiSettingInfo);
  64 + $this->curlDelRoute($project_id);
  65 + DB::disconnect('custom_mysql');
  66 + }
  67 + return true;
  68 + }
  69 +
  70 + /**
  71 + * @remark :更新列表页数据
  72 + * @name :updateBlogList
  73 + * @author :lyh
  74 + * @method :post
  75 + * @time :2025/3/5 11:07
  76 + */
  77 + public function updateBlogList($aiSettingInfo){
  78 + $aiBlogService = new AiBlogService();
  79 + $aiBlogService->mch_id = $aiSettingInfo['mch_id'];
  80 + $aiBlogService->key = $aiSettingInfo['key'];
  81 + $page = 1;
  82 + $saveData = [];
  83 + $result = $aiBlogService->getAiBlogList($page,15);
  84 + if(!isset($result['status']) || $result['status'] != 200){
  85 + return true;
  86 + }
  87 + $total_page = $result['data']['total_page'];
  88 + //组装数据保存
  89 + $saveData[] = [
  90 + 'route'=>$page,
  91 + 'text'=>$result['data']['section'],
  92 + ];
  93 + while ($total_page > $page){
  94 + $page++;
  95 + $result = $aiBlogService->getAiBlogList($page,15);
  96 + if(isset($result['status']) && $result['status'] == 200){
  97 + $saveData[] = [
  98 + 'route'=>$page,
  99 + 'text'=>$result['data']['section'],
  100 + ];
  101 + }
  102 + }
  103 + $aiBlogListModel = new AiBlogList();
  104 + if(!empty($saveData)){
  105 + //写一条路由信息
  106 + $aiBlogListModel->truncate();
  107 + $aiBlogListModel->insertAll($saveData);
  108 + }
  109 + return true;
  110 + }
  111 +
  112 + /**
  113 + * @remark :通知C端生成界面
  114 + * @name :sendNotice
  115 + * @author :lyh
  116 + * @method :post
  117 + * @time :2025/3/6 11:51
  118 + */
  119 + public function curlDelRoute($project_id){
  120 + $domainModel = new DomainInfo();
  121 + //获取项目域名
  122 + $domain = $domainModel->getProjectIdDomain($project_id);
  123 + if(!empty($domain)){
  124 + $c_url = $domain.'api/update_page/';
  125 + $param = [
  126 + 'project_id' => $project_id,
  127 + 'type' => 1,
  128 + 'route' => 3,
  129 + 'url' => ['top-blog'],
  130 + 'language'=> [],
  131 + 'is_sitemap' => 0
  132 + ];
  133 + http_post($c_url, json_encode($param));
  134 + }
  135 + return true;
  136 + }
  137 +}
@@ -72,7 +72,7 @@ class AiBlogListTask extends Command @@ -72,7 +72,7 @@ class AiBlogListTask extends Command
72 $page = 1; 72 $page = 1;
73 $saveData = []; 73 $saveData = [];
74 $result = $aiBlogService->getAiBlogList($page,15); 74 $result = $aiBlogService->getAiBlogList($page,15);
75 - if(!isset($result['status']) && $result['status'] != 200){ 75 + if(!isset($result['status']) || $result['status'] != 200){
76 return true; 76 return true;
77 } 77 }
78 $total_page = $result['data']['total_page']; 78 $total_page = $result['data']['total_page'];
@@ -47,7 +47,7 @@ class GeoQuestionRes extends Command @@ -47,7 +47,7 @@ class GeoQuestionRes extends Command
47 sleep(300); 47 sleep(300);
48 continue; 48 continue;
49 } 49 }
50 - echo date('Y-m-d H:i:s').'执行的任务id:'.$task_id.PHP_EOL; 50 + $this->output('执行的任务ID:' . $task_id);
51 $geoQuestionModel = new GeoQuestion(); 51 $geoQuestionModel = new GeoQuestion();
52 $taskInfo = $geoQuestionModel->read(['id'=>$task_id]); 52 $taskInfo = $geoQuestionModel->read(['id'=>$task_id]);
53 if ($taskInfo === false) { 53 if ($taskInfo === false) {
@@ -85,23 +85,20 @@ class GeoQuestionRes extends Command @@ -85,23 +85,20 @@ class GeoQuestionRes extends Command
85 GET_RESULT: 85 GET_RESULT:
86 $error_num++; 86 $error_num++;
87 try { 87 try {
88 - if ($error_num >= 3) { 88 + if ($error_num > 3) {
  89 + $this->output('任务ID:' . $task_id . ', 项目ID:' . $taskInfo['project_id'] . ', 平台:' . $platform . ', 问题:' . $question . ', 获取失败.');
89 continue; 90 continue;
90 } 91 }
91 - $this->output('执行平台:' . $platform . '执行次数:' . $error_num); 92 + $this->output('平台:' . $platform . ', 执行次数:' . $error_num);
92 switch ($platform){ 93 switch ($platform){
93 case 'google_ai_overview': 94 case 'google_ai_overview':
94 // overview 数据结构不确定, 需要单独处理数据 95 // overview 数据结构不确定, 需要单独处理数据
95 $data = $geo_service->getGooglePlatformResult($question); 96 $data = $geo_service->getGooglePlatformResult($question);
96 $result = $this->dealGoogleData($data); 97 $result = $this->dealGoogleData($data);
97 break; 98 break;
98 - case 'deep_seek':  
99 - $data = $geo_service->getDeepSeekResult($question);  
100 - $result = $this->dealDeepSeek($data);  
101 - break;  
102 case 'openai-not-network': 99 case 'openai-not-network':
103 - $data = $geo_service->getDeepSeekResult($question,'gpt-4o-mini');  
104 - $result = $this->dealDeepSeek($data,'gpt-4o-mini'); 100 + $data = $geo_service->getChatResult($question, 'gpt-4o-mini');
  101 + $result = $this->dealChatData($data, 'gpt-4o-mini');
105 break; 102 break;
106 default: 103 default:
107 $result = $geo_service->getAiPlatformResult($question, $platform); 104 $result = $geo_service->getAiPlatformResult($question, $platform);
@@ -158,7 +155,7 @@ class GeoQuestionRes extends Command @@ -158,7 +155,7 @@ class GeoQuestionRes extends Command
158 } 155 }
159 $save_data['text'] = json_encode(!empty($data) ? $data : $result,true); 156 $save_data['text'] = json_encode(!empty($data) ? $data : $result,true);
160 $geoLogModel->addReturnId($save_data); 157 $geoLogModel->addReturnId($save_data);
161 - echo '执行结束:'.$platform.PHP_EOL; 158 + $this->output('平台:' . $platform . ' 完成');
162 } 159 }
163 } 160 }
164 $next_time = date('Y-m-d', strtotime('+' . ($projectInfo['geo_frequency'] ?? 3) . ' days')); 161 $next_time = date('Y-m-d', strtotime('+' . ($projectInfo['geo_frequency'] ?? 3) . ' days'));
@@ -168,13 +165,12 @@ class GeoQuestionRes extends Command @@ -168,13 +165,12 @@ class GeoQuestionRes extends Command
168 } 165 }
169 166
170 /** 167 /**
171 - * @remark :获取命中的url  
172 - * @name :getUrl  
173 - * @author :lyh  
174 - * @method :post  
175 - * @time :2025/7/3 16:38 168 + * 获取命中的url
  169 + * @param array $urlArr
  170 + * @param array $result_annotations
  171 + * @return array
176 */ 172 */
177 - public function getUrl($urlArr = [],$result_annotations = []){ 173 + public function getUrl($urlArr = [], $result_annotations = []){
178 $url = []; 174 $url = [];
179 $url_num = []; 175 $url_num = [];
180 if(!empty($urlArr)){ 176 if(!empty($urlArr)){
@@ -187,17 +183,16 @@ class GeoQuestionRes extends Command @@ -187,17 +183,16 @@ class GeoQuestionRes extends Command
187 } 183 }
188 } 184 }
189 } 185 }
190 - return ['url'=>$url,'url_num'=>$url_num]; 186 + return ['url' => $url, 'url_num' => $url_num];
191 } 187 }
192 188
193 /** 189 /**
194 - * @remark :获取命中的关键词  
195 - * @name :getKeywords  
196 - * @author :lyh  
197 - * @method :post  
198 - * @time :2025/7/3 16:26 190 + * 获取命中的关键词
  191 + * @param array $keywordArr
  192 + * @param array $result_text
  193 + * @return array
199 */ 194 */
200 - public function getKeywords($keywordArr = [],$result_text = []){ 195 + public function getKeywords($keywordArr = [], $result_text = []){
201 $keywords = []; 196 $keywords = [];
202 $keywords_num = []; 197 $keywords_num = [];
203 if(!empty($keywordArr) && !empty($result_text)){ 198 if(!empty($keywordArr) && !empty($result_text)){
@@ -210,17 +205,16 @@ class GeoQuestionRes extends Command @@ -210,17 +205,16 @@ class GeoQuestionRes extends Command
210 } 205 }
211 } 206 }
212 } 207 }
213 - return ['keywords'=>$keywords,'keywords_num'=>$keywords_num]; 208 + return ['keywords' => $keywords, 'keywords_num' => $keywords_num];
214 } 209 }
215 210
216 /** 211 /**
217 - * @remark :整合deepSeek  
218 - * @name :requestDeepSeek  
219 - * @author :lyh  
220 - * @method :post  
221 - * @time :2025/7/15 10:58 212 + * 处理 会话 返回数据
  213 + * @param $data
  214 + * @param string $model
  215 + * @return array
222 */ 216 */
223 - public function dealDeepSeek($data,$model = 'DeepSeek'){ 217 + public function dealChatData($data, $model){
224 $result = [ 218 $result = [
225 'code' => 200, 219 'code' => 200,
226 'model' => $model, 220 'model' => $model,
@@ -3,6 +3,7 @@ @@ -3,6 +3,7 @@
3 namespace App\Console\Commands\WebTraffic; 3 namespace App\Console\Commands\WebTraffic;
4 4
5 use App\Helper\Arr; 5 use App\Helper\Arr;
  6 +use App\Models\Ai\AiBlog;
6 use App\Models\Product\Category; 7 use App\Models\Product\Category;
7 use App\Models\Product\Product; 8 use App\Models\Product\Product;
8 use App\Models\Project\OnlineCheck; 9 use App\Models\Project\OnlineCheck;
@@ -361,8 +362,32 @@ class WebTraffic extends Command @@ -361,8 +362,32 @@ class WebTraffic extends Command
361 $data['urls_details'] = DB::connection('custom_mysql')->table('gl_product') 362 $data['urls_details'] = DB::connection('custom_mysql')->table('gl_product')
362 ->where('project_id', $project_id)->where('status', Product::STATUS_ON) 363 ->where('project_id', $project_id)->where('status', Product::STATUS_ON)
363 ->whereNull('deleted_at') 364 ->whereNull('deleted_at')
  365 + ->inRandomOrder()
  366 + ->limit(100)
364 ->pluck('route', 'id')->toArray(); 367 ->pluck('route', 'id')->toArray();
365 368
  369 + //已发布AI博客
  370 + $ai_blog_urls = DB::connection('custom_mysql')->table('gl_ai_blog')
  371 + ->where('project_id', $project_id)->where('status', AiBlog::STATUS_FINISH)
  372 + ->inRandomOrder()
  373 + ->limit(20)
  374 + ->pluck('route', 'id')->toArray();
  375 + foreach ($ai_blog_urls as &$ai_blog_url){
  376 + $ai_blog_url = 'blog/' . $ai_blog_url;
  377 + }
  378 +
  379 + //已发布AI视频
  380 + $ai_video_urls = DB::connection('custom_mysql')->table('gl_ai_video')
  381 + ->where('project_id', $project_id)->where('status', 2)
  382 + ->inRandomOrder()
  383 + ->limit(20)
  384 + ->pluck('route', 'id')->toArray();
  385 + foreach ($ai_video_urls as &$ai_video_url){
  386 + $ai_video_url = 'video/' . $ai_video_url;
  387 + }
  388 +
  389 + $data['urls_details'] = array_merge($data['urls_details'], $ai_blog_urls, $ai_video_urls);
  390 +
366 $data['urls_cats'] = array_merge($data['urls_cats'], $data['urls_page']); 391 $data['urls_cats'] = array_merge($data['urls_cats'], $data['urls_page']);
367 if(empty($data['urls_cats'])){ 392 if(empty($data['urls_cats'])){
368 $data['urls_cats'] = $data['urls_details']; 393 $data['urls_cats'] = $data['urls_details'];
@@ -3,6 +3,7 @@ @@ -3,6 +3,7 @@
3 namespace App\Console\Commands\WebTraffic; 3 namespace App\Console\Commands\WebTraffic;
4 4
5 use App\Helper\Arr; 5 use App\Helper\Arr;
  6 +use App\Models\Ai\AiBlog;
6 use App\Models\HomeCount\Count; 7 use App\Models\HomeCount\Count;
7 use App\Models\Product\Category; 8 use App\Models\Product\Category;
8 use App\Models\Product\Product; 9 use App\Models\Product\Product;
@@ -320,6 +321,7 @@ class WebTrafficFix extends Command @@ -320,6 +321,7 @@ class WebTrafficFix extends Command
320 * 获取产品分类、单页和详情链接 321 * 获取产品分类、单页和详情链接
321 */ 322 */
322 protected function getProductUrls($project_id){ 323 protected function getProductUrls($project_id){
  324 + ProjectServer::useProject($project_id);
323 //已发布产品分类页面 325 //已发布产品分类页面
324 $data['urls_cats'] = DB::connection('custom_mysql')->table('gl_product_category') 326 $data['urls_cats'] = DB::connection('custom_mysql')->table('gl_product_category')
325 ->where('project_id', $project_id)->where('status', Category::STATUS_ACTIVE) 327 ->where('project_id', $project_id)->where('status', Category::STATUS_ACTIVE)
@@ -335,8 +337,31 @@ class WebTrafficFix extends Command @@ -335,8 +337,31 @@ class WebTrafficFix extends Command
335 $data['urls_details'] = DB::connection('custom_mysql')->table('gl_product') 337 $data['urls_details'] = DB::connection('custom_mysql')->table('gl_product')
336 ->where('project_id', $project_id)->where('status', Product::STATUS_ON) 338 ->where('project_id', $project_id)->where('status', Product::STATUS_ON)
337 ->whereNull('deleted_at') 339 ->whereNull('deleted_at')
  340 + ->inRandomOrder()
  341 + ->limit(100)
338 ->pluck('route', 'id')->toArray(); 342 ->pluck('route', 'id')->toArray();
339 343
  344 + //已发布AI博客
  345 + $ai_blog_urls = DB::connection('custom_mysql')->table('gl_ai_blog')
  346 + ->where('project_id', $project_id)->where('status', AiBlog::STATUS_FINISH)
  347 + ->inRandomOrder()
  348 + ->limit(20)
  349 + ->pluck('route', 'id')->toArray();
  350 + foreach ($ai_blog_urls as &$ai_blog_url){
  351 + $ai_blog_url = 'blog/' . $ai_blog_url;
  352 + }
  353 + //已发布AI视频
  354 + $ai_video_urls = DB::connection('custom_mysql')->table('gl_ai_video')
  355 + ->where('project_id', $project_id)->where('status', 2)
  356 + ->inRandomOrder()
  357 + ->limit(20)
  358 + ->pluck('route', 'id')->toArray();
  359 + foreach ($ai_video_urls as &$ai_video_url){
  360 + $ai_video_url = 'video/' . $ai_video_url;
  361 + }
  362 +
  363 + $data['urls_details'] = array_merge($data['urls_details'], $ai_blog_urls, $ai_video_urls);
  364 +
340 $data['urls_cats'] = array_merge($data['urls_cats'], $data['urls_page']); 365 $data['urls_cats'] = array_merge($data['urls_cats'], $data['urls_page']);
341 if(empty($data['urls_cats'])){ 366 if(empty($data['urls_cats'])){
342 $data['urls_cats'] = $data['urls_details']; 367 $data['urls_cats'] = $data['urls_details'];
@@ -3,6 +3,7 @@ @@ -3,6 +3,7 @@
3 namespace App\Console\Commands\WebTraffic; 3 namespace App\Console\Commands\WebTraffic;
4 4
5 use App\Helper\Arr; 5 use App\Helper\Arr;
  6 +use App\Models\Ai\AiBlog;
6 use App\Models\Product\Category; 7 use App\Models\Product\Category;
7 use App\Models\Product\Product; 8 use App\Models\Product\Product;
8 use App\Models\Project\OnlineCheck; 9 use App\Models\Project\OnlineCheck;
@@ -391,8 +392,31 @@ class WebTrafficRussia extends Command @@ -391,8 +392,31 @@ class WebTrafficRussia extends Command
391 $data['urls_details'] = DB::connection('custom_mysql')->table('gl_product') 392 $data['urls_details'] = DB::connection('custom_mysql')->table('gl_product')
392 ->where('project_id', $project_id)->where('status', Product::STATUS_ON) 393 ->where('project_id', $project_id)->where('status', Product::STATUS_ON)
393 ->whereNull('deleted_at') 394 ->whereNull('deleted_at')
  395 + ->inRandomOrder()
  396 + ->limit(100)
394 ->pluck('route', 'id')->toArray(); 397 ->pluck('route', 'id')->toArray();
395 398
  399 + //已发布AI博客
  400 + $ai_blog_urls = DB::connection('custom_mysql')->table('gl_ai_blog')
  401 + ->where('project_id', $project_id)->where('status', AiBlog::STATUS_FINISH)
  402 + ->inRandomOrder()
  403 + ->limit(20)
  404 + ->pluck('route', 'id')->toArray();
  405 + foreach ($ai_blog_urls as &$ai_blog_url){
  406 + $ai_blog_url = 'blog/' . $ai_blog_url;
  407 + }
  408 + //已发布AI视频
  409 + $ai_video_urls = DB::connection('custom_mysql')->table('gl_ai_video')
  410 + ->where('project_id', $project_id)->where('status', 2)
  411 + ->inRandomOrder()
  412 + ->limit(20)
  413 + ->pluck('route', 'id')->toArray();
  414 + foreach ($ai_video_urls as &$ai_video_url){
  415 + $ai_video_url = 'video/' . $ai_video_url;
  416 + }
  417 +
  418 + $data['urls_details'] = array_merge($data['urls_details'], $ai_blog_urls, $ai_video_urls);
  419 +
396 $data['urls_cats'] = array_merge($data['urls_cats'], $data['urls_page']); 420 $data['urls_cats'] = array_merge($data['urls_cats'], $data['urls_page']);
397 if(empty($data['urls_cats'])){ 421 if(empty($data['urls_cats'])){
398 $data['urls_cats'] = $data['urls_details']; 422 $data['urls_cats'] = $data['urls_details'];
@@ -3,6 +3,7 @@ @@ -3,6 +3,7 @@
3 namespace App\Console\Commands\WebTraffic; 3 namespace App\Console\Commands\WebTraffic;
4 4
5 use App\Helper\Arr; 5 use App\Helper\Arr;
  6 +use App\Models\Ai\AiBlog;
6 use App\Models\Product\Category; 7 use App\Models\Product\Category;
7 use App\Models\Product\Product; 8 use App\Models\Product\Product;
8 use App\Models\Project\OnlineCheck; 9 use App\Models\Project\OnlineCheck;
@@ -382,8 +383,31 @@ class WebTrafficRussiaSpecial extends Command @@ -382,8 +383,31 @@ class WebTrafficRussiaSpecial extends Command
382 $data['urls_details'] = DB::connection('custom_mysql')->table('gl_product') 383 $data['urls_details'] = DB::connection('custom_mysql')->table('gl_product')
383 ->where('project_id', $project_id)->where('status', Product::STATUS_ON) 384 ->where('project_id', $project_id)->where('status', Product::STATUS_ON)
384 ->whereNull('deleted_at') 385 ->whereNull('deleted_at')
  386 + ->inRandomOrder()
  387 + ->limit(100)
385 ->pluck('route', 'id')->toArray(); 388 ->pluck('route', 'id')->toArray();
386 389
  390 + //已发布AI博客
  391 + $ai_blog_urls = DB::connection('custom_mysql')->table('gl_ai_blog')
  392 + ->where('project_id', $project_id)->where('status', AiBlog::STATUS_FINISH)
  393 + ->inRandomOrder()
  394 + ->limit(20)
  395 + ->pluck('route', 'id')->toArray();
  396 + foreach ($ai_blog_urls as &$ai_blog_url){
  397 + $ai_blog_url = 'blog/' . $ai_blog_url;
  398 + }
  399 + //已发布AI视频
  400 + $ai_video_urls = DB::connection('custom_mysql')->table('gl_ai_video')
  401 + ->where('project_id', $project_id)->where('status', 2)
  402 + ->inRandomOrder()
  403 + ->limit(20)
  404 + ->pluck('route', 'id')->toArray();
  405 + foreach ($ai_video_urls as &$ai_video_url){
  406 + $ai_video_url = 'video/' . $ai_video_url;
  407 + }
  408 +
  409 + $data['urls_details'] = array_merge($data['urls_details'], $ai_blog_urls, $ai_video_urls);
  410 +
387 $data['urls_cats'] = array_merge($data['urls_cats'], $data['urls_page']); 411 $data['urls_cats'] = array_merge($data['urls_cats'], $data['urls_page']);
388 if(empty($data['urls_cats'])){ 412 if(empty($data['urls_cats'])){
389 $data['urls_cats'] = $data['urls_details']; 413 $data['urls_cats'] = $data['urls_details'];
@@ -3,6 +3,7 @@ @@ -3,6 +3,7 @@
3 namespace App\Console\Commands\WebTraffic; 3 namespace App\Console\Commands\WebTraffic;
4 4
5 use App\Helper\Arr; 5 use App\Helper\Arr;
  6 +use App\Models\Ai\AiBlog;
6 use App\Models\Product\Category; 7 use App\Models\Product\Category;
7 use App\Models\Product\Product; 8 use App\Models\Product\Product;
8 use App\Models\Project\OnlineCheck; 9 use App\Models\Project\OnlineCheck;
@@ -348,8 +349,31 @@ class WebTrafficSpecial extends Command @@ -348,8 +349,31 @@ class WebTrafficSpecial extends Command
348 $data['urls_details'] = DB::connection('custom_mysql')->table('gl_product') 349 $data['urls_details'] = DB::connection('custom_mysql')->table('gl_product')
349 ->where('project_id', $project_id)->where('status', Product::STATUS_ON) 350 ->where('project_id', $project_id)->where('status', Product::STATUS_ON)
350 ->whereNull('deleted_at') 351 ->whereNull('deleted_at')
  352 + ->inRandomOrder()
  353 + ->limit(100)
351 ->pluck('route', 'id')->toArray(); 354 ->pluck('route', 'id')->toArray();
352 355
  356 + //已发布AI博客
  357 + $ai_blog_urls = DB::connection('custom_mysql')->table('gl_ai_blog')
  358 + ->where('project_id', $project_id)->where('status', AiBlog::STATUS_FINISH)
  359 + ->inRandomOrder()
  360 + ->limit(20)
  361 + ->pluck('route', 'id')->toArray();
  362 + foreach ($ai_blog_urls as &$ai_blog_url){
  363 + $ai_blog_url = 'blog/' . $ai_blog_url;
  364 + }
  365 + //已发布AI视频
  366 + $ai_video_urls = DB::connection('custom_mysql')->table('gl_ai_video')
  367 + ->where('project_id', $project_id)->where('status', 2)
  368 + ->inRandomOrder()
  369 + ->limit(20)
  370 + ->pluck('route', 'id')->toArray();
  371 + foreach ($ai_video_urls as &$ai_video_url){
  372 + $ai_video_url = 'video/' . $ai_video_url;
  373 + }
  374 +
  375 + $data['urls_details'] = array_merge($data['urls_details'], $ai_blog_urls, $ai_video_urls);
  376 +
353 $data['urls_cats'] = array_merge($data['urls_cats'], $data['urls_page']); 377 $data['urls_cats'] = array_merge($data['urls_cats'], $data['urls_page']);
354 if(empty($data['urls_cats'])){ 378 if(empty($data['urls_cats'])){
355 $data['urls_cats'] = $data['urls_details']; 379 $data['urls_cats'] = $data['urls_details'];
@@ -229,7 +229,7 @@ class FetchTicketProjects extends Command @@ -229,7 +229,7 @@ class FetchTicketProjects extends Command
229 || $item->site_status == 1 229 || $item->site_status == 1
230 ) ? 1 : 0; 230 ) ? 1 : 0;
231 231
232 - $team_ids = [ 232 + $team_ids_in = [
233 $item->deploy_build->leader_mid, 233 $item->deploy_build->leader_mid,
234 $item->deploy_build->manager_mid, 234 $item->deploy_build->manager_mid,
235 $item->deploy_build->designer_mid, 235 $item->deploy_build->designer_mid,
@@ -240,11 +240,18 @@ class FetchTicketProjects extends Command @@ -240,11 +240,18 @@ class FetchTicketProjects extends Command
240 $item->deploy_optimize->tech_mid, 240 $item->deploy_optimize->tech_mid,
241 $item->deploy_optimize->tech_leader, 241 $item->deploy_optimize->tech_leader,
242 ]; 242 ];
  243 +
243 // $team_ids 去重复 244 // $team_ids 去重复
244 - $team_ids = array_unique($team_ids);  
245 - $team_ids = array_filter($team_ids); 245 + $team_ids_in = array_unique($team_ids_in);
  246 + $team_ids_in = array_filter($team_ids_in);
246 // $team_ids 去掉下标 247 // $team_ids 去掉下标
247 - $team_ids = array_values($team_ids); 248 + $team_ids_in = array_values($team_ids_in);
  249 +
  250 + $team_ids = ManageHr::whereIn('manage_id', $team_ids_in)->where('status', 1)->pluck('manage_id')
  251 + ->unique()
  252 + ->filter(fn($v) => !is_null($v) && $v !== 0)
  253 + ->values()
  254 + ->toArray();
248 255
249 $fields = [ 256 $fields = [
250 'company_name' => $item->company, 257 'company_name' => $item->company,
@@ -210,7 +210,7 @@ class CNoticeController extends BaseController @@ -210,7 +210,7 @@ class CNoticeController extends BaseController
210 * 更新通知C端 210 * 更新通知C端
211 * @param Request $request 211 * @param Request $request
212 * @return \Illuminate\Http\JsonResponse 212 * @return \Illuminate\Http\JsonResponse
213 - * @param : type : 1->主站更新 4->聚合页更新 7->ai博客 213 + * @param : route : 1->主站更新 4->聚合页更新 7->ai博客
214 */ 214 */
215 public function sendNotify(Request $request) 215 public function sendNotify(Request $request)
216 { 216 {
@@ -223,7 +223,7 @@ class CNoticeController extends BaseController @@ -223,7 +223,7 @@ class CNoticeController extends BaseController
223 $url = $request->input('url', []); 223 $url = $request->input('url', []);
224 $language = $request->input('language', []); 224 $language = $request->input('language', []);
225 $is_sitemap = intval($request->input('is_sitemap', 0)); 225 $is_sitemap = intval($request->input('is_sitemap', 0));
226 - if($type == 4){//代表聚合页更新 226 + if($route == 4){//代表聚合页更新
227 $keywordModel = new Keyword(); 227 $keywordModel = new Keyword();
228 $keywordInfo = $keywordModel->whereNull('seo_title')->orWhereNull('seo_keywords')->orWhereNull('seo_description')->first(); 228 $keywordInfo = $keywordModel->whereNull('seo_title')->orWhereNull('seo_keywords')->orWhereNull('seo_description')->first();
229 if(!empty($keywordInfo)){ 229 if(!empty($keywordInfo)){
@@ -302,7 +302,7 @@ class CNoticeController extends BaseController @@ -302,7 +302,7 @@ class CNoticeController extends BaseController
302 'is_sitemap' => $is_sitemap 302 'is_sitemap' => $is_sitemap
303 ]; 303 ];
304 try { 304 try {
305 - http_post($c_url, json_encode($c_param)); 305 + http_post($c_url, json_encode($c_param,true));
306 }catch (\Exception $e){ 306 }catch (\Exception $e){
307 NoticeLog::createLog(NoticeLog::GENERATE_PAGE, ['c_url'=>$c_url,'c_params'=>$c_param]); 307 NoticeLog::createLog(NoticeLog::GENERATE_PAGE, ['c_url'=>$c_url,'c_params'=>$c_param]);
308 } 308 }
@@ -37,6 +37,9 @@ class GeoLinkLogic extends BaseLogic @@ -37,6 +37,9 @@ class GeoLinkLogic extends BaseLogic
37 */ 37 */
38 public function getLinkList($map = [],$page = 1,$row = 20,$order = 'id'){ 38 public function getLinkList($map = [],$page = 1,$row = 20,$order = 'id'){
39 $filed = ['*']; 39 $filed = ['*'];
  40 + if(isset($map['url']) && !empty($map['url'])){
  41 + $map['url'] = ['like','%'.$map['url'].'%'];
  42 + }
40 $lists = $this->model->lists($map,$page,$row,$order,$filed); 43 $lists = $this->model->lists($map,$page,$row,$order,$filed);
41 return $this->success($lists); 44 return $this->success($lists);
42 } 45 }
@@ -64,13 +67,6 @@ class GeoLinkLogic extends BaseLogic @@ -64,13 +67,6 @@ class GeoLinkLogic extends BaseLogic
64 * @time :2025/7/14 16:50 67 * @time :2025/7/14 16:50
65 */ 68 */
66 public function saveLink(){ 69 public function saveLink(){
67 - $data = [  
68 - 'project_id' => 1,  
69 - 'data' => [  
70 - ['da'=>'ce_shi1', 'url'=>'www.baidu.com', 'send_time'=>'2021-07-09 11:12:12'],  
71 - ['da'=>'ce_shi2', 'url'=>'www.baidu1.com', 'send_time'=>'2021-07-10 11:13:12'],  
72 - ],  
73 - ];  
74 try { 70 try {
75 if(!empty($this->param['data'])){ 71 if(!empty($this->param['data'])){
76 $data = []; 72 $data = [];
@@ -88,19 +88,17 @@ class GeoQuestionResLogic extends BaseLogic @@ -88,19 +88,17 @@ class GeoQuestionResLogic extends BaseLogic
88 $questionModel = new GeoQuestion(); 88 $questionModel = new GeoQuestion();
89 $list = $questionModel->list(['project_id'=>$this->user['project_id']],['question','keywords','url']); 89 $list = $questionModel->list(['project_id'=>$this->user['project_id']],['question','keywords','url']);
90 $questionTotalCount = $urlTotalCount = $keywordsTotalCount = $keywordUrlCount = 0; 90 $questionTotalCount = $urlTotalCount = $keywordsTotalCount = $keywordUrlCount = 0;
  91 + $keywordArr = [];
  92 + $questionLogModel = new GeoQuestionLog();
  93 + $keywordUrlCount = $questionLogModel->counts(['project_id'=>$this->user['project_id'],'hit'=>['!=',0]]);
91 foreach ($list as $item){ 94 foreach ($list as $item){
92 $questionTotalCount += count($item['question'] ?? []); 95 $questionTotalCount += count($item['question'] ?? []);
93 $keywordsTotalCount += count($item['keywords'] ?? []); 96 $keywordsTotalCount += count($item['keywords'] ?? []);
94 $urlTotalCount += count($item['url'] ?? []); 97 $urlTotalCount += count($item['url'] ?? []);
95 - }  
96 - $keywordArr = [];  
97 - $questionResModel = new GeoQuestionLog();  
98 - $resList = $questionResModel->list(['project_id'=>$this->user['project_id']],['keywords','url','keywords_num','url_num']);  
99 - foreach ($resList as $resItem){  
100 - $keywordUrlCount += count($resItem['keywords']);  
101 - $keywordUrlCount += count($resItem['url']);  
102 - foreach ($resItem['keywords_num'] as $key => $value) {  
103 - $keywordArr[$key] = ($keywordArr[$key] ?? 0) + (($value != 0) ? 1 : 0); 98 + foreach ($item['keywords'] as $keyWordItem){
  99 + if (!array_key_exists($keyWordItem, $keywordArr)) {
  100 + $keywordArr[$keyWordItem] = $questionLogModel->counts(['project_id'=>$this->user['project_id'],'keywords'=>['like','%"'.$keyWordItem.'"%']]);
  101 + }
104 } 102 }
105 } 103 }
106 $data = [ 104 $data = [
@@ -124,7 +122,7 @@ class GeoQuestionResLogic extends BaseLogic @@ -124,7 +122,7 @@ class GeoQuestionResLogic extends BaseLogic
124 $data = []; 122 $data = [];
125 $platformModel = new GeoPlatform(); 123 $platformModel = new GeoPlatform();
126 $list = $platformModel->list(['status'=>1],'id',['name','en_name']); 124 $list = $platformModel->list(['status'=>1],'id',['name','en_name']);
127 - $questionResModel = new GeoQuestionResult(); 125 + $questionResModel = new GeoQuestionLog();
128 foreach ($list as $item){ 126 foreach ($list as $item){
129 $data[$item['name']] = $questionResModel->counts(['project_id'=>$this->user['project_id'],'hit'=>['!=',0],'platform'=>$item['en_name']]); 127 $data[$item['name']] = $questionResModel->counts(['project_id'=>$this->user['project_id'],'hit'=>['!=',0],'platform'=>$item['en_name']]);
130 } 128 }
@@ -139,7 +137,7 @@ class GeoQuestionResLogic extends BaseLogic @@ -139,7 +137,7 @@ class GeoQuestionResLogic extends BaseLogic
139 * @time :2025/7/21 16:36 137 * @time :2025/7/21 16:36
140 */ 138 */
141 public function getSearchDate(){ 139 public function getSearchDate(){
142 - $dates = $this->model->select(DB::raw('DATE(created_at) as date_only'))->distinct()->pluck('date_only'); 140 + $dates = $this->model->where('project_id',$this->user['project_id'])->select(DB::raw('DATE(created_at) as date_only'))->distinct()->pluck('date_only');
143 return $this->success($dates); 141 return $this->success($dates);
144 } 142 }
145 143
@@ -16,6 +16,16 @@ class AsideTicketStoreRequest extends FormRequest @@ -16,6 +16,16 @@ class AsideTicketStoreRequest extends FormRequest
16 return true; 16 return true;
17 } 17 }
18 18
  19 + protected function prepareForValidation()
  20 + {
  21 + if ($this->has('close_wechat')) {
  22 + $this->merge([
  23 + // 将 "true", "1", "on", "yes" 等转换为 true,其他转换为 false
  24 + 'close_wechat' => filter_var($this->close_wechat, FILTER_VALIDATE_BOOLEAN),
  25 + ]);
  26 + }
  27 + }
  28 +
19 /** 29 /**
20 * Get the validation rules that apply to the request. 30 * Get the validation rules that apply to the request.
21 * 31 *
@@ -70,13 +70,12 @@ class GeoService @@ -70,13 +70,12 @@ class GeoService
70 } 70 }
71 71
72 /** 72 /**
73 - * @remark :请求deepSeek数据  
74 - * @name :getDeepSeek  
75 - * @author :lyh  
76 - * @method :post  
77 - * @time :2025/7/15 10:59 73 + * 请求chat会话, 自定义模型
  74 + * @param $content
  75 + * @param string $model
  76 + * @return mixed|string
78 */ 77 */
79 - public function getDeepSeekResult($content,$model = 'deepseek-r1'){ 78 + public function getChatResult($content, $model = 'deepseek-r1'){
80 $url = $this->api_url . 'v1/chat'; 79 $url = $this->api_url . 'v1/chat';
81 switch ($model){ 80 switch ($model){
82 case 'deepseek-r1': 81 case 'deepseek-r1':