作者 赵彬吉
@@ -16,6 +16,7 @@ use App\Models\Project\CountryCustom; @@ -16,6 +16,7 @@ use App\Models\Project\CountryCustom;
16 use App\Models\Project\Project; 16 use App\Models\Project\Project;
17 use Illuminate\Console\Command; 17 use Illuminate\Console\Command;
18 use App\Models\Domain\DomainInfo as DomainInfoModel; 18 use App\Models\Domain\DomainInfo as DomainInfoModel;
  19 +use Illuminate\Support\Facades\Log;
19 use Symfony\Component\Process\Process; 20 use Symfony\Component\Process\Process;
20 21
21 class DomainInfo extends Command 22 class DomainInfo extends Command
@@ -43,6 +44,9 @@ class DomainInfo extends Command @@ -43,6 +44,9 @@ class DomainInfo extends Command
43 */ 44 */
44 public function handle() 45 public function handle()
45 { 46 {
  47 + //先更新所有域名证书有效期
  48 + $this->startUpdateSslTime();
  49 +
46 //主站证书到期更新 50 //主站证书到期更新
47 $this->startUpdateCert(); 51 $this->startUpdateCert();
48 52
@@ -56,6 +60,47 @@ class DomainInfo extends Command @@ -56,6 +60,47 @@ class DomainInfo extends Command
56 } 60 }
57 61
58 /** 62 /**
  63 + * 更新域名证书有效期
  64 + * @author Akun
  65 + * @date 2024/09/06 11:16
  66 + */
  67 + public function startUpdateSslTime()
  68 + {
  69 + $domainModel = new DomainInfoModel();
  70 + $projectModel = new Project();
  71 + $serverIpModel = new ServersIp();
  72 + $list = $domainModel->where('status', '=', 1)->get();
  73 + foreach ($list as $v) {
  74 + $project_info = $projectModel->read(['id' => $v['project_id']], ['serve_id']);
  75 + if (!$project_info) {
  76 + continue;
  77 + }
  78 +
  79 + $servers_ip_info = $serverIpModel->read(['id' => $project_info['serve_id']], ['servers_id', 'ip', 'domain']);
  80 + if (!$servers_ip_info) {
  81 + continue;
  82 + }
  83 +
  84 + //除自建站项目外,记录已解析到别的ip的域名
  85 + if ($servers_ip_info['servers_id'] != ServerConfig::SELF_SITE_ID) {
  86 + //过滤已解析到别的ip的域名
  87 + if (!$this->check_cname($v['domain'], $servers_ip_info)) {
  88 + Log::channel('analyze_other')->error('域名 [' . $v['domain'] . '] 已解析到别的IP');
  89 + continue;
  90 + }
  91 + }
  92 +
  93 + //获取证书有效期并更新
  94 + $ssl_time = $this->getDomainSslTime($v['domain']);
  95 + if ($ssl_time['from'] && $ssl_time['to']) {
  96 + $v->certificate_start_time = $ssl_time['from'];
  97 + $v->certificate_end_time = $ssl_time['to'];
  98 + $v->save();
  99 + }
  100 + }
  101 + }
  102 +
  103 + /**
59 * 主站证书到期更新 104 * 主站证书到期更新
60 * @author Akun 105 * @author Akun
61 * @date 2024/02/26 10:26 106 * @date 2024/02/26 10:26
@@ -190,6 +235,7 @@ class DomainInfo extends Command @@ -190,6 +235,7 @@ class DomainInfo extends Command
190 235
191 //过滤已解析到别的ip的域名 236 //过滤已解析到别的ip的域名
192 if (!$this->check_cname($v['custom_domain'], $servers_ip_info)) { 237 if (!$this->check_cname($v['custom_domain'], $servers_ip_info)) {
  238 + Log::channel('analyze_other')->error('自定义跳转域名 [' . $v['custom_domain'] . '] 已解析到别的IP');
193 continue; 239 continue;
194 } 240 }
195 241
@@ -207,6 +253,42 @@ class DomainInfo extends Command @@ -207,6 +253,42 @@ class DomainInfo extends Command
207 } 253 }
208 254
209 /** 255 /**
  256 + * 获取域名证书有效时间
  257 + * @param $domain
  258 + * @return string[]
  259 + * @author Akun
  260 + * @date 2024/08/29 9:59
  261 + */
  262 + public function getDomainSslTime($domain)
  263 + {
  264 + $valid_from = '';
  265 + $valid_to = '';
  266 + try {
  267 + $context = stream_context_create([
  268 + 'ssl' => [
  269 + 'capture_peer_cert' => true,
  270 + 'capture_peer_cert_chain' => false,
  271 + 'verify_peer' => false,
  272 + 'verify_peer_name' => false
  273 + ],
  274 + ]);
  275 + $stream = stream_socket_client('ssl://' . $domain . ':443', $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $context);
  276 + if ($stream) {
  277 + $remote_cert = stream_context_get_params($stream)['options']['ssl']['peer_certificate'];
  278 + if ($remote_cert) {
  279 + $valid_from = date('Y-m-d H:i:s', openssl_x509_parse($remote_cert)['validFrom_time_t']);
  280 + $valid_to = date('Y-m-d H:i:s', openssl_x509_parse($remote_cert)['validTo_time_t']);
  281 + }
  282 + }
  283 + fclose($stream);
  284 + } catch (\Exception $e) {
  285 + $valid_from = '';
  286 + $valid_to = '';
  287 + }
  288 + return ['from' => $valid_from, 'to' => $valid_to];
  289 + }
  290 +
  291 + /**
210 * 验证是否cname或者A记录解析到目标服务器 292 * 验证是否cname或者A记录解析到目标服务器
211 * @param $domain 293 * @param $domain
212 * @param $server_info 294 * @param $server_info
@@ -10,10 +10,8 @@ @@ -10,10 +10,8 @@
10 namespace App\Console\Commands\Update; 10 namespace App\Console\Commands\Update;
11 11
12 use App\Models\Log\OperationHeartbeat; 12 use App\Models\Log\OperationHeartbeat;
13 -use App\Models\Project\Project;  
14 -use App\Services\ProjectServer;  
15 use Illuminate\Console\Command; 13 use Illuminate\Console\Command;
16 -use Illuminate\Support\Facades\DB; 14 +
17 15
18 class UpdateHeartbeat extends Command 16 class UpdateHeartbeat extends Command
19 { 17 {
@@ -40,9 +38,10 @@ class UpdateHeartbeat extends Command @@ -40,9 +38,10 @@ class UpdateHeartbeat extends Command
40 * @time :2024/8/28 15:25 38 * @time :2024/8/28 15:25
41 */ 39 */
42 public function handle(){ 40 public function handle(){
43 - $date = date('Y-m-d H:i:s',time() - 30 * 60); 41 + $date = date('Y-m-d H:i:s',time() - 10 * 60);
44 $operationHeartbeatModel = new OperationHeartbeat(); 42 $operationHeartbeatModel = new OperationHeartbeat();
45 $operationHeartbeatModel->edit(['status'=>0],['updated_at'=>['<=',$date]]); 43 $operationHeartbeatModel->edit(['status'=>0],['updated_at'=>['<=',$date]]);
46 echo date('Y-m-d H:i:s') . 'end' . PHP_EOL; 44 echo date('Y-m-d H:i:s') . 'end' . PHP_EOL;
  45 + return true;
47 } 46 }
48 } 47 }
@@ -40,13 +40,13 @@ class OperationHeartbeatController extends BaseController @@ -40,13 +40,13 @@ class OperationHeartbeatController extends BaseController
40 'is_list'=>$this->param['is_list'],'is_custom'=>$this->param['is_custom'],'is_template'=>$this->param['is_template']]; 40 'is_list'=>$this->param['is_list'],'is_custom'=>$this->param['is_custom'],'is_template'=>$this->param['is_template']];
41 $operationHeartbeatModel = new OperationHeartbeat(); 41 $operationHeartbeatModel = new OperationHeartbeat();
42 $info = $operationHeartbeatModel->read($condition,['id','status']); 42 $info = $operationHeartbeatModel->read($condition,['id','status']);
43 - $condition['status'] = $condition['status'] ?? 0; 43 + $condition['status'] = $this->param['status'] ?? 0;
44 if($info === false){ 44 if($info === false){
45 $condition['operator_id'] = $this->user['id']; 45 $condition['operator_id'] = $this->user['id'];
46 $condition['project_id'] = $this->user['project_id']; 46 $condition['project_id'] = $this->user['project_id'];
47 $operationHeartbeatModel->addReturnId($condition); 47 $operationHeartbeatModel->addReturnId($condition);
48 }else{ 48 }else{
49 - $operationHeartbeatModel->edit(['status'=>1],['id'=>$info['id']]); 49 + $operationHeartbeatModel->edit(['status'=>$condition['status'] ?? 0],['id'=>$info['id']]);
50 } 50 }
51 $this->response('success'); 51 $this->response('success');
52 } 52 }
@@ -76,6 +76,9 @@ class OperationHeartbeatController extends BaseController @@ -76,6 +76,9 @@ class OperationHeartbeatController extends BaseController
76 'is_list'=>$this->param['is_list'],'is_custom'=>$this->param['is_custom'],'is_template'=>$this->param['is_template']]; 76 'is_list'=>$this->param['is_list'],'is_custom'=>$this->param['is_custom'],'is_template'=>$this->param['is_template']];
77 $operationHeartbeatModel = new OperationHeartbeat(); 77 $operationHeartbeatModel = new OperationHeartbeat();
78 $info = $operationHeartbeatModel->read($condition,['id','status']); 78 $info = $operationHeartbeatModel->read($condition,['id','status']);
  79 + if($info === false){
  80 + $info = [];
  81 + }
