作者 ZhengBing He

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

正在显示 52 个修改的文件 包含 1338 行增加149 行删除
@@ -13,6 +13,7 @@ use App\Helper\Arr; @@ -13,6 +13,7 @@ use App\Helper\Arr;
13 use App\Models\Ai\AiBlog; 13 use App\Models\Ai\AiBlog;
14 use App\Models\Ai\AiBlogAuthor; 14 use App\Models\Ai\AiBlogAuthor;
15 use App\Models\Ai\AiBlogList; 15 use App\Models\Ai\AiBlogList;
  16 +use App\Models\Com\NoticeLog;
16 use App\Models\Com\Notify; 17 use App\Models\Com\Notify;
17 use App\Models\Devops\ServerConfig; 18 use App\Models\Devops\ServerConfig;
18 use App\Models\Devops\ServersIp; 19 use App\Models\Devops\ServersIp;
@@ -337,6 +338,9 @@ class AiBlogTask extends Command @@ -337,6 +338,9 @@ class AiBlogTask extends Command
337 'is_sitemap' => 0 338 'is_sitemap' => 0
338 ]; 339 ];
339 $res = http_post($c_url, json_encode($param,true)); 340 $res = http_post($c_url, json_encode($param,true));
  341 + if(empty($res)){
  342 + NoticeLog::createLog(NoticeLog::GENERATE_PAGE, json_encode(['c_url'=>$c_url,'c_params'=>$param]),date('Y-m-d H:i:s',time()+300));
  343 + }
340 $this->output('notify: project id: ' . $project_id . ', result: ' . json_encode($res,JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); 344 $this->output('notify: project id: ' . $project_id . ', result: ' . json_encode($res,JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
341 } 345 }
342 } 346 }
  1 +<?php
  2 +/**
  3 + * @remark :
  4 + * @name :AiDomainTask.php
  5 + * @author :lyh
  6 + * @method :post
  7 + * @time :2025/6/19 10:53
  8 + */
  9 +
  10 +namespace App\Console\Commands\Ai;
  11 +
  12 +use App\Models\Domain\DomainInfo;
  13 +use Illuminate\Console\Command;
  14 +
  15 +/**
  16 + * @remark :拉取项目Ai域名
  17 + * @name :AiDomainTask
  18 + * @author :lyh
  19 + * @method :post
  20 + * @time :2025/6/19 10:54
  21 + */
  22 +class AiDomainTask extends Command
  23 +{
  24 + /**
  25 + * The name and signature of the console command.
  26 + *
  27 + * @var string
  28 + */
  29 + protected $signature = 'ai_domain';
  30 +
  31 + /**
  32 + * The console command description.
  33 + *
  34 + * @var string
  35 + */
  36 + protected $description = '获取对应域名的ai复制站域名';
  37 +
  38 + public $url = 'https://www.cmer.site/api/globalso_site';
  39 +
  40 + /**
  41 + * @remark :执行方法
  42 + * @name :handle
  43 + * @author :lyh
  44 + * @method :post
  45 + * @time :2025/6/19 11:32
  46 + */
  47 + public function handle(){
  48 + $pageSize = 300;
  49 + $page = 1;
  50 + $res = http_get($this->url.'?pagesize='.$pageSize.'&page='.$page);
  51 + if($res['status'] != 200){
  52 + echo date('Y-m-d H:i:s').'请求失败,状态码错误'.PHP_EOL;
  53 + return false;
  54 + }
  55 + if(empty($res['data']['data'])){
  56 + echo date('Y-m-d H:i:s').'请求失败,未拉取到数据'.PHP_EOL;
  57 + return false;
  58 + }
  59 + $data = $res['data']['data'];
  60 + while($page <= $res['data']['last_page']){
  61 + $res = http_get($this->url.'?pagesize='.$pageSize.'&page='.$page);
  62 + if($res['status'] != 200){
  63 + echo date('Y-m-d H:i:s').'第'.$page.'请求失败,未拉取到数据'.PHP_EOL;
  64 + return false;
  65 + }
  66 + $data = array_values(array_merge($data,$res['data']['data']));
  67 + $page++;
  68 + }
  69 + //处理数据
  70 + $this->handleData($data);
  71 + echo 'end'.PHP_EOL;
  72 + return true;
  73 + }
  74 +
  75 + /**
  76 + * @remark :处理数据
  77 + * @name :handleData
  78 + * @author :lyh
  79 + * @method :post
  80 + * @time :2025/6/19 11:21
  81 + */
  82 + public function handleData($data){
  83 + $domainInfoModel = new DomainInfo();
  84 + foreach ($data as $item){
  85 + $info = $domainInfoModel->read(['domain'=>$item['domain']],'id');
  86 + if($info === false){
  87 + $info = $domainInfoModel->read(['domain'=>$item['globalso_domain']],'id');
  88 + if($info !== false){
  89 + $domainInfoModel->edit(['ai_domain'=>$item['domain']],['id'=>$info['id']]);
  90 + }
  91 + }else{
  92 + $domainInfoModel->edit(['ai_domain'=>$item['globalso_domain']],['id'=>$info['id']]);
  93 + }
  94 + }
  95 + return true;
  96 + }
  97 +}
@@ -43,7 +43,9 @@ class RemainDay extends Command @@ -43,7 +43,9 @@ class RemainDay extends Command
43 1893, 43 1893,
44 2066, 44 2066,
45 2250, 45 2250,
46 - 2193 46 + 2193,
  47 + 2399,
  48 + 1685
