作者 lyh

Merge branch 'develop' of http://47.244.231.31:8099/zhl/globalso-v6 into develop

  1 +<?php
  2 +
  3 +namespace App\Console\Commands;
  4 +
  5 +use App\Helper\Arr;
  6 +use App\Helper\Common;
  7 +use App\Helper\Gpt;
  8 +use App\Helper\Translate;
  9 +use App\Http\Logic\Aside\Project\ProjectLogic;
  10 +use App\Models\Ai\AiCommand;
  11 +use App\Models\Mail\Mail;
  12 +use App\Models\Project\DeployOptimize;
  13 +use App\Models\Project\ProjectUpdateTdk;
  14 +use App\Models\User\User;
  15 +use App\Services\ProjectServer;
  16 +use Illuminate\Console\Command;
  17 +use Illuminate\Support\Facades\Cache;
  18 +use Illuminate\Support\Facades\DB;
  19 +use Illuminate\Support\Facades\Redis;
  20 +
  21 +/**
  22 + * 清除项目sdk
  23 + * Class InitProject
  24 + * @package App\Console\Commands
  25 + * @author zbj
  26 + * @date 2023/10/8
  27 + */
  28 +class ClearSeoTdk extends Command
  29 +{
  30 + /**
  31 + * The name and signature of the console command.
  32 + *
  33 + * @var string
  34 + */
  35 + protected $signature = 'clear_seo_tdk {project_id}';
  36 +
  37 + /**
  38 + * The console command description.
  39 + *
  40 + * @var string
  41 + */
  42 + protected $description = '清除项目sdk';
  43 +
  44 + /**
  45 + * Create a new command instance.
  46 + *
  47 + * @return void
  48 + */
  49 + public function __construct()
  50 + {
  51 + parent::__construct();
  52 + }
  53 +
  54 + /**
  55 + * '表' => [
  56 + * '指令key' => '表字段'
  57 + * ]
  58 + * @return array
  59 + * @author zbj
  60 + * @date 2023/11/3
  61 + */
  62 + protected $maps = [
  63 + 'gl_web_custom_template' => [
  64 + 'title' => '',
  65 + 'keywords' => '',
  66 + 'description' => '',
  67 + ],
  68 + 'gl_product' => [
  69 + 'seo_mate' => null
  70 + ],
  71 + 'gl_product_category' => [
  72 + 'seo_title' => '',
  73 + 'seo_keywords' => '',
  74 + 'seo_des' => '',
  75 + ],
  76 + 'gl_blog' => [
  77 + 'seo_title' => '',
  78 + 'seo_keywords' => '',
  79 + 'seo_description' => '',
  80 + ],
  81 + 'gl_blog_category' => [
  82 + 'seo_title' => '',
  83 + 'seo_keywords' => '',
  84 + 'seo_des' => '',
  85 + ],
  86 + 'gl_news' => [
  87 + 'seo_title' => '',
  88 + 'seo_keywords' => '',
  89 + 'seo_description' => '',
  90 + ],
  91 + 'gl_news_category' => [
  92 + 'seo_title' => '',
  93 + 'seo_keywords' => '',
  94 + 'seo_des' => '',
  95 + ],
  96 + 'gl_product_keyword' => [
  97 + 'seo_title' => '',
  98 + 'seo_keywords' => '',
  99 + 'seo_description' => '',
  100 + 'keyword_title' => '',
  101 + 'keyword_content' => '',
  102 + ]
  103 + ];
  104 +
  105 + /**
  106 + * @return bool
  107 + */
  108 + public function handle()
  109 + {
  110 + $project_id = $this->argument('project_id');
  111 + $project = ProjectServer::useProject($project_id);
  112 + if(!$project){
  113 + echo '项目不存在或数据库未配置' . PHP_EOL;
  114 + exit;
  115 + }
  116 + if ($this->confirm('你确认清空['. $project['title'] .']的sdk?')) {
  117 + foreach ($this->maps as $table => $data) {
  118 + echo date('Y-m-d H:i:s') . '清空SDK--' . $table . PHP_EOL;
  119 + DB::connection('custom_mysql')->table($table)->update($data);
  120 + }
  121 + }
  122 +
  123 + echo date('Y-m-d H:i:s') . '清空完成' . PHP_EOL;
  124 + }
  125 +}
