作者 刘锟

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

@@ -218,9 +218,6 @@ class CopyProject extends Command @@ -218,9 +218,6 @@ class CopyProject extends Command
218 ProjectServer::createDatabase($project); 218 ProjectServer::createDatabase($project);
219 //创建表 219 //创建表
220 $this->initTable($project_id,$new_project_id); 220 $this->initTable($project_id,$new_project_id);
221 - //修改项目状态  
222 - $projectModel = new Project();  
223 - $projectModel->edit(['delete_status'=>0],['id'=>$new_project_id]);  
224 } 221 }
225 222
226 /** 223 /**
@@ -299,7 +299,7 @@ class SyncProject extends Command @@ -299,7 +299,7 @@ class SyncProject extends Command
299 DB::commit(); 299 DB::commit();
300 }catch (\Exception $e){ 300 }catch (\Exception $e){
301 DB::rollBack(); 301 DB::rollBack();
302 - throw new \Exception($e->getMessage()); 302 + throw new \Exception($e->getMessage() . $e->getFile() . $e->getLine());
303 } 303 }
304 } 304 }
305 305
@@ -73,24 +73,33 @@ class SyncSubmitTaskDistribution extends Command @@ -73,24 +73,33 @@ class SyncSubmitTaskDistribution extends Command
73 try { 73 try {
74 $table = (new SyncSubmitTaskModel())->getTable(); 74 $table = (new SyncSubmitTaskModel())->getTable();
75 $new_table = $table . '_backup_' . date('Ymd'); 75 $new_table = $table . '_backup_' . date('Ymd');
76 - 76 + if(Schema::hasTable($new_table)){
  77 + $new_table = $table . '_backup_' . date('YmdH');
  78 + }
77 //重命名当前表 79 //重命名当前表
78 Schema::rename($table, $new_table); 80 Schema::rename($table, $new_table);
79 //克隆表数据 81 //克隆表数据
80 DB::statement('CREATE TABLE ' . $table . ' LIKE ' . $new_table); 82 DB::statement('CREATE TABLE ' . $table . ' LIKE ' . $new_table);
81 83
82 //未入队的写到新表 84 //未入队的写到新表
83 - $list = DB::table($new_table)->where('status', 0)->get();  
84 - $data = [];  
85 - foreach ($list as $task) {  
86 - $data[] = [  
87 - 'type' => $task->type,  
88 - 'data' => $task->data,  
89 - 'created_at' => $task->created_at,  
90 - 'updated_at' => $task->updated_at,  
91 - ]; 85 + $page = 1;
  86 + while (true){
  87 + $list = DB::table($new_table)->where('status', 0)->forPage($page, 5000)->get();
  88 + if(!count($list)){
  89 + break;
  90 + }
  91 + $data = [];
  92 + foreach ($list as $task) {
  93 + $data[] = [
  94 + 'type' => $task->type,
  95 + 'data' => $task->data,
  96 + 'created_at' => $task->created_at,
  97 + 'updated_at' => $task->updated_at,
  98 + ];
  99 + }
  100 + $data && SyncSubmitTaskModel::insert($data);
  101 + $page++;
92 } 102 }
93 - $data && SyncSubmitTaskModel::insert($data);  
94 103
95 DB::commit(); 104 DB::commit();
96 105
@@ -32,36 +32,36 @@ class SyncImage extends Command @@ -32,36 +32,36 @@ class SyncImage extends Command
32 protected $description = '同步图片与文件'; 32 protected $description = '同步图片与文件';
33 33
34 34
35 -// public function handle(){  
36 -// $str = $this->getProjectConfig(4240);  
37 -// $imageModel = new Image();  
38 -// $strImage = '/upload/p/4240/image_other/2025-09/picture-18-copy-3.jpg,/upload/p/4240/image_other/2025-09/picture-17-copy-2.jpg,/upload/p/4240/image_other/2025-09/picture-16-copy-2.jpg,/upload/p/4240/image_other/2025-09/picture-12-copy-3.jpg,/upload/p/4240/image_other/2025-09/picture-5-copy-1.jpg,/upload/p/4240/image_other/2025-09/picture-6-copy-1.jpg,/upload/p/4240/image_other/2025-09/picture-10-copy-2.jpg,/upload/p/4240/image_other/2025-09/picture-11-copy-2.jpg,/upload/p/4240/image_other/2025-09/4-1.jpg,/upload/p/4240/image_other/2025-09/picture-18-copy-2.jpg,/upload/p/4240/image_other/2025-09/picture-16-copy-1.jpg,/upload/p/4240/image_other/2025-09/picture-17-copy-1.jpg,/upload/p/4240/image_other/2025-09/picture-15-copy-2.jpg,/upload/p/4240/image_other/2025-09/picture-13-copy-1.jpg,/upload/p/4240/image_other/2025-09/picture-14-copy-1.jpg,/upload/p/4240/image_other/2025-09/picture-12-copy-2.jpg,/upload/p/4240/image_other/2025-09/picture-10-copy-1.jpg,/upload/p/4240/image_other/2025-09/picture-11-copy-1.jpg,/upload/p/4240/image_other/2025-09/picture-20-copy-1.jpg,/upload/p/4240/image_other/2025-09/picture-18-copy-1.jpg,/upload/p/4240/image_other/2025-09/picture-19-copy-1.jpg,/upload/p/4240/image_other/2025-09/image-1-copy.jpg,/upload/p/4240/image_other/2025-09/image-2-copy.jpg,/upload/p/4240/image_other/2025-09/picture-3-copy.jpg,/upload/p/4240/image_other/2025-09/picture-6-copy.jpg,/upload/p/4240/image_other/2025-09/picture-4-copy.jpg,/upload/p/4240/image_other/2025-09/picture-5-copy.jpg,/upload/p/4240/image_other/2025-09/picture-9-copy.jpg,/upload/p/4240/image_other/2025-09/picture-7-copy.jpg,/upload/p/4240/image_other/2025-09/picture-8-copy.jpg,/upload/p/4240/image_other/2025-09/picture-15-copy-1.jpg,/upload/p/4240/image_other/2025-09/picture-14-copy.jpg,/upload/p/4240/image_other/2025-09/picture-13-copy.jpg,/upload/p/4240/image_other/2025-09/picture-12-copy-1.jpg,/upload/p/4240/image_other/2025-08/picture-44-copy.jpg,/upload/p/4240/image_other/2025-08/45.jpg,/upload/p/4240/image_other/2025-09/picture-10-copy.jpg,/upload/p/4240/image_other/2025-09/picture-11-copy.jpg,/upload/p/4240/image_other/2025-08/43.jpg,/upload/p/4240/image_other/2025-08/42.jpg,/upload/p/4240/image_other/2025-08/picture-38-copy.jpg,/upload/p/4240/image_other/2025-08/picture-37-copy.jpg,/upload/p/4240/image_other/2025-08/picture-36-copy.jpg,/upload/p/4240/image_other/2025-08/picture-35-copy-1.jpg,/upload/p/4240/image_other/2025-08/picture-30-copy.jpg,/upload/p/4240/image_other/2025-08/29.jpg,/upload/p/4240/image_other/2025-08/28-1.jpg,/upload/p/4240/image_other/2025-08/27-1.jpg,/upload/p/4240/image_other/2025-08/picture-23-copy.jpg,/upload/p/4240/image_other/2025-08/22-1.jpg,/upload/p/4240/image_other/2025-08/21.jpg,/upload/p/4240/image_other/2025-08/17.jpg,/upload/p/4240/image_other/2025-08/16.jpg,/upload/p/4240/image_other/2025-08/picture-15-copy.jpg,/upload/p/4240/image_other/2025-08/11-2.jpg,/upload/p/4240/image_other/2025-08/10-1.jpg,/upload/p/4240/image_other/2025-08/picture-6.jpg,/upload/p/4240/image_other/2025-08/picture-5.jpg,/upload/p/4240/image_other/2025-08/picture-4.jpg,/upload/p/4240/image_other/2025-08/api-standard-welded-pipe.jpg,/upload/p/4240/image_other/2025-08/gb-standard-welded-pipe.jpg,/upload/p/4240/image_other/2025-08/gost-standard-welded-pipe.jpg,/upload/p/4240/image_other/2025-08/jis-standard-welded-pipe.jpg,/upload/p/4240/image_other/2025-08/asmeastm-welded-pipe.jpg,/upload/p/4240/image_other/2025-08/en-standard-welded-pipe.jpg,/upload/p/4240/image_other/2025-08/api-corrosion-resistant-alloy-cra-pipe.jpg,/upload/p/4240/image_other/2025-08/nickel-alloy-seamless-pipe.jpg,/upload/p/4240/image_other/2025-08/duplexsuper-duplex-seamless-pipe.jpg,/upload/p/4240/image_other/2025-08/super-austenitic-seamless-pipe.jpg,/upload/p/4240/image_other/2025-08/austenitic-stainless-steel-seamless-pipe.jpg,/upload/p/4240/image_other/2025-08/thick-zinc-coated-pipe.jpg,/upload/p/4240/image_other/2025-08/galvanized-fbe-pipe.jpg,/upload/p/4240/image_other/2025-08/electro-galvanized-pipe.jpg,/upload/p/4240/image_other/2025-08/hot-dip-galvanized-pipe.jpg,/upload/p/4240/image_other/2025-08/q235-galvanized-pipe.jpg,/upload/p/4240/image_other/2025-08/q195-galvanized-pipe.jpg,/upload/p/4240/image_other/2025-08/bare-ssaw-steel-pipe.jpg,/upload/p/4240/image_other/2025-08/fbe-coated-ssaw-steel-pipe.jpg,/upload/p/4240/image_other/2025-08/x52-ssaw-steel-pipe.jpg,/upload/p/4240/image_other/2025-08/q235b-ssaw-steel-pipe.jpg,/upload/p/4240/image_other/2025-08/low-alloy-steel-erw-pipe.jpg,/upload/p/4240/image_other/2025-08/carbon-steel-erw-pipe.jpg,/upload/p/4240/image_other/2025-08/black-carbon-steel-pipe.jpg,/upload/p/4240/image_other/2025-08/picture-19-copy.jpg,/upload/p/4240/image_other/2025-08/hydrogen-energy-skid.jpg';  
39 -//// $lists = $imageModel->selectField(['project_id'=>4240],'path');  
40 -// $lists = explode(',',$strImage);  
41 -// $domain = 'http://globalso-v6-1309677403.cos.ap-hongkong.myqcloud.com';//cos域名  
42 -// foreach ($lists as $v){  
43 -// $url = $domain . $v.'?'.$str;  
44 -// echo date('Y-m-d H:i:s') . '水印路径:'. $url . PHP_EOL;  
45 -// $cdu_url = $this->coverOriginalImage($url,$v);  
46 -// echo date('Y-m-d H:i:s') . '返回的url:'. $cdu_url . PHP_EOL;  
47 -// }  
48 -// return true;  
49 -// }  
50 -  
51 public function handle(){ 35 public function handle(){
52 - $data = [];  
53 - $domain = 'https://ecdn6.globalso.com/'; 36 + $str = $this->getProjectConfig(4636);
54 $imageModel = new Image(); 37 $imageModel = new Image();
55 - $lists = $imageModel->list(['project_id'=>4240]);  
56 - foreach ($lists as $k => $v){  
57 - $url = $domain . $v['path'];  
58 - echo date('Y-m-d H:i:s') . '刷新路径:'. $url .',主键id:'. $v['id'] . PHP_EOL;  
59 - $data[] = $url; 38 +// $strImage = '/upload/p/4240/image_other/2025-09/picture-18-copy-3.jpg,/upload/p/4240/image_other/2025-09/picture-17-copy-2.jpg,/upload/p/4240/image_other/2025-09/picture-16-copy-2.jpg,/upload/p/4240/image_other/2025-09/picture-12-copy-3.jpg,/upload/p/4240/image_other/2025-09/picture-5-copy-1.jpg,/upload/p/4240/image_other/2025-09/picture-6-copy-1.jpg,/upload/p/4240/image_other/2025-09/picture-10-copy-2.jpg,/upload/p/4240/image_other/2025-09/picture-11-copy-2.jpg,/upload/p/4240/image_other/2025-09/4-1.jpg,/upload/p/4240/image_other/2025-09/picture-18-copy-2.jpg,/upload/p/4240/image_other/2025-09/picture-16-copy-1.jpg,/upload/p/4240/image_other/2025-09/picture-17-copy-1.jpg,/upload/p/4240/image_other/2025-09/picture-15-copy-2.jpg,/upload/p/4240/image_other/2025-09/picture-13-copy-1.jpg,/upload/p/4240/image_other/2025-09/picture-14-copy-1.jpg,/upload/p/4240/image_other/2025-09/picture-12-copy-2.jpg,/upload/p/4240/image_other/2025-09/picture-10-copy-1.jpg,/upload/p/4240/image_other/2025-09/picture-11-copy-1.jpg,/upload/p/4240/image_other/2025-09/picture-20-copy-1.jpg,/upload/p/4240/image_other/2025-09/picture-18-copy-1.jpg,/upload/p/4240/image_other/2025-09/picture-19-copy-1.jpg,/upload/p/4240/image_other/2025-09/image-1-copy.jpg,/upload/p/4240/image_other/2025-09/image-2-copy.jpg,/upload/p/4240/image_other/2025-09/picture-3-copy.jpg,/upload/p/4240/image_other/2025-09/picture-6-copy.jpg,/upload/p/4240/image_other/2025-09/picture-4-copy.jpg,/upload/p/4240/image_other/2025-09/picture-5-copy.jpg,/upload/p/4240/image_other/2025-09/picture-9-copy.jpg,/upload/p/4240/image_other/2025-09/picture-7-copy.jpg,/upload/p/4240/image_other/2025-09/picture-8-copy.jpg,/upload/p/4240/image_other/2025-09/picture-15-copy-1.jpg,/upload/p/4240/image_other/2025-09/picture-14-copy.jpg,/upload/p/4240/image_other/2025-09/picture-13-copy.jpg,/upload/p/4240/image_other/2025-09/picture-12-copy-1.jpg,/upload/p/4240/image_other/2025-08/picture-44-copy.jpg,/upload/p/4240/image_other/2025-08/45.jpg,/upload/p/4240/image_other/2025-09/picture-10-copy.jpg,/upload/p/4240/image_other/2025-09/picture-11-copy.jpg,/upload/p/4240/image_other/2025-08/43.jpg,/upload/p/4240/image_other/2025-08/42.jpg,/upload/p/4240/image_other/2025-08/picture-38-copy.jpg,/upload/p/4240/image_other/2025-08/picture-37-copy.jpg,/upload/p/4240/image_other/2025-08/picture-36-copy.jpg,/upload/p/4240/image_other/2025-08/picture-35-copy-1.jpg,/upload/p/4240/image_other/2025-08/picture-30-copy.jpg,/upload/p/4240/image_other/2025-08/29.jpg,/upload/p/4240/image_other/2025-08/28-1.jpg,/upload/p/4240/image_other/2025-08/27-1.jpg,/upload/p/4240/image_other/2025-08/picture-23-copy.jpg,/upload/p/4240/image_other/2025-08/22-1.jpg,/upload/p/4240/image_other/2025-08/21.jpg,/upload/p/4240/image_other/2025-08/17.jpg,/upload/p/4240/image_other/2025-08/16.jpg,/upload/p/4240/image_other/2025-08/picture-15-copy.jpg,/upload/p/4240/image_other/2025-08/11-2.jpg,/upload/p/4240/image_other/2025-08/10-1.jpg,/upload/p/4240/image_other/2025-08/picture-6.jpg,/upload/p/4240/image_other/2025-08/picture-5.jpg,/upload/p/4240/image_other/2025-08/picture-4.jpg,/upload/p/4240/image_other/2025-08/api-standard-welded-pipe.jpg,/upload/p/4240/image_other/2025-08/gb-standard-welded-pipe.jpg,/upload/p/4240/image_other/2025-08/gost-standard-welded-pipe.jpg,/upload/p/4240/image_other/2025-08/jis-standard-welded-pipe.jpg,/upload/p/4240/image_other/2025-08/asmeastm-welded-pipe.jpg,/upload/p/4240/image_other/2025-08/en-standard-welded-pipe.jpg,/upload/p/4240/image_other/2025-08/api-corrosion-resistant-alloy-cra-pipe.jpg,/upload/p/4240/image_other/2025-08/nickel-alloy-seamless-pipe.jpg,/upload/p/4240/image_other/2025-08/duplexsuper-duplex-seamless-pipe.jpg,/upload/p/4240/image_other/2025-08/super-austenitic-seamless-pipe.jpg,/upload/p/4240/image_other/2025-08/austenitic-stainless-steel-seamless-pipe.jpg,/upload/p/4240/image_other/2025-08/thick-zinc-coated-pipe.jpg,/upload/p/4240/image_other/2025-08/galvanized-fbe-pipe.jpg,/upload/p/4240/image_other/2025-08/electro-galvanized-pipe.jpg,/upload/p/4240/image_other/2025-08/hot-dip-galvanized-pipe.jpg,/upload/p/4240/image_other/2025-08/q235-galvanized-pipe.jpg,/upload/p/4240/image_other/2025-08/q195-galvanized-pipe.jpg,/upload/p/4240/image_other/2025-08/bare-ssaw-steel-pipe.jpg,/upload/p/4240/image_other/2025-08/fbe-coated-ssaw-steel-pipe.jpg,/upload/p/4240/image_other/2025-08/x52-ssaw-steel-pipe.jpg,/upload/p/4240/image_other/2025-08/q235b-ssaw-steel-pipe.jpg,/upload/p/4240/image_other/2025-08/low-alloy-steel-erw-pipe.jpg,/upload/p/4240/image_other/2025-08/carbon-steel-erw-pipe.jpg,/upload/p/4240/image_other/2025-08/black-carbon-steel-pipe.jpg,/upload/p/4240/image_other/2025-08/picture-19-copy.jpg,/upload/p/4240/image_other/2025-08/hydrogen-energy-skid.jpg';
  39 + $lists = $imageModel->selectField(['project_id'=>4636],'path');
  40 +// $lists = explode(',',$strImage);
  41 + $domain = 'http://globalso-v6-1309677403.cos.ap-hongkong.myqcloud.com';//cos域名
  42 + foreach ($lists as $v){
  43 + $url = $domain . $v.'?'.$str;
  44 + echo date('Y-m-d H:i:s') . '水印路径:'. $url . PHP_EOL;
  45 + $cdu_url = $this->coverOriginalImage($url,$v);
  46 + echo date('Y-m-d H:i:s') . '返回的url:'. $cdu_url . PHP_EOL;
60 } 47 }
61 - $yunService = new UpyunService();  
62 - return $yunService->preheatPush($data); 48 + return true;
63 } 49 }
64 50
  51 +// public function handle(){
  52 +// $data = [];
  53 +// $domain = 'https://ecdn6.globalso.com/';
  54 +// $imageModel = new Image();
  55 +// $lists = $imageModel->list(['project_id'=>4240]);
  56 +// foreach ($lists as $k => $v){
  57 +// $url = $domain . $v['path'];
  58 +// echo date('Y-m-d H:i:s') . '刷新路径:'. $url .',主键id:'. $v['id'] . PHP_EOL;
  59 +// $data[] = $url;
  60 +// }
  61 +// $yunService = new UpyunService();
  62 +// return $yunService->preheatPush($data);
  63 +// }
  64 +
65 /** 65 /**
66 * @remark :添加水印后保存图片(覆盖/非覆盖的文件未存入数据库) 66 * @remark :添加水印后保存图片(覆盖/非覆盖的文件未存入数据库)
67 * @name :uploadImages 67 * @name :uploadImages
@@ -11,12 +11,14 @@ namespace App\Http\Controllers\Api\WorkOrder; @@ -11,12 +11,14 @@ namespace App\Http\Controllers\Api\WorkOrder;
11 11
12 use App\Enums\Common\Code; 12 use App\Enums\Common\Code;
13 use App\Http\Controllers\Api\BaseController; 13 use App\Http\Controllers\Api\BaseController;
  14 +use App\Models\Ai\AiCommand;
14 use App\Models\Blog\BlogCategory; 15 use App\Models\Blog\BlogCategory;
15 use App\Models\News\NewsCategory; 16 use App\Models\News\NewsCategory;
16 use App\Models\Product\Category; 17 use App\Models\Product\Category;
17 use App\Models\Product\Keyword; 18 use App\Models\Product\Keyword;
18 use App\Models\RouteMap\RouteMap; 19 use App\Models\RouteMap\RouteMap;
19 use App\Models\Ticket\TicketUploadData; 20 use App\Models\Ticket\TicketUploadData;
  21 +use App\Services\AiCommandService;
20 use App\Services\ProjectServer; 22 use App\Services\ProjectServer;
21 use Illuminate\Http\Request; 23 use Illuminate\Http\Request;
22 use Illuminate\Support\Facades\DB; 24 use Illuminate\Support\Facades\DB;
@@ -431,4 +433,80 @@ class TicketUploadDataController extends BaseController @@ -431,4 +433,80 @@ class TicketUploadDataController extends BaseController
431 return ['id'=>$id,'title'=>$title]; 433 return ['id'=>$id,'title'=>$title];
432 } 434 }
433 } 435 }
  436 +
  437 + /**
  438 + * @remark :根据指令获取内容
  439 + * @name :sendLayoutDesign
  440 + * @author :lyh
  441 + * @method :post
  442 + * @time :2025/5/26 17:39
  443 + */
  444 + public function sendLayoutDesign(){
  445 + $this->request->validate([
  446 + 'html'=>['required'],
  447 + 'project_id'=>['required']
  448 + ],[
  449 + 'html.required' => 'html不能为空',
  450 + 'project_id.required' => '项目ID不能为空',
  451 + ]);
  452 + $aiCommonModel = new AiCommand();
  453 + $info = $aiCommonModel->read(['key'=>'ai_layout_design','project_id'=>$this->param['project_id']],['ai']);
  454 + if($info === false){
  455 + $info = $aiCommonModel->read(['key'=>'ai_layout_design','project_id'=>0],['ai']);
  456 + }
  457 + $aiCommandService = new AiCommandService();
  458 + $ai = str_replace('{html}',$this->param['html'],$info['ai']);
  459 + $result = $aiCommandService->send_layout_design($ai);
  460 + $this->response('success', Code::SUCCESS, $result);
  461 + }
  462 +
  463 + /**
  464 + * @remark :保存指令
  465 + * @name :saveAiCommand
  466 + * @author :lyh
  467 + * @method :post
  468 + * @time :2025/5/26 17:15
  469 + */
  470 + public function saveLayoutDesign(){
  471 + $this->request->validate([
  472 + 'ai'=>['required'],
  473 + 'project_id'=>['required']
  474 + ],[
  475 + 'ai.required' => '指令不能为空',
  476 + 'project_id.required' => '项目ID不能为空',
  477 + ]);
  478 + $aiCommonModel = new AiCommand();
  479 + $data = $aiCommonModel->read(['key'=>'ai_layout_design','project_id'=>$this->param['project_id']],['id']);
  480 + if($data === false) {
  481 + $param = $aiCommonModel->read(['key'=>'ai_layout_design','project_id'=>0],['name','key']);
  482 + $param['project_id'] = $this->param['project_id'];
  483 + $param['ai'] = $this->param['ai'];
  484 + $id = $aiCommonModel->addReturnId($param);
  485 + }else{
  486 + $id = $data['id'];
  487 + $aiCommonModel->edit(['ai'=>$this->param['ai']],['id'=>$data['id']]);
  488 + }
  489 + $this->response('success', Code::SUCCESS, ['id'=>$id]);
  490 + }
  491 +
  492 + /**
  493 + * @remark :获取排版指令
  494 + * @name :getAiTypesetting
  495 + * @author :lyh
  496 + * @method :post
  497 + * @time :2025/5/26 17:11
  498 + */
  499 + public function getLayoutDesignInfo(){
  500 + $this->request->validate([
  501 + 'project_id'=>['required']
  502 + ],[
  503 + 'project_id.required' => '项目ID不能为空',
  504 + ]);
  505 + $aiCommonModel = new AiCommand();
  506 + $data = $aiCommonModel->read(['key'=>'ai_layout_design','project_id'=>$this->param['project_id']],['key','ai']);
  507 + if($data === false){
  508 + $data = $aiCommonModel->read(['key'=>'ai_layout_design','project_id'=>0],['key','ai']);
  509 + }
  510 + $this->response('success', Code::SUCCESS, $data);
  511 + }