47 ];//需要单独处理的项目 49 ];//需要单独处理的项目
48 /** 50 /**
49 * The console command description. 51 * The console command description.
@@ -736,7 +736,12 @@ class RelayInquiry extends Command @@ -736,7 +736,12 @@ class RelayInquiry extends Command
736 // 所有可用url 736 // 所有可用url
737 $urls = $inquiry_urls = []; 737 $urls = $inquiry_urls = [];
738 //入口url 首页30%,单页10%,聚合页60% 738 //入口url 首页30%,单页10%,聚合页60%
739 - $type = getRandByRatio([40,20,40]); 739 + if ($re_website == 'https://www.hikelok.com/') {
  740 + $type = getRandByRatio([50,49,1]);
  741 + } else {
  742 + $type = getRandByRatio([40,20,40]);
  743 + }
  744 +
740 $inlet = $re_website; 745 $inlet = $re_website;
741 $type == 1 && $inlet = $page_url ? Arr::random($page_url) : $re_website; 746 $type == 1 && $inlet = $page_url ? Arr::random($page_url) : $re_website;
742 $type == 2 && $inlet = $keywords_url ? Arr::random($keywords_url) : $re_website; 747 $type == 2 && $inlet = $keywords_url ? Arr::random($keywords_url) : $re_website;
@@ -10,12 +10,15 @@ @@ -10,12 +10,15 @@
10 namespace App\Console\Commands\LyhTest; 10 namespace App\Console\Commands\LyhTest;
11 11
12 use App\Helper\Common; 12 use App\Helper\Common;
  13 +use App\Models\Blog\Blog;
13 use App\Models\Com\V6WeeklyReport; 14 use App\Models\Com\V6WeeklyReport;
  15 +use App\Models\News\News;
14 use App\Models\Product\Category; 16 use App\Models\Product\Category;
15 use App\Models\Product\CategoryRelated; 17 use App\Models\Product\CategoryRelated;
16 use App\Models\Product\Product; 18 use App\Models\Product\Product;
17 use App\Models\ProjectAssociation\ProjectAssociation; 19 use App\Models\ProjectAssociation\ProjectAssociation;
18 use App\Models\RouteMap\RouteMap; 20 use App\Models\RouteMap\RouteMap;
  21 +use App\Models\Template\BTemplate;
19 use App\Models\Visit\Visit; 22 use App\Models\Visit\Visit;
20 use App\Models\Visit\VisitItem; 23 use App\Models\Visit\VisitItem;
21 use App\Models\Workchat\MessagePush; 24 use App\Models\Workchat\MessagePush;
@@ -43,16 +46,51 @@ class DownloadProject extends Command @@ -43,16 +46,51 @@ class DownloadProject extends Command
43 46
44 public function handle(){ 47 public function handle(){
45 echo date('Y-m-d H:i:s') . 'start' . PHP_EOL; 48 echo date('Y-m-d H:i:s') . 'start' . PHP_EOL;
46 - ProjectServer::useProject(535);  
47 - $this->model = new Visit();  
48 - $data = $this->importVisit();  
49 - dd($data); 49 + ProjectServer::useProject(671);
  50 + $this->newsImportBlog();
50 DB::disconnect('custom_mysql'); 51 DB::disconnect('custom_mysql');
51 echo date('Y-m-d H:i:s') . 'end' . PHP_EOL; 52 echo date('Y-m-d H:i:s') . 'end' . PHP_EOL;
52 return true; 53 return true;
53 } 54 }
54 55
55 /** 56 /**
  57 + * @remark :新闻导入到博客
  58 + * @name :newsImportBlog
  59 + * @author :lyh
  60 + * @method :post
  61 + * @time :2025/6/7 11:12
  62 + */
  63 + public function newsImportBlog(){
  64 + $newsModel = new News();
  65 + $newsLists = $newsModel->list(['status'=>1]);
  66 + $blogModel = new Blog();
  67 + foreach ($newsLists as $item){
  68 + $data = [
  69 + 'name'=>$item['name'],
  70 + 'status'=>1,
  71 + 'remark'=>$item['remark'],
  72 + 'text'=>$item['text'],
  73 + 'image'=>$item['image'],
  74 + 'url'=>$item['url'],
  75 + 'seo_title'=>$item['seo_title'],
  76 + 'seo_description'=>$item['seo_title'],
  77 + 'seo_keywords'=>$item['seo_title'],
  78 + 'project_id'=>671,
  79 + 'release_at'=>$item['release_at'],
  80 + 'og_image'=>$item['og_image']
  81 + ];
  82 + $id = $blogModel->addReturnId($data);
  83 + RouteMap::delRoute(RouteMap::SOURCE_NEWS,$item['id'],671);
  84 + $route = RouteMap::setRoute($item['url'],RouteMap::SOURCE_BLOG,$id,671);
  85 + $blogModel->edit(['url'=>$route],['id'=>$id]);
  86 + //更新当前的可视化归宿
  87 + $templateModel = new BTemplate();
  88 + $templateModel->edit(['source'=>3,'source_id'=>$id],['source'=>4,'source_id'=>$item['id'],'is_custom'=>0,'is_list'=>0]);
  89 + }
  90 + return true;
  91 + }
  92 +
  93 + /**
56 * @remark :导出明细 94 * @remark :导出明细
57 * @name :importVisit 95 * @name :importVisit
58 * @author :lyh 96 * @author :lyh
@@ -52,9 +52,9 @@ class LyhImportTest extends Command @@ -52,9 +52,9 @@ class LyhImportTest extends Command
52 * @time :2023/11/20 15:13 52 * @time :2023/11/20 15:13
53 */ 53 */
54 public function handle(){ 54 public function handle(){
55 - ProjectServer::useProject(3951); 55 + ProjectServer::useProject(3654);
56 echo date('Y-m-d H:i:s') . 'start' . PHP_EOL; 56 echo date('Y-m-d H:i:s') . 'start' . PHP_EOL;
57 - $this->import2140CustomModule('https://ecdn6.globalso.com/upload/p/2140/file/2025-05/daoru.csv',3951); 57 + $this->importProductCategory('https://ecdn6-nc.globalso.com/upload/p/3654/file/2025-06/products-1.csv',3654);
58 DB::disconnect('custom_mysql'); 58 DB::disconnect('custom_mysql');
59 echo date('Y-m-d H:i:s') . 'end' . PHP_EOL; 59 echo date('Y-m-d H:i:s') . 'end' . PHP_EOL;
60 } 60 }
@@ -129,23 +129,43 @@ class LyhImportTest extends Command @@ -129,23 +129,43 @@ class LyhImportTest extends Command
129 if($k < 1){ 129 if($k < 1){
130 continue; 130 continue;
131 } 131 }
132 - if(empty($val[1])){  
133 - echo '跳过的名称:'.$val[1]; 132 + if(empty($val[0])){
  133 + echo '跳过的名称:'.$val[0];
134 continue; 134 continue;
135 } 135 }
136 try { 136 try {
137 - $categoryModel->edit(['sort'=>$val[1]],['title'=>$val[0]]);  
138 -// $id = $categoryModel->addReturnId(['project_id'=>$project_id,'title'=>$val[1],'seo_title'=>$val[0],'seo_des'=>$val[2]]);  
139 -// $pid = 0;  
140 -// if($val[2] != 0){  
141 -// //查询上级id  
142 -// $pidCate = $categoryModel->read(['seo_title'=>$val[2]]);  
143 -// if($pidCate !== false){  
144 -// $pid = $pidCate['id'];  
145 -// }  
146 -// }  
147 -// $route = RouteMap::setRoute($val[1],RouteMap::SOURCE_PRODUCT_CATE,$id,$project_id);  
148 -// $categoryModel->edit(['route'=>$route,'pid'=>$pid],['id'=>$id]); 137 + $cateArr = explode('/',$val[0]);
  138 + $pid = 0;
  139 + $two_pid = 0;
  140 + foreach ($cateArr as $key => $item){
  141 + if($key == 0){
  142 + //查看一级分类是否存在
  143 + $info = $categoryModel->read(['title'=>$item,'pid'=>0],['id']);
  144 + if($info === false){
  145 + $pid = $categoryModel->addReturnId(['project_id'=>$project_id,'title'=>$item]);
  146 + //设置路由
  147 + $route = RouteMap::setRoute($item,RouteMap::SOURCE_PRODUCT_CATE,$pid,$project_id);
  148 + $categoryModel->edit(['route'=>$route],['id'=>$pid]);
  149 + }else{
  150 + $pid = $info['id'];
  151 + }
  152 + }elseif ($key == 1){
  153 + //查看当前下面的子级别是否存在
  154 + $two_info = $categoryModel->read(['title'=>$item,'pid'=>$pid],['id']);
  155 + if($two_info === false){
  156 + $two_pid = $categoryModel->addReturnId(['project_id'=>$project_id,'title'=>$item,'pid'=>$pid]);
  157 + //设置路由
  158 + $route = RouteMap::setRoute($item,RouteMap::SOURCE_PRODUCT_CATE,$two_pid,$project_id);
  159 + $categoryModel->edit(['route'=>$route],['id'=>$two_pid]);
  160 + }else{
  161 + $two_pid = $two_info['id'];
  162 + }
  163 + }else{
  164 + $id = $categoryModel->addReturnId(['project_id'=>$project_id,'title'=>$item,'pid'=>$two_pid]);
  165 + $route = RouteMap::setRoute($item,RouteMap::SOURCE_PRODUCT_CATE,$id,$project_id);
  166 + $categoryModel->edit(['route'=>$route],['id'=>$id]);
  167 + }
  168 + }
149 echo date('Y-m-d H:i:s') . '产品分类id:'.PHP_EOL; 169 echo date('Y-m-d H:i:s') . '产品分类id:'.PHP_EOL;
150 }catch (\Exception $e){ 170 }catch (\Exception $e){
151 echo date('Y-m-d H:i:s') . '跳过的名称:'. $val[1]; 171 echo date('Y-m-d H:i:s') . '跳过的名称:'. $val[1];
@@ -68,7 +68,9 @@ class UpdateRoute extends Command @@ -68,7 +68,9 @@ class UpdateRoute extends Command
68 */ 68 */
69 public function handle() 69 public function handle()
70 { 70 {
71 - return $this->getAiBlog(); 71 + ProjectServer::useProject(1181);
  72 + return $this->setProductKeyword();
  73 + DB::disconnect('custom_mysql');
72 } 74 }
73 75
74 /** 76 /**
@@ -299,18 +301,18 @@ class UpdateRoute extends Command @@ -299,18 +301,18 @@ class UpdateRoute extends Command
299 if(!empty($lists)){ 301 if(!empty($lists)){
300 foreach ($lists as $v){ 302 foreach ($lists as $v){
301 if(!empty($v['route'])){ 303 if(!empty($v['route'])){
302 -// echo date('Y-m-d H:i:s') . 'route :'.$v['id'] . PHP_EOL;  
303 -// $route = $this->setRoute($v['route'], RouteMap::SOURCE_PRODUCT_KEYWORD, $v['id'], $v['project_id']);  
304 -// $keywordModel->edit(['route'=>$route],['id'=>$v['id']]); 304 + echo date('Y-m-d H:i:s') . 'route :'.$v['id'] . PHP_EOL;
  305 + $route = $this->setRoute($v['title'], RouteMap::SOURCE_PRODUCT_KEYWORD, $v['id'], $v['project_id']);
  306 + $keywordModel->edit(['route'=>$route],['id'=>$v['id']]);
305 continue; 307 continue;
306 }else{ 308 }else{
307 - echo date('Y-m-d H:i:s') . 'route :'.$v['id'] . PHP_EOL;  
308 - $route = Translate::tran($v['title'], 'en');  
309 - if(!empty($route)){  
310 - echo date('Y-m-d H:i:s') . $route . PHP_EOL;  
311 - $route = $this->setRoute($route, RouteMap::SOURCE_PRODUCT_KEYWORD, $v['id'], $v['project_id']);  
312 - $keywordModel->edit(['route'=>$route],['id'=>$v['id']]);  
313 - } 309 +// echo date('Y-m-d H:i:s') . 'route :'.$v['id'] . PHP_EOL;
  310 +// $route = Translate::tran($v['title'], 'en');
  311 +// if(!empty($route)){
  312 +// echo date('Y-m-d H:i:s') . $route . PHP_EOL;
  313 +// $route = $this->setRoute($route, RouteMap::SOURCE_PRODUCT_KEYWORD, $v['id'], $v['project_id']);
  314 +// $keywordModel->edit(['route'=>$route],['id'=>$v['id']]);
  315 +// }
314 } 316 }
315 } 317 }
316 } 318 }
@@ -372,7 +374,7 @@ class UpdateRoute extends Command @@ -372,7 +374,7 @@ class UpdateRoute extends Command
372 } 374 }
373 } 375 }
374 $route = $sign.$suffix; 376 $route = $sign.$suffix;
375 - while(RouteMap::isExist($route, $source_id, $project_id)){ 377 + while(RouteMap::isExist($route, $source_id, $project_id,$source)){
376 $route = $sign .'-'.$i.$suffix; 378 $route = $sign .'-'.$i.$suffix;
377 $i++; 379 $i++;
378 } 380 }
@@ -10,6 +10,7 @@ @@ -10,6 +10,7 @@
10 namespace App\Console\Commands\LyhTest; 10 namespace App\Console\Commands\LyhTest;
11 11
12 use App\Console\Commands\Domain\DomainInfo; 12 use App\Console\Commands\Domain\DomainInfo;
  13 +use App\Helper\OaGlobalsoApi;
13 use App\Http\Logic\Aside\Project\ProjectLogic; 14 use App\Http\Logic\Aside\Project\ProjectLogic;
14 use App\Models\Ai\AiBlog; 15 use App\Models\Ai\AiBlog;
15 use App\Models\Ai\AiBlogAuthor; 16 use App\Models\Ai\AiBlogAuthor;
@@ -28,6 +29,7 @@ use App\Models\RouteMap\RouteMap; @@ -28,6 +29,7 @@ use App\Models\RouteMap\RouteMap;
28 use App\Models\Template\BTemplateMain; 29 use App\Models\Template\BTemplateMain;
29 use App\Models\Template\TemplateTypeMain; 30 use App\Models\Template\TemplateTypeMain;
30 use App\Models\Visit\Visit; 31 use App\Models\Visit\Visit;
  32 +use App\Models\WebSetting\TranslateBigProject;
31 use App\Models\WebSetting\WebLanguage; 33 use App\Models\WebSetting\WebLanguage;
32 use App\Models\WebSetting\WebSetting; 34 use App\Models\WebSetting\WebSetting;
33 use App\Models\Workchat\MessagePush; 35 use App\Models\Workchat\MessagePush;
@@ -56,19 +58,7 @@ class lyhDemo extends Command @@ -56,19 +58,7 @@ class lyhDemo extends Command
56 protected $description = '更新路由'; 58 protected $description = '更新路由';
57 59
58 public function handle(){ 60 public function handle(){
59 - $projectModel = new Project();  
60 - $lists = $projectModel->list(['delete_status' => 0,'project_type'=>0,'extend_type'=>0,'type'=>['in',[1,2,3,4,6]]], 'id', ['id']);  
61 - foreach ($lists as $item){  
62 -// echo date('Y-m-d H:i:s') . '开始--项目的id:'. $item['id'] . PHP_EOL;  
63 - ProjectServer::useProject($item['id']);  
64 - $webSettingModel = new WebSetting();  
65 - $info = $webSettingModel->read(['project_id'=>$item['id']]);  
66 - if($info === false){  
67 - $webSettingModel->addReturnId(['project_id'=>$item['id']]);  
68 - echo '当前数据为空:'.$item['id'].PHP_EOL;  
69 - }  
70 - DB::disconnect('custom_mysql');  
71 - } 61 +
72 } 62 }
73 63
74 public function _actionTemplateMain(){ 64 public function _actionTemplateMain(){
@@ -188,6 +188,7 @@ class Supervisory extends Command @@ -188,6 +188,7 @@ class Supervisory extends Command
188 ->where('gl_project.type', Project::TYPE_TWO) 188 ->where('gl_project.type', Project::TYPE_TWO)
189 ->where('gl_project.extend_type', 0) // 是否续费是由extend_type字段控制 189 ->where('gl_project.extend_type', 0) // 是否续费是由extend_type字段控制
190 ->where('gl_project.delete_status', Project::IS_DEL_FALSE) 190 ->where('gl_project.delete_status', Project::IS_DEL_FALSE)
  191 + ->where('gl_project.project_type', '!=', Project::PROJECT_TYPE_SEO)//排除白帽项目
191 ->where(function ($subQuery) { 192 ->where(function ($subQuery) {
192 $subQuery->orwhere('c.qa_status', OnlineCheck::STATUS_ONLINE_TRUE)->orwhere('gl_project.is_upgrade', Project::IS_UPGRADE_TRUE); 193 $subQuery->orwhere('c.qa_status', OnlineCheck::STATUS_ONLINE_TRUE)->orwhere('gl_project.is_upgrade', Project::IS_UPGRADE_TRUE);
193 }) 194 })
@@ -75,6 +75,7 @@ class CopyProject extends Command @@ -75,6 +75,7 @@ class CopyProject extends Command
75 }catch (\Exception $e){ 75 }catch (\Exception $e){
76 echo $e->getMessage().PHP_EOL; 76 echo $e->getMessage().PHP_EOL;
77 echo '复制数据库失败:'.$old_project_id . '<->'.$project_id; 77 echo '复制数据库失败:'.$old_project_id . '<->'.$project_id;
  78 + continue;
78 } 79 }
79 //修改项目状态 80 //修改项目状态
80 $projectModel->edit(['delete_status'=>0],['id'=>$project_id]); 81 $projectModel->edit(['delete_status'=>0],['id'=>$project_id]);
@@ -183,6 +183,7 @@ class CountAllProject extends Command @@ -183,6 +183,7 @@ class CountAllProject extends Command
183 } 183 }
184 } 184 }
185 $channel = Channel::getChannelText($v['channel']['user_id'] ?? 0); 185 $channel = Channel::getChannelText($v['channel']['user_id'] ?? 0);
  186 + $plan = Project::planMap();
186 $data[] = [ 187 $data[] = [
187 'project_id'=>$v['id'], 188 'project_id'=>$v['id'],
188 'version'=>1,//代表6.0 189 'version'=>1,//代表6.0
@@ -196,7 +197,7 @@ class CountAllProject extends Command @@ -196,7 +197,7 @@ class CountAllProject extends Command
196 'keywords_num'=>$v['key'], 197 'keywords_num'=>$v['key'],
197 'service_num'=>$v['day'], 198 'service_num'=>$v['day'],
198 'production_num'=>intval(abs((empty($v['uptime']) ? time() : strtotime($v['uptime'])) - strtotime($v['created_at'])) / 86400), 199 'production_num'=>intval(abs((empty($v['uptime']) ? time() : strtotime($v['uptime'])) - strtotime($v['created_at'])) / 86400),
199 - 'plan'=>Project::planMap()[$v['plan']], 200 + 'plan'=>$plan[$v['plan']] ?? '无版本信息',
200 'status'=>$type, 201 'status'=>$type,
201 'category'=>$category, 202 'category'=>$category,
202 'is_admin5' => 6, 203 'is_admin5' => 6,
@@ -51,11 +51,12 @@ class GeneratePage extends Command @@ -51,11 +51,12 @@ class GeneratePage extends Command
51 { 51 {
52 $noticeModel = new NoticeLog(); 52 $noticeModel = new NoticeLog();
53 while (true){ 53 while (true){
54 - $noticeInfo = $noticeModel->read(['status'=>0,'type'=>$noticeModel::GENERATE_PAGE,'start_at'=>['<=',date('Y-m-d H:i:s')]]); 54 + $task_id = $this->getTaskId();
55 if (empty($noticeInfo)) { 55 if (empty($noticeInfo)) {
56 sleep(10); 56 sleep(10);
57 continue; 57 continue;
58 } 58 }
  59 + $noticeInfo = $noticeModel->read(['id'=>$task_id]);
59 try { 60 try {
60 $this->output(' taskID: ' . $noticeInfo['id'] . ' start'); 61 $this->output(' taskID: ' . $noticeInfo['id'] . ' start');
61 $notice_data = json_decode($noticeInfo['data'],true); 62 $notice_data = json_decode($noticeInfo['data'],true);
@@ -80,6 +81,28 @@ class GeneratePage extends Command @@ -80,6 +81,28 @@ class GeneratePage extends Command
80 return true; 81 return true;
81 } 82 }
82 83
  84 + /**
  85 + * @remark :获取任务id
  86 + * @name :getTaskId
  87 + * @author :lyh
  88 + * @method :post
  89 + * @time :2025/6/19 10:02
  90 + */
  91 + public function getTaskId()
  92 + {
  93 + $task_id = Redis::rpop('generate_page_id');
  94 + if (empty($task_id)) {
  95 + $noticeModel = new NoticeLog();
  96 + $ids = $noticeModel->selectField(['status'=>0],'id');
  97 + if(!empty($ids)){
  98 + foreach ($ids as $id) {
  99 + Redis::lpush('generate_page_id', $id);
  100 + }
  101 + }
  102 + $task_id = Redis::rpop('generate_page_id');
  103 + }
  104 + return $task_id;
  105 + }
83 106
84 /** 107 /**
85 * 输出message 108 * 输出message
  1 +<?php
  2 +/**
  3 + * @remark :
  4 + * @name :InitKeywordComment.php
  5 + * @author :lyh
  6 + * @method :post
  7 + * @time :2025/6/3 15:38
  8 + */
  9 +
  10 +namespace App\Console\Commands\Project;
  11 +
  12 +use App\Helper\Common;
  13 +use App\Helper\Gpt;
  14 +use App\Models\Ai\AiCommand;
  15 +use App\Models\Com\NoticeLog;
  16 +use App\Models\Project\AggregateKeywordComment;
  17 +use App\Models\Project\Project;
  18 +use Illuminate\Console\Command;
  19 +
  20 +class InitKeywordComment extends Command
  21 +{
  22 + /**
  23 + * The name and signature of the console command.
  24 + *
  25 + * @var string
  26 + */
  27 + protected $signature = 'init_keyword_comment';
  28 +
  29 + /**
  30 + * The console command description.
  31 + *
  32 + * @var string
  33 + */
  34 + protected $description = '初始化关键字评论';
  35 +
  36 + public $number = 100;
  37 +
  38 + public function handle(){
  39 + return $this->_action(467);
  40 + while (true){
  41 + $list = NoticeLog::where('type', NoticeLog::TYPE_INIT_KEYWORD_COMMON)->where('status', NoticeLog::STATUS_PENDING)->get();
  42 + if(empty($list)){
  43 + sleep(200);
  44 + continue;
  45 + }
  46 + foreach ($list as $item){
  47 + echo date('Y-m-d H:i:s').'start:' . $item['id'] . PHP_EOL;
  48 + $project_id = $item['data']['project_id'];
  49 + echo date('Y-m-d H:i:s').'执行的项目id:' . $project_id . PHP_EOL;
  50 + try {
  51 + $this->_action($project_id);
  52 + $count = $keywordCommonModel->counts(['project_id'=>$project_id]);
  53 + if($count > 100){
  54 + $item->status = NoticeLog::STATUS_SUCCESS;
  55 + $item->save();
  56 + }
  57 + }catch (\Exception $e){
  58 + echo date('Y-m-d H:i:s').'错误信息:'.$e->getMessage().PHP_EOL;
  59 + continue;
  60 + }
  61 + echo date('Y-m-d H:i:s').'end:' . $item['id'] . PHP_EOL;
  62 + }
  63 + }
  64 + return true;
  65 + }
  66 +
  67 + /**
  68 + * @remark :执行的方法
  69 + * @name :_action
  70 + * @author :lyh
  71 + * @method :post
  72 + * @time :2025/6/3 15:42
  73 + */
  74 + public function _action($project_id){
  75 + $aiCommonModel = new AiCommand();
  76 + $info = $aiCommonModel->read(['key'=>'tag_comment']);
  77 + $text = Gpt::instance()->openai_chat_qqs($info['ai']);
  78 + $text = Common::deal_keywords($text);
  79 + preg_match_all('/\{[^{}]*\}/', $text, $matches);
  80 + if(!empty($text)){
  81 + $data = [];
  82 + foreach ($matches[0] as $item){
  83 + $item = str_replace("'", '"', $item);
  84 + // 解码成 PHP 关联数组
  85 + $item = json_decode($item, true);
  86 + if(!isset($item['name']) || !isset($item['comment'])){
  87 + continue;
  88 + }
  89 + $data[] = [
  90 + 'nickname'=>$item['name'],
  91 + 'text'=>$item['comment'],
  92 + 'project_id'=>$project_id,
  93 + 'type'=>1,
  94 + 'uid'=>0,
  95 + 'created_at'=>date('Y-m-d H:i:s'),
  96 + 'updated_at'=>date('Y-m-d H:i:s')
  97 + ];
  98 + }
  99 + $keywordCommonModel = new AggregateKeywordComment();
  100 + $keywordCommonModel->insertAll($data);
  101 + }
  102 + return true;
  103 + }
  104 +}
@@ -227,7 +227,8 @@ class SyncProject extends Command @@ -227,7 +227,8 @@ class SyncProject extends Command
227 'version'=>$version 227 'version'=>$version
228 ], 228 ],
229 'deploy_build' => [ 229 'deploy_build' => [
230 - 'login_mobile'=>$param['principal_mobile'] 230 + 'login_mobile'=>$param['principal_mobile'],
  231 + 'ads_price'=>$param['ads_price'] ?? 0
231 ], 232 ],
232 'deploy_optimize' => [ 233 'deploy_optimize' => [
233 // 'api_no' => 0 234 // 'api_no' => 0
  1 +<?php
  2 +
  3 +namespace App\Console\Commands\Tdk;
  4 +
  5 +use App\Exceptions\ValidateException;
  6 +use App\Helper\Arr;
  7 +use App\Helper\Gpt;
  8 +use App\Models\Ai\AiCommand;
  9 +use App\Models\Com\NoticeLog;
  10 +use App\Models\Domain\DomainInfo;
  11 +use App\Models\Product\Keyword;
  12 +use App\Models\Project\AggregateKeywordAffix;
  13 +use App\Models\Project\DeployBuild;
  14 +use App\Models\Project\DeployOptimize;
  15 +use App\Models\Project\ProjectKeywordAiTask;
  16 +use App\Services\ProjectServer;
  17 +use Illuminate\Console\Command;
  18 +use Illuminate\Support\Facades\DB;
  19 +use Illuminate\Support\Facades\Redis;
  20 +
  21 +/**
  22 + * 关键词聚合页AI生成内容
  23 + * Class InitProject
  24 + * @package App\Console\Commands
  25 + * @author zbj
  26 + * @date 2025/06/06
  27 + */
  28 +class KeywordPageAiContent extends Command
  29 +{
  30 + /**
  31 + * The name and signature of the console command.
  32 + *
  33 + * @var string
  34 + */
  35 + protected $signature = 'keyword_page_ai_content';
  36 +
  37 + /**
  38 + * The console command description.
  39 + *
  40 + * @var string
  41 + */
  42 + protected $description = '关键词聚合页AI生成内容';
  43 +
  44 + /**
  45 + * 统计图表类型 随机一个
  46 + * @var string[]
  47 + */
  48 + protected $chart_types = [
  49 + '柱状图',
  50 + '折线图',
  51 + ];
  52 +
  53 + /**
  54 + * @return bool
  55 + */
  56 + public function handle()
  57 + {
  58 + while (true) {
  59 + $task = ProjectKeywordAiTask::getPendingTask();
  60 + if (!$task) {
  61 + sleep(10);
  62 + continue;
  63 + }
  64 + $project_id = $task->project_id;
  65 +
  66 + echo getmypid() . ' ' . date('Y-m-d H:i:s') . ' start project_id: ' . $project_id . PHP_EOL;
  67 + try {
  68 + ProjectServer::useProject($project_id);
  69 +
  70 + $update_rows = $this->ai_content($task);
  71 +
  72 + DB::disconnect('custom_mysql');
  73 +
  74 + ProjectKeywordAiTask::finish($task->id, $update_rows);
  75 +
  76 + $update_rows && $this->sendNotify($project_id);
  77 +
  78 + } catch (ValidateException $e) {
  79 + echo getmypid() . ' ' . date('Y-m-d H:i:s') . 'line: ' . $e->getLine() . ' error: ' . $project_id . '->' . $e->getMessage() . PHP_EOL;
  80 + $task->status = ProjectKeywordAiTask::STATUS_FAIL;
  81 + $task->remark = mb_substr($e->getMessage(), 0, 250);
  82 + $task->save();
  83 + } catch (\Exception $e) {
  84 + echo getmypid() . ' ' . date('Y-m-d H:i:s') . 'line: ' . $e->getLine() . ' error: ' . $project_id . '->' . $e->getMessage() . PHP_EOL;
  85 + ProjectKeywordAiTask::retry($task->id, $e->getMessage());
  86 + }
  87 + echo getmypid() . ' ' . date('Y-m-d H:i:s') . ' end project_id: ' . $project_id . PHP_EOL;
  88 + }
  89 + }
  90 +
  91 +
  92 + /**
  93 + * @param ProjectKeywordAiTask $task
  94 + * @author zbj
  95 + * @date 2025/6/6
  96 + */
  97 + public function ai_content(ProjectKeywordAiTask $task)
  98 + {
  99 + //前后缀
  100 + $affix = AggregateKeywordAffix::where('project_id', $task->project_id)->first();
  101 + $prefix = empty($affix['prefix']) ? [] : explode("\r\n", $affix['prefix']);
  102 + $suffix = empty($affix['suffix']) ? [] : explode("\r\n", $affix['suffix']);
  103 + if (!$prefix || !$suffix) {
  104 + throw new ValidateException('扩展标题前后缀不存在');
  105 + }
  106 + //公司英文描述
  107 + $company_en_description = DeployOptimize::where('project_id', $task->project_id)->value('company_en_description');
  108 + if (!$company_en_description) {
  109 + throw new ValidateException('公司英文描述不存在');
  110 + }
  111 + //指令
  112 + $ai_commands = AiCommand::whereIn('key', ['tag_sale_content', 'tag_count_content', 'tag_data_table'])->where('project_id', 0)->select('key', 'scene', 'ai')->get()->toArray();
  113 + $project_ai_commands = AiCommand::whereIn('key', ['tag_sale_content', 'tag_count_content', 'tag_data_table'])->where('project_id', $task->project_id)->select('key', 'scene', 'ai')->get()->toArray();
  114 + $ai_commands = Arr::setValueToKey($ai_commands, 'key');
  115 + $project_ai_commands = Arr::setValueToKey($project_ai_commands, 'key');
  116 + foreach ($ai_commands as $k => $ai_command) {
  117 + if (!empty($project_ai_commands[$k])) {
  118 + $ai_commands[$k] = $project_ai_commands[$k];
  119 + }
  120 + }
  121 +
  122 + //没有标题、文案、图表的关键词
  123 + $keyword_ids = Keyword::whereNull('sale_title')->orWhereNull('sale_content')->orWhereNull('table_html')
  124 + ->orWhereNull('count_title')->orWhereNull('count_html')
  125 + ->pluck('id')
  126 + ->toArray();
  127 + $update_rows = 0;
  128 + foreach ($keyword_ids as $id) {
  129 + //缓存 在处理的项目数据 id
  130 + $cache_key = "keyword_page_ai_content_task_lock_{$task->project_id}_{$id}";
  131 + if (!Redis::setnx($cache_key, 1)) {
  132 + continue;
  133 + }
  134 + Redis::expire($cache_key, 120);
  135 +
  136 + $keyword = Keyword::where('id', $id)->select(['id', 'title', 'sale_title', 'sale_content', 'table_html', 'count_title', 'count_html'])->first();
  137 +
  138 + echo getmypid() . ' ' . date('Y-m-d H:i:s') . ' id:' . $keyword['id'] . ' project_id:' . $task->project_id . PHP_EOL;
  139 +
  140 + $update = false;
  141 + if (empty($keyword['sale_title'])) {
  142 + $sale_title = $this->new_title($keyword['title'], $prefix, $suffix);
  143 + $keyword->sale_title = $sale_title;
  144 + $update = true;
  145 + }
  146 + if (empty($keyword['sale_content']) && $keyword->sale_title) {
  147 + $content = $this->ai_send($keyword->sale_title, $company_en_description, $ai_commands['tag_sale_content']['ai']);
  148 + if ($content) {
  149 + $keyword->sale_content = $content;
  150 + $update = true;
  151 + }
  152 + }
  153 + if (empty($keyword['table_html']) && $keyword->sale_title) {
  154 + $content = $this->ai_send($keyword->sale_title, $company_en_description, $ai_commands['tag_data_table']['ai']);
  155 + if ($content) {
  156 + $keyword->table_html = str_replace(['```html', '``html', '```'], '', $content);
  157 + $update = true;
  158 + }
  159 + }
  160 + if (empty($keyword['count_title'])) {
  161 + $count_title = $this->new_title($keyword['title'], $prefix, $suffix);
  162 + $count_title && $keyword->count_title = $count_title;
  163 + $update = true;
  164 + }
  165 + if (empty($keyword['count_html']) && $keyword->sale_title) {
  166 + $content = $this->ai_send($keyword->sale_title, $company_en_description, $ai_commands['tag_count_content']['ai']);
  167 + if ($content) {
  168 + $keyword->count_html = $this->fixChart(str_replace(['```html', '``html', '```'], '', $content));
  169 + $update = true;
  170 + }
  171 + }
  172 + if ($update) {
  173 + $keyword->save();
  174 + $update_rows++;
  175 + }
  176 + }
  177 + return $update_rows;
  178 + }
  179 +
  180 + public function new_title($title, $prefix, $suffix)
  181 + {
  182 + //打乱顺序
  183 + shuffle($prefix);
  184 + shuffle($suffix);
  185 + //标题(title):{聚合页扩展标题前缀} keywords {聚合页扩展标题后缀} {聚合页扩展标题后缀}
  186 +
  187 + return sprintf('%s %s %s %s', $prefix[0], $title, $suffix[0], $suffix[1]);
  188 + }
  189 +
  190 +
  191 + public function ai_send($title, $company_description, $prompt)
  192 + {
  193 + if (strpos($prompt, '{title}') !== false) {
  194 + $prompt = str_replace('{title}', $title, $prompt);
  195 + }
  196 + if (strpos($prompt, '{company introduction}') !== false) {
  197 + $prompt = str_replace('{company introduction}', $company_description, $prompt);
  198 + }
  199 + if (strpos($prompt, '{chart_type}') !== false) {
  200 + shuffle($this->chart_types);
  201 + $prompt = str_replace('{chart_type}', $this->chart_types[0], $prompt);
  202 + }
  203 +
  204 + $text = Gpt::instance()->openai_chat_qqs($prompt);
  205 + if (!$text) {
  206 + echo getmypid() . ' ' . '生成失败' . PHP_EOL;
  207 + }
  208 + return $text;
  209 + }
  210 +
  211 + function fixChart($html)
  212 + {
  213 + $html = '<body>' . $html . '</body>';
  214 + $dom = new \DOMDocument();
  215 + @$dom->loadHTML(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'));
  216 + $canvas_count = $dom->getElementsByTagName('canvas')->count();
  217 + //没有canvas
  218 + if (!$canvas_count) {
  219 + $div = $dom->getElementsByTagName('div');
  220 + foreach ($div as $element) {
  221 + if ($element->hasAttribute('id')) {
  222 + $canvas = $dom->createElement('canvas');
  223 + $canvas->setAttribute('id', $element->getAttribute('id'));
  224 + $element->removeAttribute('id');
  225 + $element->appendChild($canvas);
  226 + break;
  227 + }
  228 + }
  229 + }
  230 + $body = $dom->getElementsByTagName('body')->item(0);
  231 + $modifiedHtml = '';
  232 + foreach ($body->childNodes as $child) {
  233 + $modifiedHtml .= $dom->saveHTML($child);
  234 + }
  235 + return $modifiedHtml;
  236 + }
  237 +
  238 + public function sendNotify($project_id)
  239 + {
  240 + //获取当前项目的域名
  241 + $domainModel = new DomainInfo();
  242 + $domainInfo = $domainModel->read(['project_id' => $project_id]);
  243 + if ($domainInfo === false) {
  244 + //获取测试域名
  245 + $deployBuildModel = new DeployBuild();
  246 + $buildInfo = $deployBuildModel->read(['project_id' => $project_id]);
  247 + $domain = $buildInfo['test_domain'];
  248 + } else {
  249 + $domain = 'https://' . $domainInfo['domain'] . '/';
  250 + }
  251 + $url = $domain . 'api/update_page/';
  252 + $param = [
  253 + 'project_id' => $project_id,
  254 + 'type' => 1,
  255 + 'route' => 2,
  256 + 'url' => [],
  257 + 'language' => [],
  258 + ];
  259 + NoticeLog::createLog(NoticeLog::GENERATE_PAGE, json_encode(['c_url' => $url, 'c_params' => $param]), date('Y-m-d H:i:s', time() + 300));
  260 + echo getmypid() . ' ' . '更新中请稍后, 更新完成将会发送站内信通知更新结果!' . PHP_EOL;
  261 + }
  262 +}
@@ -3,6 +3,7 @@ @@ -3,6 +3,7 @@
3 namespace App\Console\Commands\Tdk; 3 namespace App\Console\Commands\Tdk;
4 4
5 use App\Models\Project\Project; 5 use App\Models\Project\Project;
  6 +use App\Models\Project\ProjectKeywordAiTask;
6 use App\Models\Project\ProjectUpdateTdk; 7 use App\Models\Project\ProjectUpdateTdk;
7 use Illuminate\Console\Command; 8 use Illuminate\Console\Command;
8 9
@@ -42,6 +43,16 @@ class UpdateSeoTdkCrontab extends Command @@ -42,6 +43,16 @@ class UpdateSeoTdkCrontab extends Command
42 dump($e->getMessage()); 43 dump($e->getMessage());
43 } 44 }
44 } 45 }
  46 +
  47 + $project_ids = Project::where('type', Project::TYPE_TWO)->where('tag_page_version', '>' ,1)->where('uptime', '<=', date('Y-m-d H:i:s'))->pluck('id')->toArray();
  48 + foreach ($project_ids as $project_id){
  49 + try {
  50 + ProjectKeywordAiTask::add_task($project_id);
  51 + }catch (\Exception $e){
  52 + dump($e->getMessage());
  53 + }
  54 + }
  55 +