@@ -12,6 +12,8 @@ use Illuminate\Http\File; @@ -12,6 +12,8 @@ use Illuminate\Http\File;
12 12
13 class ProjectFilePDF extends Command 13 class ProjectFilePDF extends Command
14 { 14 {
  15 + use CmdSignal;
  16 +
15 /** 17 /**
16 * The name and signature of the console command. 18 * The name and signature of the console command.
17 * 19 *
@@ -26,12 +28,17 @@ class ProjectFilePDF extends Command @@ -26,12 +28,17 @@ class ProjectFilePDF extends Command
26 */ 28 */
27 protected $description = '网站项目数据,生成PDF文件'; 29 protected $description = '网站项目数据,生成PDF文件';
28 30
29 - protected $AiccWechat; 31 + protected ProjectAssociation $AiccWechat;
30 32
31 - protected $DataFile; 33 + protected DataFile $DataFile;
32 34
33 protected $time; 35 protected $time;
34 36
  37 + // 最大支持5个进程
  38 + public int $maxRunNumber = 50;
  39 +
  40 + public FileController $fileController;
  41 +
35 /** 42 /**
36 * Create a new command instance. 43 * Create a new command instance.
37 * 44 *
@@ -42,40 +49,27 @@ class ProjectFilePDF extends Command @@ -42,40 +49,27 @@ class ProjectFilePDF extends Command
42 $this->AiccWechat = new ProjectAssociation(); 49 $this->AiccWechat = new ProjectAssociation();
43 $this->DataFile = new DataFile(); 50 $this->DataFile = new DataFile();
44 $this->time = date("Y-m"); 51 $this->time = date("Y-m");
  52 + $this->fileController = new FileController();
45 parent::__construct(); 53 parent::__construct();
46 } 54 }
47 55
48 - /**  
49 - * Execute the console command.  
50 - *  
51 - * @return int  
52 - */  
53 - public function handle() 56 + public function start(): int
54 { 57 {
55 - $data = $this->get_data();  
56 - # 详细数据  
57 - $items = $data['items'];  
58 - # 总分页  
59 - $totalPage = $data['totalPage'];  
60 - $this->dataPush($items);  
61 - if ($totalPage > 1) {  
62 - for ($page = 2; $page <= $totalPage; $page++) {  
63 - $da = $this->get_data();  
64 - $this->dataPush($da['items']);  
65 - }  
66 - }  
67 - $this->info('生成pdf完成'); 58 + $status = 1; # 1 - 正常, 0 - 禁用
  59 + $is_pdf = 0; # 0 - 未生成 1 - 已生成 2 - 其它问题
  60 + $lists = $this->DataFile::query()->where('status', $status)
  61 + ->where('project_id', '!=', 0)
  62 + ->where('friend_id', '!=', 0)
  63 + ->where('user_id', '!=', 0)
  64 + ->where('is_pdf', $is_pdf)->where('created_at', 'like', $this->time . '%')->first();
  65 + if (is_null($lists)) {
  66 + $this->debug_echo('没有任务,等待中');
  67 + sleep(60);
68 return 0; 68 return 0;
69 } 69 }
70 -  
71 - /**  
72 - * 数据生成并保存  
73 - * @param array $items  
74 - * @return void  
75 - */  
76 - public function dataPush(array $items)  
77 - {  
78 - foreach ($items as $item) { 70 + $key = $this->signature . '-' . $lists->id;
  71 + $count = redis_get($key);
  72 + $item = $lists->getOriginal();
79 $project_id = $item->project_id; 73 $project_id = $item->project_id;
80 $user_id = $item->user_id; 74 $user_id = $item->user_id;
81 $friend_id = $item->friend_id; 75 $friend_id = $item->friend_id;
@@ -84,28 +78,25 @@ class ProjectFilePDF extends Command @@ -84,28 +78,25 @@ class ProjectFilePDF extends Command
84 $html = $this->html($project_data); 78 $html = $this->html($project_data);
85 $filename = hash('md5', $this->time . '-' . $project_id . '-' . $friend_id . '-' . $user_id); 79 $filename = hash('md5', $this->time . '-' . $project_id . '-' . $friend_id . '-' . $user_id);
86 $file_path = $this->savePDF($html, $filename); 80 $file_path = $this->savePDF($html, $filename);
87 - var_dump($file_path);  
88 - $this->DataFile->saveData(compact('project_id', 'user_id', 'friend_id', 'file_path') + ['time' => $this->time]); 81 + if (empty($file_path)) {
  82 + $this->debug_echo('pdf生成失败!');
  83 + return 0;
89 } 84 }
  85 + $isRes = $this->DataFile->saveData(compact('project_id', 'user_id', 'friend_id', 'file_path') + ['time' => $this->time]);
  86 + if (!$isRes) {
  87 + if ($count == 2) {
  88 + $lists->is_pdf = 2;
  89 + $lists->save();
  90 + $this->debug_echo('项目文件数据保存失败! - 其他原因 - ' . $key);
  91 + } else {
  92 + redis_add($key, $count + 1);
  93 + $this->debug_echo('项目文件数据保存失败! - ' . $key);
90 } 94 }
91 -  
92 -  
93 - public function get_data($page = 1, $perPage = 20)  
94 - {  
95 - $data = $this->AiccWechat->allData($page, $perPage);  
96 - # 总条数  
97 - $total = $data['total'];  
98 - if (empty($total)) {  
99 - $this->error('暂无绑定AICC微信数据');  
100 - return 0;  
101 } 95 }
102 - # 详细数据  
103 - $items = $data['items'];  
104 - # 总分页  
105 - $totalPage = $data['totalPage'];  
106 - # 当前页  
107 - $currentPage = $data['currentPage'];  
108 - return compact('total', 'items', 'totalPage', 'currentPage'); 96 + $lists->is_pdf = 1;
  97 + $lists->save();
  98 + $this->debug_echo('项目文件数据保存成功!');
  99 + return 0;
109 } 100 }
110 101
111 public function savePDF($html, $filename) 102 public function savePDF($html, $filename)
@@ -138,16 +129,13 @@ class ProjectFilePDF extends Command @@ -138,16 +129,13 @@ class ProjectFilePDF extends Command
138 // 获取PDF内容 129 // 获取PDF内容
139 $pdfContent = $dompdf->output(); 130 $pdfContent = $dompdf->output();
140 131
141 - $fileController = new FileController();  
142 -  
143 // 将PDF内容保存到文件 132 // 将PDF内容保存到文件
144 @file_put_contents($savePath, $pdfContent); 133 @file_put_contents($savePath, $pdfContent);
145 134
146 // 创建一个文件实例 135 // 创建一个文件实例
147 $file = new File($savePath); 136 $file = new File($savePath);
148 -var_dump($file->getFilename());  
149 -exit();  
150 - return $fileController->single($file); 137 +
  138 + return $this->fileController->single($file);
151 } 139 }
152 140
153 /** 141 /**
  1 +<?php
  2 +
  3 +namespace App\Console\Commands;
  4 +
  5 +use App\Helper\Arr;
  6 +use App\Helper\Common;
  7 +use App\Helper\Gpt;
  8 +use App\Helper\Translate;
  9 +use App\Models\Ai\AiCommand;
  10 +use App\Models\Mail\Mail;
  11 +use App\Models\Project\DeployOptimize;
  12 +use App\Models\Project\Project;
  13 +use App\Models\Project\ProjectUpdateTdk;
  14 +use App\Models\User\User;
  15 +use App\Services\ProjectServer;
  16 +use Illuminate\Console\Command;
  17 +use Illuminate\Support\Facades\Cache;
  18 +use Illuminate\Support\Facades\DB;
  19 +use Illuminate\Support\Facades\Redis;
  20 +
  21 +/**
  22 + * 初始化项目
  23 + * Class InitProject
  24 + * @package App\Console\Commands
  25 + * @author zbj
  26 + * @date 2023/10/8
  27 + */
  28 +class TdkTest extends Command
  29 +{
  30 + /**
  31 + * The name and signature of the console command.
  32 + *
  33 + * @var string
  34 + */
  35 + protected $signature = 'tdk_test';
  36 +
  37 + /**
  38 + * The console command description.
  39 + *
  40 + * @var string
  41 + */
  42 + protected $description = 'keywords ,分割加空格';
  43 +
  44 + /**
  45 + * Create a new command instance.
  46 + *
  47 + * @return void
  48 + */
  49 + public function __construct()
  50 + {
  51 + parent::__construct();
  52 + }
  53 +
  54 + /**
  55 + * '表' => [
  56 + * '指令key' => '表字段'
  57 + * ]
  58 + * @return array
  59 + * @author zbj
  60 + * @date 2023/11/3
  61 + */
  62 + protected $maps = [
  63 + 'gl_web_custom_template' => 'keywords',
  64 + 'gl_product' => 'seo_mate.keyword',
  65 + 'gl_product_category' => 'seo_keywords',
  66 + 'gl_blog' => 'seo_keywords',
  67 + 'gl_blog_category' => 'seo_keywords',
  68 + 'gl_news' => 'seo_keywords',
  69 + 'gl_news_category' => 'seo_keywords',
  70 + 'gl_product_keyword' => 'seo_keywords',
  71 + ];
  72 +
  73 + /**
  74 + * @return bool
  75 + */
  76 + public function handle()
  77 + {
  78 + $project_ids = Project::where('type', Project::TYPE_TWO)->pluck('id')->toArray();
  79 + foreach ($project_ids as $project_id){
  80 + echo date('Y-m-d H:i:s') . ' start project_id: ' . $project_id . PHP_EOL;
  81 + ProjectServer::useProject($project_id);
  82 + foreach ($this->maps as $table=>$field){
  83 + $list = DB::connection('custom_mysql')->table($table)->get();
  84 + foreach ($list as $item){
  85 + $item = (array) $item;
  86 + $field_arr = explode('.', $field);
  87 + if ($field == 'seo_mate.keyword') {
  88 + $data = json_decode($item[$field_arr[0]], true);
  89 + $value = $data['keyword'] ?? '';
  90 + if(!$value){
  91 + continue;
  92 + }
  93 + $data['keyword'] = implode(', ', array_map('trim', explode(',', $value)));
  94 + DB::connection('custom_mysql')->table($table)->where('id', $item['id'])->update(['seo_mate' => json_encode($data)]);
  95 + } else {
  96 + $value = $item[$field];
  97 + if(!$value){
  98 + continue;
  99 + }
  100 + $value = implode(', ', array_map('trim', explode(',', $value)));
  101 + DB::connection('custom_mysql')->table($table)->where('id', $item['id'])->update([$field => $value]);
  102 + }
  103 + }
  104 + }
  105 + }
  106 + }
  107 +}
