作者 zhl

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

@@ -139,9 +139,9 @@ class DomainInfo extends Command @@ -139,9 +139,9 @@ class DomainInfo extends Command
139 $serverIpModel = new ServersIp(); 139 $serverIpModel = new ServersIp();
140 $domainCreateTaskModel = new DomainCreateTask(); 140 $domainCreateTaskModel = new DomainCreateTask();
141 $end_day = date('Y-m-d H:i:s', time() + 3 * 24 * 3600);//3天后到期 141 $end_day = date('Y-m-d H:i:s', time() + 3 * 24 * 3600);//3天后到期
142 - $list = $domainModel->where('status', '=', 1)->where('type', '!=', 2)->where('certificate_end_time', '<', $end_day)->get()->toArray(); 142 + $list = $domainModel->where('status', '=', 1)->where('type', '=', 1)->where('certificate_end_time', '<', $end_day)->get()->toArray();
143 foreach ($list as $v) { 143 foreach ($list as $v) {
144 - $project_info = $projectModel->read(['id' => $v['project_id'], 'type' => ['!=', Project::TYPE_CLOSE]], ['serve_id']); 144 + $project_info = $projectModel->read(['id' => $v['project_id'], 'type' => ['!=', Project::TYPE_CLOSE]], ['serve_id', 'project_type']);
145 if (!$project_info) { 145 if (!$project_info) {
146 continue; 146 continue;
147 } 147 }
@@ -161,14 +161,20 @@ class DomainInfo extends Command @@ -161,14 +161,20 @@ class DomainInfo extends Command
161 continue; 161 continue;
162 } 162 }
163 163
  164 + if ($project_info['project_type'] == Project::PROJECT_TYPE_SEO) {
  165 + $type = DomainCreateTask::TYPE_BLOG;
  166 + } else {
  167 + $type = DomainCreateTask::TYPE_MAIN;
  168 + }
  169 +