45 } 56 }
46 57
47 } 58 }
@@ -5,6 +5,7 @@ namespace App\Console\Commands\Test; @@ -5,6 +5,7 @@ namespace App\Console\Commands\Test;
5 use App\Helper\Arr; 5 use App\Helper\Arr;
6 use App\Http\Logic\Bside\Product\CategoryLogic; 6 use App\Http\Logic\Bside\Product\CategoryLogic;
7 use App\Models\Com\Notify; 7 use App\Models\Com\Notify;
  8 +use App\Models\CustomModule\CustomModuleContent;
8 use App\Models\Devops\ServerConfig; 9 use App\Models\Devops\ServerConfig;
9 use App\Models\Devops\ServersIp; 10 use App\Models\Devops\ServersIp;
10 use App\Models\Domain\DomainCreateTask; 11 use App\Models\Domain\DomainCreateTask;
@@ -16,6 +17,7 @@ use App\Models\Product\Product; @@ -16,6 +17,7 @@ use App\Models\Product\Product;
16 use App\Models\Project\DeployBuild; 17 use App\Models\Project\DeployBuild;
17 use App\Models\Project\DeployOptimize; 18 use App\Models\Project\DeployOptimize;
18 use App\Models\Project\Project; 19 use App\Models\Project\Project;
  20 +use App\Models\RouteMap\RouteMap;