@@ -139,18 +139,16 @@ class ProjectUpdate extends Command @@ -139,18 +139,16 @@ class ProjectUpdate extends Command
139 'seo_title' => $item['seo_title'] ?? '', 139 'seo_title' => $item['seo_title'] ?? '',
140 'seo_keywords' => $item['seo_keywords'] ?? '', 140 'seo_keywords' => $item['seo_keywords'] ?? '',
141 'seo_description' => $item['seo_description'] ?? '', 141 'seo_description' => $item['seo_description'] ?? '',
  142 + 'route' => $this->get_url_route($item['url'])
142 ]); 143 ]);
143 - $route = $this->set_map($this->get_url_route($item['url']), RouteMap::SOURCE_PRODUCT_KEYWORD, $id, $project_id);  
144 - $model->edit(['route' => $route], ['id' => $id]); 144 + $this->set_map($this->get_url_route($item['url']), RouteMap::SOURCE_PRODUCT_KEYWORD, $id, $project_id);
  145 +
  146 + CollectTask::_insert($item['url'], $project_id, RouteMap::SOURCE_PRODUCT_KEYWORD, $id, $link_type, $language_list, $page_list);
145 } catch (\Exception $e) { 147 } catch (\Exception $e) {
146 echo 'date:' . date('Y-m-d H:i:s') . ', task_id: ' . $task->id . ', error: ' . $e->getMessage() . PHP_EOL; 148 echo 'date:' . date('Y-m-d H:i:s') . ', task_id: ' . $task->id . ', error: ' . $e->getMessage() . PHP_EOL;
147 continue; 149 continue;
148 } 150 }
149 - } else {  
150 - $id = $keyword['id'];  
151 } 151 }
152 -  
153 - CollectTask::_insert($item['url'], $project_id, RouteMap::SOURCE_PRODUCT_KEYWORD, $id, $link_type, $language_list, $page_list);  
154 } 152 }
155 } 153 }
156 } 154 }
@@ -271,19 +269,17 @@ class ProjectUpdate extends Command @@ -271,19 +269,17 @@ class ProjectUpdate extends Command
271 'keyword' => $item['keywords'] ?? '', 269 'keyword' => $item['keywords'] ?? '',
272 'description' => $item['description'] ?? '' 270 'description' => $item['description'] ?? ''
273 ]), 271 ]),
274 - 'status' => Product::STATUS_ON 272 + 'status' => Product::STATUS_ON,
  273 + 'route' => $this->get_url_route($item['url'])
275 ]); 274 ]);
276 - $route = $this->set_map($this->get_url_route($item['url']), RouteMap::SOURCE_PRODUCT, $id, $project_id);  
277 - $model->edit(['route' => $route], ['id' => $id]); 275 + $this->set_map($this->get_url_route($item['url']), RouteMap::SOURCE_PRODUCT, $id, $project_id);
  276 +
  277 + CollectTask::_insert($item['url'], $project_id, RouteMap::SOURCE_PRODUCT, $id, $link_type, $language_list, $page_list);