434 } 512 }
@@ -237,7 +237,7 @@ class CNoticeController extends BaseController @@ -237,7 +237,7 @@ class CNoticeController extends BaseController
237 $this->fail('未查询到项目数据'); 237 $this->fail('未查询到项目数据');
238 } 238 }
239 // --------------------------------------------------- 特殊处理通知生成页面 -------------------------------------------------------------- 239 // --------------------------------------------------- 特殊处理通知生成页面 --------------------------------------------------------------
240 - if ($type == 2 && ($project_id != 4041) && ($project_info['main_lang_id'] == 8)) { 240 + if ($type == 2 && ($project_id != 4041) && ($project_id != 4094) && ($project_info['main_lang_id'] == 8)) {
241 $this->fail('申请项目主语种为俄语,禁止翻译小语种,如若需要翻译小语种, 请联系售后人员确认!'); 241 $this->fail('申请项目主语种为俄语,禁止翻译小语种,如若需要翻译小语种, 请联系售后人员确认!');
242 } 242 }
243 243
@@ -22,6 +22,8 @@ use App\Models\Com\UpdateLog; @@ -22,6 +22,8 @@ use App\Models\Com\UpdateLog;
22 use App\Models\Devops\Servers; 22 use App\Models\Devops\Servers;
23 use App\Models\Devops\ServersIp; 23 use App\Models\Devops\ServersIp;
24 use App\Models\Domain\DomainInfo; 24 use App\Models\Domain\DomainInfo;
  25 +use App\Models\Domain\DomainInfo as DomainInfoModel;
  26 +use App\Models\Geo\GeoQuestionResult;
