作者 Your Name
  1 +<?php
  2 +
  3 +namespace App\Console\Commands\Domain;
  4 +
  5 +use App\Models\Project\Project;
  6 +use App\Models\Project\ProjectServerBackup;
  7 +use Illuminate\Console\Command;
  8 +
  9 +class EmergencyRelieve extends Command
  10 +{
  11 + protected $signature = 'emergency_relieve';
  12 + protected $description = '危机解除,恢复项目服务器';
  13 +
  14 + public function handle()
  15 + {
  16 + $backup_list = ProjectServerBackup::where('status', ProjectServerBackup::STATUS_NO)->get();
  17 +
  18 + $project_model = new Project();
  19 + if ($backup_list->count() > 0) {
  20 + foreach ($backup_list as $item) {
  21 + $project_model->edit(['serve_id' => $item->serve_id], ['id' => $item->project_id]);
  22 + $item->status = ProjectServerBackup::STATUS_YES;
  23 + $item->save();
  24 +
  25 + $this->output('项目ID:' . $item->project_id . ',恢复成功');
  26 + }
  27 + }
  28 + }
  29 +
  30 + /**
  31 + * 输出处理日志
  32 + * @param $message
  33 + */
  34 + public function output($message)
  35 + {
  36 + echo date('Y-m-d H:i:s') . ' | ' . $message . PHP_EOL;
  37 + }
  38 +}
  1 +<?php
  2 +
  3 +namespace App\Console\Commands\Domain;
  4 +
  5 +use App\Models\Com\Notify;
  6 +use App\Models\Devops\ServersIp;
  7 +use App\Models\Domain\DomainCreateTask;
  8 +use App\Models\Project\Project;
  9 +use App\Models\Project\ProjectServerBackup;
  10 +use App\Models\Domain\DomainInfo;
  11 +use Illuminate\Console\Command;
  12 +use Symfony\Component\Process\Process;
  13 +
  14 +class EmergencyRenewSite extends Command
  15 +{
  16 + protected $signature = 'emergency_renew_site';
  17 + protected $description = '紧急重建站点';
  18 +
  19 + public function handle()
  20 + {
  21 + //目标服务器
  22 + $target_server_id = 1;
  23 + $target_server = ServersIp::select(['id', 'ip', 'domain'])->where('servers_id', $target_server_id)->first()->toArray();
  24 +
  25 + //受灾服务器
  26 + $server_ids = [9, 13];
  27 + $server_ip_ids = ServersIp::whereIn('servers_id', $server_ids)->get()->pluck('id')->toArray();
  28 +
  29 + //获取所有受灾项目
  30 + $project_list = Project::select(['id', 'serve_id', 'title'])->whereIn('serve_id', $server_ip_ids)->get();
  31 + $domain_model = new DomainInfo();
  32 + $create_model = new DomainCreateTask();
  33 + $notify_model = new Notify();
  34 + $backup_model = new ProjectServerBackup();
  35 + foreach ($project_list as $value) {
  36 + $domain_info = $domain_model->read(['project_id' => $value->id, 'status' => 1], ['id', 'domain']);
  37 + if (!$domain_info) {
  38 + //过滤未绑定正式域名的项目
  39 + continue;
  40 + }
  41 +
  42 + //判断域名是否已经解析到目标服务器
  43 + if (!$this->check_cname($domain_info['domain'], $target_server)) {
  44 + $this->output($domain_info['domain'] . ' | 未解析到目标服务器');
  45 + }
  46 +
  47 + //获取站点其他域名
  48 + $other_domain = [];
  49 + if (strpos($domain_info['domain'], 'www.') === 0) {
  50 + $other_domain[] = str_replace('www', '*', $domain_info['domain']);
  51 +
  52 + $top_domain = str_replace('www.', '', $domain_info['domain']);
  53 + if ($this->check_cname($top_domain, $target_server)) {
  54 + $other_domain[] = $top_domain;
  55 + }
  56 + }
  57 +
  58 + //创建目标服务器建站任务
  59 + $map_create = [
  60 + 'type' => DomainCreateTask::TYPE_MAIN,
  61 + 'server_id' => $target_server_id,
  62 + 'project_id' => $value->id,
  63 + 'domain_id' => $domain_info['id'],
  64 + 'status' => DomainCreateTask::STATUS_UN,
  65 + ];
  66 + $task_info = $create_model->read($map_create, ['id']);
  67 + if (!$task_info) {
  68 + $map_create['other_domain'] = json_encode($other_domain);
  69 + $create_model->add($map_create);
  70 + }
  71 +
  72 + //创建目标服务器站点页面生成任务
  73 + $map_notify = [
  74 + 'type' => Notify::TYPE_MASTER,
  75 + 'server_id' => $target_server_id,
  76 + 'project_id' => $value->id,
  77 + 'status' => Notify::STATUS_INIT,
  78 + 'route' => Notify::ROUTE_ALL,
  79 + ];
  80 + $notify_info = $notify_model->read($map_notify);
  81 + if (!$notify_info) {
  82 + $map_notify['data'] = json_encode(['domain' => $domain_info['domain'], 'url' => [], 'language' => []]);
  83 + $map_notify['sort'] = 9;
  84 + $notify_model->add($map_notify);
  85 + }
  86 +
  87 + //备份项目原始服务器
  88 + $backup_info = $backup_model->read(['project_id' => $value->id, 'status' => ProjectServerBackup::STATUS_NO], ['id']);
  89 + if ($backup_info) {
  90 + $backup_model->edit(['serve_id' => $value->serve_id], ['id' => $backup_info['id']]);
  91 + } else {
  92 + $backup_model->add(['project_id' => $value->id, 'serve_id' => $value->serve_id]);
  93 + }
  94 +
  95 + //更改项目服务器
  96 + $value->serve_id = $target_server_id;
  97 + $value->save();
  98 +
  99 + $this->output($domain_info['domain'] . ' | success');
  100 + }
  101 + }
  102 +
  103 + /**
  104 + * 验证是否cname或者A记录解析到目标服务器
  105 + * @param $domain
  106 + * @param $server_info
  107 + * @return mixed
  108 + * @author zbj
  109 + * @date 2023/11/13
  110 + */
  111 + public function check_cname($domain, $server_info)
  112 + {
  113 + $process = new Process(['nslookup', '-qt=a', $domain]);
  114 + $process->run();
  115 + $output = explode(PHP_EOL, $process->getOutput());
  116 + foreach ($output as $line) {
  117 + if ($line) {
  118 + $checkA = strpos($line, $server_info['ip']) !== false;
  119 + if ($checkA) {
  120 + return $domain;
  121 + }
  122 + }
  123 + }
  124 +
  125 + //是否cname
  126 + $process = new Process(['nslookup', '-qt=cname', $domain]);
  127 + $process->run();
  128 + $output = explode(PHP_EOL, $process->getOutput());
  129 + foreach ($output as $line) {
  130 + if ($line) {
  131 + $checkCname = (strpos($line, $server_info['domain']) !== false);
  132 + if ($checkCname) {
  133 + return $domain;
  134 + }
  135 + }
  136 + }
  137 + return false;
  138 + }
  139 +
  140 + /**
  141 + * 输出处理日志
  142 + * @param $message
  143 + */
  144 + public function output($message)
  145 + {
  146 + echo date('Y-m-d H:i:s') . ' | ' . $message . PHP_EOL;
  147 + }
  148 +}
  1 +<?php
  2 +/**
  3 + * @remark :
  4 + * @name :SyncImage.php
  5 + * @author :lyh
  6 + * @method :post
  7 + * @time :2024/9/11 10:39
  8 + */
  9 +
  10 +namespace App\Console\Commands\Sync;
  11 +
  12 +use App\Models\File\Image;
  13 +use App\Models\File\ImageSetting;
  14 +use Illuminate\Console\Command;
  15 +use Qcloud\Cos\Client;
  16 +
  17 +class SyncImage extends Command
  18 +{
  19 + /**
  20 + * The name and signature of the console command.
  21 + *
  22 + * @var string
  23 + */
  24 + protected $signature = 'sync_file';
  25 +
  26 + /**
  27 + * The console command description.
  28 + *
  29 + * @var string
  30 + */
  31 + protected $description = '同步图片与文件';
  32 +
  33 +
  34 + public function handle(){
  35 + $str = $this->getProjectConfig(501);
  36 + $imageModel = new Image();
  37 + $lists = $imageModel->list(['project_id'=>501]);
  38 + $domain = 'http://globalso-v6-1309677403.cos.ap-hongkong.myqcloud.com';//cos域名
  39 + foreach ($lists as $k => $v){
  40 + $url = $domain . $v['path'].'/'.$str;
  41 + echo date('Y-m-d H:i:s') . '水印路径:'. $url .',主键id:'. $v['id'] . PHP_EOL;
  42 +// $this->coverOriginalImage($url,$v['path']);
  43 + }
  44 + return true;
  45 + }
  46 +
  47 + /**
  48 + * @remark :添加水印后保存图片(覆盖/非覆盖的文件未存入数据库)
  49 + * @name :uploadImages
  50 + * @author :lyh
  51 + * @method :post
  52 + * @time :2024/8/19 17:06
  53 + */
  54 + public function coverOriginalImage($url,$cdnUrl){
  55 + // 获取水印后的图片内容
  56 + $imageContent = file_get_contents($url);
  57 + // 使用 COS SDK 将图片重新上传并覆盖原图
  58 + $cos = config('filesystems.disks.cos');
  59 + $cosClient = new Client([
  60 + 'region' => $cos['region'],
  61 + 'credentials' => [
  62 + 'secretId' => $cos['credentials']['secretId'],
  63 + 'secretKey' => $cos['credentials']['secretKey'],
  64 + ],
  65 + ]);
  66 + // 上传并覆盖原图
  67 + $cosClient->putObject([
  68 + 'Bucket' => $cos['bucket'],
  69 + 'Key' => $cdnUrl, // 去掉域名部分,得到存储桶内的路径
  70 + 'Body' => $imageContent,
  71 + ]);
  72 + return $cos['cdn'].$cdnUrl;
  73 + }
  74 +
  75 + /**
  76 + * @remark :获取图片配置
  77 + * @name :getProjectConfig
  78 + * @author :lyh
  79 + * @method :post
  80 + * @time :2024/8/24 11:03
  81 + */
  82 + public function getProjectConfig($project_id = 0){
  83 + $str = '';
  84 + $imageSettingModel = new ImageSetting();
  85 + $settingInfo = $imageSettingModel->read(['project_id'=>$project_id]);
  86 + if($settingInfo !== false){
  87 + if($settingInfo['status'] == 1 && !empty($settingInfo['image_data'])){
  88 + $image_data = json_decode($settingInfo['image_data'],true);
  89 + foreach ($image_data as $k => $v){
  90 + if (str_starts_with($v, "image/")) {
  91 + $v = 'image/'.urlSafeBase64Encode(substr($v, strlen("image/")));
  92 + }
  93 + $image_data[$k] = $v;
  94 + }
  95 + $str = 'watermark/1/'.implode('/',$image_data);
  96 + return $str;
  97 + }
  98 + if($settingInfo['status'] == 2 && !empty($settingInfo['str_data'])){
  99 + $str_data = json_decode($settingInfo['str_data'],true);
  100 + foreach ($str_data as $k => $v){
  101 + $arr = explode('/',$v);
  102 + if ($arr[0] == 'text') {
  103 + $arr[1] = urlSafeBase64Encode($arr[1]);
  104 + $v = implode('/',$arr);
  105 + }
  106 + if ($arr[0] == 'font') {
  107 + $arr[1] = urlSafeBase64Encode($arr[1]);
  108 + $v = implode('/',$arr);
  109 + }
  110 + if ($arr[0] == 'fill') {
  111 + $arr[1] = urlSafeBase64Encode($arr[1]);
  112 + $v = implode('/',$arr);
  113 + }
  114 + $str_data[$k] = $v;
  115 + }
  116 + $str = 'watermark/2/'.implode('/',$str_data);
  117 + return $str;
  118 + }
  119 + }
  120 + return $str;
  121 + }
  122 +}
  1 +<?php
  2 +namespace App\Models\Project;
  3 +
  4 +use App\Models\Base;
  5 +
  6 +class ProjectServerBackup extends Base
  7 +{
  8 + protected $table = 'gl_project_server_backup';
  9 +
  10 + const STATUS_NO = 0;
  11 + const STATUS_YES = 1;
  12 +}