278 } catch (\Exception $e) { 278 } catch (\Exception $e) {
279 echo 'date:' . date('Y-m-d H:i:s') . ', task_id: ' . $task->id . ', error: ' . $e->getMessage() . PHP_EOL; 279 echo 'date:' . date('Y-m-d H:i:s') . ', task_id: ' . $task->id . ', error: ' . $e->getMessage() . PHP_EOL;
280 continue; 280 continue;
281 } 281 }
282 - } else {  
283 - $id = $product['id'];  
284 } 282 }
285 -  
286 - CollectTask::_insert($item['url'], $project_id, RouteMap::SOURCE_PRODUCT, $id, $link_type, $language_list, $page_list);  
287 } 283 }
288 } 284 }
289 } 285 }
@@ -318,6 +314,15 @@ class ProjectUpdate extends Command @@ -318,6 +314,15 @@ class ProjectUpdate extends Command
318 if (!$news) { 314 if (!$news) {
319 try { 315 try {
320 $item['ttile'] = $this->special2str($item['ttile']); 316 $item['ttile'] = $this->special2str($item['ttile']);
  317 +
  318 + if (is_array($item['images'])) {
  319 + $image = $item['images'][0] ?? '';
  320 + } else {
  321 + $image = $item['images'] ?? '';
  322 + }
  323 + if(strpos($image,'//') === 0){
  324 + $image = 'https:'.$image;
  325 + }
321 $id = $model->addReturnId([ 326 $id = $model->addReturnId([
322 'project_id' => $project_id, 327 'project_id' => $project_id,
323 'name' => $item['ttile'], 328 'name' => $item['ttile'],
@@ -325,20 +330,18 @@ class ProjectUpdate extends Command @@ -325,20 +330,18 @@ class ProjectUpdate extends Command
325 'seo_keywords' => $item['keywords'] ?? '', 330 'seo_keywords' => $item['keywords'] ?? '',
326 'seo_description' => $item['description'] ?? '', 331 'seo_description' => $item['description'] ?? '',
327 'text' => $item['content'] ?? '', 332 'text' => $item['content'] ?? '',
328 - 'image' => $item['images'][0] ?? '',  
329 - 'status' => $api_type == 'news' ? News::STATUS_ONE : Blog::STATUS_ONE 333 + 'image' => $image,
  334 + 'status' => $api_type == 'news' ? News::STATUS_ONE : Blog::STATUS_ONE,
  335 + 'url' => $this->get_url_route($item['url'])
330 ]); 336 ]);
331 - $route = $this->set_map($this->get_url_route($item['url']), $api_type == 'news' ? RouteMap::SOURCE_NEWS : RouteMap::SOURCE_BLOG, $id, $project_id);  
332 - $model->edit(['url' => $route], ['id' => $id]); 337 + $this->set_map($this->get_url_route($item['url']), $api_type == 'news' ? RouteMap::SOURCE_NEWS : RouteMap::SOURCE_BLOG, $id, $project_id);
  338 +
  339 + CollectTask::_insert($item['url'], $project_id, $api_type == 'news' ? RouteMap::SOURCE_NEWS : RouteMap::SOURCE_BLOG, $id, $link_type, $language_list, $page_list);
333 } catch (\Exception $e) { 340 } catch (\Exception $e) {
334 echo 'date:' . date('Y-m-d H:i:s') . ', task_id: ' . $task->id . ', error: ' . $e->getMessage() . PHP_EOL; 341 echo 'date:' . date('Y-m-d H:i:s') . ', task_id: ' . $task->id . ', error: ' . $e->getMessage() . PHP_EOL;
335 continue; 342 continue;
336 } 343 }
337 - } else {  
338 - $id = $news['id'];  
339 } 344 }
340 -  
341 - CollectTask::_insert($item['url'], $project_id, $api_type == 'news' ? RouteMap::SOURCE_NEWS : RouteMap::SOURCE_BLOG, $id, $link_type, $language_list, $page_list);  
342 } 345 }
343 } 346 }
344 } 347 }
@@ -375,19 +378,17 @@ class ProjectUpdate extends Command @@ -375,19 +378,17 @@ class ProjectUpdate extends Command
375 'keywords' => $item['keywords'] ?? '', 378 'keywords' => $item['keywords'] ?? '',
376 'description' => $item['description'] ?? '', 379 'description' => $item['description'] ?? '',
377 'html' => $item['content'] ?? '', 380 'html' => $item['content'] ?? '',
378 - 'status' => 1 381 + 'status' => 1,
  382 + 'url' => $this->get_url_route($item['url'])
379 ]); 383 ]);
380 - $route = $this->set_map($this->get_url_route($item['url']), RouteMap::SOURCE_PAGE, $id, $project_id);  
381 - $model->edit(['url' => $route], ['id' => $id]); 384 + $this->set_map($this->get_url_route($item['url']), RouteMap::SOURCE_PAGE, $id, $project_id);
  385 +
  386 + CollectTask::_insert($item['url'], $project_id, RouteMap::SOURCE_PAGE, $id, $link_type, $language_list, $page_list);
382 } catch (\Exception $e) { 387 } catch (\Exception $e) {
383 echo 'date:' . date('Y-m-d H:i:s') . ', task_id: ' . $task->id . ', error: ' . $e->getMessage() . PHP_EOL; 388 echo 'date:' . date('Y-m-d H:i:s') . ', task_id: ' . $task->id . ', error: ' . $e->getMessage() . PHP_EOL;
384 continue; 389 continue;
385 } 390 }
386 - } else {  
387 - $id = $custom['id'];  
388 } 391 }
389 -  
390 - CollectTask::_insert($item['url'], $project_id, RouteMap::SOURCE_PAGE, $id, $link_type, $language_list, $page_list);  
391 } 392 }
392 } 393 }
393 } 394 }
@@ -463,10 +464,10 @@ class ProjectUpdate extends Command @@ -463,10 +464,10 @@ class ProjectUpdate extends Command
463 'title' => $item['name'], 464 'title' => $item['name'],
464 'pid' => $pid, 465 'pid' => $pid,
465 'keywords' => $item['keywords'] ?? '', 466 'keywords' => $item['keywords'] ?? '',
466 - 'describe' => $item['description'] ?? '' 467 + 'describe' => $item['description'] ?? '',
  468 + 'route' => $this->get_url_route($item['url'])
