作者 赵彬吉
@@ -2,29 +2,124 @@ @@ -2,29 +2,124 @@
2 2
3 namespace App\Console\Commands\Domain; 3 namespace App\Console\Commands\Domain;
4 4
  5 +use App\Models\Com\Notify;
  6 +use App\Models\Devops\ServersIp;
  7 +use App\Models\Domain\DomainCreateTask;
  8 +use App\Models\Domain\DomainInfo;
5 use App\Models\Project\Project; 9 use App\Models\Project\Project;
6 use App\Models\Project\ProjectServerBackup; 10 use App\Models\Project\ProjectServerBackup;
7 use Illuminate\Console\Command; 11 use Illuminate\Console\Command;
  12 +use Symfony\Component\Process\Process;
8 13
9 class EmergencyRelieve extends Command 14 class EmergencyRelieve extends Command
10 { 15 {
11 - protected $signature = 'emergency_relieve'; 16 + protected $signature = 'emergency_relieve {server_id}';
12 protected $description = '危机解除,恢复项目服务器'; 17 protected $description = '危机解除,恢复项目服务器';
13 18
14 public function handle() 19 public function handle()
15 { 20 {
16 - $backup_list = ProjectServerBackup::where('status', ProjectServerBackup::STATUS_NO)->get(); 21 + //需要恢复的服务器
  22 + $server_id = $this->argument('server_id');
  23 +
  24 + //获取所有需要恢复的项目
  25 + $backup_model = new ProjectServerBackup();
  26 + $backup_list = $backup_model->where('server_id', $server_id)->where('status', ProjectServerBackup::STATUS_NO)->get();
17 27
18 - $project_model = new Project();  
19 if ($backup_list->count() > 0) { 28 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(); 29 + $project_model = new Project();
  30 + $domain_model = new DomainInfo();
  31 + $create_model = new DomainCreateTask();
  32 + $notify_model = new Notify();
  33 + $server_ip_model = new ServersIp();
  34 + foreach ($backup_list as $value) {
  35 + $domain_info = $domain_model->read(['project_id' => $value->project_id, 'status' => 1], ['id', 'domain']);
  36 + if (!$domain_info) {
  37 + //过滤未绑定正式域名的项目
  38 + continue;
  39 + }
  40 +
  41 + //判断域名是否已经解析到目标服务器
  42 + $target_server = $server_ip_model->select(['id', 'ip', 'domain'])->where('id', $value->server_ip_id)->first()->toArray();
  43 + if (!$this->check_cname($domain_info['domain'], $target_server)) {
  44 + $this->output($domain_info['domain'] . ' | 未解析到目标服务器');
  45 + continue;
  46 + }
  47 +
  48 + //创建目标服务器建站任务
  49 + $map_create = [
  50 + 'type' => DomainCreateTask::TYPE_MAIN,
  51 + 'server_id' => $value->server_id,
  52 + 'project_id' => $value->project_id,
  53 + 'domain_id' => $domain_info['id'],
  54 + 'status' => DomainCreateTask::STATUS_UN,
  55 + ];
  56 + $task_info = $create_model->read($map_create, ['id']);
  57 + if (!$task_info) {
  58 + $create_model->add($map_create);
  59 + }
  60 +
  61 + //创建目标服务器站点页面生成任务
  62 + $map_notify = [
  63 + 'type' => Notify::TYPE_MASTER,
  64 + 'server_id' => $value->server_id,
  65 + 'project_id' => $value->project_id,
  66 + 'status' => Notify::STATUS_INIT,
  67 + 'route' => Notify::ROUTE_ALL,
  68 + ];
  69 + $notify_info = $notify_model->read($map_notify);
  70 + if (!$notify_info) {
  71 + $map_notify['data'] = json_encode(['domain' => $domain_info['domain'], 'url' => [], 'language' => []]);
  72 + $map_notify['sort'] = 10;
  73 + $notify_model->add($map_notify);
  74 + }
  75 +
  76 + //更改项目服务器
  77 + $project_model->edit(['serve_id' => $value->server_ip_id], ['id' => $value->project_id]);
  78 +
  79 + //更改恢复状态
  80 + $value->status = ProjectServerBackup::STATUS_YES;
  81 + $value->save();
  82 +
  83 + $this->output('项目ID:' . $value->project_id . ' | success');
  84 + }
  85 + }
  86 + }
  87 +
  88 + /**
  89 + * 验证是否cname或者A记录解析到目标服务器
  90 + * @param $domain
  91 + * @param $server_info
  92 + * @return mixed
  93 + * @author zbj
  94 + * @date 2023/11/13
  95 + */
  96 + public function check_cname($domain, $server_info)
  97 + {
  98 + $process = new Process(['nslookup', '-qt=a', $domain]);
  99 + $process->run();
  100 + $output = explode(PHP_EOL, $process->getOutput());
  101 + foreach ($output as $line) {
  102 + if ($line) {
  103 + $checkA = strpos($line, $server_info['ip']) !== false;
  104 + if ($checkA) {
  105 + return $domain;
  106 + }
  107 + }
  108 + }
24 109
25 - $this->output('项目ID:' . $item->project_id . ',恢复成功'); 110 + //是否cname
  111 + $process = new Process(['nslookup', '-qt=cname', $domain]);
  112 + $process->run();
  113 + $output = explode(PHP_EOL, $process->getOutput());
  114 + foreach ($output as $line) {
  115 + if ($line) {
  116 + $checkCname = (strpos($line, $server_info['domain']) !== false);
  117 + if ($checkCname) {
  118 + return $domain;
  119 + }
26 } 120 }
27 } 121 }
  122 + return false;
28 } 123 }
29 124
30 /** 125 /**
@@ -13,18 +13,19 @@ use Symfony\Component\Process\Process; @@ -13,18 +13,19 @@ use Symfony\Component\Process\Process;
13 13
14 class EmergencyRenewSite extends Command 14 class EmergencyRenewSite extends Command
15 { 15 {
16 - protected $signature = 'emergency_renew_site'; 16 + protected $signature = 'emergency_renew_site {server_id}';
17 protected $description = '紧急重建站点'; 17 protected $description = '紧急重建站点';
18 18
19 public function handle() 19 public function handle()
20 { 20 {
21 //目标服务器 21 //目标服务器
22 $target_server_id = 1; 22 $target_server_id = 1;
23 - $target_server = ServersIp::select(['id', 'ip', 'domain'])->where('servers_id', $target_server_id)->first()->toArray(); 23 + $server_ip_model = new ServersIp();
  24 + $target_server = $server_ip_model->select(['id', 'ip', 'domain'])->where('servers_id', $target_server_id)->first()->toArray();
24 25
25 //受灾服务器 26 //受灾服务器
26 - $server_ids = [9, 13];  
27 - $server_ip_ids = ServersIp::whereIn('servers_id', $server_ids)->get()->pluck('id')->toArray(); 27 + $server_id = $this->argument('server_id');;
  28 + $server_ip_ids = $server_ip_model->where('servers_id', $server_id)->get()->pluck('id')->toArray();
28 29
29 //获取所有受灾项目 30 //获取所有受灾项目
30 $project_list = Project::select(['id', 'serve_id', 'title'])->whereIn('serve_id', $server_ip_ids)->get(); 31 $project_list = Project::select(['id', 'serve_id', 'title'])->whereIn('serve_id', $server_ip_ids)->get();
@@ -32,71 +33,74 @@ class EmergencyRenewSite extends Command @@ -32,71 +33,74 @@ class EmergencyRenewSite extends Command
32 $create_model = new DomainCreateTask(); 33 $create_model = new DomainCreateTask();
33 $notify_model = new Notify(); 34 $notify_model = new Notify();
34 $backup_model = new ProjectServerBackup(); 35 $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 - } 36 + if ($project_list->count() > 0) {
  37 + foreach ($project_list as $value) {
  38 + $domain_info = $domain_model->read(['project_id' => $value->id, 'status' => 1], ['id', 'domain']);
  39 + if (!$domain_info) {
  40 + //过滤未绑定正式域名的项目
  41 + continue;
  42 + }
41 43
42 - //判断域名是否已经解析到目标服务器  
43 - if (!$this->check_cname($domain_info['domain'], $target_server)) {  
44 - $this->output($domain_info['domain'] . ' | 未解析到目标服务器');  
45 - } 44 + //判断域名是否已经解析到目标服务器
  45 + if (!$this->check_cname($domain_info['domain'], $target_server)) {
  46 + $this->output($domain_info['domain'] . ' | 未解析到目标服务器');
  47 + continue;
  48 + }
46 49
47 - //获取站点其他域名  
48 - $other_domain = [];  
49 - if (strpos($domain_info['domain'], 'www.') === 0) {  
50 - $other_domain[] = str_replace('www', '*', $domain_info['domain']); 50 + //获取站点其他域名
  51 + $other_domain = [];
  52 + if (strpos($domain_info['domain'], 'www.') === 0) {
  53 + $other_domain[] = str_replace('www', '*', $domain_info['domain']);
51 54
52 - $top_domain = str_replace('www.', '', $domain_info['domain']);  
53 - if ($this->check_cname($top_domain, $target_server)) {  
54 - $other_domain[] = $top_domain; 55 + $top_domain = str_replace('www.', '', $domain_info['domain']);
  56 + if ($this->check_cname($top_domain, $target_server)) {
  57 + $other_domain[] = $top_domain;
  58 + }
55 } 59 }
56 - }  
57 60
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 - } 61 + //创建目标服务器建站任务
  62 + $map_create = [
  63 + 'type' => DomainCreateTask::TYPE_MAIN,
  64 + 'server_id' => $target_server_id,
  65 + 'project_id' => $value->id,
  66 + 'domain_id' => $domain_info['id'],
  67 + 'status' => DomainCreateTask::STATUS_UN,
  68 + ];
  69 + $task_info = $create_model->read($map_create, ['id']);
  70 + if (!$task_info) {
  71 + $map_create['other_domain'] = json_encode($other_domain);
  72 + $create_model->add($map_create);
  73 + }
71 74
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 - } 75 + //创建目标服务器站点页面生成任务
  76 + $map_notify = [
  77 + 'type' => Notify::TYPE_MASTER,
  78 + 'server_id' => $target_server_id,
  79 + 'project_id' => $value->id,
  80 + 'status' => Notify::STATUS_INIT,
  81 + 'route' => Notify::ROUTE_ALL,
  82 + ];
  83 + $notify_info = $notify_model->read($map_notify);
  84 + if (!$notify_info) {
  85 + $map_notify['data'] = json_encode(['domain' => $domain_info['domain'], 'url' => [], 'language' => []]);
  86 + $map_notify['sort'] = 9;
  87 + $notify_model->add($map_notify);
  88 + }
86 89
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 - } 90 + //备份项目原始服务器
  91 + $backup_info = $backup_model->read(['project_id' => $value->id, 'status' => ProjectServerBackup::STATUS_NO], ['id']);
  92 + if ($backup_info) {
  93 + $backup_model->edit(['server_id' => $server_id, 'server_ip_id' => $value->serve_id], ['id' => $backup_info['id']]);
  94 + } else {
  95 + $backup_model->add(['project_id' => $value->id, 'server_id' => $server_id, 'server_ip_id' => $value->serve_id]);
  96 + }
94 97
95 - //更改项目服务器  
96 - $value->serve_id = $target_server_id;  
97 - $value->save(); 98 + //更改项目服务器
  99 + $value->serve_id = $target_server_id;
  100 + $value->save();
98 101
99 - $this->output($domain_info['domain'] . ' | success'); 102 + $this->output($domain_info['domain'] . ' | success');
  103 + }
100 } 104 }
101 } 105 }
102 106
  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 App\Services\UpyunService;
  15 +use Illuminate\Console\Command;
  16 +use Qcloud\Cos\Client;
  17 +
  18 +class SyncImage extends Command
  19 +{
  20 + /**
  21 + * The name and signature of the console command.
  22 + *
  23 + * @var string
  24 + */
  25 + protected $signature = 'sync_shuiying_image';
  26 +
  27 + /**
  28 + * The console command description.
  29 + *
  30 + * @var string
  31 + */
  32 + protected $description = '同步图片与文件';
  33 +
  34 +
  35 +// public function handle(){
  36 +// $str = $this->getProjectConfig(501);
  37 +// $imageModel = new Image();
  38 +// $lists = $imageModel->list(['project_id'=>501]);
  39 +// $domain = 'http://globalso-v6-1309677403.cos.ap-hongkong.myqcloud.com';//cos域名
  40 +// foreach ($lists as $k => $v){
  41 +// if($v['path'] == '/upload/p/501/image_product/2024-09/6569ac3a212aa39368.png'){
  42 +// continue;
  43 +// }
  44 +// $url = $domain . $v['path'].'?'.$str;
  45 +// echo date('Y-m-d H:i:s') . '水印路径:'. $url .',主键id:'. $v['id'] . PHP_EOL;
  46 +// $this->coverOriginalImage($url,$v['path']);
  47 +// }
  48 +// return true;
  49 +// }
  50 +
  51 + public function handle(){
  52 + $data = [];
  53 + $domain = 'https://ecdn6-nc.globalso.com/';
  54 + $imageModel = new Image();
  55 + $lists = $imageModel->list(['project_id'=>501]);
  56 + foreach ($lists as $k => $v){
  57 + if($v['path'] == '/upload/p/501/image_product/2024-09/6569ac3a212aa39368.png'){
  58 + continue;
  59 + }
  60 + $url = $domain . $v['path'];
  61 + echo date('Y-m-d H:i:s') . '刷新路径:'. $url .',主键id:'. $v['id'] . PHP_EOL;
  62 + $data[] = $url;
  63 + }
  64 + $yunService = new UpyunService();
  65 + return $yunService->preheatPush($data);
  66 + }
  67 +
  68 + /**
  69 + * @remark :添加水印后保存图片(覆盖/非覆盖的文件未存入数据库)
  70 + * @name :uploadImages
  71 + * @author :lyh
  72 + * @method :post
  73 + * @time :2024/8/19 17:06
  74 + */
  75 + public function coverOriginalImage($url,$cdnUrl){
  76 + // 获取水印后的图片内容
  77 + $imageContent = file_get_contents($url);
  78 + // 使用 COS SDK 将图片重新上传并覆盖原图
  79 + $cos = config('filesystems.disks.cos');
  80 + $cosClient = new Client([
  81 + 'region' => $cos['region'],
  82 + 'credentials' => [
  83 + 'secretId' => $cos['credentials']['secretId'],
  84 + 'secretKey' => $cos['credentials']['secretKey'],
  85 + ],
  86 + ]);
  87 + // 上传并覆盖原图
  88 + $cosClient->putObject([
  89 + 'Bucket' => $cos['bucket'],
  90 + 'Key' => $cdnUrl, // 去掉域名部分,得到存储桶内的路径
  91 + 'Body' => $imageContent,
  92 + ]);
  93 + return $cos['cdn'].$cdnUrl;
  94 + }
  95 +
  96 + /**
  97 + * @remark :获取图片配置
  98 + * @name :getProjectConfig
  99 + * @author :lyh
  100 + * @method :post
  101 + * @time :2024/8/24 11:03
  102 + */
  103 + public function getProjectConfig($project_id = 0){
  104 + $str = '';
  105 + $imageSettingModel = new ImageSetting();
  106 + $settingInfo = $imageSettingModel->read(['project_id'=>$project_id]);
  107 + if($settingInfo !== false){
  108 + if($settingInfo['status'] == 1 && !empty($settingInfo['image_data'])){
  109 + $image_data = json_decode($settingInfo['image_data'],true);
  110 + foreach ($image_data as $k => $v){
  111 + if (str_starts_with($v, "image/")) {
  112 + $v = 'image/'.urlSafeBase64Encode(substr($v, strlen("image/")));
  113 + }
  114 + $image_data[$k] = $v;
  115 + }
  116 + $str = 'watermark/1/'.implode('/',$image_data);
  117 + return $str;
  118 + }
  119 + if($settingInfo['status'] == 2 && !empty($settingInfo['str_data'])){
  120 + $str_data = json_decode($settingInfo['str_data'],true);
  121 + foreach ($str_data as $k => $v){
  122 + $arr = explode('/',$v);
  123 + if ($arr[0] == 'text') {
  124 + $arr[1] = urlSafeBase64Encode($arr[1]);
  125 + $v = implode('/',$arr);
  126 + }
  127 + if ($arr[0] == 'font') {
  128 + $arr[1] = urlSafeBase64Encode($arr[1]);
  129 + $v = implode('/',$arr);
  130 + }
  131 + if ($arr[0] == 'fill') {
  132 + $arr[1] = urlSafeBase64Encode($arr[1]);
  133 + $v = implode('/',$arr);
  134 + }
  135 + $str_data[$k] = $v;
  136 + }
  137 + $str = 'watermark/2/'.implode('/',$str_data);
  138 + return $str;
  139 + }
  140 + }
  141 + return $str;
  142 + }
  143 +}