@@ -56,7 +56,7 @@ class MessagePush extends Base @@ -56,7 +56,7 @@ class MessagePush extends Base
56 $model->friend_id = $friend_id; 56 $model->friend_id = $friend_id;
57 $model->type = self::TYPE_INQUIRY; 57 $model->type = self::TYPE_INQUIRY;
58 $model->ref_ids = $id; 58 $model->ref_ids = $id;
59 - $model->content = '[' . date('H:i', strtotime($submit_at)) . '] 您的站点收到来自【' . $country . '】的询盘信息,请登录全球搜后台进行查看!'; 59 + $model->content = '[' . date('H:i', strtotime($submit_at)) . '] 您的全球搜网站收到来自【' . $country . '】的询盘信息,请登录后台或APP进行查看!';
60 }else{ 60 }else{
61 //定时发送时间 61 //定时发送时间
62 $send_time = $hour >= 9 ? date('Y-m-d 09:00:00', strtotime('+1 day')) : date('Y-m-d 09:00:00'); 62 $send_time = $hour >= 9 ? date('Y-m-d 09:00:00', strtotime('+1 day')) : date('Y-m-d 09:00:00');
@@ -69,7 +69,7 @@ class MessagePush extends Base @@ -69,7 +69,7 @@ class MessagePush extends Base
69 $model->type = self::TYPE_INQUIRY; 69 $model->type = self::TYPE_INQUIRY;
70 $model->ref_ids = $id; 70 $model->ref_ids = $id;
71 $model->send_time = $send_time; 71 $model->send_time = $send_time;
72 - $model->content = '[09:00] 您的站点收到来自【' . $country . '】的询盘信息,请登录全球搜后台进行查看!'; 72 + $model->content = '[09:00] 您的全球搜网站收到来自【' . $country . '】的询盘信息,请登录后台或APP进行查看!';
73 }else{ 73 }else{
74 $ref_ids = explode(',', $model->ref_ids); 74 $ref_ids = explode(',', $model->ref_ids);
75 $ref_ids[] = $id; 75 $ref_ids[] = $id;
@@ -82,7 +82,7 @@ class MessagePush extends Base @@ -82,7 +82,7 @@ class MessagePush extends Base
82 }else{ 82 }else{
83 $country = implode(',', $countries); 83 $country = implode(',', $countries);
84 } 84 }
85 - $model->content = '[09:00] 您的站点收到来自【' . $country . '】'.$count.'条询盘信息,请登录全球搜后台进行查看!'; 85 + $model->content = '[09:00] 您的全球搜网站收到来自【' . $country . '】'.$count.'条询盘信息,请登录后台或APP进行查看!';
86 } 86 }
87 } 87 }
88 $model->save(); 88 $model->save();
@@ -295,14 +295,14 @@ class SyncSubmitTaskService @@ -295,14 +295,14 @@ class SyncSubmitTaskService
295 //过滤内容关键字 295 //过滤内容关键字
296 if ($config['filter_contents']){ 296 if ($config['filter_contents']){
297 foreach ($config['filter_contents'] as $filter_content) { 297 foreach ($config['filter_contents'] as $filter_content) {
298 - if (Str::contains($data['data']['message'], $filter_content)) { 298 + if (Str::contains(strtolower($data['data']['message']), strtolower($filter_content))) {
299 throw new InquiryFilterException('过滤内容:' . $filter_content); 299 throw new InquiryFilterException('过滤内容:' . $filter_content);
300 } 300 }
301 } 301 }
302 } 302 }
303 //是否允许包含链接 303 //是否允许包含链接
304 if(!$config['is_allow_link']){ 304 if(!$config['is_allow_link']){
305 - if (Str::contains($data['data']['message'], ['http://', 'https://', 'www.'])) { 305 + if (Str::contains(strtolower($data['data']['message']), ['http://', 'https://', 'www.'])) {
306 throw new InquiryFilterException('不允许包含链接'); 306 throw new InquiryFilterException('不允许包含链接');
307 } 307 }
308 } 308 }
@@ -326,7 +326,7 @@ class SyncSubmitTaskService @@ -326,7 +326,7 @@ class SyncSubmitTaskService
326 //过滤邮箱 326 //过滤邮箱
327 if($config['filter_emails'] && !empty($data['data']['email'])){ 327 if($config['filter_emails'] && !empty($data['data']['email'])){
328 foreach ($config['filter_emails'] as $filter_email){ 328 foreach ($config['filter_emails'] as $filter_email){
329 - if(Str::contains($data['data']['email'], $filter_email)){ 329 + if(Str::contains(strtolower($data['data']['email']), strtolower($filter_email))){
330 throw new InquiryFilterException( '过滤邮箱:' . $filter_email); 330 throw new InquiryFilterException( '过滤邮箱:' . $filter_email);
331 } 331 }
332 } 332 }
@@ -334,7 +334,7 @@ class SyncSubmitTaskService @@ -334,7 +334,7 @@ class SyncSubmitTaskService
334 //过滤电话 334 //过滤电话
335 if($config['filter_mobiles'] && !empty($data['data']['phone'])){ 335 if($config['filter_mobiles'] && !empty($data['data']['phone'])){
336 foreach ($config['filter_mobiles'] as $filter_mobile){ 336 foreach ($config['filter_mobiles'] as $filter_mobile){
337 - if(Str::contains($data['data']['phone'], $filter_mobile)){ 337 + if(Str::contains(strtolower($data['data']['phone']), strtolower($filter_mobile))){
338 throw new InquiryFilterException( '过滤电话:' . $filter_mobile); 338 throw new InquiryFilterException( '过滤电话:' . $filter_mobile);
339 } 339 }
340 } 340 }
@@ -342,7 +342,7 @@ class SyncSubmitTaskService @@ -342,7 +342,7 @@ class SyncSubmitTaskService
342 //过滤姓名 342 //过滤姓名
343 if($config['filter_names'] && !empty($data['data']['name'])){ 343 if($config['filter_names'] && !empty($data['data']['name'])){
344 foreach ($config['filter_names'] as $filter_name){ 344 foreach ($config['filter_names'] as $filter_name){
345 - if( Str::contains($data['data']['name'], $filter_name)){ 345 + if( Str::contains(strtolower($data['data']['name']), strtolower($filter_name))){
346 throw new InquiryFilterException( '过滤姓名:' . $filter_name); 346 throw new InquiryFilterException( '过滤姓名:' . $filter_name);
347 } 347 }
348 } 348 }