467 ]); 469 ]);
468 - $route = $this->set_map($this->get_url_route($item['url']), RouteMap::SOURCE_PRODUCT_CATE, $parent_id, $project_id);  
469 - $model->edit(['route' => $route], ['id' => $parent_id]); 470 + $this->set_map($this->get_url_route($item['url']), RouteMap::SOURCE_PRODUCT_CATE, $parent_id, $project_id);
470 } catch (\Exception $e) { 471 } catch (\Exception $e) {
471 echo 'date:' . date('Y-m-d H:i:s') . ', category_insert error: ' . $e->getMessage() . PHP_EOL; 472 echo 'date:' . date('Y-m-d H:i:s') . ', category_insert error: ' . $e->getMessage() . PHP_EOL;
472 continue; 473 continue;
@@ -520,10 +521,9 @@ class ProjectUpdate extends Command @@ -520,10 +521,9 @@ class ProjectUpdate extends Command
520 //路由入库 521 //路由入库
521 protected function set_map($route, $source, $source_id, $project_id) 522 protected function set_map($route, $source, $source_id, $project_id)
522 { 523 {
523 - if (empty($route)) {  
524 - return '';  
525 - }  
526 - 524 + if ($route) {
  525 + $route_map = RouteMap::where('project_id', $project_id)->where('source', $source)->where('source_id', $source_id)->first();
  526 + if (!$route_map) {
527 $route_map = new RouteMap(); 527 $route_map = new RouteMap();
528 $route_map->project_id = $project_id; 528 $route_map->project_id = $project_id;
529 $route_map->source = $source; 529 $route_map->source = $source;
@@ -537,7 +537,7 @@ class ProjectUpdate extends Command @@ -537,7 +537,7 @@ class ProjectUpdate extends Command
537 } 537 }
538 538
539 $route_map->save(); 539 $route_map->save();
540 -  
541 - return $route; 540 + }
  541 + }
542 } 542 }
543 } 543 }
  1 +<?php
  2 +
  3 +namespace App\Console\Commands\Update;
  4 +
  5 +use App\Helper\Arr;
  6 +use App\Http\Logic\Bside\Product\CategoryLogic;
  7 +use App\Models\Blog\Blog;
  8 +use App\Models\Collect\CollectTask;
  9 +use App\Models\Com\UpdateLog;
  10 +use App\Models\News\News;
  11 +use App\Models\Product\Category;
  12 +use App\Models\Product\Keyword;
  13 +use App\Models\Product\Product;
  14 +use App\Models\RouteMap\RouteMap;
  15 +use App\Models\Template\BCustomTemplate;
  16 +use App\Models\WebSetting\WebSettingReceiving;
  17 +use App\Services\ProjectServer;
  18 +use Illuminate\Console\Command;
  19 +use Illuminate\Support\Facades\DB;
  20 +use Illuminate\Support\Facades\Redis;
  21 +
  22 +/**
  23 + * 4.0,5.0升级到6.0,内容同步
  24 + * Class ProjectImport
  25 + * @package App\Console\Commands
  26 + * @author Akun
  27 + * @date 2023/10/9 15:04
  28 + */
  29 +class Temp extends Command
  30 +{
  31 + /**
  32 + * The name and signature of the console command.
  33 + *
  34 + * @var string
  35 + */
  36 + protected $signature = 'project_update_temp';
  37 +
  38 + /**
  39 + * The console command description.
  40 + *
  41 + * @var string
  42 + */
  43 + protected $description = '执行项目升级任务';
  44 +
  45 +
  46 + public function handle()
  47 + {
  48 + $this->start_update();
  49 + }
  50 +
  51 + protected function start_update()
  52 + {
  53 +
  54 +// $data = UpdateLog::where('project_id','<=',530)->where('api_type','category')->get();
  55 + $data = UpdateLog::where('project_id', '=', 298)->where('api_type', 'category')->get();
  56 + foreach ($data as $task) {
  57 + $project_id = $task->project_id;
  58 + $api_type = $task->api_type;
  59 + $api_url_arr = explode('?', $task->api_url);
  60 + $api_url = $api_url_arr[0];
  61 +
  62 + echo 'date:' . date('Y-m-d H:i:s') . ', task_id: ' . $task->id . ', task_type: ' . $api_type . ', update start' . PHP_EOL;
  63 +
  64 + //设置数据库
  65 + $project = ProjectServer::useProject($project_id);
  66 + if ($project) {
  67 + //分类
  68 + $url = $api_url . '?' . http_build_query(['w' => 'category']);
  69 + $data = curl_c($url);
  70 + if (isset($data['code']) && $data['code'] == 200) {
  71 + $items = $data['data'] ?? [];
  72 + $this->category_insert($project_id, $items, 0);
  73 + } else {
  74 + continue;
  75 + }
  76 + }
  77 + //关闭数据库
  78 + DB::disconnect('custom_mysql');
  79 +
  80 + echo 'date:' . date('Y-m-d H:i:s') . ', task_id: ' . $task->id . ', task_type: ' . $api_type . ', update end ' . PHP_EOL;
  81 + }
  82 + }
  83 +
  84 + //获取地址路由
  85 + protected function get_url_route($url)
  86 + {
  87 + $arr = parse_url($url);
  88 + if (empty($arr['path'])) {
  89 + return '';
  90 + }
  91 + $path = $arr['path'];
  92 +
  93 + if (strpos($path, '.') !== false) {
  94 + $path = substr($path, 0, strpos($path, '.'));
  95 + }
  96 +
  97 + $path_arr = explode('/', $path);
  98 +
  99 + return end($path_arr) ? end($path_arr) : $path_arr[count($path_arr) - 2];
  100 + }
  101 +
  102 + //多级分类入库
  103 + protected function category_insert($project_id, $items, $pid = 0)
  104 + {
  105 + $model = new Category();
  106 + foreach ($items as $item) {
  107 + if ($item['name'] ?? '') {
  108 + $parent = $model->read(['pid' => $pid, 'title' => $item['name']], 'id');
  109 + if (!$parent) {
  110 + try {
  111 + $item['name'] = $this->special2str($item['name']);
  112 + $parent_id = $model->addReturnId([
  113 + 'project_id' => $project_id,
  114 + 'title' => $item['name'],
  115 + 'pid' => $pid,
  116 + 'keywords' => $item['keywords'] ?? '',
  117 + 'describe' => $item['description'] ?? '',
  118 + 'route' => $this->get_url_route($item['url'])
  119 + ]);
  120 + $this->set_map($this->get_url_route($item['url']), RouteMap::SOURCE_PRODUCT_CATE, $parent_id, $project_id);
  121 + } catch (\Exception $e) {
  122 + echo 'date:' . date('Y-m-d H:i:s') . ', category_insert error: ' . $e->getMessage() . PHP_EOL;
  123 + continue;
  124 + }
  125 + } else {
  126 + $parent_id = $parent['id'];
  127 + }
  128 +
  129 + if (!empty($item['children'])) {
  130 + $this->category_insert($project_id, $item['children'], $parent_id);
  131 + }
  132 + }
  133 + }
  134 + }
  135 +
  136 + //获取分类名称数组
  137 + protected function get_category_name_arr($category, $pid = 0)
  138 + {
  139 + foreach ($category as $k => $v) {
  140 + if ($v['parent'] == $pid) {
  141 + return $v;
  142 + }
  143 + }
  144 +
  145 + return [];
  146 + }
  147 +
  148 + //特殊字符转换
  149 + protected function special2str($str)
  150 + {
  151 + if (strpos($str, ';') === false) {
  152 + return $str;
  153 + }
  154 +
  155 + $list = [
  156 + '&lt;' => '<',
  157 + '&gt;' => '>',
  158 + '&amp;' => '&',
  159 + '&acute;' => '´',
  160 + '&quot;' => '“',
  161 + '&nbsp;' => ' '
  162 + ];
  163 +
  164 + foreach ($list as $k => $v) {
  165 + $str = str_replace($k, $v, $str);
  166 + }
  167 +
  168 + return $str;
  169 + }
  170 +
  171 + //路由入库
  172 + protected function set_map($route, $source, $source_id, $project_id)
  173 + {
  174 + if ($route) {
  175 + $route_map = RouteMap::where('project_id', $project_id)->where('source', $source)->where('source_id', $source_id)->first();
  176 + if (!$route_map) {
  177 + $route_map = new RouteMap();
  178 + $route_map->project_id = $project_id;
  179 + $route_map->source = $source;
  180 + $route_map->source_id = $source_id;
  181 + $route_map->route = $route;
  182 +
  183 + if ($source == RouteMap::SOURCE_NEWS) {
  184 + $route_map->path = RouteMap::SOURCE_NEWS;
  185 + } elseif ($source == RouteMap::SOURCE_BLOG) {
  186 + $route_map->path = RouteMap::SOURCE_BLOG;
  187 + }
  188 +
  189 + $route_map->save();
  190 + }
  191 + }
  192 + }
  193 +}