19 use App\Models\Template\BCustomTemplate; 21 use App\Models\Template\BCustomTemplate;
20 use App\Models\WebSetting\WebLanguage; 22 use App\Models\WebSetting\WebLanguage;
21 use App\Services\BatchExportService; 23 use App\Services\BatchExportService;
@@ -41,7 +43,197 @@ class Temp extends Command @@ -41,7 +43,197 @@ class Temp extends Command
41 43
42 public function handle() 44 public function handle()
43 { 45 {
  46 + $this->check_no_cname_projects();
  47 + }
  48 +
  49 + /**
  50 + * 3531项目导入扩展模块内容
  51 + * @return bool
  52 + * @author Akun
  53 + * @date 2025/06/05 10:47
  54 + */
  55 + public function specialImport()
  56 + {
  57 + $file_url = 'https://ecdn6.globalso.com/upload/p/3531/file/2025-06/news.csv';
  58 + $domain = 'www.hybio.com.cn';
  59 + $project_id = 3531;
  60 + $is_gbk = 0;
  61 + $file_code_type = $this->get_code_type($file_url);
  62 + if ($file_code_type === false) {
  63 + echo 'date:' . date('Y-m-d H:i:s') . ', import fail, error: 文件编码格式错误' . PHP_EOL;
  64 + return true;
  65 + } elseif ($file_code_type === 'GBK') {
  66 + $is_gbk = 1;
  67 + setlocale(LC_ALL, 'zh_CN');
  68 + }
  69 +
  70 + //读取csv文件
  71 + $line_of_text = [];
  72 + try {
  73 + $opts = [
  74 + 'http' => [
  75 + 'method' => 'GET',
  76 + 'header' => 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.246'
  77 + ],
  78 + 'ssl' => [
  79 + 'verify_peer' => false,
  80 + 'verify_peer_name' => false
  81 + ]
  82 + ];
  83 + $file_handle = fopen($file_url, 'r', null, stream_context_create($opts));
  84 + while (!feof($file_handle)) {
  85 + $line_of_text[] = fgetcsv($file_handle, 0, ',');
  86 + }
  87 + fclose($file_handle);
  88 + } catch (\Exception $e) {
  89 + $this->output('import fail, error: ' . $e->getMessage());
  90 + return true;
  91 + }
  92 +
  93 + $total_count = 0; //总条数
  94 + $success_count = 0; //成功导入条数
  95 + $repeat_count = 0; //过滤已存在条数
  96 + $fail_count = 0;//导入失败条数
  97 + $fail_line = [];//失败行数
  98 + if (count($line_of_text) > 1) {
  99 +
  100 + //设置数据库
  101 + $project = ProjectServer::useProject($project_id);
  102 + if ($project) {
  103 + foreach ($line_of_text as $k => $v) {
  104 + if ($k > 0 && isset($v[0]) && $v[0]) {
  105 +
  106 + if ($is_gbk) {
  107 + foreach ($v as $kk => $vv) {
  108 + $v[$kk] = mb_convert_encoding($vv, 'utf-8', 'gbk');
  109 + }
  110 + }
  111 +
  112 + $v[0] = $this->special2str($v[0]);
44 113
  114 + $total_count += 1;
  115 + try {
  116 + if ($this->importModule($project_id, $domain, $v)) {
  117 + $success_count += 1;
  118 + } else {
  119 + $repeat_count += 1;
  120 + }
  121 + } catch (\Exception $e) {
  122 + $fail_count += 1;
  123 + $fail_line[] = $k + 1;
  124 + $this->output('title: ' . $v[0] . ', import fail, error: ' . $e->getMessage());
  125 + }
  126 + }
  127 + }
  128 + }
  129 + //关闭数据库
  130 + DB::disconnect('custom_mysql');
  131 + }
  132 +
  133 + $this->output('import end, total count: ' . $total_count . ', success count: ' . $success_count . ', repeat_count count: ' . $repeat_count . ', fail_count count: ' . $fail_count);
  134 +
  135 + return true;
  136 + }
  137 +
  138 + protected function importModule($project_id, $domain, $data)
  139 + {
  140 + $model = new CustomModuleContent();
  141 + $module = $model->read(['name' => $data[0]]);
  142 + if (!$module) {
  143 +
  144 + $content = '';
  145 + if ($data[4] ?? '') {
  146 + //处理内容中的图片
  147 + preg_match_all('/<img\s+[^>]*?src\s*=\s*(\'|\")(.*?)\\1[^>]*?\/?\s*>/i', $data[4], $result);
  148 + if ($result[2] ?? []) {
  149 + foreach ($result[2] as $img) {
  150 + $new_img = check_remote_url_down($img, $project_id, $domain, 1);
  151 + $new_img && $data[4] = str_replace($img, $new_img, $data[4]);
  152 + }
  153 + }
  154 +
  155 + //处理内容中的视频
  156 + preg_match_all('/<source\s+[^>]*?src\s*=\s*(\'|\")(.*?)\\1[^>]*?\/?\s*>/i', $data[4], $result_video);
  157 + if ($result_video[2] ?? []) {
  158 + foreach ($result_video[2] as $video) {
  159 + $new_video = check_remote_url_down($video, $project_id, $domain, 1);
  160 + $new_video && $data[4] = str_replace($video, $new_video, $data[4]);
  161 + }
  162 + }
  163 +
  164 + $content = $data[4];
  165 + }
  166 +
  167 + $seo_title = '';
  168 + if ($data[6] ?? '') {
  169 + $seo_title = substr(strip_tags($data[6]), 0, 70);
  170 + }
  171 +
  172 + $seo_keywords = '';
  173 + if ($data[7] ?? '') {
  174 + $seo_keywords = substr(strip_tags(str_replace('^v6sp$', ',', $data[7])), 0, 255);
  175 + }
  176 +
  177 + $seo_description = '';
  178 + if ($data[8] ?? '') {
  179 + $seo_description = substr(strip_tags($data[8]), 0, 200);
  180 + }
  181 +
  182 + $release_at = date('Y-m-d H:i:s');
  183 + if ($data[9] ?? '') {
  184 + $release_at = date('Y-m-d H:i:s', strtotime($data[9]));
  185 + }
  186 +
  187 +
  188 + $id = $model->addReturnId(
  189 + [
  190 + 'name' => $data[0],
  191 + 'category_id' => ',1,',
  192 + 'module_id' => 2,
  193 + 'content' => $content,
  194 + 'seo_title' => $seo_title,
  195 + 'seo_keywords' => $seo_keywords,
  196 + 'seo_description' => $seo_description,
  197 + 'project_id' => $project_id,
  198 + 'operator_id' => 8143,
  199 + 'status' => 0,
  200 + 'route' => '',
  201 + 'release_at' => $release_at
  202 + ]
  203 + );
  204 +
  205 + $route = RouteMap::setRoute($data[0], RouteMap::SOURCE_MODULE, $id, $project_id);
  206 +
  207 + $model->edit(['route' => $route], ['id' => $id]);
  208 +
  209 + return true;
  210 + }
  211 +
  212 + return false;
  213 + }
  214 +
  215 + //特殊字符转换
  216 + protected function special2str($str)
  217 + {
  218 + if (strpos($str, ';') === false) {
  219 + return $str;
  220 + }
  221 +
  222 + $list = [
  223 + '&lt;' => '<',
  224 + '&gt;' => '>',
  225 + '&amp;' => '&',
  226 + '&acute;' => "'",
  227 + '&quot;' => '"',
  228 + '&nbsp;' => ' ',
  229 + '&#x27;' => "'"
  230 + ];
  231 +
  232 + foreach ($list as $k => $v) {
  233 + $str = str_replace($k, $v, $str);
  234 + }
  235 +
  236 + return $str;
45 } 237 }
46 238
47 /** 239 /**
@@ -820,8 +1012,8 @@ class Temp extends Command @@ -820,8 +1012,8 @@ class Temp extends Command
820 */ 1012 */
821 public function check_no_cname_projects() 1013 public function check_no_cname_projects()
822 { 1014 {
823 - $server_id = 1;  
824 - $server_name = '硅谷云服务器'; 1015 + $server_id = 20;
  1016 + $server_name = '建站服务器01';
825 1017
826 $server_ip_model = new ServersIp(); 1018 $server_ip_model = new ServersIp();
827 1019
@@ -839,7 +1031,13 @@ class Temp extends Command @@ -839,7 +1031,13 @@ class Temp extends Command
839 } 1031 }
840 $domain = $domain_info['domain']; 1032 $domain = $domain_info['domain'];
841 1033
842 - $check = dns_get_record($domain, DNS_A); 1034 + $check = [];
  1035 + try {
  1036 + $check = dns_get_record($domain, DNS_A);
  1037 + } catch (\Exception $e) {
  1038 + $this->output($domain . ' | ' . $e->getMessage());
  1039 + }
  1040 +