25 use App\Models\Industry\ProjectIndustryRelated; 27 use App\Models\Industry\ProjectIndustryRelated;
26 use App\Models\Inquiry\InquiryIP; 28 use App\Models\Inquiry\InquiryIP;
27 use App\Models\Inquiry\InquirySet; 29 use App\Models\Inquiry\InquirySet;
@@ -121,7 +123,10 @@ class ProjectLogic extends BaseLogic @@ -121,7 +123,10 @@ class ProjectLogic extends BaseLogic
121 $info['collect_test_domain'] = $info['is_upgrade'] ? CollectLog::getCollectTestDomain($id) : ''; 123 $info['collect_test_domain'] = $info['is_upgrade'] ? CollectLog::getCollectTestDomain($id) : '';
122 //获取项目所属行业 124 //获取项目所属行业
123 $info['deploy_optimize']['industry'] = ProjectIndustryRelated::where('project_id', $id)->pluck('industry_id')->toArray(); 125 $info['deploy_optimize']['industry'] = ProjectIndustryRelated::where('project_id', $id)->pluck('industry_id')->toArray();
124 - 126 + $questionModel = new GeoQuestionResult();
  127 + $info['question_qualify_count'] = $questionModel->where('project_id', $id)
  128 + ->where('hit','!=',0)->whereIn('platform',['openai', 'gemini','google_ai_overview'])
  129 + ->count();