@@ -360,7 +360,7 @@ class UpdateSeoTdk extends Command @@ -360,7 +360,7 @@ class UpdateSeoTdk extends Command
360 //随机取 360 //随机取
361 shuffle($main_keywords); 361 shuffle($main_keywords);
362 $main_keywords = array_slice($main_keywords, 0, $num); 362 $main_keywords = array_slice($main_keywords, 0, $num);
363 - $str = implode(",", $main_keywords); 363 + $str = implode(", ", $main_keywords);
364 } 364 }
365 return $str; 365 return $str;
366 } 366 }
@@ -24,10 +24,12 @@ class WebsiteData extends Command @@ -24,10 +24,12 @@ class WebsiteData extends Command
24 protected $description = '向AICC推送数据'; 24 protected $description = '向AICC推送数据';
25 25
26 // 最大支持5个进程 26 // 最大支持5个进程
27 - public $maxRunNumber = 50; 27 + public int $maxRunNumber = 50;
28 28
29 protected $time; 29 protected $time;
30 30
  31 + protected $url;
  32 +
31 /** 33 /**
32 * Create a new command instance. 34 * Create a new command instance.
33 * 35 *
@@ -35,13 +37,17 @@ class WebsiteData extends Command @@ -35,13 +37,17 @@ class WebsiteData extends Command
35 */ 37 */
36 public function __construct() 38 public function __construct()
37 { 39 {
38 - $this->time = date('y-d'); 40 + $this->time = date('Y-m');
  41 + $this->url = env('AICC_URL');
39 parent::__construct(); 42 parent::__construct();
40 } 43 }
41 44
42 45
43 public function start(): int 46 public function start(): int
44 { 47 {
  48 + # 0 - 未推送
  49 + # 1 - 已推送
  50 + # 2 - 其他问题
45 $status = 0; 51 $status = 0;
46 $lists = DataFile::query()->where('status', $status) 52 $lists = DataFile::query()->where('status', $status)
47 ->where('created_at', 'like', $this->time . '%')->first(); 53 ->where('created_at', 'like', $this->time . '%')->first();
@@ -50,44 +56,23 @@ class WebsiteData extends Command @@ -50,44 +56,23 @@ class WebsiteData extends Command
50 sleep(60); 56 sleep(60);
51 return 0; 57 return 0;
52 } 58 }
53 - var_dump($lists);  
54 - exit();  
55 - $data = $lists['items'];  
56 -  
57 - $url = env('AICC_URL');  
58 - $msg = http_post($url, json_encode(compact('data')));  
59 - 59 + $key = $this->signature . '-' . $lists->id;
  60 + $count = redis_get($key);
  61 + $isRes = http_post($this->url, json_encode(['data' => $lists->getOriginal()]));
  62 + if (!$isRes) {
  63 + if ($count == 2) {
  64 + $lists->is_pdf = 2;
  65 + $lists->save();
  66 + $this->debug_echo('项目文件数据推送失败! - 其他原因 - ' . $key);
  67 + } else {
  68 + redis_add($key, $count + 1);
  69 + $this->debug_echo('项目文件数据推送失败! - ' . $key);
60 } 70 }
61 -  
62 - /**  
63 - * Execute the console command.  
64 - *  
65 - * @return int  
66 - */  
67 -// public function handle()  
68 -// {  
69 -// $DataFile = new DataFile();  
70 -// $data = $DataFile->allData();  
71 -// # 详细数据  
72 -// $items = $data['items'];  
73 -// # 总分页  
74 -// $totalPage = $data['totalPage'];  
75 -// $this->post_data($items);  
76 -// if ($totalPage > 1) {  
77 -// for ($page = 2; $page <= $totalPage; $page++) {  
78 -// $da = $DataFile->allData($page);  
79 -// $this->post_data($da['items']);  
80 -// }  
81 -// }  
82 -// $this->info('项目文件数据推送完成!');  
83 -// return 0;  
84 -// }  
85 -  
86 - public function post_data($data)  
87 - {  
88 - $url = env('AICC_URL');  
89 - $msg = http_post($url, json_encode(compact('data')));  
90 - print_r($msg); 71 + }
  72 + $lists->status = 1;
  73 + $lists->save();
  74 + $this->debug_echo('项目文件数据保存成功!');
  75 + return 0;