843 $ip = $check[0]['ip'] ?? ''; 1041 $ip = $check[0]['ip'] ?? '';
844 $host = $check[0]['host'] ?? ''; 1042 $host = $check[0]['host'] ?? '';
845 if (strpos($host, 'globalso.com') === false) { 1043 if (strpos($host, 'globalso.com') === false) {
@@ -35,7 +35,6 @@ class UpdateKeyword extends Command @@ -35,7 +35,6 @@ class UpdateKeyword extends Command
35 35
36 36
37 public function handle(){ 37 public function handle(){
38 - dd(1111);  
39 while (true){ 38 while (true){
40 $keywordPageModel = new KeywordPage(); 39 $keywordPageModel = new KeywordPage();
41 $lists = $keywordPageModel->list(['status'=>0]); 40 $lists = $keywordPageModel->list(['status'=>0]);
  1 +<?php
  2 +
  3 +namespace App\Exceptions;
  4 +
  5 +use Exception;
  6 +
  7 +/**
  8 + * @notes: 验证
  9 + * Class ValidateException
  10 + * @package App\Exceptions
  11 + */
  12 +class ValidateException extends Exception
  13 +{
  14 +
  15 +}
@@ -61,7 +61,7 @@ if (!function_exists('http_post')) { @@ -61,7 +61,7 @@ if (!function_exists('http_post')) {
61 * @param type $url 61 * @param type $url
62 * @param type $post_data 62 * @param type $post_data
63 */ 63 */
64 - function http_post($url, $post_data, $header = [],$is_json = true) 64 + function http_post($url, $post_data, $header = [],$is_json = true,$timeout = 60)
65 { 65 {
66 if (empty($header)) { 66 if (empty($header)) {
67 $header = array( 67 $header = array(
@@ -73,6 +73,7 @@ if (!function_exists('http_post')) { @@ -73,6 +73,7 @@ if (!function_exists('http_post')) {
73 curl_setopt($ch, CURLOPT_URL, $url); 73 curl_setopt($ch, CURLOPT_URL, $url);
74 curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); 74 curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
75 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 75 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  76 + curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
76 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); 77 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
77 curl_setopt($ch, CURLOPT_HTTPHEADER, $header); 78 curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
78 curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)'); 79 curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)');
@@ -1189,7 +1190,7 @@ function getDeployOptimize($project_id){ @@ -1189,7 +1190,7 @@ function getDeployOptimize($project_id){
1189 $info = Cache::get($cache_key); 1190 $info = Cache::get($cache_key);
1190 if(!$info){ 1191 if(!$info){
1191 $projectOptimizeModel = new DeployOptimize(); 1192 $projectOptimizeModel = new DeployOptimize();
1192 - $info = $projectOptimizeModel->read(['project_id' => $project_id], ['id', 'company_en_name', 'company_en_description', 'keyword_prefix', 'keyword_suffix']); 1193 + $info = $projectOptimizeModel->read(['project_id' => $project_id], ['id', 'company_en_name', 'company_en_description', 'keyword_prefix', 'keyword_suffix', 'special']);
1193 $projectKeywordModel = new ProjectKeyword(); 1194 $projectKeywordModel = new ProjectKeyword();
1194 $keywordInfo = $projectKeywordModel->read(['project_id'=>$project_id]); 1195 $keywordInfo = $projectKeywordModel->read(['project_id'=>$project_id]);
1195 $info['main_keyword'] = ''; 1196 $info['main_keyword'] = '';
@@ -52,6 +52,7 @@ class PrivateController extends BaseController @@ -52,6 +52,7 @@ class PrivateController extends BaseController
52 ->leftJoin('gl_project_online_check as c', 'gl_project.id', '=', 'c.project_id') 52 ->leftJoin('gl_project_online_check as c', 'gl_project.id', '=', 'c.project_id')
53 ->leftJoin('gl_domain_info as d', 'gl_project.id', '=', 'd.project_id') 53 ->leftJoin('gl_domain_info as d', 'gl_project.id', '=', 'd.project_id')
54 ->where('gl_project.type', Project::TYPE_TWO) 54 ->where('gl_project.type', Project::TYPE_TWO)
  55 + ->where('gl_project.project_type',Project::TYPE_ZERO)
55 ->where('gl_project.extend_type', 0) // 是否续费是由extend_type字段控制 56 ->where('gl_project.extend_type', 0) // 是否续费是由extend_type字段控制
56 ->where('gl_project.delete_status', Project::IS_DEL_FALSE) 57 ->where('gl_project.delete_status', Project::IS_DEL_FALSE)
57 ->where(function ($subQuery) { 58 ->where(function ($subQuery) {
@@ -142,7 +142,7 @@ class IndexController extends BaseController @@ -142,7 +142,7 @@ class IndexController extends BaseController
142 Cache::add($token,$info,12 * 3600); 142 Cache::add($token,$info,12 * 3600);
143 $languageModel = new WebLanguage(); 143 $languageModel = new WebLanguage();
144 $languageInfo = $languageModel->read(['id'=>$info['main_lang_id']],['short','english','chinese']); 144 $languageInfo = $languageModel->read(['id'=>$info['main_lang_id']],['short','english','chinese']);
145 - $data = ['token'=>$token,'main_lang_id'=>$info['main_lang_id'],'language_info'=>$languageInfo]; 145 + $data = ['token'=>$token,'main_lang_id'=>$info['main_lang_id'],'language_info'=>$languageInfo,'project_seo_type'=>$info['project_seo_type']];
146 $this->response('success',Code::SUCCESS,$data); 146 $this->response('success',Code::SUCCESS,$data);
147 } 147 }
148 148
@@ -51,10 +51,10 @@ class UpdateController extends BaseController @@ -51,10 +51,10 @@ class UpdateController extends BaseController
51 if (empty($info['company_en_description'])) { 51 if (empty($info['company_en_description'])) {
52 $this->fail('公司英文描述未设置'); 52 $this->fail('公司英文描述未设置');
53 } 53 }
54 - if (empty($info['keyword_prefix'])) { 54 + if (empty($info['keyword_prefix']) && !in_array(8, explode(',', $info['special']))) {
55 $this->fail('前缀关键词未设置'); 55 $this->fail('前缀关键词未设置');
56 } 56 }
57 - if (empty($info['keyword_suffix'])) { 57 + if (empty($info['keyword_suffix']) && !in_array(8, explode(',', $info['special']))) {
58 $this->fail('后缀关键词未设置'); 58 $this->fail('后缀关键词未设置');
59 } 59 }
60 try { 60 try {
@@ -31,6 +31,19 @@ class HrController extends BaseController @@ -31,6 +31,19 @@ class HrController extends BaseController
31 } 31 }
32 32
33 /** 33 /**
  34 + * @remark :获取列表数据
  35 + * @name :getManagerList
  36 + * @author :lyh
  37 + * @method :post
  38 + * @time :2025/6/7 9:22
  39 + */
  40 + public function getManagerList(){
  41 + $manageHrModel = new ManageHr();
  42 + $lists = $manageHrModel->lists($this->map,$this->page,$this->row);
  43 + $this->response('success', Code::SUCCESS, $lists);
  44 + }
  45 +
  46 + /**
34 * @remark :获取详情 47 * @remark :获取详情
35 * @name :info 48 * @name :info
36 * @author :lyh 49 * @author :lyh
@@ -234,6 +234,7 @@ class OptimizeController extends BaseController @@ -234,6 +234,7 @@ class OptimizeController extends BaseController
234 'gl_project_deploy_optimize.first_compliance_time AS first_compliance_time', 234 'gl_project_deploy_optimize.first_compliance_time AS first_compliance_time',
235 'gl_domain_info.amp_status AS amp_status', 235 'gl_domain_info.amp_status AS amp_status',
236 'gl_domain_info.domain AS domain', 236 'gl_domain_info.domain AS domain',
  237 + 'gl_domain_info.ai_domain AS ai_domain',
237 ]; 238 ];
238 return $select; 239 return $select;
239 } 240 }
@@ -262,6 +263,9 @@ class OptimizeController extends BaseController @@ -262,6 +263,9 @@ class OptimizeController extends BaseController
262 if(isset($this->map['ai_video']) && !empty($this->map['ai_video'])){ 263 if(isset($this->map['ai_video']) && !empty($this->map['ai_video'])){
263 $query = $query->where('gl_project_deploy_optimize.ai_video',$this->map['ai_video']); 264 $query = $query->where('gl_project_deploy_optimize.ai_video',$this->map['ai_video']);
264 } 265 }
  266 + if(isset($this->map['ai_domain']) && !empty($this->map['ai_domain'])){
  267 + $query = $query->whereNotNull('gl_domain_info.ai_domain');
  268 + }
265 if(isset($this->map['amp_status'])){ 269 if(isset($this->map['amp_status'])){
266 $query = $query->where('gl_domain_info.amp_status',$this->map['amp_status']); 270 $query = $query->where('gl_domain_info.amp_status',$this->map['amp_status']);
267 } 271 }
@@ -15,6 +15,7 @@ use App\Models\Channel\Channel; @@ -15,6 +15,7 @@ use App\Models\Channel\Channel;
15 use App\Models\Channel\User; 15 use App\Models\Channel\User;
16 use App\Models\Channel\Zone; 16 use App\Models\Channel\Zone;
17 use App\Models\Com\City; 17 use App\Models\Com\City;
  18 +use App\Models\Com\NoticeLog;
18 use App\Models\Com\UpdateLog; 19 use App\Models\Com\UpdateLog;
19 use App\Models\Devops\ServerConfig; 20 use App\Models\Devops\ServerConfig;
20 use App\Models\Devops\ServersIp; 21 use App\Models\Devops\ServersIp;
@@ -60,6 +61,7 @@ class ProjectController extends BaseController @@ -60,6 +61,7 @@ class ProjectController extends BaseController
60 ->leftJoin('gl_project_deploy_optimize', 'gl_project.id', '=', 'gl_project_deploy_optimize.project_id') 61 ->leftJoin('gl_project_deploy_optimize', 'gl_project.id', '=', 'gl_project_deploy_optimize.project_id')
61 ->leftJoin('gl_project_online_check', 'gl_project.id', '=', 'gl_project_online_check.project_id') 62 ->leftJoin('gl_project_online_check', 'gl_project.id', '=', 'gl_project_online_check.project_id')
62 ->leftJoin('gl_web_setting_template', 'gl_project.id', '=', 'gl_web_setting_template.project_id') 63 ->leftJoin('gl_web_setting_template', 'gl_project.id', '=', 'gl_web_setting_template.project_id')
  64 + ->leftJoin('gl_project_association', 'gl_project.id', '=', 'gl_project_association.project_id')
63 ->where('gl_project.delete_status',Project::TYPE_ZERO); 65 ->where('gl_project.delete_status',Project::TYPE_ZERO);
64 $query = $this->searchParam($query); 66 $query = $this->searchParam($query);
65 $query = $this->orderByList($query); 67 $query = $this->orderByList($query);
@@ -121,6 +123,7 @@ class ProjectController extends BaseController @@ -121,6 +123,7 @@ class ProjectController extends BaseController
121 'gl_project_deploy_optimize.design_mid AS design_mid', 123 'gl_project_deploy_optimize.design_mid AS design_mid',
122 'gl_project_deploy_optimize.api_no AS api_no', 124 'gl_project_deploy_optimize.api_no AS api_no',
123 'gl_web_setting_template.template_id AS template_id', 125 'gl_web_setting_template.template_id AS template_id',
  126 + 'gl_project_association.friend_id as friend_id',
124 ]; 127 ];
125 return $select; 128 return $select;
126 } 129 }
@@ -171,7 +174,7 @@ class ProjectController extends BaseController @@ -171,7 +174,7 @@ class ProjectController extends BaseController
171 */ 174 */
172 public function searchType(&$query){ 175 public function searchType(&$query){
173 if(isset($this->map['type'])){ 176 if(isset($this->map['type'])){
174 - $query->where('gl_project.extend_type', '!=' ,5); 177 + $query->where('gl_project.extend_type', '!=' ,5)->where('gl_project.extend_type', '!=' ,8);
175 if (in_array($this->map['type'], [Project::TYPE_ZERO, Project::TYPE_ONE, Project::TYPE_TWO, Project::TYPE_THREE])){ 178 if (in_array($this->map['type'], [Project::TYPE_ZERO, Project::TYPE_ONE, Project::TYPE_TWO, Project::TYPE_THREE])){
176 $query->where('gl_project.type', $this->map['type']); 179 $query->where('gl_project.type', $this->map['type']);
177 } elseif ($this->map['type'] == 8){ 180 } elseif ($this->map['type'] == 8){
@@ -294,6 +297,16 @@ class ProjectController extends BaseController @@ -294,6 +297,16 @@ class ProjectController extends BaseController
294 if(isset($this->map['plan'])){ 297 if(isset($this->map['plan'])){
295 $query = $query->where('gl_project_deploy_build.plan',$this->map['plan']); 298 $query = $query->where('gl_project_deploy_build.plan',$this->map['plan']);
296 } 299 }
  300 + if(isset($this->map['friend_id'])){
  301 + if($this->map['friend_id'] == 1){
  302 + $query = $query->where('gl_project_association.friend_id', '!=', 0);
  303 + }else{
  304 + $query = $query->where(function ($subQuery) {
  305 + $subQuery->where('gl_project_association.friend_id', 0)
  306 + ->orWhereNull('gl_project_association.friend_id');
  307 + });
  308 + }
  309 + }
297 if(isset($this->map['seo_plan'])){ 310 if(isset($this->map['seo_plan'])){
298 $query = $query->where('gl_project_deploy_build.seo_plan',$this->map['seo_plan']); 311 $query = $query->where('gl_project_deploy_build.seo_plan',$this->map['seo_plan']);
299 } 312 }
@@ -960,14 +973,10 @@ class ProjectController extends BaseController @@ -960,14 +973,10 @@ class ProjectController extends BaseController
960 'id'=>'required', 973 'id'=>'required',
961 'aicc'=>'required', 974 'aicc'=>'required',
962 'hagro'=>'required', 975 'hagro'=>'required',
963 -// 'exclusive_aicc_day'=>'required',  
964 -// 'exclusive_hagro_day'=>'required',  
965 ],[ 976 ],[
966 'id.required' => 'id不能为空', 977 'id.required' => 'id不能为空',
967 'aicc.required' => 'aicc是否开启不能为空', 978 'aicc.required' => 'aicc是否开启不能为空',
968 'hagro.required' => 'hagro是否开启不能为空', 979 'hagro.required' => 'hagro是否开启不能为空',
969 -// 'exclusive_aicc_day.required' => '服务天数不能为空',  
970 -// 'exclusive_hagro_day.required' => '服务天数不能为空',  
971 ]); 980 ]);
972 $logic->saveOtherProject(); 981 $logic->saveOtherProject();
973 $this->response('success'); 982 $this->response('success');
@@ -1136,7 +1145,7 @@ class ProjectController extends BaseController @@ -1136,7 +1145,7 @@ class ProjectController extends BaseController
1136 1145
1137 //获取项目数据 1146 //获取项目数据
1138 $projectModel = new Project(); 1147 $projectModel = new Project();
1139 - $projectInfo = $projectModel->read(['id'=>$this->param['id']],['project_type','serve_id','site_status']); 1148 + $projectInfo = $projectModel->read(['id'=>$this->param['id']],['project_type','serve_id','site_status','site_token']);
1140 if(!$projectInfo){ 1149 if(!$projectInfo){
1141 $this->fail('获取项目数据失败'); 1150 $this->fail('获取项目数据失败');
1142 } 1151 }
@@ -1144,61 +1153,75 @@ class ProjectController extends BaseController @@ -1144,61 +1153,75 @@ class ProjectController extends BaseController
1144 $this->response('success'); 1153 $this->response('success');
1145 } 1154 }
1146 1155
1147 - //获取域名数据  
1148 - $domainModel = new DomainInfoModel();  
1149 - $domainInfo = $domainModel->read(['project_id'=>$this->param['id']],['id','domain','amp_status']);  
1150 - if(!$domainInfo){  
1151 - $this->fail('获取域名数据失败');  
1152 - }  
1153 -  
1154 - if($this->param['site_status'] == 1){  
1155 - //关闭站点:通知C端  
1156 - $re = curl_get('https://'.$domainInfo['domain'].'/api/stop_or_start_website');  
1157 - if(isset($re['status']) && $re['status'] !== 200){  
1158 - $this->fail($re['message']); 1156 + if($projectInfo['serve_id'] == 8){
  1157 + //自建站项目
  1158 + if($this->param['site_status'] == 1){
  1159 + //关闭站点
  1160 + $site_token = $projectInfo['site_token'] ? $projectInfo['site_token'].'_expired' : '';
  1161 + }else{
  1162 + //开启站点
  1163 + $site_token = str_replace('_expired','',$projectInfo['site_token']);
1159 } 1164 }
  1165 +
  1166 + $projectModel->edit(['site_status'=>$this->param['site_status'],'site_token'=>$site_token],['id'=>$this->param['id']]);
1160 }else{ 1167 }else{
1161 - //开启站点:创建建站任务  
1162 - $serverIpModel = new ServersIp();  
1163 - $serversIpInfo = $serverIpModel->read(['id' => $projectInfo['serve_id']], ['servers_id']);  
1164 - if(!$serversIpInfo){  
1165 - $this->fail('获取项目所属服务器失败'); 1168 + //普通项目
  1169 + //获取域名数据
  1170 + $domainModel = new DomainInfoModel();
  1171 + $domainInfo = $domainModel->read(['project_id'=>$this->param['id']],['id','domain','amp_status']);
  1172 + if(!$domainInfo){
  1173 + $this->fail('获取域名数据失败');
1166 } 1174 }
1167 1175
1168 - if ($projectInfo['project_type'] == Project::PROJECT_TYPE_SEO) {  
1169 - $type = DomainCreateTask::TYPE_BLOG;  
1170 - } else {  
1171 - $type = DomainCreateTask::TYPE_MAIN;  
1172 - } 1176 + if($this->param['site_status'] == 1){
  1177 + //关闭站点:通知C端
  1178 + $re = curl_get('https://'.$domainInfo['domain'].'/api/stop_or_start_website');
  1179 + if(isset($re['status']) && $re['status'] !== 200){
  1180 + $this->fail($re['message']);
  1181 + }
  1182 + }else{
  1183 + //开启站点:创建建站任务
  1184 + $serverIpModel = new ServersIp();
  1185 + $serversIpInfo = $serverIpModel->read(['id' => $projectInfo['serve_id']], ['servers_id']);
  1186 + if(!$serversIpInfo){
  1187 + $this->fail('获取项目所属服务器失败');
  1188 + }
1173 1189
1174 - //创建更新站点证书任务  
1175 - $domainCreateTaskModel = new DomainCreateTask();  
1176 - $task_info = $domainCreateTaskModel->read(['type' => $type, 'domain_id' => $domainInfo['id'], 'is_open' => DomainCreateTask::IS_OPEN, 'status' => ['<', DomainCreateTask::STATUS_SUC]], ['id']);  
1177 - if (!$task_info) {  
1178 - $domainCreateTaskModel->add([  
1179 - 'server_id' => $serversIpInfo['servers_id'],  
1180 - 'project_id' => $this->param['id'],  
1181 - 'domain_id' => $domainInfo['id'],  
1182 - 'type' => $type,  
1183 - 'is_open' => DomainCreateTask::IS_OPEN  
1184 - ]);  
1185 - } 1190 + if ($projectInfo['project_type'] == Project::PROJECT_TYPE_SEO) {
  1191 + $type = DomainCreateTask::TYPE_BLOG;
  1192 + } else {
  1193 + $type = DomainCreateTask::TYPE_MAIN;
  1194 + }
1186 1195
1187 - if($domainInfo['amp_status']){  
1188 - $task_info_amp = $domainCreateTaskModel->read(['type' => DomainCreateTask::TYPE_AMP, 'domain_id' => $domainInfo['id'], 'is_open' => DomainCreateTask::IS_OPEN, 'status' => ['<', DomainCreateTask::STATUS_SUC]], ['id']);  
1189 - if (!$task_info_amp) { 1196 + //创建更新站点证书任务
  1197 + $domainCreateTaskModel = new DomainCreateTask();
  1198 + $task_info = $domainCreateTaskModel->read(['type' => $type, 'domain_id' => $domainInfo['id'], 'is_open' => DomainCreateTask::IS_OPEN, 'status' => ['<', DomainCreateTask::STATUS_SUC]], ['id']);
  1199 + if (!$task_info) {
1190 $domainCreateTaskModel->add([ 1200 $domainCreateTaskModel->add([
1191 'server_id' => $serversIpInfo['servers_id'], 1201 'server_id' => $serversIpInfo['servers_id'],
1192 'project_id' => $this->param['id'], 1202 'project_id' => $this->param['id'],
1193 'domain_id' => $domainInfo['id'], 1203 'domain_id' => $domainInfo['id'],
1194 - 'type' => DomainCreateTask::TYPE_AMP, 1204 + 'type' => $type,
1195 'is_open' => DomainCreateTask::IS_OPEN 1205 'is_open' => DomainCreateTask::IS_OPEN
1196 ]); 1206 ]);
1197 } 1207 }
  1208 +
  1209 + if($domainInfo['amp_status']){
  1210 + $task_info_amp = $domainCreateTaskModel->read(['type' => DomainCreateTask::TYPE_AMP, 'domain_id' => $domainInfo['id'], 'is_open' => DomainCreateTask::IS_OPEN, 'status' => ['<', DomainCreateTask::STATUS_SUC]], ['id']);
  1211 + if (!$task_info_amp) {
  1212 + $domainCreateTaskModel->add([
  1213 + 'server_id' => $serversIpInfo['servers_id'],
  1214 + 'project_id' => $this->param['id'],
  1215 + 'domain_id' => $domainInfo['id'],
  1216 + 'type' => DomainCreateTask::TYPE_AMP,
  1217 + 'is_open' => DomainCreateTask::IS_OPEN
  1218 + ]);
  1219 + }
  1220 + }
1198 } 1221 }
1199 - }  
1200 1222
1201 - $projectModel->edit(['site_status'=>$this->param['site_status']],['id'=>$this->param['id']]); 1223 + $projectModel->edit(['site_status'=>$this->param['site_status']],['id'=>$this->param['id']]);
  1224 + }
1202 1225
1203 $this->response('success'); 1226 $this->response('success');
1204 } 1227 }
@@ -1215,4 +1238,25 @@ class ProjectController extends BaseController @@ -1215,4 +1238,25 @@ class ProjectController extends BaseController
1215 $this->response('success', Code::SUCCESS, $lists); 1238 $this->response('success', Code::SUCCESS, $lists);
1216 } 1239 }
1217 1240
  1241 + /**
  1242 + * @remark :生成关键词图表数据
  1243 + * @name :generateCountCharts
  1244 + * @author :lyh
  1245 + * @method :post
  1246 + * @time :2025/6/10 10:51
  1247 + */
  1248 + public function generateCountCharts(){
  1249 + $this->request->validate([
  1250 + 'project_id'=>'required',
  1251 + ],[
  1252 + 'project_id.required' => '项目id不能为空',
  1253 + ]);
  1254 + $noticeModel = new NoticeLog();
  1255 + $info = $noticeModel->read(['type'=>NoticeLog::TYPE_GENERATE_COUNT_CHARTS,'status'=>0,'data'=>['like','%"'.$this->param['project_id'].'"%']]);
  1256 + if($info !== false){
  1257 + $this->fail('当前数据在生成中');
  1258 + }
  1259 + NoticeLog::createLog(NoticeLog::TYPE_GENERATE_COUNT_CHARTS, ['project_id' => $this->param['project_id']]);
  1260 + $this->response('success');
  1261 + }
1218 } 1262 }
@@ -143,9 +143,15 @@ class AyrShareController extends BaseController @@ -143,9 +143,15 @@ class AyrShareController extends BaseController
143 $data = [ 143 $data = [
144 'profileKey'=>$info['profile_key'] 144 'profileKey'=>$info['profile_key']
145 ]; 145 ];
146 - $res = $ayrShareHelper->post_generate_jwt($data);  
147 - if($res['status'] == 'fail'){  
148 - $this->response($res['message'],Code::USER_ERROR); 146 + try {
  147 + $res = $ayrShareHelper->post_generate_jwt($data);
  148 + if($res['status'] == 'fail'){
  149 + $ayrShareLogic->ayr_share_edit(['profile_key'=>null,'bind_platforms'=>null,'ref_id'=>null],$info['id']);
  150 + $this->response('当前key值已过期,请刷新重新绑定',Code::USER_ERROR);
  151 + }
  152 + }catch (\Exception $e){
  153 + $ayrShareLogic->ayr_share_edit(['profile_key'=>null,'bind_platforms'=>null,'ref_id'=>null],$info['id']);
  154 + $this->response('当前key值已过期,请刷新重新绑定',Code::USER_ERROR);
149 } 155 }
150 $this->response('success',Code::SUCCESS,$res); 156 $this->response('success',Code::SUCCESS,$res);
151 } 157 }
@@ -34,6 +34,7 @@ use App\Models\Project\Country as CountryModel; @@ -34,6 +34,7 @@ use App\Models\Project\Country as CountryModel;
34 use App\Models\Project\Project; 34 use App\Models\Project\Project;
35 use App\Models\RouteMap\RouteMap; 35 use App\Models\RouteMap\RouteMap;
36 use App\Models\WebSetting\SettingNum; 36 use App\Models\WebSetting\SettingNum;
  37 +use App\Models\WebSetting\TranslateBigProject;
37 use App\Models\WebSetting\WebLanguage; 38 use App\Models\WebSetting\WebLanguage;
38 use Illuminate\Http\Request; 39 use Illuminate\Http\Request;
39 use Illuminate\Support\Facades\DB; 40 use Illuminate\Support\Facades\DB;
@@ -61,7 +62,8 @@ class CNoticeController extends BaseController @@ -61,7 +62,8 @@ class CNoticeController extends BaseController
61 ],[ 62 ],[
62 'language.required' => 'language不能为空', 63 'language.required' => 'language不能为空',
63 ]); 64 ]);
64 - $project_id_arr = explode(',',env('PROJECT_ID')) ?? []; 65 + $bigProjectModel = new TranslateBigProject();
  66 + $project_id_arr = $bigProjectModel->selectField(['status'=>1],'project_id') ?? [];
65 if(in_array($this->user['project_id'],$project_id_arr)){ 67 if(in_array($this->user['project_id'],$project_id_arr)){
66 $this->response('success'); 68 $this->response('success');
67 } 69 }
@@ -208,7 +210,7 @@ class CNoticeController extends BaseController @@ -208,7 +210,7 @@ class CNoticeController extends BaseController
208 * 更新通知C端 210 * 更新通知C端
209 * @param Request $request 211 * @param Request $request
210 * @return \Illuminate\Http\JsonResponse 212 * @return \Illuminate\Http\JsonResponse
211 - * @param : type : 1->主站更新 4->聚合页更新 213 + * @param : type : 1->主站更新 4->聚合页更新 7->ai博客
212 */ 214 */
213 public function sendNotify(Request $request) 215 public function sendNotify(Request $request)
214 { 216 {
@@ -299,8 +301,11 @@ class CNoticeController extends BaseController @@ -299,8 +301,11 @@ class CNoticeController extends BaseController
299 'language'=> $language, 301 'language'=> $language,
300 'is_sitemap' => $is_sitemap 302 'is_sitemap' => $is_sitemap
301 ]; 303 ];
302 -// http_post($c_url, json_encode($c_param));  
303 - NoticeLog::createLog(NoticeLog::GENERATE_PAGE, json_encode(['c_url'=>$c_url,'c_params'=>$c_param])); 304 + try {
  305 + http_post($c_url, json_encode($c_param));
  306 + }catch (\Exception $e){
  307 + NoticeLog::createLog(NoticeLog::GENERATE_PAGE, json_encode(['c_url'=>$c_url,'c_params'=>$c_param]));
  308 + }
304 } 309 }
305 $this->response('更新中请稍后, 更新完成将会发送站内信通知更新结果!'); 310 $this->response('更新中请稍后, 更新完成将会发送站内信通知更新结果!');
306 } 311 }
@@ -93,7 +93,7 @@ class OperationHeartbeatController extends BaseController @@ -93,7 +93,7 @@ class OperationHeartbeatController extends BaseController
93 if($info === false){ 93 if($info === false){
94 $info = []; 94 $info = [];
95 }else{ 95 }else{
96 - $date_time = strtotime($info['updated_at']) + 120; 96 + $date_time = strtotime($info['updated_at']) + 60;
97 if($date_time < time()){ 97 if($date_time < time()){
98 $operationHeartbeatModel->edit(['status'=>0,'ip'=>'127.0.0.1'],$condition); 98 $operationHeartbeatModel->edit(['status'=>0,'ip'=>'127.0.0.1'],$condition);
99 $info['status'] = 0; 99 $info['status'] = 0;
@@ -3,13 +3,17 @@ @@ -3,13 +3,17 @@
3 namespace App\Http\Controllers\Bside\Product; 3 namespace App\Http\Controllers\Bside\Product;
4 4
5 use App\Enums\Common\Code; 5 use App\Enums\Common\Code;
  6 +use App\Helper\Common;
  7 +use App\Helper\Gpt;
6 use App\Http\Controllers\Bside\BaseController; 8 use App\Http\Controllers\Bside\BaseController;
7 use App\Http\Logic\Bside\Product\KeywordLogic; 9 use App\Http\Logic\Bside\Product\KeywordLogic;
8 use App\Http\Requests\Bside\Product\KeywordRequest; 10 use App\Http\Requests\Bside\Product\KeywordRequest;
  11 +use App\Models\Ai\AiCommand;
9 use App\Models\Product\Keyword; 12 use App\Models\Product\Keyword;
10 use App\Models\Product\KeywordPage; 13 use App\Models\Product\KeywordPage;
11 use App\Models\Product\KeywordRelated; 14 use App\Models\Product\KeywordRelated;
12 use App\Models\Product\Product; 15 use App\Models\Product\Product;
  16 +use App\Models\Project\AggregateKeywordComment;
13 use App\Rules\Ids; 17 use App\Rules\Ids;
14 use Illuminate\Http\Request; 18 use Illuminate\Http\Request;
15 19
@@ -312,4 +316,73 @@ class KeywordController extends BaseController @@ -312,4 +316,73 @@ class KeywordController extends BaseController
312 $logic->delAllRelated($this->param['keyword_id']); 316 $logic->delAllRelated($this->param['keyword_id']);
313 $this->response('success'); 317 $this->response('success');
314 } 318 }
  319 +
  320 + /**
  321 + * @remark :添加评论
  322 + * @name :saveComment
  323 + * @author :lyh
  324 + * @method :post
  325 + * @time :2025/6/9 14:27
  326 + */
  327 + public function saveComment(KeywordLogic $logic){
  328 + $this->request->validate([
  329 + 'text'=>'required',
  330 + 'nickname'=>'required',
  331 + 'start_time'=>'required',
  332 + ],[
  333 + 'text.required' => '评论内容不能为空',
  334 + 'nickname.required'=>'昵称不能为空',
  335 + 'start_time.required'=>'发布时间不能为空',
  336 + ]);
  337 + $data = $logic->saveComment();
  338 + $this->response('success',Code::SUCCESS,$data);
  339 + }
  340 +
  341 + /**
  342 + * @remark :生成评论
  343 + * @name :sendComment
  344 + * @author :lyh
  345 + * @method :post
  346 + * @time :2025/6/9 11:10
  347 + */
  348 + public function sendComment(KeywordLogic $logic){
  349 + $this->request->validate([
  350 + 'count' => 'required|integer|max:100',
  351 + ], [
  352 + 'count.required' => '生成条数不能为空',
  353 + 'count.integer' => '生成条数必须是整数',
  354 + 'count.max' => '生成条数最大不能超过100',
  355 + ]);
  356 + $data = $logic->sendComment();
  357 + $this->response('success',Code::SUCCESS,$data);
  358 + }
  359 +
  360 + /**
  361 + * @remark :获取评论
  362 + * @name :getComment
  363 + * @author :lyh
  364 + * @method :post
  365 + * @time :2025/6/9 11:45
  366 + */
  367 + public function getComment(KeywordLogic $logic){
  368 + $data = $logic->getComment($this->map,$this->page,$this->row);
  369 + $this->response('success',Code::SUCCESS,$data);
  370 + }
  371 +
  372 + /**
  373 + * @remark :删除评论
  374 + * @name :getComment
  375 + * @author :lyh
  376 + * @method :post
  377 + * @time :2025/6/9 11:45
  378 + */
  379 + public function delComment(KeywordLogic $logic){
  380 + $this->request->validate([
  381 + 'id'=>'required',
  382 + ],[
  383 + 'id.required' => '主键不能为空',
  384 + ]);
  385 + $data = $logic->delComment();
  386 + $this->response('success',Code::SUCCESS,$data);
  387 + }
315 } 388 }
@@ -359,7 +359,7 @@ class ProductController extends BaseController @@ -359,7 +359,7 @@ class ProductController extends BaseController
359 } 359 }
360 if (!empty($new_content)){ 360 if (!empty($new_content)){
361 $detailModel = new Detail(); 361 $detailModel = new Detail();
362 - $detailInfo = $detailModel->read(['column_id'=>1]); 362 + $detailInfo = $detailModel->read(['column_id'=>1,'product_id'=>$this->param['product_id']]);
363 if($detailInfo !== false && !empty($detailInfo['content'])){ 363 if($detailInfo !== false && !empty($detailInfo['content'])){
364 $productInfo['content'] = $new_content . $detailInfo['content']['content']; 364 $productInfo['content'] = $new_content . $detailInfo['content']['content'];
365 } 365 }
@@ -23,7 +23,7 @@ class WebSettingImageController extends BaseController @@ -23,7 +23,7 @@ class WebSettingImageController extends BaseController
23 * @time :2023/9/21 15:12 23 * @time :2023/9/21 15:12
24 */ 24 */
25 public function lists(WebSettingImage $webSettingImage){ 25 public function lists(WebSettingImage $webSettingImage){
26 - $list = $webSettingImage->list($this->map,'id',['id','image','type']); 26 + $list = $webSettingImage->list($this->map,'id',['id','image','type','is_call']);
27 foreach ($list as $k=>$v){ 27 foreach ($list as $k=>$v){
28 $v['image'] = getImageUrl($v['image'],$this->user['storage_type'],$this->user['project_location']); 28 $v['image'] = getImageUrl($v['image'],$this->user['storage_type'],$this->user['project_location']);
29 $list[$k] = $v; 29 $list[$k] = $v;
@@ -40,11 +40,15 @@ class WebSettingImageController extends BaseController @@ -40,11 +40,15 @@ class WebSettingImageController extends BaseController
40 */ 40 */
41 public function save(WebSettingImage $webSettingImage){ 41 public function save(WebSettingImage $webSettingImage){
42 try { 42 try {
43 - $webSettingImage->del(['project_id'=>$this->user['project_id']]);  
44 foreach ($this->param['data'] as $v){ 43 foreach ($this->param['data'] as $v){
45 - $v['project_id'] = $this->user['project_id'];  
46 - $v['image'] = str_replace_url($v['image']);  
47 - $webSettingImage->add($v); 44 + if(isset($v['id']) && !empty($v['id'])){
  45 + $v['image'] = str_replace_url($v['image']);
  46 + $webSettingImage->edit($v,['id'=>$v['id']]);
  47 + }else{
  48 + $v['project_id'] = $this->user['project_id'];
  49 + $v['image'] = str_replace_url($v['image']);
  50 + $webSettingImage->add($v);
  51 + }
48 } 52 }
49 }catch (\Exception $e){ 53 }catch (\Exception $e){
50 $this->response('系统错误请联系管理员'); 54 $this->response('系统错误请联系管理员');
@@ -514,22 +514,22 @@ class ImageController extends Controller @@ -514,22 +514,22 @@ class ImageController extends Controller
514 foreach ($files as $file){ 514 foreach ($files as $file){
515 if(isset($this->cache['image_max']) && ($this->cache['image_max'] != 0)){ 515 if(isset($this->cache['image_max']) && ($this->cache['image_max'] != 0)){
516 if ($file->getSize() > $this->cache['image_max'] * 1024) { 516 if ($file->getSize() > $this->cache['image_max'] * 1024) {
517 - $this->response('图片最大为'.$this->cache['image_max'],Code::SYSTEM_ERROR); 517 + $this->response('图片最大为'.$this->cache['image_max'].'k',Code::SYSTEM_ERROR);
518 } 518 }
519 }else{ 519 }else{
520 if ($file->getSize() > $max) { 520 if ($file->getSize() > $max) {
521 - $this->response('图片最大为1024K',Code::SYSTEM_ERROR); 521 + $this->response('图片最大为2m',Code::SYSTEM_ERROR);
522 } 522 }
523 } 523 }
524 } 524 }
525 }else{ 525 }else{
526 if(isset($this->cache['image_max']) && ($this->cache['image_max'] != 0)){ 526 if(isset($this->cache['image_max']) && ($this->cache['image_max'] != 0)){
527 if ($files->getSize() > $this->cache['image_max'] * 1024) { 527 if ($files->getSize() > $this->cache['image_max'] * 1024) {
528 - $this->response('图片最大为'.$this->cache['image_max'],Code::SYSTEM_ERROR); 528 + $this->response('图片最大为'.$this->cache['image_max'].'k',Code::SYSTEM_ERROR);
529 } 529 }
530 }else{ 530 }else{
531 if ($files->getSize() > $max) { 531 if ($files->getSize() > $max) {
532 - $this->response('图片最大为1024K',Code::SYSTEM_ERROR); 532 + $this->response('图片最大为2m',Code::SYSTEM_ERROR);
533 } 533 }
534 } 534 }
535 } 535 }
@@ -70,7 +70,7 @@ class LoginLogic extends BaseLogic @@ -70,7 +70,7 @@ class LoginLogic extends BaseLogic
70 // Cache::pull(Common::MANAGE_TOKEN . $manage['token']); 70 // Cache::pull(Common::MANAGE_TOKEN . $manage['token']);
71 // } 71 // }
72 //生成新token 72 //生成新token
73 - $token = md5(uniqid().$manage['id']); 73 + $token = $manage['id'].'_a'.md5(uniqid().$manage['id']);
74 unset($manage['password']); 74 unset($manage['password']);
75 //更新用户信息 75 //更新用户信息
76 $manage->token = $token; 76 $manage->token = $token;
@@ -81,12 +81,14 @@ class RenewLogic extends BaseLogic @@ -81,12 +81,14 @@ class RenewLogic extends BaseLogic
81 } 81 }
82 DB::beginTransaction(); 82 DB::beginTransaction();
83 try { 83 try {
84 - $this->model->edit(['project_id'=>$this->param['id'],'operator_id'=>$this->manager['id']],['id'=>$this->param['renew_id']]); 84 + if($this->param['renew_id'] != 0){
  85 + $this->model->edit(['project_id'=>$this->param['id'],'operator_id'=>$this->manager['id']],['id'=>$this->param['renew_id']]);
  86 + }
85 $param = $this->param; 87 $param = $this->param;
86 $param['api_no'] = $info['api_no'] ?? 0; 88 $param['api_no'] = $info['api_no'] ?? 0;
87 $this->saveLog($param); 89 $this->saveLog($param);
88 $this->updateProject($this->param['id'],$this->param['type']); 90 $this->updateProject($this->param['id'],$this->param['type']);
89 - $this->updateProjectBuild($this->param['id'],$this->param['service_duration'],$this->param['plan']); 91 + $this->updateProjectBuild($this->param['id'],$this->param['service_duration'] ?? 0,$this->param['plan']);
90 DB::commit(); 92 DB::commit();
91 }catch (\Exception $e){ 93 }catch (\Exception $e){
92 DB::rollBack(); 94 DB::rollBack();
@@ -120,12 +122,12 @@ class RenewLogic extends BaseLogic @@ -120,12 +122,12 @@ class RenewLogic extends BaseLogic
120 public function saveLog($param){ 122 public function saveLog($param){
121 $data = [ 123 $data = [
122 'renew_id'=>$param['renew_id'], 124 'renew_id'=>$param['renew_id'],
123 - 'service_duration'=>$param['service_duration'], 125 + 'service_duration'=>$param['service_duration'] ?? 0,
124 'plan'=>$param['plan'], 126 'plan'=>$param['plan'],
125 'old_plan'=>$param['old_plan'], 127 'old_plan'=>$param['old_plan'],
126 'type'=>$param['type'], 128 'type'=>$param['type'],
127 'old_type'=>$param['old_type'], 129 'old_type'=>$param['old_type'],
128 - 'amount'=>$param['amount'], 130 + 'amount'=>$param['amount'] ?? 0,
129 'api_no'=>$param['api_no'], 131 'api_no'=>$param['api_no'],
130 'project_id'=>$param['id'], 132 'project_id'=>$param['id'],
131 'operator_id'=>$this->manager['id'], 133 'operator_id'=>$this->manager['id'],
@@ -68,6 +68,7 @@ class AiBlogLogic extends BaseLogic @@ -68,6 +68,7 @@ class AiBlogLogic extends BaseLogic
68 }catch (\Exception $e){ 68 }catch (\Exception $e){
69 $this->fail('保存失败,请联系管理员'); 69 $this->fail('保存失败,请联系管理员');
70 } 70 }
  71 + $this->sendHttpC([$this->param['route'],'top-blog']);
71 shell_exec("php artisan save_ai_blog_list {$this->user['project_id']} > /dev/null 2>&1 &"); 72 shell_exec("php artisan save_ai_blog_list {$this->user['project_id']} > /dev/null 2>&1 &");
72 return $this->success(); 73 return $this->success();
73 } 74 }
@@ -9,7 +9,6 @@ @@ -9,7 +9,6 @@
9 9
10 namespace App\Http\Logic\Bside\Gpt; 10 namespace App\Http\Logic\Bside\Gpt;
11 11
12 -use App\Helper\Stream;  
13 use App\Http\Logic\Bside\BaseLogic; 12 use App\Http\Logic\Bside\BaseLogic;
14 use App\Models\Gpt\Chat; 13 use App\Models\Gpt\Chat;
15 use App\Models\Gpt\ChatItem; 14 use App\Models\Gpt\ChatItem;
@@ -81,7 +81,7 @@ class NewsLogic extends BaseLogic @@ -81,7 +81,7 @@ class NewsLogic extends BaseLogic
81 $this->edit(['url' => $route], ['id' => $id]); 81 $this->edit(['url' => $route], ['id' => $id]);
82 $this->curlDelRoute(['new_route'=>$route]); 82 $this->curlDelRoute(['new_route'=>$route]);
83 } 83 }
84 - $this->model->saveExtendInfo($id,$this->param['extend'] ?? []); 84 + $this->model->saveExtendInfo($id,$this->param['extend'] ?? [],$this->user['project_id']);
85 $this->addUpdateNotify(RouteMap::SOURCE_NEWS,$route); 85 $this->addUpdateNotify(RouteMap::SOURCE_NEWS,$route);
86 return $this->success(['id'=>$id]); 86 return $this->success(['id'=>$id]);
87 } 87 }
@@ -175,6 +175,9 @@ class NewsLogic extends BaseLogic @@ -175,6 +175,9 @@ class NewsLogic extends BaseLogic
175 RouteMap::delRoute(RouteMap::SOURCE_NEWS, $id, $this->user['project_id']); 175 RouteMap::delRoute(RouteMap::SOURCE_NEWS, $id, $this->user['project_id']);
176 $this->delRoute($id); 176 $this->delRoute($id);
177 $this->model->del(['id' => $id]); 177 $this->model->del(['id' => $id]);
  178 + //删除扩展字段
  179 + $extendInfoModel = new NewsExtendInfo();
  180 + $extendInfoModel->del(['news_id'=>$id]);
178 } 181 }
179 } 182 }
180 DB::commit(); 183 DB::commit();
@@ -5,12 +5,15 @@ namespace App\Http\Logic\Bside\Product; @@ -5,12 +5,15 @@ namespace App\Http\Logic\Bside\Product;
5 use App\Exceptions\BsideGlobalException; 5 use App\Exceptions\BsideGlobalException;
6 use App\Helper\Arr; 6 use App\Helper\Arr;
7 use App\Helper\Common; 7 use App\Helper\Common;
  8 +use App\Helper\Gpt;
