作者 赵彬吉

seo tdk

@@ -13,6 +13,7 @@ use App\Models\Domain\DomainInfo; @@ -13,6 +13,7 @@ use App\Models\Domain\DomainInfo;
13 use App\Models\Mail\Mail; 13 use App\Models\Mail\Mail;
14 use App\Models\Project\DeployBuild; 14 use App\Models\Project\DeployBuild;
15 use App\Models\Project\DeployOptimize; 15 use App\Models\Project\DeployOptimize;
  16 +use App\Models\Project\KeywordPrefix;
16 use App\Models\Project\Project; 17 use App\Models\Project\Project;
17 use App\Models\Project\ProjectKeyword; 18 use App\Models\Project\ProjectKeyword;
18 use App\Models\Project\ProjectUpdateTdk; 19 use App\Models\Project\ProjectUpdateTdk;
@@ -373,39 +374,9 @@ class UpdateSeoTdk extends Command @@ -373,39 +374,9 @@ class UpdateSeoTdk extends Command
373 $seo_title = $v[$this->topic_fields[$table]];; 374 $seo_title = $v[$this->topic_fields[$table]];;
374 //只有推广项目 且未标记特殊前后缀 才加 前后缀 375 //只有推广项目 且未标记特殊前后缀 才加 前后缀
375 if($project->type == Project::TYPE_TWO && !in_array(8, explode(',', $project->deploy_optimize->special))) { 376 if($project->type == Project::TYPE_TWO && !in_array(8, explode(',', $project->deploy_optimize->special))) {
376 - $prefix = $this->getPrefixKeyword($project_id, 'prefix', 1);  
377 - $suffix = $this->getPrefixKeyword($project_id, 'suffix', 2);  
378 - if (empty($prefix) || empty($suffix)) {  
379 - continue;  
380 - }  
381 -  
382 - $title = $seo_title;  
383 -  
384 - $prefix = $this->getPrefixKeyword($project_id, 'prefix', 1, $title);  
385 - //in,for,with,to,near,from 这些介词 只拼前缀,不拼后缀  
386 - $is_contains_jieci = false;  
387 - $words = explode(' ', $title);  
388 - foreach ($words as $word){  
389 - $word = Str::replace([',', '!', '?'], '', $word);  
390 - if(in_array(strtolower($word), ['in', 'for', 'with', 'to', 'near','from'])){  
391 - $is_contains_jieci = true;  
392 - }  
393 - }  
394 - $suffix = '';  
395 - if(!$is_contains_jieci){  
396 - // 某些后缀不能并存的情况  
397 - $ban_suffix = [];  
398 - //services/service 结尾的词,后缀不拼manufacturer,factory  
399 - if (Str::endsWith($title, ['services', 'service', 'Services', 'Service'])) {  
400 - $ban_suffix = ['manufacturer', 'factory', 'Manufacturer', 'Factory', 'Factories', 'Manufacturers'];  
401 - }  
402 - //前缀有wholesale或cheap的词,后缀不拼 manufacturer,factory,exporter,company  
403 - if (Str::startsWith($title, ['wholesale', 'cheap', 'Wholesale', 'Cheap'])) {  
404 - $ban_suffix = array_merge($ban_suffix, ['manufacturer', 'factory', 'exporter', 'company', 'Manufacturer', 'Factory', 'Exporter', 'Company', 'Factories', 'Manufacturers', 'Exporters', 'Companies']);  
405 - }  
406 - $suffix = $this->getPrefixKeyword($project_id, 'suffix', 2, $title, $ban_suffix);  
407 - }  
408 - $seo_title = $prefix . ' ' . $title . ' ' . $suffix; 377 + $prefix = $this->getPrefixKeyword($project_id, 'prefix', 1, $project->main_lang_id, $seo_title);
  378 + $suffix = $this->getPrefixKeyword($project_id, 'suffix', 2, $project->main_lang_id, $seo_title);
  379 + $seo_title = $prefix . ' ' . $seo_title . ' ' . $suffix;
409 } 380 }
410 381
411 $data[$field] = trim($seo_title); 382 $data[$field] = trim($seo_title);
@@ -576,62 +547,111 @@ class UpdateSeoTdk extends Command @@ -576,62 +547,111 @@ class UpdateSeoTdk extends Command
576 * @param $project_id 547 * @param $project_id
577 * @param $type 548 * @param $type
578 * @param $num 549 * @param $num
  550 + * @param int $main_lang_id