91 } 76 }
92 77
93 } 78 }
@@ -213,7 +213,7 @@ class Common @@ -213,7 +213,7 @@ class Common
213 } 213 }
214 } 214 }
215 } 215 }
216 - return implode(',',$ar_keywords); 216 + return implode(', ',$ar_keywords);
217 } 217 }
218 218
219 219
@@ -9,6 +9,7 @@ use GuzzleHttp\Client; @@ -9,6 +9,7 @@ use GuzzleHttp\Client;
9 use GuzzleHttp\Exception\GuzzleException; 9 use GuzzleHttp\Exception\GuzzleException;
10 use Illuminate\Support\Carbon; 10 use Illuminate\Support\Carbon;
11 use App\Models\File\File; 11 use App\Models\File\File;
  12 +use Illuminate\Support\Facades\Redis;
12 13
13 define('HTTP_OPENAI_URL', 'http://openai.waimaoq.com/'); 14 define('HTTP_OPENAI_URL', 'http://openai.waimaoq.com/');
14 /** 15 /**
@@ -616,3 +617,29 @@ function getRouteMap($source,$source_id){ @@ -616,3 +617,29 @@ function getRouteMap($source,$source_id){
616 } 617 }
617 return $route; 618 return $route;
618 } 619 }
  620 +
  621 +function redis_get($key){
  622 + return Redis::connection()->client()->get($key);
  623 +}
  624 +function redis_del(...$key){
  625 + return Redis::connection()->client()->del(...$key);
  626 +}
  627 +
  628 +function redis_set($key,$val,$ttl=3600){
  629 + return Redis::connection()->client()->set($key,$val,$ttl);
  630 +}
  631 +
  632 +/**
  633 + * 添加缓存,存在则失败
  634 + * @param $key
  635 + * @param $val
  636 + * @param int $ttl
  637 + * @return mixed
  638 + * @author:dc
  639 + * @time 2023/10/25 9:48
  640 + */
  641 +function redis_add($key,$val,$ttl=3600){
  642 + return Redis::connection()->client()->eval(
  643 + "return redis.call('exists',KEYS[1])<1 and redis.call('setex',KEYS[1],ARGV[2],ARGV[1])", [$key, $val, $ttl], 1
  644 + );
  645 +}
@@ -7,18 +7,17 @@ use App\Helper\Common; @@ -7,18 +7,17 @@ use App\Helper\Common;
7 use App\Helper\Translate; 7 use App\Helper\Translate;
8 use App\Http\Controllers\Bside\BaseController; 8 use App\Http\Controllers\Bside\BaseController;
9 use App\Http\Controllers\Bside\:写入日志; 9 use App\Http\Controllers\Bside\:写入日志;
  10 +use App\Http\Logic\Bside\Ai\AiCommandLogic;
  11 +use App\Models\Ai\AiCommand;