8 use App\Http\Logic\Bside\BaseLogic; 9 use App\Http\Logic\Bside\BaseLogic;
  10 +use App\Models\Ai\AiCommand;
9 use App\Models\Com\NoticeLog; 11 use App\Models\Com\NoticeLog;
10 use App\Models\News\News; 12 use App\Models\News\News;
11 use App\Models\Product\Keyword; 13 use App\Models\Product\Keyword;
12 use App\Models\Product\KeywordRelated; 14 use App\Models\Product\KeywordRelated;
13 use App\Models\Product\Product; 15 use App\Models\Product\Product;
  16 +use App\Models\Project\AggregateKeywordComment;
14 use App\Models\RouteMap\RouteMap; 17 use App\Models\RouteMap\RouteMap;
15 use App\Models\User\User; 18 use App\Models\User\User;
16 use Illuminate\Support\Facades\DB; 19 use Illuminate\Support\Facades\DB;
@@ -345,4 +348,110 @@ class KeywordLogic extends BaseLogic @@ -345,4 +348,110 @@ class KeywordLogic extends BaseLogic
345 return $this->success(); 348 return $this->success();
346 } 349 }
347 350
  351 + /**
  352 + * @remark :手动添加评论
  353 + * @name :saveComment
  354 + * @author :lyh
  355 + * @method :post
  356 + * @time :2025/6/9 14:29
  357 + */
  358 + public function saveComment(){
  359 + $keywordCommonModel = new AggregateKeywordComment();
  360 + if(isset($this->param['id']) && !empty($this->param['id'])){
  361 + $id = $this->param['id'];
  362 + $keywordCommonModel->edit($this->param,['id'=>$this->param['id']]);
  363 + }else{
  364 + $param = [
  365 + 'nickname' => $this->param['nickname'],
  366 + 'text' => $this->param['text'],
  367 + 'project_id' => $this->user['project_id'],
  368 + 'type' => 1,
  369 + 'uid' => 0,
  370 + 'start_time'=>$this->param['start_time'],
  371 + 'created_at' => date('Y-m-d H:i:s'),
  372 + 'updated_at' => date('Y-m-d H:i:s')
  373 + ];
  374 + $id = $keywordCommonModel->addReturnId($param);
  375 + }
  376 + return $this->success(['id'=>$id]);
  377 + }
  378 +
  379 + /**
  380 + * @remark :保存数据
  381 + * @name :sendComment
  382 + * @author :lyh
  383 + * @method :post
  384 + * @time :2025/6/9 11:19
  385 + */
  386 + public function sendComment()
  387 + {
  388 + $aiCommonModel = new AiCommand();
  389 + $info = $aiCommonModel->read(['key' => 'tag_comment','project_id'=>$this->user['project_id']]);
  390 + if($info === false){
  391 + $info = $aiCommonModel->read(['key' => 'tag_comment']);
  392 + $info['ai'] = str_replace('50', $this->param['count'], $info['ai']);
  393 + }
  394 + $text = Gpt::instance()->openai_chat_qqs($info['ai']);
  395 + $text = Common::deal_keywords($text);
  396 + preg_match_all('/\{[^{}]*\}/', $text, $matches);
  397 + $data = [];
  398 + $twoMonthsAgo = strtotime('-2 months');
  399 +
  400 + if (!empty($text)) {
  401 + foreach ($matches[0] as $item) {
  402 + $item = str_replace("'", '"', $item);
  403 + // 解码成 PHP 关联数组
  404 + $item = json_decode($item, true);
  405 + if (!isset($item['name']) || !isset($item['comment'])) {
  406 + continue;
  407 + }
  408 + $randomTimestamp = rand($twoMonthsAgo, time());
  409 + $randomDateTime = date('Y-m-d H:i:s', $randomTimestamp);
  410 + $data[] = [
  411 + 'nickname' => $item['name'],
  412 + 'text' => $item['comment'],
  413 + 'project_id' => $this->user['project_id'],
  414 + 'type' => 1,
  415 + 'uid' => 0,
  416 + 'start_time'=>$randomDateTime,
  417 + 'created_at' => date('Y-m-d H:i:s'),
  418 + 'updated_at' => date('Y-m-d H:i:s')
  419 + ];
  420 + }
  421 + }
  422 + $keywordCommonModel = new AggregateKeywordComment();
  423 + $keywordCommonModel->insertAll($data);
  424 + return $this->success($data);
  425 + }
  426 +
  427 + /**
  428 + * @remark :获取评论
  429 + * @name :getComment
  430 + * @author :lyh
  431 + * @method :post
  432 + * @time :2025/6/9 11:46
  433 + */
  434 + public function getComment($map,$page,$row){
  435 + $keywordCommonModel = new AggregateKeywordComment();
  436 + $map['project_id'] = $this->user['project_id'];
  437 + $lists = $keywordCommonModel->lists($map,$page,$row);
  438 + return $this->success($lists);
  439 + }
  440 +
  441 + /**
  442 + * @remark :删除评论
  443 + * @name :delComment
  444 + * @author :lyh
  445 + * @method :post
  446 + * @time :2025/6/9 11:48
  447 + */
  448 + public function delComment(){
  449 + $keywordCommonModel = new AggregateKeywordComment();
  450 + if($this->param['id'] == 0){
  451 + $keywordCommonModel->del(['project_id'=>$this->user['project_id']]);
  452 + }else{
  453 + $keywordCommonModel->del(['id'=>$this->param['id']]);
  454 + }
  455 + return $this->success();
  456 + }