79 $this->response('success',Code::SUCCESS,$info); 82 $this->response('success',Code::SUCCESS,$info);
80 } 83 }
81 } 84 }
@@ -210,6 +210,9 @@ class ExtensionModuleController extends BaseController @@ -210,6 +210,9 @@ class ExtensionModuleController extends BaseController
210 $status_data[$value] = $number; 210 $status_data[$value] = $number;
211 $number++; 211 $number++;
212 } 212 }
  213 + if(($status_data[$info['value']] + 1) != $status_data[$v['value']]){
  214 + $this->fail('流程控制不能跳流程选择');
  215 + }
213 if($status_data[$info['value']] > $status_data[$v['value']]){ 216 if($status_data[$info['value']] > $status_data[$v['value']]){
214 $this->fail('流程控制不能回滚'); 217 $this->fail('流程控制不能回滚');
215 } 218 }
@@ -794,7 +794,6 @@ class RankDataLogic extends BaseLogic @@ -794,7 +794,6 @@ class RankDataLogic extends BaseLogic
794 if (!$rank_week) { 794 if (!$rank_week) {
795 $rank_week = new RankWeekModel(); 795 $rank_week = new RankWeekModel();
796 } 796 }
797 -  
798 $rank_week->project_id = $project_id; 797 $rank_week->project_id = $project_id;
799 $rank_week->data = $res['data'][$api_no] ?? []; 798 $rank_week->data = $res['data'][$api_no] ?? [];
800 $rank_week->date = $res['date']; 799 $rank_week->date = $res['date'];
@@ -101,6 +101,12 @@ return [ @@ -101,6 +101,12 @@ return [
101 'via' => \App\Factory\LogFormatterFactory::class, 101 'via' => \App\Factory\LogFormatterFactory::class,
102 'prefix' => 'wechatside', 102 'prefix' => 'wechatside',
103 ], 103 ],
  104 + //域名解析别处记录日志
  105 + 'analyze_other' => [
  106 + 'driver' => 'custom',
  107 + 'via' => \App\Factory\LogFormatterFactory::class,
  108 + 'prefix' => 'analyze_other',
  109 + ],
104 'stack' => [ 110 'stack' => [
105 'driver' => 'stack', 111 'driver' => 'stack',
106 'channels' => ['single'], 112 'channels' => ['single'],