@@ -24,7 +24,7 @@ class CommentController extends BaseController @@ -24,7 +24,7 @@ class CommentController extends BaseController
24 */ 24 */
25 public function lists(){ 25 public function lists(){
26 $commentModel = new Comment(); 26 $commentModel = new Comment();
27 - $lists = $commentModel->list(); 27 + $lists = $commentModel->lists($this->map,$this->page,$this->row);
28 $this->response('success',Code::SUCCESS,$lists); 28 $this->response('success',Code::SUCCESS,$lists);
29 } 29 }
30 30
@@ -47,7 +47,7 @@ class ProductController extends BaseController @@ -47,7 +47,7 @@ class ProductController extends BaseController
47 */ 47 */
48 public function index(Product $product) 48 public function index(Product $product)
49 { 49 {
50 - $filed = ['id', 'project_id', 'title', 'sort' ,'thumb' ,'product_type' , 'route' , 'intro' , 'content' , 50 + $filed = ['id', 'project_id', 'title', 'sort' ,'thumb' ,'product_type' , 'route' ,
51 'category_id', 'keyword_id', 'status', 'created_uid', 'is_upgrade' ,'created_at', 'updated_at','six_read']; 51 'category_id', 'keyword_id', 'status', 'created_uid', 'is_upgrade' ,'created_at', 'updated_at','six_read'];
52 $this->order = 'sort'; 52 $this->order = 'sort';
53 $query = $product->orderBy($this->order ,'desc')->orderBy('id','desc'); 53 $query = $product->orderBy($this->order ,'desc')->orderBy('id','desc');