348 } 457 }
@@ -101,6 +101,7 @@ class RankDataLogic extends BaseLogic @@ -101,6 +101,7 @@ class RankDataLogic extends BaseLogic
101 'keyword_num' => $project['deploy_build']['keyword_num'], 101 'keyword_num' => $project['deploy_build']['keyword_num'],
102 'compliance_day' => $project['finish_remain_day'] ?? 0, 102 'compliance_day' => $project['finish_remain_day'] ?? 0,
103 'remain_day' => $project['remain_day'], 103 'remain_day' => $project['remain_day'],
  104 + 'seo_remain_day' => $project['seo_remain_day'],
104 'g_top_plan' => $g_top_plan ?? [], 105 'g_top_plan' => $g_top_plan ?? [],
105 ]; 106 ];
106 //小语种列表 107 //小语种列表
@@ -553,7 +554,7 @@ class RankDataLogic extends BaseLogic @@ -553,7 +554,7 @@ class RankDataLogic extends BaseLogic
553 $without_extension_project_ids = [658]; //是否达标只统计主词的 554 $without_extension_project_ids = [658]; //是否达标只统计主词的
554 $extension_project_ids = [354]; //扩展词也到达标的 555 $extension_project_ids = [354]; //扩展词也到达标的
555 $compliance_project_ids = [2163,257,823,1750,497]; //直接达标处理的 556 $compliance_project_ids = [2163,257,823,1750,497]; //直接达标处理的
556 - $ceaseProjectId = [354, 378, 649, 1226, 1283, 1703, 1893, 2066, 2250,2193];//暂停的项目 557 + $ceaseProjectId = [354, 378, 649, 1226, 1283, 1703, 1893, 2066, 2250,2193,2399,1685];//暂停的项目
557 $uptimeProjectId = [1434,1812,276,2414,2974];//按上线时间统计的项目 558 $uptimeProjectId = [1434,1812,276,2414,2974];//按上线时间统计的项目
558 //一个项目多个api_no 559 //一个项目多个api_no
559 $multiple_api_no_project_ids = [ 560 $multiple_api_no_project_ids = [
@@ -74,6 +74,7 @@ class TranslateLogic extends BaseLogic @@ -74,6 +74,7 @@ class TranslateLogic extends BaseLogic
74 } 74 }
75 $arr2 = []; 75 $arr2 = [];
76 foreach ($text_array as $val) { 76 foreach ($text_array as $val) {
  77 + $val = str_replace(['%22', '%', '+'], ['"', '%', '+'], $val);
77 $val = rawurldecode($val); 78 $val = rawurldecode($val);
78 $val = str_replace(' ','',$val);//处理特殊字符 79 $val = str_replace(' ','',$val);//处理特殊字符
79 $val = trim(str_replace(' ','',$val)); 80 $val = trim(str_replace(' ','',$val));
@@ -272,14 +273,10 @@ class TranslateLogic extends BaseLogic @@ -272,14 +273,10 @@ class TranslateLogic extends BaseLogic
272 $data = []; 273 $data = [];
273 if(!empty($this->param['data'])){ 274 if(!empty($this->param['data'])){
274 //处理传递的data 275 //处理传递的data
275 - foreach ($this->param['data'] as $k => $v){  
276 - if(!empty($v) && is_array($v)){  
277 - foreach ($v as $text => $translate){  
278 - $text = str_replace(['%22', '%', '+'], ['"', '%', '+'], $text);  
279 - $translate = str_replace(['%22', '%', '+'], ['"', '%', '+'], $translate);  
280 - $data[$text] = $translate;  
281 - }  
282 - } 276 + foreach ($this->param['data'] as $k => $translate){
  277 + $text = str_replace(['%22', '%', '+'], ['"', '%', '+'], $translate[0]);
  278 + $translate = str_replace(['%22', '%', '+'], ['"', '%', '+'], $translate[1]);
  279 + $data[$text] = $translate;
283 } 280 }
284 $this->param['data'] = $data; 281 $this->param['data'] = $data;
285 } 282 }
@@ -7,6 +7,7 @@ use App\Exceptions\AsideGlobalException; @@ -7,6 +7,7 @@ use App\Exceptions\AsideGlobalException;
7 use App\Exceptions\BsideGlobalException; 7 use App\Exceptions\BsideGlobalException;
8 use App\Helper\Common; 8 use App\Helper\Common;
9 use App\Models\Domain\DomainInfo; 9 use App\Models\Domain\DomainInfo;
  10 +use App\Models\Manage\ManageHr;
10 use App\Models\Project\Project; 11 use App\Models\Project\Project;
11 use App\Models\Scoring\ScoringSystem; 12 use App\Models\Scoring\ScoringSystem;
12 use App\Models\Sms\SmsLog; 13 use App\Models\Sms\SmsLog;
@@ -89,7 +90,7 @@ class UserLoginLogic @@ -89,7 +90,7 @@ class UserLoginLogic
89 Cache::pull($info['token']); 90 Cache::pull($info['token']);
90 } 91 }
91 //生成新token 92 //生成新token
92 - $token = md5(uniqid().$info['id']); 93 + $token = $info['id'].'_b'.md5(uniqid().$info['id']);
93 //存储缓存 94 //存储缓存
94 $info['token'] = $token; 95 $info['token'] = $token;
95 Cache::add($token,$info,3600 * 12); 96 Cache::add($token,$info,3600 * 12);
@@ -292,6 +293,9 @@ class UserLoginLogic @@ -292,6 +293,9 @@ class UserLoginLogic
292 $info['service_duration'] = $project['deploy_build']['service_duration'] ?? 0; 293 $info['service_duration'] = $project['deploy_build']['service_duration'] ?? 0;
293 $info['is_comment'] = $project['deploy_build']['is_comment'] ?? 0; 294 $info['is_comment'] = $project['deploy_build']['is_comment'] ?? 0;
294 $info['is_ai_blog_send'] = $project['deploy_optimize']['is_ai_blog_send'] ?? 0; 295 $info['is_ai_blog_send'] = $project['deploy_optimize']['is_ai_blog_send'] ?? 0;
  296 + $info['tech_leader'] = $project['deploy_optimize']['tech_leader'] ?? 0;
  297 + $manageModel = new ManageHr();
  298 + $info['tech_leader_name'] = $manageModel->getName($project['deploy_optimize']['tech_leader'] ?? 0);
295 $info['remain_day'] = $project['remain_day'] ?? 0; 299 $info['remain_day'] = $project['remain_day'] ?? 0;
296 $info['project_created_at'] = $project['created_at']; 300 $info['project_created_at'] = $project['created_at'];
297 $info['type'] = $project['type'] ?? 1; 301 $info['type'] = $project['type'] ?? 1;
@@ -26,6 +26,8 @@ class AutoPullNotify extends Base @@ -26,6 +26,8 @@ class AutoPullNotify extends Base
26 22 => '白帽专属服务器01', 26 22 => '白帽专属服务器01',
27 24 => '白帽专属服务器02', 27 24 => '白帽专属服务器02',
28 23 => '西班牙服务器', 28 23 => '西班牙服务器',
  29 + 6 => '自建站服务器群',
  30 + 27 => '硅谷建站服务器03',
29 ]; 31 ];
30 } 32 }
31 33
@@ -13,6 +13,8 @@ class NoticeLog extends Base @@ -13,6 +13,8 @@ class NoticeLog extends Base
13 const TYPE_PROJECT = 'project'; 13 const TYPE_PROJECT = 'project';
14 const TYPE_RANK_DATA = 'rank_data'; 14 const TYPE_RANK_DATA = 'rank_data';
15 const TYPE_INIT_PROJECT = 'init_project'; 15 const TYPE_INIT_PROJECT = 'init_project';
  16 + const TYPE_INIT_KEYWORD_COMMON = 'init_keyword_common';//聚合页关键词评论
  17 + const TYPE_GENERATE_COUNT_CHARTS = 'generate_count_charts';//聚合页关键字图表生成