125 return $this->success($info); 130 return $this->success($info);
126 } 131 }
127 132
@@ -794,6 +799,17 @@ class ProjectLogic extends BaseLogic @@ -794,6 +799,17 @@ class ProjectLogic extends BaseLogic
794 if(($info['type'] == Project::TYPE_ZERO) && ($info['type'] != Project::TYPE_FIVE)){ 799 if(($info['type'] == Project::TYPE_ZERO) && ($info['type'] != Project::TYPE_FIVE)){
795 $param['type'] = Project::TYPE_ONE; 800 $param['type'] = Project::TYPE_ONE;
796 } 801 }
  802 + if($param['type'] == Project::TYPE_CLOSE){
  803 + $param['site_status'] = 1;//关闭站点
  804 + $domainModel = new DomainInfoModel();
  805 + $domainInfo = $domainModel->read(['project_id'=>$this->param['id']],['id','domain','amp_status']);
  806 + if($domainInfo){
  807 + $re = curl_get('https://'.$domainInfo['domain'].'/api/stop_or_start_website');
  808 + if(isset($re['status']) && $re['status'] !== 200){
  809 + $this->fail($re['message']);
  810 + }
  811 + }
  812 + }
797 //创建默认数据库 813 //创建默认数据库
798 if($param['type'] == Project::TYPE_ONE){ 814 if($param['type'] == Project::TYPE_ONE){
799 //改为异步 815 //改为异步
@@ -17,6 +17,7 @@ use App\Models\News\News; @@ -17,6 +17,7 @@ use App\Models\News\News;
17 use App\Models\News\NewsCategory; 17 use App\Models\News\NewsCategory;
18 use App\Models\Product\Category; 18 use App\Models\Product\Category;
19 use App\Models\Product\CategoryRelated; 19 use App\Models\Product\CategoryRelated;
  20 +use App\Models\Product\Detail;
20 use App\Models\Product\Keyword; 21 use App\Models\Product\Keyword;
21 use App\Models\Product\KeywordRelated; 22 use App\Models\Product\KeywordRelated;
22 use App\Models\Product\Product; 23 use App\Models\Product\Product;
@@ -209,6 +210,11 @@ class TicketUploadDataLogic extends BaseLogic @@ -209,6 +210,11 @@ class TicketUploadDataLogic extends BaseLogic
209 CategoryRelated::saveRelated($id, $info['text']['category_id'] ?? []);//分类关联 210 CategoryRelated::saveRelated($id, $info['text']['category_id'] ?? []);//分类关联
210 KeywordRelated::saveRelated($id,$info['text']['keyword_id'] ?? []);//关键字关联 211 KeywordRelated::saveRelated($id,$info['text']['keyword_id'] ?? []);//关键字关联
211 $route = RouteMap::setRoute($data['title'],RouteMap::SOURCE_PRODUCT,$id,$info['project_id']); 212 $route = RouteMap::setRoute($data['title'],RouteMap::SOURCE_PRODUCT,$id,$info['project_id']);
  213 + //保存一条描述
  214 + if(!empty($info['text']['remark'])){
  215 + $detailModel = new Detail();
  216 + $detailModel->addReturnId(['content'=>json_encode(['content'=>$info['text']['remark']],true),'product_id'=>$id,'title'=>$info['text']['title'],'project_id'=>$info['project_id'],'column_id'=>1,'text_type'=>1]);
  217 + }
212 $productModel->edit(['route'=>$route],['id'=>$id]); 218 $productModel->edit(['route'=>$route],['id'=>$id]);
213 }catch (\Exception $e){ 219 }catch (\Exception $e){
214 $this->fail('保存失败,请联系管理员'); 220 $this->fail('保存失败,请联系管理员');
@@ -207,7 +207,7 @@ class UserLogic extends BaseLogic @@ -207,7 +207,7 @@ class UserLogic extends BaseLogic
207 $roleInfo = $roleModel->where('project_id',$this->param['project_id'])->orderBy('id','asc')->first(); 207 $roleInfo = $roleModel->where('project_id',$this->param['project_id'])->orderBy('id','asc')->first();
208 $info = $this->model->read(['role_id'=>0,'project_id'=>$this->param['project_id']]); 208 $info = $this->model->read(['role_id'=>0,'project_id'=>$this->param['project_id']]);
209 if(empty($info) || empty($roleInfo)){ 209 if(empty($info) || empty($roleInfo)){
210 - $this->fail('请先添加角色'); 210 + $this->fail('请先添加角色,联系管理员');
211 } 211 }
212 try { 212 try {
213 $this->model->edit(['role_id'=>$roleInfo['id']],['id'=>$info['id']]); 213 $this->model->edit(['role_id'=>$roleInfo['id']],['id'=>$info['id']]);
@@ -180,7 +180,7 @@ class AiBlogLogic extends BaseLogic @@ -180,7 +180,7 @@ class AiBlogLogic extends BaseLogic
180 //推送到ai的数据结构 180 //推送到ai的数据结构
181 $data = [ 181 $data = [
182 'title'=>$param['new_title'], 'thumb'=>$param['image'], 'foreword'=>$param['description'] ?? '', 182 'title'=>$param['new_title'], 'thumb'=>$param['image'], 'foreword'=>$param['description'] ?? '',
183 - 'author_id'=>$this->param['author_id'], 'url'=>$param['route'], 183 + 'author_id'=>$param['author_id'], 'url'=>$param['route'],
184 ]; 184 ];
185 if(!isset($param['description']) || empty($param['description'])){ 185 if(!isset($param['description']) || empty($param['description'])){
186 $param['description'] = truncate_text($param['text']); 186 $param['description'] = truncate_text($param['text']);
@@ -217,10 +217,12 @@ class AiBlogLogic extends BaseLogic @@ -217,10 +217,12 @@ class AiBlogLogic extends BaseLogic
217 } 217 }
218 $aiBlogService = new AiBlogService($this->user['project_id']); 218 $aiBlogService = new AiBlogService($this->user['project_id']);
219 $result = $aiBlogService->createCustomBlog($data); 219 $result = $aiBlogService->createCustomBlog($data);
  220 + $this->model->edit(['task_id'=>$result['data']['task_id'] ?? '','status'=>$this->model::STATUS_FINISH],['id'=>$id]);
220 if(isset($result['status']) && $result['status'] == 200){ 221 if(isset($result['status']) && $result['status'] == 200){
221 - $this->model->edit(['task_id'=>$result['data']['task_id'],'status'=>$this->model::STATUS_FINISH],['id'=>$id]);  
222 //todo::更新列表页 222 //todo::更新列表页
223 shell_exec("php artisan save_ai_blog_list {$this->user['project_id']} > /dev/null 2>&1 &"); 223 shell_exec("php artisan save_ai_blog_list {$this->user['project_id']} > /dev/null 2>&1 &");
  224 + }else{
  225 + $this->fail('发布失败,请编辑后重新发布');
224 } 226 }
225 return $this->success(); 227 return $this->success();
226 } 228 }
@@ -339,10 +339,17 @@ class CustomModuleContentLogic extends BaseLogic @@ -339,10 +339,17 @@ class CustomModuleContentLogic extends BaseLogic
339 DB::beginTransaction(); 339 DB::beginTransaction();
340 try { 340 try {
341 foreach ($this->param['id'] as $id) { 341 foreach ($this->param['id'] as $id) {
342 - //删除当前扩展字段  
343 - $this->delRoute($id);  
344 - $this->delContentExtend($id);  
345 - $this->model->del(['id' => $id]); 342 + $info = $this->model->read(['id' => $id], ['id','status']);
  343 + if($info !== false){
  344 + if($info['status'] != 2){
  345 + $this->model->edit(['status' => 2],['id' => $id]);
  346 + }else{
  347 + //删除当前扩展字段
  348 + $this->delRoute($id);
  349 + $this->delContentExtend($id);
  350 + $this->model->del(['id' => $id]);
  351 + }
  352 + }
346 } 353 }
347 DB::commit(); 354 DB::commit();
348 } catch (Exception $e) { 355 } catch (Exception $e) {
@@ -145,8 +145,7 @@ class GeoQuestionResLogic extends BaseLogic @@ -145,8 +145,7 @@ class GeoQuestionResLogic extends BaseLogic
145 //问题达标数据 145 //问题达标数据
146 $data['question_qualify_count'] = $questionLogModel->where('project_id', $this->user['project_id']) 146 $data['question_qualify_count'] = $questionLogModel->where('project_id', $this->user['project_id'])
147 ->where('hit','!=',0)->whereIn('platform',['openai', 'gemini','google_ai_overview']) 147 ->where('hit','!=',0)->whereIn('platform',['openai', 'gemini','google_ai_overview'])
148 - ->select(DB::raw('COUNT(DISTINCT question) as total'))  
149 - ->value('total'); 148 + ->count();
150 $latestCreatedAt = $questionLogModel 149 $latestCreatedAt = $questionLogModel
151 ->where('project_id', $this->user['project_id']) 150 ->where('project_id', $this->user['project_id'])
152 ->orderBy('id', 'desc') 151 ->orderBy('id', 'desc')
@@ -306,6 +306,8 @@ class UserLoginLogic @@ -306,6 +306,8 @@ class UserLoginLogic
306 $info['is_visualization'] = json_decode($project['is_visualization']); 306 $info['is_visualization'] = json_decode($project['is_visualization']);
307 } 307 }
308 $info['is_visualization_authority'] = $project['deploy_build']['is_visualization_authority']; 308 $info['is_visualization_authority'] = $project['deploy_build']['is_visualization_authority'];
  309 + $info['is_enable_product_cate'] = $project['deploy_build']['is_enable_product_cate'];
  310 + $info['is_enable_wrap'] = $project['deploy_build']['is_enable_wrap'];
309 $info['is_inquiry_country'] = $project['is_inquiry_country']; 311 $info['is_inquiry_country'] = $project['is_inquiry_country'];
310 $info['is_subscribe'] = $project['is_subscribe']; 312 $info['is_subscribe'] = $project['is_subscribe'];
311 $info['is_news'] = $project['is_news'] ?? 0; 313 $info['is_news'] = $project['is_news'] ?? 0;
@@ -32,24 +32,28 @@ class APublicModel extends Base @@ -32,24 +32,28 @@ class APublicModel extends Base
32 */ 32 */
33 public static function getNumByProjectId($project_id){ 33 public static function getNumByProjectId($project_id){
34 ProjectServer::useProject($project_id); 34 ProjectServer::useProject($project_id);
35 - $data = Cache::get('product_blog_news_'.$project_id);  
36 - if(!$data){  
37 - $productNumber = DB::connection('custom_mysql')->table('gl_product')  
38 - ->where('project_id', $project_id)->where('status', self::STATUS_ON)->count();  
39 - $blogNumber = DB::connection('custom_mysql')->table('gl_blog')  
40 - ->where('project_id', $project_id)->where('status', self::STATUS_ON)->count();  
41 - $newsNumber = DB::connection('custom_mysql')->table('gl_news')  
42 - ->where('project_id', $project_id)->where('status', self::STATUS_ON)->count();  
43 - $keyNumber = DB::connection('custom_mysql')->table('gl_product_keyword')  
44 - ->where('project_id', $project_id)->where('status', self::STATUS_ON)->count();  
45 - //获取项目的询盘数量  
46 - $inquiryNumber = 0;  
47 - $countInfo = DB::table('gl_count')->where('project_id', $project_id)->orderBy('id', 'desc')->first();  
48 - if(!empty($countInfo)){  
49 - $inquiryNumber = $countInfo->inquiry_num ?? 0; 35 + try {
  36 + $data = Cache::get('product_blog_news_'.$project_id);
  37 + if(!$data){
  38 + $productNumber = DB::connection('custom_mysql')->table('gl_product')
  39 + ->where('project_id', $project_id)->where('status', self::STATUS_ON)->count();
  40 + $blogNumber = DB::connection('custom_mysql')->table('gl_blog')
  41 + ->where('project_id', $project_id)->where('status', self::STATUS_ON)->count();
  42 + $newsNumber = DB::connection('custom_mysql')->table('gl_news')
  43 + ->where('project_id', $project_id)->where('status', self::STATUS_ON)->count();
  44 + $keyNumber = DB::connection('custom_mysql')->table('gl_product_keyword')
  45 + ->where('project_id', $project_id)->where('status', self::STATUS_ON)->count();
  46 + //获取项目的询盘数量
  47 + $inquiryNumber = 0;
  48 + $countInfo = DB::table('gl_count')->where('project_id', $project_id)->orderBy('id', 'desc')->first();
  49 + if(!empty($countInfo)){
  50 + $inquiryNumber = $countInfo->inquiry_num ?? 0;
  51 + }
  52 + $data = ['product'=>$productNumber,'blog'=>$blogNumber,'news'=>$newsNumber,'key'=>$keyNumber,'inquiry'=>$inquiryNumber];
  53 + Cache::add('product_blog_news_'.$project_id,$data,30 * 60);
50 } 54 }
51 - $data = ['product'=>$productNumber,'blog'=>$blogNumber,'news'=>$newsNumber,'key'=>$keyNumber,'inquiry'=>$inquiryNumber];  
52 - Cache::add('product_blog_news_'.$project_id,$data,30 * 60); 55 + }catch (\Exception $e){
  56 + return [];
53 } 57 }
54 DB::disconnect('custom_mysql'); 58 DB::disconnect('custom_mysql');
55 return $data; 59 return $data;
@@ -453,8 +453,8 @@ class SyncSubmitTaskService @@ -453,8 +453,8 @@ class SyncSubmitTaskService
453 453
454 //关杰 全局过滤 满足 name、message 8-16 纯字母不含空格 ip 荷兰 mobile 10位纯数字 过滤 454 //关杰 全局过滤 满足 name、message 8-16 纯字母不含空格 ip 荷兰 mobile 10位纯数字 过滤
455 if( 455 if(
456 - strlen($data['data']['name']??'') <= 16 && strlen($data['data']['name']??'') >= 8 &&  
457 - strlen($data['data']['message']??'') <= 16 && strlen($data['data']['message']??'') >= 8 && 456 + strlen($data['data']['name']??'') >= 8 &&
  457 + strlen($data['data']['message']??'') >= 8 &&
458 preg_match('/^[a-zA-Z]+$/', $data['data']['name']??'') && 458 preg_match('/^[a-zA-Z]+$/', $data['data']['name']??'') &&
459 preg_match('/^[a-zA-Z]+$/', $data['data']['message']??'') && 459 preg_match('/^[a-zA-Z]+$/', $data['data']['message']??'') &&
460 preg_match('/^\d+$/', $data['data']['phone']??'') && 460 preg_match('/^\d+$/', $data['data']['phone']??'') &&
@@ -464,8 +464,8 @@ class SyncSubmitTaskService @@ -464,8 +464,8 @@ class SyncSubmitTaskService
464 throw new InquiryFilterException( '全局过滤'); 464 throw new InquiryFilterException( '全局过滤');
465 } 465 }
466 if( 466 if(
467 - strlen($data['data']['name']??'') <= 16 && strlen($data['data']['name']??'') >= 8 &&  
468 - strlen($data['data']['message']??'') <= 16 && strlen($data['data']['message']??'') >= 8 && 467 + strlen($data['data']['name']??'') >= 8 &&
  468 + strlen($data['data']['message']??'') >= 8 &&
469 preg_match('/^[a-zA-Z]+$/', $data['data']['name']??'') && 469 preg_match('/^[a-zA-Z]+$/', $data['data']['name']??'') &&
470 preg_match('/^[a-zA-Z]+$/', $data['data']['message']??'') && 470 preg_match('/^[a-zA-Z]+$/', $data['data']['message']??'') &&
471 in_array($data['country']??'', ['荷兰', '俄罗斯']) 471 in_array($data['country']??'', ['荷兰', '俄罗斯'])
@@ -484,10 +484,17 @@ class SyncSubmitTaskService @@ -484,10 +484,17 @@ class SyncSubmitTaskService
484 ){ 484 ){
485 throw new InquiryFilterException( '全局过滤2'); 485 throw new InquiryFilterException( '全局过滤2');
486 } 486 }
  487 + if(
  488 + in_array($data['country']??'', ['荷兰', '俄罗斯']) &&
  489 + strlen($data['data']['message']??'') >= 8 &&
  490 + preg_match('/^[a-zA-Z]+$/', $data['data']['message']??'')
  491 + ){
  492 + throw new InquiryFilterException( '全局过滤3');
  493 + }
487 494
488 //1913宁波市鄞州永鑫 ip荷兰 message 8-16 纯字母不含空格 495 //1913宁波市鄞州永鑫 ip荷兰 message 8-16 纯字母不含空格
489 if($project_id == 1913 && in_array($data['country']??'', ['荷兰', '俄罗斯']) 496 if($project_id == 1913 && in_array($data['country']??'', ['荷兰', '俄罗斯'])
490 - && strlen($data['data']['message']??'') <= 16 && strlen($data['data']['message']??"") >= 8 497 + && strlen($data['data']['message']??"") >= 8
491 && preg_match('/^[a-zA-Z]+$/', $data['data']['message']??'') 498 && preg_match('/^[a-zA-Z]+$/', $data['data']['message']??'')
492 ){ 499 ){
493 throw new InquiryFilterException( '被刷数据'); 500 throw new InquiryFilterException( '被刷数据');
@@ -57,7 +57,6 @@ Route::any('get_external_link_by_domain', [\App\Http\Controllers\Api\PrivateCont @@ -57,7 +57,6 @@ Route::any('get_external_link_by_domain', [\App\Http\Controllers\Api\PrivateCont
57 Route::any('get_project_detail', [\App\Http\Controllers\Api\PrivateController::class, 'getProjectByDomain'])->name('api.project_detail'); 57 Route::any('get_project_detail', [\App\Http\Controllers\Api\PrivateController::class, 'getProjectByDomain'])->name('api.project_detail');
58 // 获取项目产品信息 58 // 获取项目产品信息
59 Route::any('get_project_product', [\App\Http\Controllers\Api\PrivateController::class, 'getProjectProduct'])->name('api.project_product'); 59 Route::any('get_project_product', [\App\Http\Controllers\Api\PrivateController::class, 'getProjectProduct'])->name('api.project_product');
60 -// --------------------- 站群服务 ------------------------------------------  
61 // --------------------- 监控服务 ------------------------------------------ 60 // --------------------- 监控服务 ------------------------------------------
62 Route::any('get_project_online', [\App\Http\Controllers\Api\PrivateController::class, 'getProjectOnline'])->name('api.get_project_online'); 61 Route::any('get_project_online', [\App\Http\Controllers\Api\PrivateController::class, 'getProjectOnline'])->name('api.get_project_online');
63 // 将项目标记为广告状态 62 // 将项目标记为广告状态
@@ -104,5 +103,8 @@ Route::prefix('ticket_upload')->group(function () { @@ -104,5 +103,8 @@ Route::prefix('ticket_upload')->group(function () {
104 Route::any('/getNewsCate', [\App\Http\Controllers\Api\WorkOrder\TicketUploadDataController::class, 'getNewsCate'])->name('ticket_upload.getNewsCate'); 103 Route::any('/getNewsCate', [\App\Http\Controllers\Api\WorkOrder\TicketUploadDataController::class, 'getNewsCate'])->name('ticket_upload.getNewsCate');
105 Route::any('/saveCategory', [\App\Http\Controllers\Api\WorkOrder\TicketUploadDataController::class, 'saveCategory'])->name('ticket_upload.saveCategory'); 104 Route::any('/saveCategory', [\App\Http\Controllers\Api\WorkOrder\TicketUploadDataController::class, 'saveCategory'])->name('ticket_upload.saveCategory');
106 Route::any('/saveKeyword', [\App\Http\Controllers\Api\WorkOrder\TicketUploadDataController::class, 'saveKeyword'])->name('ticket_upload.saveKeyword'); 105 Route::any('/saveKeyword', [\App\Http\Controllers\Api\WorkOrder\TicketUploadDataController::class, 'saveKeyword'])->name('ticket_upload.saveKeyword');
  106 + Route::any('/sendLayoutDesign', [\App\Http\Controllers\Api\WorkOrder\TicketUploadDataController::class, 'sendLayoutDesign'])->name('ticket_upload.sendLayoutDesign');
  107 + Route::any('/saveLayoutDesign', [\App\Http\Controllers\Api\WorkOrder\TicketUploadDataController::class, 'saveLayoutDesign'])->name('ticket_upload.saveLayoutDesign');
  108 + Route::any('/getLayoutDesignInfo', [\App\Http\Controllers\Api\WorkOrder\TicketUploadDataController::class, 'getLayoutDesignInfo'])->name('ticket_upload.getLayoutDesignInfo');
107 }); 109 });
108 110