164 //创建更新站点证书任务 170 //创建更新站点证书任务
165 - $task_info = $domainCreateTaskModel->read(['type' => DomainCreateTask::TYPE_MAIN, 'domain_id' => $v['id'], 'status' => ['<', DomainCreateTask::STATUS_SUC]]); 171 + $task_info = $domainCreateTaskModel->read(['type' => $type, 'domain_id' => $v['id'], 'status' => ['<', DomainCreateTask::STATUS_SUC]]);
166 if (!$task_info) { 172 if (!$task_info) {
167 $domainCreateTaskModel->add([ 173 $domainCreateTaskModel->add([
168 'server_id' => $servers_ip_info['servers_id'], 174 'server_id' => $servers_ip_info['servers_id'],
169 'project_id' => $v['project_id'], 175 'project_id' => $v['project_id'],
170 'domain_id' => $v['id'], 176 'domain_id' => $v['id'],
171 - 'type' => DomainCreateTask::TYPE_MAIN 177 + 'type' => $type
172 ]); 178 ]);
173 } 179 }
174 } 180 }
@@ -186,7 +192,7 @@ class DomainInfo extends Command @@ -186,7 +192,7 @@ class DomainInfo extends Command
186 $serverIpModel = new ServersIp(); 192 $serverIpModel = new ServersIp();
187 $domainCreateTaskModel = new DomainCreateTask(); 193 $domainCreateTaskModel = new DomainCreateTask();
188 $end_day = date('Y-m-d H:i:s', time() + 3 * 24 * 3600);//3天后到期 194 $end_day = date('Y-m-d H:i:s', time() + 3 * 24 * 3600);//3天后到期
189 - $list = $domainModel->where('status', '=', 1)->where('amp_status', 1)->where('amp_type', '!=', 2)->where('amp_certificate_end_time', '<', $end_day)->get()->toArray(); 195 + $list = $domainModel->where('status', '=', 1)->where('amp_status', 1)->where('amp_type', '=', 1)->where('amp_certificate_end_time', '<', $end_day)->get()->toArray();
190 foreach ($list as $v) { 196 foreach ($list as $v) {
191 $domain_array = parse_url($v['domain']); 197 $domain_array = parse_url($v['domain']);
192 $host = $domain_array['host'] ?? $domain_array['path']; 198 $host = $domain_array['host'] ?? $domain_array['path'];
@@ -243,7 +249,7 @@ class DomainInfo extends Command @@ -243,7 +249,7 @@ class DomainInfo extends Command
243 $serverIpModel = new ServersIp(); 249 $serverIpModel = new ServersIp();
244 $domainCreateTaskModel = new DomainCreateTask(); 250 $domainCreateTaskModel = new DomainCreateTask();
245 $end_day = date('Y-m-d H:i:s', time() + 3 * 24 * 3600);//3天后到期 251 $end_day = date('Y-m-d H:i:s', time() + 3 * 24 * 3600);//3天后到期
246 - $list = $customModel->where('status', 1)->where('is_create', 1)->where('type', '!=', 2)->where('certificate_end_time', '<', $end_day)->get()->toArray(); 252 + $list = $customModel->where('status', 1)->where('is_create', 1)->where('type', '=', 1)->where('certificate_end_time', '<', $end_day)->get()->toArray();
247 foreach ($list as $v) { 253 foreach ($list as $v) {
248 $project_info = $projectModel->read(['id' => $v['project_id'], 'type' => ['!=', Project::TYPE_CLOSE]], ['serve_id']); 254 $project_info = $projectModel->read(['id' => $v['project_id'], 'type' => ['!=', Project::TYPE_CLOSE]], ['serve_id']);
249 if (!$project_info) { 255 if (!$project_info) {
@@ -67,7 +67,30 @@ class UpdateRoute extends Command @@ -67,7 +67,30 @@ class UpdateRoute extends Command
67 */ 67 */
68 public function handle() 68 public function handle()
69 { 69 {
70 - return $this->settingSeo(); 70 + return $this->getNullRoute();
  71 + }
  72 +
  73 + /**
  74 + * @remark :查询 路由为空的关键词项目id
  75 + * @name :getNullRoute
  76 + * @author :lyh
  77 + * @method :post
  78 + * @time :2025/4/21 11:52
  79 + */
  80 + public function getNullRoute(){
  81 + $projectModel = new Project();
  82 + $lists = $projectModel->list(['delete_status' => 0,'extend_type'=>0,'type'=>['in',[1,2,3,4]]], 'id', ['id']);
  83 + foreach ($lists as $val) {
  84 + echo date('Y-m-d H:i:s') . '开始--项目的id:'. $val['id'] . PHP_EOL;
  85 + ProjectServer::useProject($val['id']);
  86 + $keywordModel = new Keyword();
  87 + $info = $keywordModel->read(['route'=>'']);
  88 + if($info !== false){
  89 + echo '存在路由为空--项目id:'.$val['id'].PHP_EOL;
  90 + }
  91 + DB::disconnect('custom_mysql');
  92 + }
  93 + return true;
71 } 94 }
72 95
73 public function keyword_actions(){ 96 public function keyword_actions(){
@@ -68,6 +68,7 @@ class RecommendedSuppliers extends Command @@ -68,6 +68,7 @@ class RecommendedSuppliers extends Command
68 if(!empty($title)){ 68 if(!empty($title)){
69 $this->savePurchaser($v['project_id'],$title); 69 $this->savePurchaser($v['project_id'],$title);
70 }else{ 70 }else{
  71 + $this->deployBuildModel->edit(['is_supplier'=>0],['project_id'=>$v['project_id']]);
71 echo '关键词已取完'.PHP_EOL; 72 echo '关键词已取完'.PHP_EOL;
72 } 73 }
73 DB::disconnect('custom_mysql'); 74 DB::disconnect('custom_mysql');
@@ -152,7 +153,7 @@ class RecommendedSuppliers extends Command @@ -152,7 +153,7 @@ class RecommendedSuppliers extends Command
152 ]; 153 ];
153 ksort($data); 154 ksort($data);
154 $token = 'company_list+'.date('Y-m-d').'+'.http_build_query($data); 155 $token = 'company_list+'.date('Y-m-d').'+'.http_build_query($data);
155 -// echo date('Y-m-d H:i:s') . '加密token:'.md5($token) . PHP_EOL; 156 + $keyword = rtrim($keyword, "\r");
156 $param = [ 157 $param = [
157 'prod_desc'=>$keyword, 158 'prod_desc'=>$keyword,
158 'token'=>md5($token), 159 'token'=>md5($token),
@@ -161,19 +162,18 @@ class RecommendedSuppliers extends Command @@ -161,19 +162,18 @@ class RecommendedSuppliers extends Command
161 $res = http_post($url,json_encode($param)); 162 $res = http_post($url,json_encode($param));
162 echo '请求返回状态'. ($res['code']?? '').PHP_EOL; 163 echo '请求返回状态'. ($res['code']?? '').PHP_EOL;
163 // echo date('Y-m-d H:i:s') . json_encode($res) . PHP_EOL; 164 // echo date('Y-m-d H:i:s') . json_encode($res) . PHP_EOL;
164 - if(!empty($res) && isset($res['code']) && $res['code'] == 200 && !empty($res['data'])){  
165 - //保存多条数据  
166 - $saveData = [  
167 - 'project_id'=>$project_id,  
168 - 'keyword'=>$keyword,  
169 - 'data'=>json_encode($res['data'])  
170 - ];  
171 - $purchaserModel = new Purchaser();  
172 - $purchaserModel->add($saveData); 165 + //保存多条数据
  166 + $saveData = [
  167 + 'project_id'=>$project_id,
  168 + 'keyword'=>$keyword,
  169 + 'data'=>json_encode($res['data'] ?? '')
  170 + ];
  171 + $purchaserModel = new Purchaser();
  172 + $purchaserModel->add($saveData);
  173 + if(isset($res['code']) && $res['code'] == 200 && !empty($res['data'])){
173 $this->savePurchaserInfo($project_id,$keyword,$res['data']); 174 $this->savePurchaserInfo($project_id,$keyword,$res['data']);
174 }else{ 175 }else{
175 - $title = $this->getKeywords($project_id);  
176 - $this->savePurchaser($project_id,$title); 176 + echo '未正常返回数据,跳过项目'.PHP_EOL;
177 } 177 }
178 return true; 178 return true;
179 } 179 }
@@ -188,11 +188,11 @@ class RecommendedSuppliers extends Command @@ -188,11 +188,11 @@ class RecommendedSuppliers extends Command
188 public function getKeywords($project_id){ 188 public function getKeywords($project_id){
189 $keywordModel = new Keyword(); 189 $keywordModel = new Keyword();
190 $keyword_array = $this->getPurchaserList($project_id); 190 $keyword_array = $this->getPurchaserList($project_id);
191 - $info = $keywordModel->read(['title'=>['not in',$keyword_array]],'title');  
192 - if($info === false){ 191 + $title = $keywordModel->whereNotIn('title', $keyword_array)->inRandomOrder()->limit(1)->value('title');
  192 + if(empty($title)){
193 return ''; 193 return '';
194 } 194 }
195 - return $info['title'] ?? ''; 195 + return $title;
196 } 196 }
197 197
198 /** 198 /**
@@ -205,6 +205,9 @@ class RecommendedSuppliers extends Command @@ -205,6 +205,9 @@ class RecommendedSuppliers extends Command
205 public function savePurchaserInfo($project_id,$keyword,$data){ 205 public function savePurchaserInfo($project_id,$keyword,$data){
206 $purchaserInfoModel = new PurchaserInfo(); 206 $purchaserInfoModel = new PurchaserInfo();
207 foreach ($data as $k =>$v){ 207 foreach ($data as $k =>$v){
  208 + if(empty($v['buyer_id'])){
  209 + continue;
  210 + }
208 $v['project_id'] = $project_id; 211 $v['project_id'] = $project_id;
209 $v['keyword'] = $keyword; 212 $v['keyword'] = $keyword;
210 $v['email'] = json_encode($v['email']??[],JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); 213 $v['email'] = json_encode($v['email']??[],JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
@@ -5,11 +5,13 @@ namespace App\Console\Commands\Tdk; @@ -5,11 +5,13 @@ namespace App\Console\Commands\Tdk;
5 5
6 use App\Helper\Arr; 6 use App\Helper\Arr;
7 use App\Models\Product\Keyword; 7 use App\Models\Product\Keyword;
  8 +use App\Models\Project\KeywordPrefix;
8 use App\Models\Project\Project; 9 use App\Models\Project\Project;
9 use App\Models\Project\ProjectUpdateTdk; 10 use App\Models\Project\ProjectUpdateTdk;
10 use App\Services\ProjectServer; 11 use App\Services\ProjectServer;
11 use App\Utils\LogUtils; 12 use App\Utils\LogUtils;
12 use Illuminate\Console\Command; 13 use Illuminate\Console\Command;
  14 +use Illuminate\Support\Facades\Cache;
13 use Illuminate\Support\Facades\DB; 15 use Illuminate\Support\Facades\DB;
14 use Illuminate\Support\Str; 16 use Illuminate\Support\Str;
15 17
@@ -64,24 +66,36 @@ class RerunSeoTdk extends Command @@ -64,24 +66,36 @@ class RerunSeoTdk extends Command
64 } 66 }
65 67
66 /** 68 /**
67 - * 判断seo_title 前缀有wholesale或cheap的词,后缀也有 manufacturer,factory,exporter,company 69 + * 判断seo_title 前缀有wholesale或cheap或buy的词,后缀也有 manufacturer,factory,exporter,company
  70 + * 判断关键词最后一个词是前缀的词,前后缀都不拼
68 * @author zbj 71 * @author zbj
69 * @date 2025/4/12 72 * @date 2025/4/12
70 */ 73 */
71 public function judgeAnomalies($project_id){ 74 public function judgeAnomalies($project_id){
  75 + dump($project_id);
  76 + $all_prefixes = $this->getAllPrefix(1, $project_id);
  77 + $all_prefixes = array_map('strtolower', $all_prefixes);
  78 +
72 //获取当前项目的所有分类 79 //获取当前项目的所有分类
73 - $seo_titles = Keyword::pluck('seo_title', 'id')->toArray(); 80 + $list = Keyword::select('title', 'seo_title', 'id')->get()->toArray();
74 //新闻 seo_keyword 和 分类名一样的 81 //新闻 seo_keyword 和 分类名一样的
75 $ids = []; 82 $ids = [];
76 - foreach ($seo_titles as $id=>$seo_title){  
77 - if(!Str::startsWith(strtolower($seo_title), ['wholesale', 'cheap'])){ 83 + foreach ($list as $k=>$item){
  84 + $seo_title = $item['seo_title'];
  85 + $id = $item['id'];
  86 + $title = $item['title'];
  87 + if(Str::startsWith(strtolower($seo_title), ['wholesale', 'cheap', 'buy']) && Str::contains(strtolower($seo_title), ['manufacturer', 'manufacturers', 'factory', 'factories', 'exporter', 'exporters', 'company', 'companies', 'supplier', 'suppliers'])){
  88 + $ids[] = $id;
  89 + dump($seo_title);
78 continue; 90 continue;
79 } 91 }
80 - if(!Str::contains(strtolower($seo_title), ['manufacturer', 'manufacturers', 'factory', 'factories', 'exporter', 'exporters', 'company', 'companies', 'supplier', 'suppliers'])){ 92 + $topic_words = explode(' ', strtolower($title));
  93 + //关键词最后一个是前缀 且 有前后缀
  94 + if(in_array(Arr::last($topic_words), $all_prefixes) && $title != $seo_title){
  95 + $ids[] = $id;
  96 + dump($seo_title);
81 continue; 97 continue;
82 } 98 }
83 - dump($seo_title);exit;  
84 - $ids[] = $id;  
85 } 99 }
86 100
87 $count = count($ids); 101 $count = count($ids);
@@ -147,4 +161,14 @@ class RerunSeoTdk extends Command @@ -147,4 +161,14 @@ class RerunSeoTdk extends Command
147 // ProjectUpdateTdk::add_task($project_id); 161 // ProjectUpdateTdk::add_task($project_id);
148 // } 162 // }
149 // } 163 // }
  164 +
  165 + public function getAllPrefix($type, int $project_id = 0){
  166 + $cache_key = 'AllPrefix_' . $type . '_' . $project_id;
  167 + $data = Cache::get($cache_key);
  168 + if(!$data){
  169 + $data = KeywordPrefix::whereIn('project_id', [0, $project_id])->where('type', $type)->pluck('keyword')->toArray();
  170 + Cache::put($cache_key, $data, 600);
  171 + }
  172 + return $data;
  173 + }
150 } 174 }
@@ -372,10 +372,10 @@ class UpdateSeoTdk extends Command @@ -372,10 +372,10 @@ class UpdateSeoTdk extends Command
372 } else if ($table == 'gl_product_keyword' && $field == 'seo_title') { 372 } else if ($table == 'gl_product_keyword' && $field == 'seo_title') {
373 # TODO 聚合页seo title 特殊处理 前缀_1 . 关键词 . 后缀_2 373 # TODO 聚合页seo title 特殊处理 前缀_1 . 关键词 . 后缀_2
374 $seo_title = $v[$this->topic_fields[$table]];; 374 $seo_title = $v[$this->topic_fields[$table]];;
375 - //只有推广项目 且未标记特殊前后缀 才加 前后缀  
376 - if($project->type == Project::TYPE_TWO && !in_array(8, explode(',', $project->deploy_optimize->special))) { 375 + //只有推广项目 才加 前后缀
  376 + if($project->type == Project::TYPE_TWO) {
377 $prefix = $this->getPrefixKeyword($project_id, 'prefix', 1, $seo_title); 377 $prefix = $this->getPrefixKeyword($project_id, 'prefix', 1, $seo_title);
378 - $suffix = $this->getPrefixKeyword($project_id, 'suffix', 2, $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;
381 }else{ 381 }else{
@@ -567,18 +567,31 @@ class UpdateSeoTdk extends Command @@ -567,18 +567,31 @@ class UpdateSeoTdk extends Command
567 } 567 }
568 568
569 //前后缀(包括自定义前后缀)如果已经存在,就不在拼接当前类型 后缀只包含了一个,要再拼一个(需去重) 569 //前后缀(包括自定义前后缀)如果已经存在,就不在拼接当前类型 后缀只包含了一个,要再拼一个(需去重)
570 - $all_prefixes = $this->getAllPrefix($type == 'prefix' ? 1 : 2, $project_id); 570 + $all_prefixes = $this->getAllPrefix(1, $project_id);
571 $all_prefixes = array_map('strtolower', $all_prefixes); 571 $all_prefixes = array_map('strtolower', $all_prefixes);
572 572
  573 + $all_suffixes = $this->getAllPrefix(2, $project_id);
  574 + $all_suffixes = array_map('strtolower', $all_suffixes);
  575 +
573 //in,for,with,to,near,from 这些介词 只拼前缀,不拼后缀 576 //in,for,with,to,near,from 这些介词 只拼前缀,不拼后缀
574 $preposition = ['in', 'for', 'with', 'to', 'near','from']; 577 $preposition = ['in', 'for', 'with', 'to', 'near','from'];
575 578
576 //标题拆成词 579 //标题拆成词
577 $topic_words = explode(' ', strtolower($topic)); 580 $topic_words = explode(' ', strtolower($topic));
  581 +
  582 + //关键词最后一个词是前缀的词,前后缀都不拼
  583 + if(in_array(Arr::last($topic_words), $all_prefixes)){
  584 + return $str;
  585 + }
  586 +
578 $i= 0; 587 $i= 0;
579 foreach ($topic_words as $topic_word){ 588 foreach ($topic_words as $topic_word){
580 - //包含了前后缀  
581 - if(in_array($topic_word, $all_prefixes)){ 589 + //关键词本身包含了前缀就不拼前缀,只拼后缀
  590 + if(in_array($topic_word, $all_prefixes) && $type == 'prefix'){
  591 + return $str;
  592 + }
  593 + //关键词本身包含了后缀,可拼前缀,也可以再拼一个不重复的后缀,包含两个后缀就不拼后缀了
  594 + if(in_array($topic_word, $all_suffixes) && $type == 'suffix'){
582 //前缀包含一个就不拼了 后缀包含两个才不再拼 595 //前缀包含一个就不拼了 后缀包含两个才不再拼
583 if($i == $num - 1){ 596 if($i == $num - 1){
584 return $str; 597 return $str;
@@ -591,7 +604,6 @@ class UpdateSeoTdk extends Command @@ -591,7 +604,6 @@ class UpdateSeoTdk extends Command
591 if(in_array($topic_word, $preposition) && $type == 'suffix'){ 604 if(in_array($topic_word, $preposition) && $type == 'suffix'){
592 return $str; 605 return $str;
593 } 606 }
594 -  
595 } 607 }
596 608
597 //services/service 结尾的词,后缀不拼manufacturer,factory 609 //services/service 结尾的词,后缀不拼manufacturer,factory
@@ -603,13 +615,13 @@ class UpdateSeoTdk extends Command @@ -603,13 +615,13 @@ class UpdateSeoTdk extends Command
603 $ban = array_merge($ban, ['services', 'service']); 615 $ban = array_merge($ban, ['services', 'service']);
604 } 616 }
605 617
606 - //前缀有wholesale或cheap的词,后缀不拼 manufacturer,factory,exporter,company  
607 - if (Str::startsWith(strtolower($topic), ['wholesale', 'cheap']) && $type == 'suffix') { 618 + //有wholesale或cheap的词,后缀不拼 manufacturer,factory,exporter,company
  619 + if (Str::contains(strtolower($topic), ['wholesale', 'cheap', 'buy']) && $type == 'suffix') {
608 $ban = array_merge($ban, ['manufacturer', 'manufacturers', 'factory', 'factories', 'exporter', 'exporters', 'company', 'companies', 'supplier', 'suppliers']); 620 $ban = array_merge($ban, ['manufacturer', 'manufacturers', 'factory', 'factories', 'exporter', 'exporters', 'company', 'companies', 'supplier', 'suppliers']);
609 } 621 }
610 //关键词以manufacturer,factory,exporter,company结尾, 前缀不拼wholesale或cheap的词 622 //关键词以manufacturer,factory,exporter,company结尾, 前缀不拼wholesale或cheap的词
611 if (Str::endsWith(strtolower($topic), ['manufacturer', 'manufacturers', 'factory', 'factories', 'exporter', 'exporters', 'company', 'companies', 'supplier', 'suppliers']) && $type == 'prefix') { 623 if (Str::endsWith(strtolower($topic), ['manufacturer', 'manufacturers', 'factory', 'factories', 'exporter', 'exporters', 'company', 'companies', 'supplier', 'suppliers']) && $type == 'prefix') {
612 - $ban = array_merge($ban, ['wholesale', 'cheap']); 624 + $ban = array_merge($ban, ['wholesale', 'cheap', 'buy']);
613 } 625 }
614 626
615 //关键词是否包含 品牌词 627 //关键词是否包含 品牌词
@@ -660,7 +672,7 @@ class UpdateSeoTdk extends Command @@ -660,7 +672,7 @@ class UpdateSeoTdk extends Command
660 $keywords[] = $v; 672 $keywords[] = $v;
661 $num--; 673 $num--;
662 } 674 }
663 - if ($type == 'suffix' && count($keywords) == 1 && in_array(Arr::last($topic_words), $all_prefixes)) { 675 + if ($type == 'suffix' && count($keywords) == 1 && in_array(Arr::last($topic_words), $all_suffixes)) {
664 return ', ' . $keywords[0]; 676 return ', ' . $keywords[0];
665 } 677 }
666 return implode(', ', $keywords); 678 return implode(', ', $keywords);
@@ -774,9 +786,12 @@ class UpdateSeoTdk extends Command @@ -774,9 +786,12 @@ class UpdateSeoTdk extends Command
774 Cache::forget($cache_key); 786 Cache::forget($cache_key);
775 } 787 }
776 } 788 }
777 - 789 + $a = $text;
778 $text = Common::deal_keywords($text); 790 $text = Common::deal_keywords($text);
779 $text = Common::deal_str($text); 791 $text = Common::deal_str($text);
  792 + if(!$text){
  793 + echo getmypid() . ' ' . 'AI生成结果['.$a.']被关键词过滤' . PHP_EOL;
  794 + }
780 795
781 //包含这写字 重新生成 796 //包含这写字 重新生成
782 if(Str::contains(Str::lower($text), ['[your brand]', '[brand name]'])){ 797 if(Str::contains(Str::lower($text), ['[your brand]', '[brand name]'])){
@@ -39,17 +39,64 @@ class Temp extends Command @@ -39,17 +39,64 @@ class Temp extends Command
39 */ 39 */
40 protected $description = '临时脚本(akun)'; 40 protected $description = '临时脚本(akun)';
41 41
42 - public function handle() 42 + public function handle(){
  43 +
  44 + }
  45 +
  46 + /**
  47 + * www.docareco.com批量设置301跳转
  48 + * @author Akun
  49 + * @date 2025/04/21 16:12
  50 + */
  51 + public function setDomain301()
43 { 52 {
  53 + $domain_extend_config = DomainInfo::where('domain', 'www.docareco.com')->value('extend_config');
  54 +
  55 + $domain_origin_list = $domain_extend_config ? array_column($domain_extend_config, 'origin') : [];
  56 +
  57 + //读取csv文件
  58 + $file = 'C:\Users\Akun\Desktop\有排名网页-还未做301-4.21.csv';
  59 + $line_of_text = [];
  60 + try {
  61 + $file_handle = fopen($file, 'r');
  62 + while (!feof($file_handle)) {
  63 + $line_of_text[] = fgetcsv($file_handle, 0, ',');
  64 + }
  65 + fclose($file_handle);
  66 + } catch (\Exception $e) {
  67 + $this->output($e->getMessage());
  68 + }
  69 +
  70 + if (count($line_of_text) > 1) {
  71 + foreach ($line_of_text as $k => $v) {
  72 + if ($k > 0 && $v) {
  73 + $origin = str_replace('https://www.docareco.com', '', $v[0]);
  74 + $target = str_replace('https://www.docareco.com', '', $v[1]);
  75 +
  76 + if (!in_array($origin, $domain_origin_list)) {
  77 + $domain_extend_config[] = [
  78 + 'origin' => $origin,
  79 + 'target' => $target
  80 + ];
  81 + }
  82 + }
  83 + }
  84 + }
  85 +
  86 + DomainInfo::where('domain', 'www.docareco.com')->update(['extend_config' => Arr::a2s($domain_extend_config)]);
44 87
  88 + $this->output('success');
45 } 89 }
46 90
  91 +
  92 +
47 /** 93 /**
48 * 未被标注 特殊前后缀 && 未达标项目 && 优化开始时间 > 2025-01-01 00:00:00 ,开启自动添加聚合页关键词的前后缀关键词配置 94 * 未被标注 特殊前后缀 && 未达标项目 && 优化开始时间 > 2025-01-01 00:00:00 ,开启自动添加聚合页关键词的前后缀关键词配置
49 * @author Akun 95 * @author Akun
50 * @date 2025/04/02 14:00 96 * @date 2025/04/02 14:00
51 */ 97 */
52 - public function changeIsAutoKeywords(){ 98 + public function changeIsAutoKeywords()
  99 + {
53 $project_list = DeployOptimize::where('special', 'not like', '%,8,%')->where('start_date', '>', '2025-01-01 00:00:00')->get(); 100 $project_list = DeployOptimize::where('special', 'not like', '%,8,%')->where('start_date', '>', '2025-01-01 00:00:00')->get();
54 101
55 foreach ($project_list as $project) { 102 foreach ($project_list as $project) {
@@ -9,6 +9,7 @@ use App\Models\User\UserLogin as UserLoginModel; @@ -9,6 +9,7 @@ use App\Models\User\UserLogin as UserLoginModel;
9 use Illuminate\Encryption\Encrypter; 9 use Illuminate\Encryption\Encrypter;
10 use Illuminate\Support\Facades\Cache; 10 use Illuminate\Support\Facades\Cache;
11 use Illuminate\Support\Facades\Http; 11 use Illuminate\Support\Facades\Http;
  12 +use Illuminate\Support\Str;
12 13
13 /** 14 /**
14 * @name: 15 * @name:
@@ -213,18 +214,23 @@ class Common @@ -213,18 +214,23 @@ class Common
213 } 214 }
214 $keyword = str_replace($str,'',$keyword); 215 $keyword = str_replace($str,'',$keyword);
215 $keyword = trim($keyword,'.'); 216 $keyword = trim($keyword,'.');
216 - if( (strpos(strtolower($keyword),'hope') === false || strpos(strtolower($keyword),'hopein') !== false)  
217 - && (strpos(strtolower($keyword),'remember') === false || strpos(strtolower($keyword),'rememberance') !== false)  
218 - && strpos(strtolower($keyword),'help') === false  
219 - && strpos(strtolower($keyword),'website') === false  
220 - && strpos(strtolower($keyword),'search keywords') === false  
221 - && strpos(strtolower($keyword),'here are 8') === false  
222 - && strpos(strtolower($keyword),'search keywords') === false  
223 - && strpos(strtolower($keyword),'thank you') === false  
224 - && (strpos(strtolower($keyword),'thanks') === false || strpos(strtolower($keyword),'thanksgiving') !== false)  
225 - && strpos(strtolower($keyword),'copywriter') === false ){  
226 - $ar_keywords[] = $keyword; 217 +
  218 + if(Str::contains($keyword, ['search keywords', 'here are 8', 'thank you'])){
  219 + continue;
  220 + }
  221 + $keyword_words = explode(' ', $keyword);
  222 +
  223 + $is_contains = false;
  224 + foreach ($keyword_words as $word){
  225 + if(in_array($word, ['hope', 'remember', 'help', 'website', 'thanks', 'copywriter'])){
  226 + $is_contains = true;
  227 + break;
  228 + }
  229 + }
  230 + if($is_contains){
  231 + continue;
227 } 232 }
  233 + $ar_keywords[] = $keyword;
228 } 234 }
229 } 235 }
230 return implode(', ',$ar_keywords); 236 return implode(', ',$ar_keywords);
@@ -37,12 +37,27 @@ class CheckListController extends BaseController @@ -37,12 +37,27 @@ class CheckListController extends BaseController
37 * @time :2025/4/17 9:31 37 * @time :2025/4/17 9:31
38 */ 38 */
39 public function lists(){ 39 public function lists(){
  40 + $this->map['status'] = 1;
40 $field = ['id','status','sort','text','created_at']; 41 $field = ['id','status','sort','text','created_at'];
41 $data = $this->model->lists($this->map,$this->page,$this->row,'id',$field); 42 $data = $this->model->lists($this->map,$this->page,$this->row,'id',$field);
42 $this->response('success',Code::SUCCESS,$data); 43 $this->response('success',Code::SUCCESS,$data);
43 } 44 }
44 45
45 /** 46 /**
  47 + * @remark :获取分页检查清单数据
  48 + * @name :lists
  49 + * @author :lyh
  50 + * @method :post
  51 + * @time :2025/4/17 9:31
  52 + */
  53 + public function list(){
  54 + $this->map['status'] = 1;
  55 + $field = ['id','status','sort','text','created_at'];
  56 + $data = $this->model->list($this->map,'id',$field);
  57 + $this->response('success',Code::SUCCESS,$data);
  58 + }
  59 +
  60 + /**
46 * @remark :获取数据详情 61 * @remark :获取数据详情
47 * @name :info 62 * @name :info
48 * @author :lyh 63 * @author :lyh
@@ -67,6 +82,7 @@ class CheckListController extends BaseController @@ -67,6 +82,7 @@ class CheckListController extends BaseController
67 * @time :2025/4/17 9:32 82 * @time :2025/4/17 9:32
68 */ 83 */
69 public function save(){ 84 public function save(){
  85 + $this->param['operator_id'] = $this->manage['id'];
70 if(isset($this->param['id']) && !empty($this->param['id'])){ 86 if(isset($this->param['id']) && !empty($this->param['id'])){
71 $id = $this->param['id']; 87 $id = $this->param['id'];
72 $this->model->edit($this->param,['id'=>$this->param['id']]); 88 $this->model->edit($this->param,['id'=>$this->param['id']]);
@@ -195,17 +195,36 @@ class DomainInfoLogic extends BaseLogic @@ -195,17 +195,36 @@ class DomainInfoLogic extends BaseLogic
195 } 195 }
196 } 196 }
197 197
198 - //如果要开通amp站点,判断m域名是否已经解析 198 + $domain_array = parse_url($info['domain']);
  199 + $host = $domain_array['host'] ?? $domain_array['path'];
  200 + $host_array = explode('.',$host);
  201 +
  202 + if($this->param['type'] == 3){
  203 + //需要申请通配符证书,判断_acme-challenge是否已经解析
  204 + $host_array_ssl = $host_array;
  205 + if (count($host_array_ssl) <= 2) {
  206 + array_unshift($host_array_ssl, '_acme-challenge');
  207 + } else {
  208 + $host_array_ssl[0] = '_acme-challenge';
  209 + }
  210 + $ssl_domain = implode('.',$host_array_ssl);
  211 +
  212 + $ssl_records = dns_get_record($ssl_domain,DNS_CNAME);
  213 + $ssl_target = $ssl_records[0]['target']??'';
  214 + if($ssl_target != '_acme-challenge.globalsosslcheck.com'){
  215 + $this->fail('缺少通配符证书必要的解析记录:'.$ssl_domain);
  216 + }
  217 + }
  218 +
199 if(isset($this->param['amp_status']) && $this->param['amp_status'] == 1){ 219 if(isset($this->param['amp_status']) && $this->param['amp_status'] == 1){
200 - $domain_array = parse_url($info['domain']);  
201 - $host = $domain_array['host'] ?? $domain_array['path'];  
202 - $host_array = explode('.',$host);  
203 - if (count($host_array) <= 2) {  
204 - array_unshift($host_array, 'm'); 220 + //需要开通amp站点,判断m域名是否已经解析
  221 + $host_array_amp = $host_array;
  222 + if (count($host_array_amp) <= 2) {
  223 + array_unshift($host_array_amp, 'm');
205 } else { 224 } else {
206 - $host_array[0] = 'm'; 225 + $host_array_amp[0] = 'm';
207 } 226 }
208 - $amp_domain = implode('.',$host_array); 227 + $amp_domain = implode('.',$host_array_amp);
209 if(!check_domain_record($amp_domain, $serversIpInfo)){ 228 if(!check_domain_record($amp_domain, $serversIpInfo)){
210 $this->fail('AMP站点域名' . $amp_domain . '未解析至目标服务器'); 229 $this->fail('AMP站点域名' . $amp_domain . '未解析至目标服务器');
211 } 230 }
@@ -496,7 +496,7 @@ class RankDataLogic extends BaseLogic @@ -496,7 +496,7 @@ class RankDataLogic extends BaseLogic
496 $without_project_ids = []; //不用处理排名的项目 496 $without_project_ids = []; //不用处理排名的项目
497 $without_extension_project_ids = [658]; //是否达标只统计主词的 497 $without_extension_project_ids = [658]; //是否达标只统计主词的
498 $extension_project_ids = [354]; //扩展词也到达标的 498 $extension_project_ids = [354]; //扩展词也到达标的
499 - $compliance_project_ids = [2163,257,823]; //直接达标处理的 499 + $compliance_project_ids = [2163,257,823,1750]; //直接达标处理的
500 $ceaseProjectId = [47, 354, 378, 649, 1226, 1283, 1703, 1893, 2066, 2250];//暂停的项目 500 $ceaseProjectId = [47, 354, 378, 649, 1226, 1283, 1703, 1893, 2066, 2250];//暂停的项目
501 $uptimeProjectId = [1434,1812,276,2414,2974];//按上线时间统计的项目 501 $uptimeProjectId = [1434,1812,276,2414,2974];//按上线时间统计的项目
502 //一个项目多个api_no 502 //一个项目多个api_no
@@ -45,8 +45,8 @@ class OptimizeCheckLog extends Base @@ -45,8 +45,8 @@ class OptimizeCheckLog extends Base
45 if(isset($param['images'])){ 45 if(isset($param['images'])){
46 $param['images'] = Arr::a2s($param['images'] ?? []); 46 $param['images'] = Arr::a2s($param['images'] ?? []);
47 } 47 }
48 - $this->param['operator_id'] = $manage_id;  
49 - $this->param['date'] = date('Y-m-d hH:i:s'); 48 + $param['operator_id'] = $manage_id;
  49 + $param['date'] = $param['date'] ?? date('Y-m-d H:i:s');
50 return $param; 50 return $param;
51 } 51 }
52 } 52 }
@@ -309,7 +309,8 @@ Route::middleware(['aloginauth'])->group(function () { @@ -309,7 +309,8 @@ Route::middleware(['aloginauth'])->group(function () {
309 309
310 //检查列表 310 //检查列表
311 Route::prefix('check_list')->group(function () { 311 Route::prefix('check_list')->group(function () {
312 - Route::any('/', [Aside\Optimize\CheckListController::class, 'lists'])->name('admin.check_list'); 312 + Route::any('/', [Aside\Optimize\CheckListController::class, 'lists'])->name('admin.check_lists');
  313 + Route::any('/list', [Aside\Optimize\CheckListController::class, 'list'])->name('admin.check_list');
313 Route::any('/info', [Aside\Optimize\CheckListController::class, 'info'])->name('admin.check_list_info'); 314 Route::any('/info', [Aside\Optimize\CheckListController::class, 'info'])->name('admin.check_list_info');
314 Route::any('/save', [Aside\Optimize\CheckListController::class, 'save'])->name('admin.check_list_save'); 315 Route::any('/save', [Aside\Optimize\CheckListController::class, 'save'])->name('admin.check_list_save');
315 Route::any('/del', [Aside\Optimize\CheckListController::class, 'del'])->name('admin.check_list_del'); 316 Route::any('/del', [Aside\Optimize\CheckListController::class, 'del'])->name('admin.check_list_del');