16 const TYPE_COPY_PROJECT = 'copy_project'; 18 const TYPE_COPY_PROJECT = 'copy_project';
17 const TYPE_INIT_KEYWORD = 'init_keyword'; 19 const TYPE_INIT_KEYWORD = 'init_keyword';
18 const DELETE_PRODUCT_CATEGORY = 'delete_product_category'; 20 const DELETE_PRODUCT_CATEGORY = 'delete_product_category';
@@ -80,7 +80,7 @@ class News extends Base @@ -80,7 +80,7 @@ class News extends Base
80 $arr = json_decode($info['values']); 80 $arr = json_decode($info['values']);
81 foreach ($arr as $k1=>$v1){ 81 foreach ($arr as $k1=>$v1){
82 $v1 = (array)$v1; 82 $v1 = (array)$v1;
83 - $v1['url'] = getImageUrl($v1['url'],$this->user['storage_type'],$this->user['project_location']); 83 + $v1['url'] = getImageUrl($v1['url']);
84 $arr[$k1] = $v1; 84 $arr[$k1] = $v1;
85 } 85 }
86 $v['values'] = $arr; 86 $v['values'] = $arr;
@@ -89,9 +89,9 @@ class News extends Base @@ -89,9 +89,9 @@ class News extends Base
89 foreach ($arr1 as $k1=>$v1){ 89 foreach ($arr1 as $k1=>$v1){
90 $v1 = (array)$v1; 90 $v1 = (array)$v1;
91 if(isset($v1['url'])){ 91 if(isset($v1['url'])){
92 - $v1['url'] = getFileUrl($v1['url'],$this->user['storage_type'],$this->user['project_location'],$this->user['file_cdn'] ?? 0); 92 + $v1['url'] = getFileUrl($v1['url']);
93 }else{ 93 }else{
94 - $v1 = getFileUrl($v1,$this->user['storage_type'],$this->user['project_location'],$this->user['file_cdn'] ?? 0); 94 + $v1 = getFileUrl($v1);
95 } 95 }
96 $arr1[$k1] = $v1; 96 $arr1[$k1] = $v1;
97 } 97 }
@@ -109,7 +109,7 @@ class News extends Base @@ -109,7 +109,7 @@ class News extends Base
109 * @method :post 109 * @method :post
110 * @time :2023/11/9 15:02 110 * @time :2023/11/9 15:02
111 */ 111 */
112 - public function saveExtendInfo($news_id,$extend){ 112 + public function saveExtendInfo($news_id,$extend,$project_id){
113 //先删除以前的数据 113 //先删除以前的数据
114 $extendInfoModel = new NewsExtendInfo(); 114 $extendInfoModel = new NewsExtendInfo();
115 $extendInfoModel->del(['news_id'=>$news_id]); 115 $extendInfoModel->del(['news_id'=>$news_id]);
@@ -120,7 +120,7 @@ class News extends Base @@ -120,7 +120,7 @@ class News extends Base
120 if(empty($v['values'])){ 120 if(empty($v['values'])){
121 continue; 121 continue;
122 } 122 }
123 - $v = $this->saveHandleExtend($v,$news_id); 123 + $v = $this->saveHandleExtend($v,$news_id,$project_id);
124 $extendInfoModel->add($v); 124 $extendInfoModel->add($v);
125 } 125 }
126 return true; 126 return true;
@@ -133,7 +133,7 @@ class News extends Base @@ -133,7 +133,7 @@ class News extends Base
133 * @method :post 133 * @method :post
134 * @time :2023/12/6 15:11 134 * @time :2023/12/6 15:11
135 */ 135 */
136 - public function saveHandleExtend(&$v,$news_id){ 136 + public function saveHandleExtend(&$v,$news_id,$project_id){
137 unset($v['title']); 137 unset($v['title']);
138 if($v['type'] == 3){ 138 if($v['type'] == 3){
139 foreach ($v['values'] as $k1=>$v1){ 139 foreach ($v['values'] as $k1=>$v1){
@@ -148,7 +148,7 @@ class News extends Base @@ -148,7 +148,7 @@ class News extends Base
148 } 148 }
149 $v['values'] = json_encode($v['values']); 149 $v['values'] = json_encode($v['values']);
150 } 150 }
151 - $v['project_id'] = $this->user['project_id']; 151 + $v['project_id'] = $project_id;
152 $v['news_id'] = $news_id; 152 $v['news_id'] = $news_id;
153 return $v; 153 return $v;
154 } 154 }
  1 +<?php
  2 +/**
  3 + * @remark :
  4 + * @name :AggregateKeywordComment.php
  5 + * @author :lyh
  6 + * @method :post
  7 + * @time :2025/6/3 17:42
  8 + */
  9 +
  10 +namespace App\Models\Project;
  11 +
  12 +use App\Models\Base;
  13 +
  14 +class AggregateKeywordComment extends Base
  15 +{
  16 + protected $table = 'gl_aggregate_keyword_comment';
  17 +}
@@ -60,6 +60,8 @@ class Project extends Base @@ -60,6 +60,8 @@ class Project extends Base
60 5 => 'Q告知书二', 60 5 => 'Q告知书二',
61 6 => 'KA', 61 6 => 'KA',
62 7 => 'CKA', 62 7 => 'CKA',
  63 + 18 => '白帽V1(AI视频)',
  64 + 19 => '白帽V2(保证排名)',
63 ]; 65 ];
64 } 66 }
65 67
  1 +<?php
  2 +
  3 +namespace App\Models\Project;
  4 +
  5 +use App\Helper\Arr;
  6 +use App\Models\Base;
  7 +use Illuminate\Support\Facades\DB;
  8 +use Illuminate\Support\Facades\Log;
  9 +use Illuminate\Support\Facades\Redis;
  10 +
  11 +class ProjectKeywordAiTask extends Base
  12 +{
  13 + //设置关联表名
  14 + protected $table = 'gl_project_keyword_ai_task';
  15 +
  16 + const STATUS_PENDING = 0;
  17 + const STATUS_SUCCESS = 1;
  18 + const STATUS_FAIL = 2;
  19 +
  20 + public static function add_task($project_id){
  21 + $task = self::where('project_id', $project_id)->where('status', self::STATUS_PENDING)->first();
  22 + if($task){
  23 + throw new \Exception('该项目有未执行的任务,请勿重复添加');
  24 + }
  25 + $model = new self();
  26 + $model->project_id = $project_id;
  27 + $model->save();
  28 +
  29 + Redis::lpush('projectKeywordAiTask', $project_id);
  30 + }
  31 +
  32 + public static function getPendingTask(){
  33 + //有其他任务 就取其他任务 没有其他任务运行未结束的任务
  34 + $project_id = Redis::rpop('projectKeywordAiTask');
  35 + $data = [];
  36 + if($project_id){
  37 + $data = self::where('status', self::STATUS_PENDING)->where('project_id', $project_id)->orderBy('id', 'asc')->first();
  38 + }
  39 + if($data){
  40 + return $data;
  41 + }
  42 + return self::where('status', self::STATUS_PENDING)->orderBy('id', 'asc')->first();
  43 + }
  44 +
  45 + /**
  46 + * 重试任务
  47 + * @param $id
  48 + * @param $remark
  49 + * @author zbj
  50 + * @date 2023/11/9
  51 + */
  52 + public static function retry($id, $remark)
  53 + {
  54 + DB::beginTransaction();
  55 + try {
  56 + //行锁 避免脏读写
  57 + $data = self::where('id', $id)->lockForUpdate()->first();
  58 + $data->retry = $data->retry + 1;
  59 + if ($data->retry > 3) {
  60 + $data->status = self::STATUS_FAIL;
  61 + }else{
  62 + $data->status = self::STATUS_PENDING;
  63 + }
  64 + $data->remark = mb_substr($remark, 0, 250);
  65 + $data->save();
  66 +
  67 + DB::commit();
  68 + } catch (\Exception $e) {
  69 + DB::rollback();
  70 + Log::error('project_keyword_ai_task retry error:' . $e->getMessage());
  71 + }
  72 + }
  73 +
  74 + /**
  75 + * 完成
  76 + * @param $id
  77 + * @param $update_rows
  78 + * @author zbj
  79 + * @date 2023/11/9
  80 + */
  81 + public static function finish($id, $update_rows){
  82 + DB::beginTransaction();
  83 + try {
  84 + //行锁 避免脏读写
  85 + $data = self::where('id', $id)->lockForUpdate()->first();
  86 + $data->status = self::STATUS_SUCCESS;
  87 + $data->update_rows = $update_rows;
  88 + $data->save();
  89 + DB::commit();
  90 + } catch (\Exception $e) {
  91 + DB::rollback();
  92 + Log::error('project_keyword_ai_task finish error:' . $e->getMessage());
  93 + }
  94 + }
  95 +}
  1 +<?php
  2 +/**
  3 + * @remark :
  4 + * @name :TranslateBigProject.php
  5 + * @author :lyh
  6 + * @method :post
  7 + * @time :2025/6/4 14:40
  8 + */
  9 +
  10 +namespace App\Models\WebSetting;
  11 +
  12 +use App\Models\Base;
  13 +
  14 +/**
  15 + * @remark :需要翻译的大网站
  16 + * @name :TranslateBigProject
  17 + * @author :lyh
  18 + * @method :post
  19 + * @time :2025/6/4 14:41
  20 + */
  21 +class TranslateBigProject extends Base
  22 +{
  23 + protected $table = 'gl_translate_big_project';
  24 +}
@@ -25,7 +25,7 @@ class ProjectServer @@ -25,7 +25,7 @@ class ProjectServer
25 <section data-section="section" data-screen="screen-large" class="section-404-wrap-block section-block-error404" 25 <section data-section="section" data-screen="screen-large" class="section-404-wrap-block section-block-error404"
26 id="sectionIdyxqu938"> 26 id="sectionIdyxqu938">
27 <div class="layout" data-unable="demo01-error404"> 27 <div class="layout" data-unable="demo01-error404">
28 - <img src="https://ecdn6.globalso.com/upload/m/image_other/2023-10/6528a87e594db30162.png" /> 28 + <img src="https://ecdn6.globalso.com/upload/m/image_other/2023-10/6528a87e594db30162.png" alt=""/>
29 </div> 29 </div>
30 <p style="text-align: center">SORRY. THE PAGE HAS EITHER MOVED OR CANNOT BE FOUND.</p> 30 <p style="text-align: center">SORRY. THE PAGE HAS EITHER MOVED OR CANNOT BE FOUND.</p>
31 <style> 31 <style>
@@ -38,7 +38,7 @@ class ProjectServer @@ -38,7 +38,7 @@ class ProjectServer
38 .section-block-error404 img { 38 .section-block-error404 img {
39 width: 400px; 39 width: 400px;
40 } 40 }
41 - @media only screen and (max-width:500) { 41 + @media only screen and (max-width:500px) {
42 .section-block-error404 img { 42 .section-block-error404 img {
43 max-width: 100%; 43 max-width: 100%;
44 } 44 }
@@ -149,6 +149,7 @@ Route::middleware(['aloginauth'])->group(function () { @@ -149,6 +149,7 @@ Route::middleware(['aloginauth'])->group(function () {
149 //人事管理 149 //人事管理
150 Route::prefix('hr')->group(function () { 150 Route::prefix('hr')->group(function () {
151 Route::any('/', [Aside\Manage\HrController::class, 'list'])->name('admin.hr'); 151 Route::any('/', [Aside\Manage\HrController::class, 'list'])->name('admin.hr');
  152 + Route::any('/getManagerList', [Aside\Manage\HrController::class, 'getManagerList'])->name('admin.hr_getManagerList');
152 Route::any('/info', [Aside\Manage\HrController::class, 'info'])->name('admin.hr_info'); 153 Route::any('/info', [Aside\Manage\HrController::class, 'info'])->name('admin.hr_info');
153 Route::post('/save', [Aside\Manage\HrController::class, 'save'])->name('admin.hr_save'); 154 Route::post('/save', [Aside\Manage\HrController::class, 'save'])->name('admin.hr_save');
154 Route::post('/sort', [Aside\Manage\HrController::class, 'sort'])->name('admin.hr_sort'); 155 Route::post('/sort', [Aside\Manage\HrController::class, 'sort'])->name('admin.hr_sort');
@@ -208,6 +209,7 @@ Route::middleware(['aloginauth'])->group(function () { @@ -208,6 +209,7 @@ Route::middleware(['aloginauth'])->group(function () {
208 Route::any('/getKeywordPrefix', [Aside\Project\KeywordPrefixController::class, 'getKeywordPrefix'])->name('admin.keyword_getKeywordPrefix'); 209 Route::any('/getKeywordPrefix', [Aside\Project\KeywordPrefixController::class, 'getKeywordPrefix'])->name('admin.keyword_getKeywordPrefix');
209 Route::any('/save', [Aside\Project\KeywordPrefixController::class, 'save'])->name('admin.keyword_save'); 210 Route::any('/save', [Aside\Project\KeywordPrefixController::class, 'save'])->name('admin.keyword_save');
210 Route::any('/del', [Aside\Project\KeywordPrefixController::class, 'del'])->name('admin.keyword_del'); 211 Route::any('/del', [Aside\Project\KeywordPrefixController::class, 'del'])->name('admin.keyword_del');
  212 + Route::any('/generateCountCharts', [Aside\Project\ProjectController::class, 'generateCountCharts'])->name('admin.keyword_generateCountCharts');
211 }); 213 });
212 //企业资料库 214 //企业资料库
213 Route::prefix('enterprise_product')->group(function () { 215 Route::prefix('enterprise_product')->group(function () {
@@ -327,6 +327,10 @@ Route::middleware(['bloginauth'])->group(function () { @@ -327,6 +327,10 @@ Route::middleware(['bloginauth'])->group(function () {
327 Route::any('keyword/batchKeywordIsVideo', [\App\Http\Controllers\Bside\Product\KeywordController::class, 'batchKeywordIsVideo'])->name('product_keyword_batchKeywordIsVideo'); 327 Route::any('keyword/batchKeywordIsVideo', [\App\Http\Controllers\Bside\Product\KeywordController::class, 'batchKeywordIsVideo'])->name('product_keyword_batchKeywordIsVideo');
328 Route::any('keyword/batchKeywordFiled', [\App\Http\Controllers\Bside\Product\KeywordController::class, 'batchKeywordFiled'])->name('product_keyword_batchKeywordFiled'); 328 Route::any('keyword/batchKeywordFiled', [\App\Http\Controllers\Bside\Product\KeywordController::class, 'batchKeywordFiled'])->name('product_keyword_batchKeywordFiled');
329 Route::any('keyword/delRelatedProductId', [\App\Http\Controllers\Bside\Product\KeywordController::class, 'delRelatedProductId'])->name('product_keyword_delRelatedProductId'); 329 Route::any('keyword/delRelatedProductId', [\App\Http\Controllers\Bside\Product\KeywordController::class, 'delRelatedProductId'])->name('product_keyword_delRelatedProductId');
  330 + Route::any('keyword/sendComment', [\App\Http\Controllers\Bside\Product\KeywordController::class, 'sendComment'])->name('product_keyword_sendComment');
  331 + Route::any('keyword/getComment', [\App\Http\Controllers\Bside\Product\KeywordController::class, 'getComment'])->name('product_keyword_getComment');
  332 + Route::any('keyword/delComment', [\App\Http\Controllers\Bside\Product\KeywordController::class, 'delComment'])->name('product_keyword_delComment');
  333 + Route::any('keyword/saveComment', [\App\Http\Controllers\Bside\Product\KeywordController::class, 'saveComment'])->name('product_keyword_saveComment');
330 //产品参数 334 //产品参数
331 Route::get('attr', [\App\Http\Controllers\Bside\Product\AttrController::class, 'index'])->name('product_attr'); 335 Route::get('attr', [\App\Http\Controllers\Bside\Product\AttrController::class, 'index'])->name('product_attr');
332 Route::get('attr/info', [\App\Http\Controllers\Bside\Product\AttrController::class, 'info'])->name('product_attr_info'); 336 Route::get('attr/info', [\App\Http\Controllers\Bside\Product\AttrController::class, 'info'])->name('product_attr_info');