579 * @param string $topic 551 * @param string $topic
580 - * @param array $ban 被禁用的前后缀  
581 * @return string 552 * @return string
582 */ 553 */
583 - public function getPrefixKeyword($project_id, $type, $num, $topic='', $ban = []) 554 + public function getPrefixKeyword($project_id, $type, $num, $main_lang_id = 0, $topic='')
584 { 555 {
585 $str = ''; 556 $str = '';
  557 + $ban = []; //被禁用的前后缀
  558 +
586 $info = $this->getDeployOptimize($project_id); 559 $info = $this->getDeployOptimize($project_id);
587 - if (!empty($info['keyword_' . $type])) {  
588 - $fix_keyword = explode(",", $info['keyword_' . $type]);  
589 - $fix_keyword = array_filter($fix_keyword);  
590 - //去掉标题存在的词  
591 - if ($topic) {  
592 - foreach ($fix_keyword as $k=>$keyword) {  
593 - // 被禁用的关键词  
594 - if (in_array($keyword, $ban)) {  
595 - unset($fix_keyword[$k]);  
596 - }  
597 - // 前后缀如果已经存在, 就不在拼接当前类型  
598 - if (FALSE !== strpos($topic, $keyword))  
599 - return $str;  
600 - //复数转单数  
601 - $keyword = Str::singular($keyword);  
602 -  
603 - $topic_words = explode(" ", $topic);  
604 - if($type == 'prefix' && Str::startsWith($topic_words[0], $keyword)){  
605 - unset($fix_keyword[$k]);  
606 - }  
607 - if($type == 'suffix' && Str::startsWith($topic_words[count($topic_words)-1], $keyword)){  
608 - unset($fix_keyword[$k]);  
609 - } 560 +
  561 + //没有勾选前后缀
  562 + if (empty($info['keyword_' . $type])) {
  563 + return $str;
  564 + }
  565 +
  566 + //前后缀(小语种包括自定义前后缀)如果已经存在,就不在拼接当前类型 后缀只包含了一个,要再拼一个(需去重)
  567 + $all_prefixes = $this->getAllPrefix($type == 'prefix' ? 1 : 2, $main_lang_id == 1 ? 0 : $project_id);
  568 + //加上选中的自定义前后缀
  569 + $all_prefixes = array_merge($all_prefixes, explode(",", $info['keyword_' . $type]));
  570 + $all_prefixes = array_filter($all_prefixes);
  571 + $all_prefixes = array_map('strtolower', $all_prefixes);
  572 +
  573 + //in,for,with,to,near,from 这些介词 只拼前缀,不拼后缀
  574 + $preposition = ['in', 'for', 'with', 'to', 'near','from'];
  575 +
  576 + //标题拆成词
  577 + $topic_words = explode(' ', strtolower($topic));
  578 + $i= 0;
  579 + foreach ($topic_words as $topic_word){
  580 + //包含了前后缀
  581 + if(in_array($topic_word, $all_prefixes)){
  582 + //前缀包含一个就不拼了 后缀包含两个才不再拼
  583 + if($i == $num - 1){
  584 + return $str;
610 } 585 }
  586 + $ban[] = $topic_word;
  587 + $i++;
  588 + $num--;
  589 + }
  590 + //in,for,with,to,near,from 这些介词 只拼前缀,不拼后缀
  591 + if(in_array($topic_word, $preposition) && $type == 'suffix'){
  592 + return $str;
  593 + }
  594 +
  595 + }
  596 +
  597 + //services/service 结尾的词,后缀不拼manufacturer,factory
  598 + if (Str::endsWith(strtolower($topic), ['services', 'service']) && $type == 'suffix') {
  599 + $ban = array_merge($ban, ['manufacturer', 'manufacturers', 'factory', 'factories']);
  600 + }
  601 + //前缀有wholesale或cheap的词,后缀不拼 manufacturer,factory,exporter,company
  602 + if (Str::startsWith(strtolower($topic), ['wholesale', 'cheap']) && $type == 'prefix') {
  603 + $ban = array_merge($ban, ['manufacturer', 'manufacturers', 'factory', 'factories', 'exporter', 'exporters', 'company', 'companies', 'supplier', 'suppliers']);
  604 + }
  605 +
  606 + //关键词是否包含 品牌词
  607 + $brand_keywords = explode("\r\n", $info['brand_keyword']);
  608 + $is_contains_brand = false;
  609 + foreach ($brand_keywords as $brand_keyword) {
  610 + if (Str::contains(strtolower($topic), strtolower(trim($brand_keyword)))) {
  611 + $is_contains_brand = true;
  612 + break;
  613 + }
  614 + }
  615 + //包含品牌词 排除自定义前后缀
  616 + if ($is_contains_brand) {
  617 + $customer_keywords = KeywordPrefix::where('project_id', $project_id)->pluck('keyword')->toArray();
  618 + $ban = array_merge($ban, $customer_keywords);
  619 + }
  620 +
  621 + //勾选的前后缀
  622 + $fix_keyword = explode(",", $info['keyword_' . $type]);
  623 + $fix_keyword = array_filter($fix_keyword);
  624 + foreach ($fix_keyword as $k => $keyword) {
  625 + // 被禁用的关键词
  626 + if (in_array(strtolower(Str::plural($keyword)), $ban)) {
  627 + unset($fix_keyword[$k]);
  628 + }
  629 + if (in_array(strtolower(Str::singular($keyword)), $ban)) {
  630 + unset($fix_keyword[$k]);
611 } 631 }
612 - //随机取 并单复数去重  
613 - shuffle($fix_keyword);  
614 - $keywords = [];  
615 - foreach ($fix_keyword as $v){  
616 - if($num == 0){ 632 + }
  633 +
  634 + //随机取 并单复数去重
  635 + shuffle($fix_keyword);
  636 + $keywords = [];
  637 + foreach ($fix_keyword as $v) {
  638 + if ($num == 0) {
  639 + break;
  640 + }
  641 + $is_repeat = false;
  642 + foreach ($keywords as $keyword) {
  643 + if (Str::singular($keyword) == Str::singular($v)) {
  644 + $is_repeat = true;
617 break; 645 break;
618 } 646 }
619 - $is_repeat = false;  
620 - foreach ($keywords as $keyword){  
621 - if(Str::singular($keyword) == Str::singular($v)){  
622 - $is_repeat = true;  
623 - break;  
624 - }  
625 - }  
626 - if($is_repeat){  
627 - continue;  
628 - }  
629 - $keywords[] = $v;  
630 - $num--;  
631 } 647 }
632 - $str = implode(', ', $keywords); 648 + if ($is_repeat) {
  649 + continue;
  650 + }
  651 + $keywords[] = $v;
  652 + $num--;
633 } 653 }
634 - return $str; 654 + return implode(', ', $keywords);
635 } 655 }
636 656
637 657
@@ -653,6 +673,24 @@ class UpdateSeoTdk extends Command @@ -653,6 +673,24 @@ class UpdateSeoTdk extends Command
653 } 673 }
654 674
655 /** 675 /**
  676 + * 所有前后缀 和 当期项目的自定义前后缀
  677 + * @param $type
  678 + * @param int $project_id
  679 + * @return mixed
  680 + * @author zbj
  681 + * @date 2025/4/15
  682 + */
  683 + public function getAllPrefix($type, int $project_id = 0){
  684 + $cache_key = 'AllPrefix_' . $type . '_' . $project_id;
  685 + $data = Cache::get($cache_key);
  686 + if(!$data){
  687 + $data = KeywordPrefix::whereIn('project_id', [0, $project_id])->where('type', $type)->pluck('keyword')->toArray();
  688 + Cache::put($cache_key, $data, 600);
  689 + }
  690 + return $data;
  691 + }
  692 +
  693 + /**
656 * @remark :获取公司英文名称 694 * @remark :获取公司英文名称
657 * @name :companyName 695 * @name :companyName
658 * @author :lyh 696 * @author :lyh