10 use App\Models\Ai\AiLog; 12 use App\Models\Ai\AiLog;
11 use App\Models\Project\DeployOptimize; 13 use App\Models\Project\DeployOptimize;
12 use App\Models\Project\Project; 14 use App\Models\Project\Project;
13 15
14 class AiCommandController extends BaseController 16 class AiCommandController extends BaseController
15 { 17 {
16 - //获取文本内容  
17 - public $chat_url = 'v2/openai_chat_qqs';  
18 /** 18 /**
19 - * @name :ai生成  
20 - * @author :liyuhang  
21 - * @method 19 + * @author zbj
  20 + * @date 2023/11/22
22 */ 21 */
23 public function ai_http_post(){ 22 public function ai_http_post(){
24 $this->request->validate([ 23 $this->request->validate([
@@ -28,39 +27,19 @@ class AiCommandController extends BaseController @@ -28,39 +27,19 @@ class AiCommandController extends BaseController
28 'keywords.required' => '关键字不能为空', 27 'keywords.required' => '关键字不能为空',
29 'key.required' => '场景不能为空', 28 'key.required' => '场景不能为空',
30 ]); 29 ]);
31 - #TODO 通过key获取到ai指令对象  
32 - $data = Common::send_openai_msg($this->chat_url,$this->param,$this->companyName($this->param['key'],$this->user['project_id']));  
33 - $data['text'] = Common::deal_keywords($data['text']);  
34 - $data['text'] = Common::deal_str($data['text']);  
35 - $param = [  
36 - 'key'=>$this->param['key'],  
37 - 'keywords'=>$this->param['keywords'],  
38 - 'remark'=>json_encode($data)  
39 - ];  
40 - $this->set_ai_log($param);  
41 - $this->response('success',Code::SUCCESS,$data);  
42 - }  
43 30
44 - /**  
45 - * @remark :获取公司英文名称  
46 - * @name :companyName  
47 - * @author :lyh  
48 - * @method :post  
49 - * @time :2023/10/30 11:22  
50 - */  
51 - public function companyName($key,$project_id){ 31 + $text = AiCommandLogic::instance()->ai_send();
52 $data = [ 32 $data = [
53 - 'news_remark',  
54 - 'blog_remark',  
55 - 'product_long_description' 33 + 'code' => $text ? 200 : 500,
  34 + 'text' => $text
56 ]; 35 ];
57 - $projectOptimizeModel = new DeployOptimize();  
58 - $info = $projectOptimizeModel->read(['project_id'=>$project_id],['id','company_en_name','company_en_description']);  
59 - if(in_array($key,$data)){  
60 - return $info['company_en_description'];  
61 - }else{  
62 - return $info['company_en_name'];  
63 - } 36 + $param = [
  37 + 'key' => $this->param['key'],
  38 + 'keywords' => $this->param['keywords'],
  39 + 'remark' => $text
  40 + ];
  41 + $this->set_ai_log($param);
  42 + $this->response('success', Code::SUCCESS, $data);
64 } 43 }
65 44
66 /** 45 /**
  1 +<?php
  2 +
  3 +namespace App\Http\Logic\Bside\Ai;
  4 +
  5 +use App\Helper\Common;
  6 +use App\Helper\Gpt;
  7 +use App\Helper\Translate;
  8 +use App\Http\Logic\Bside\BaseLogic;
  9 +use App\Models\Ai\AiCommand;
  10 +use App\Models\Project\DeployOptimize;
  11 +use Illuminate\Support\Facades\Cache;
  12 +
  13 +class AiCommandLogic extends BaseLogic
  14 +{
  15 + public function __construct()
  16 + {
  17 + parent::__construct();
  18 + $this->param = $this->requestAll;
  19 + $this->model = new AiCommand();
  20 + }
  21 +
  22 + /**
  23 + * @author zbj
  24 + * @date 2023/11/22
  25 + */
  26 + public function getPrompt($is_batch = 0){
  27 + $ai_command = $this->model->where('key', $this->param['key'])->where('is_batch', $is_batch)->first();
  28 + if(!$ai_command){
  29 + $this->fail('指令不存在');
  30 + }
  31 + $prompt = $ai_command->ai;
  32 +
  33 + if(strpos($prompt, '{keyword}') !== false) {
  34 + $prompt = str_replace('{keyword}', $this->param['keywords'], $prompt);
  35 + }
  36 + if(strpos($prompt, '{company introduction}') !== false) {
  37 + $company_introduction = $this->getDeployOptimize('company_en_description');
  38 + $prompt = str_replace('{company introduction}', $company_introduction, $prompt);
  39 + }
  40 + if(strpos($prompt, '{company name}') !== false) {
  41 + $company_name = $this->getDeployOptimize('company_en_name');
  42 + $prompt = str_replace('{company name}', $company_name, $prompt);
  43 + }
  44 + if(strpos($prompt, '{core keywords 8}') !== false) {
  45 + $main_keywords = $this->getDeployOptimize('main_keywords');
  46 + if ($main_keywords) {
  47 + $main_keywords = explode("\r\n", $main_keywords);
  48 + //随机取
  49 + shuffle($main_keywords);
  50 + $main_keywords = array_slice($main_keywords, 0, 8);
  51 + $main_keywords = implode(", ", $main_keywords);
  52 + $prompt = str_replace('{core keywords 8}', $main_keywords, $prompt);
  53 + }else{
  54 + $prompt = '';
  55 + }
  56 + }
  57 +
  58 + if(trim($ai_command->ai) == '{core keywords 8}'){
  59 + $ai_send = false;
  60 + }else{
  61 + $lang = $this->getLang($this->param['keywords']);
  62 + $prompt .= '.Please answer in ' . ($lang ?: 'English');
  63 + $ai_send = true;
  64 + }
  65 +
  66 + return [
  67 + 'prompt' => $prompt,
  68 + 'scene' => $ai_command->scene,
  69 + 'ai_send' => $ai_send,
  70 + ];
  71 + }
  72 +
  73 + /**
  74 + * @param $content
  75 + * @return string
  76 + * @author zbj
  77 + * @date 2023/11/22
  78 + */
  79 + public function getLang($content){
  80 + $result = Translate::translateSl($content);
  81 + if (isset($result['texts']['sl']) && isset(Translate::$tls_list[$result['texts']['sl']])) {
  82 + $lang = Translate::$tls_list[$result['texts']['sl']]['lang_en'];
  83 + } else {
  84 + $lang = 'English';
  85 + }
  86 + return $lang;
  87 + }
  88 +
  89 + /**
  90 + * @param string $key
  91 + * @return false|mixed|string
  92 + * @author zbj
  93 + * @date 2023/11/22
  94 + */
  95 + public function getDeployOptimize($key = ''){
  96 + $project_id = $this->project['id'];
  97 + $cache_key = 'project_deploy_optimize_info_' . $project_id;
  98 + $info = Cache::get($cache_key);
  99 + if(!$info){
  100 + $projectOptimizeModel = new DeployOptimize();
  101 + $info = $projectOptimizeModel->read(['project_id' => $project_id], ['id', 'company_en_name', 'company_en_description', 'main_keywords']);
  102 + Cache::put($cache_key, $info, 600);
  103 + }
  104 + if($key){
  105 + return $info[$key] ??'';
  106 + }
  107 + return $info;
  108 + }
  109 +
  110 + /**
  111 + * @param int $is_batch
  112 + * @return array|string|string[]
  113 + * @author zbj
  114 + * @date 2023/11/22
  115 + */
  116 + public function ai_send($is_batch = 0){
  117 + $prompt = $this->getPrompt($is_batch);
  118 + if(!$prompt['ai_send']){
  119 + return $prompt['prompt'];
  120 + }
  121 + $text = Gpt::instance()->openai_chat_qqs($prompt['prompt'], $prompt['scene']);
  122 + $text = Common::deal_keywords($text);
  123 + return Common::deal_str($text);
  124 + }
  125 +}
@@ -29,8 +29,6 @@ class CollectTask extends Base @@ -29,8 +29,6 @@ class CollectTask extends Base
29 'project_id' => $project_id, 29 'project_id' => $project_id,
30 'source' => $source, 30 'source' => $source,
31 'source_id' => $source_id, 31 'source_id' => $source_id,
32 - 'domain' => $url_arr['host'],  
33 - 'route' => $url_arr['path'],  
34 'language' => '' 32 'language' => ''
35 ]; 33 ];
36 34
@@ -48,7 +46,6 @@ class CollectTask extends Base @@ -48,7 +46,6 @@ class CollectTask extends Base
48 'created_at' => $now, 46 'created_at' => $now,
49 'updated_at' => $now, 47 'updated_at' => $now,
50 ]; 48 ];
51 - }  
52 49
53 if ($link_type > 0 && $language_list && in_array($url_arr['path'], $page_list)) { 50 if ($link_type > 0 && $language_list && in_array($url_arr['path'], $page_list)) {
54 $domain_arr = explode('.', $url_arr['host']); 51 $domain_arr = explode('.', $url_arr['host']);
@@ -77,4 +74,5 @@ class CollectTask extends Base @@ -77,4 +74,5 @@ class CollectTask extends Base
77 74
78 self::insert($data); 75 self::insert($data);
79 } 76 }
  77 + }
80 } 78 }