作者 李美松

优化程序

  1 +<?php
  2 +
  3 +namespace App\Console\Commands;
  4 +
  5 +
  6 +use Illuminate\Console\Command;
  7 +
  8 +/**
  9 + * TODO:: 如果想要在终止 任务时不让数据丢失或者异常,请使用此类
  10 + * @author:dc
  11 + * @time 2023/8/21 11:03
  12 + * Class CmdSignal
  13 + * @package App\Console\Commands
  14 + */
  15 +trait CmdSignal
  16 +{
  17 +
  18 + /**
  19 + * 是否停止
  20 + * @var bool
  21 + */
  22 + public $isStop = false;
  23 +
  24 + /**
  25 + * 超时未退出,强制退出 暂时未实现
  26 + * @var int
  27 + */
  28 + public $stopTimeOut = 30;
  29 +
  30 +
  31 + public $debugLogFile = null;
  32 +
  33 + /**
  34 + * 调试输出
  35 + * @param $msg
  36 + * @author:dc
  37 + * @time 2023/8/21 11:22
  38 + */
  39 + public function debug_echo($msg){
  40 + if($this->debugLogFile){
  41 + @file_put_contents($this->debugLogFile,date('Y-m-d H:i:s')." ===> ".print_r($msg,1).PHP_EOL,FILE_APPEND);
  42 + }else{
  43 + echo date('Y-m-d H:i:s')." ===> ".print_r($msg,1).PHP_EOL;
  44 + }
  45 + }
  46 +
  47 + /**
  48 + * @return bool
  49 + */
  50 + public function handle()
  51 + {
  52 +
  53 + if($this->isRunning()){
  54 + $this->debug_echo('脚本已运行,请无重复运行');
  55 + return 1;
  56 + }
  57 +
  58 + $this->debug_echo('已启动脚本');
  59 +
  60 + // 启动时
  61 + if(method_exists($this,'init')){
  62 + $this->init();
  63 + }
  64 +
  65 +// 注册信号处理程序
  66 +// SIGHUP:终端控制进程时终止或挂起进程
  67 +//SIGINT:中断进程(通常由CTRL+C发出)
  68 +//SIGQUIT:退出进程并生成核心转储
  69 +//SIGILL:非法指令
  70 +//SIGABRT:由调试程序触发的异常终止信号
  71 +//SIGFPE:浮点异常
  72 +//SIGKILL:无条件终止进程
  73 +//SIGSEGV:无效的内存引用
  74 +//SIGPIPE:写入已关闭的FIFO或套接字时产生的信号
  75 +//SIGTERM:要求终止进程的信号
  76 +//SIGUSR1:用户定义的信号1
  77 +//SIGUSR2:用户定义的信号2
  78 + $handler = function ($signal){
  79 + // 可以处理其他程序
  80 + $this->isStop = true;
  81 + };
  82 + pcntl_signal(SIGTERM, $handler);
  83 + pcntl_signal(SIGINT, $handler);
  84 +// pcntl_signal(SIGHUP, $handler);
  85 +
  86 + // 检查是否接收到信号
  87 + pcntl_signal_dispatch();
  88 +
  89 + $tryNum = 0;
  90 +// 无限循环,模拟进程运行
  91 + while (true) {
  92 + // 做一些工作... 异常超过5次就重启下进程
  93 + if($this->isStop || $tryNum>5){
  94 + break;
  95 + }
  96 +
  97 + try {
  98 + $this->start();
  99 + }catch (\Throwable $e){
  100 + $tryNum++;
  101 + // 保证此程序正常
  102 + $this->debug_echo('异常消息:'.$e->getMessage());
  103 + $this->debug_echo('异常文件:'.$e->getFile().':'.$e->getLine());
  104 + $this->debug_echo($e->getTraceAsString());
  105 + }
  106 +
  107 +
  108 + }
  109 +
  110 + $this->debug_echo('已退出程序');
  111 +
  112 +
  113 + return Command::SUCCESS;
  114 + }
  115 +
  116 +
  117 + /**
  118 + * 获取进程启动名称
  119 + * @return mixed
  120 + * @throws \Exception
  121 + * @author:dc
  122 + * @time 2023/8/21 11:43
  123 + */
  124 + public function getSignature(){
  125 + if(empty($this->signature)){
  126 + throw new \Exception('无法获取到启动命令');
  127 + }
  128 + return $this->signature;
  129 + }
  130 +
  131 + /**
  132 + * 是否已运行
  133 + * @param int $max 最大运行多少进程
  134 + * @return bool
  135 + * @throws \Exception
  136 + * @author:dc
  137 + * @time 2023/8/21 11:54
  138 + */
  139 + public function isRunning($max=1):bool {
  140 +
  141 + $ps = "ps -ef | grep \"artisan ".$this->getSignature()."\" | grep -v grep | wc -l";
  142 +
  143 + $num = exec($ps);
  144 +
  145 + if(property_exists($this,'maxRunNumber')){
  146 + $max = $this->maxRunNumber;
  147 + }
  148 +
  149 + if($num>$max){
  150 + return true;
  151 + }
  152 +
  153 + return false;
  154 + }
  155 +
  156 +
  157 +
  158 +}
@@ -2,11 +2,13 @@ @@ -2,11 +2,13 @@
2 2
3 namespace App\Console\Commands; 3 namespace App\Console\Commands;
4 4
  5 +use App\Http\Controllers\File\FileController;
5 use App\Models\ProjectAssociation\ProjectAssociation; 6 use App\Models\ProjectAssociation\ProjectAssociation;
6 use App\Models\File\DataFile; 7 use App\Models\File\DataFile;
7 use Dompdf\Dompdf; 8 use Dompdf\Dompdf;
8 use Dompdf\Options; 9 use Dompdf\Options;
9 use Illuminate\Console\Command; 10 use Illuminate\Console\Command;
  11 +use Illuminate\Http\File;
10 12
11 class ProjectFilePDF extends Command 13 class ProjectFilePDF extends Command
12 { 14 {
@@ -82,6 +84,7 @@ class ProjectFilePDF extends Command @@ -82,6 +84,7 @@ class ProjectFilePDF extends Command
82 $html = $this->html($project_data); 84 $html = $this->html($project_data);
83 $filename = hash('md5', $this->time . '-' . $project_id . '-' . $friend_id . '-' . $user_id); 85 $filename = hash('md5', $this->time . '-' . $project_id . '-' . $friend_id . '-' . $user_id);
84 $file_path = $this->savePDF($html, $filename); 86 $file_path = $this->savePDF($html, $filename);
  87 + var_dump($file_path);
85 $this->DataFile->saveData(compact('project_id', 'user_id', 'friend_id', 'file_path') + ['time' => $this->time]); 88 $this->DataFile->saveData(compact('project_id', 'user_id', 'friend_id', 'file_path') + ['time' => $this->time]);
86 } 89 }
87 } 90 }
@@ -107,6 +110,18 @@ class ProjectFilePDF extends Command @@ -107,6 +110,18 @@ class ProjectFilePDF extends Command
107 110
108 public function savePDF($html, $filename) 111 public function savePDF($html, $filename)
109 { 112 {
  113 +
  114 + $pdf_path = public_path('PDF/');
  115 + if (!file_exists($pdf_path)) {
  116 + mkdir($pdf_path, 0777, true);
  117 + }
  118 +
  119 + // 指定保存路径和文件名
  120 + $savePath = $pdf_path . $filename . '.pdf';
  121 + if (file_exists($savePath)) {
  122 + echo '文件已经存在';
  123 +// return 0;
  124 + }
110 // todo 生成中文有问题 125 // todo 生成中文有问题
111 # 实例化并使用dompdf类 126 # 实例化并使用dompdf类
112 // $options = new Options(); 127 // $options = new Options();
@@ -122,18 +137,17 @@ class ProjectFilePDF extends Command @@ -122,18 +137,17 @@ class ProjectFilePDF extends Command
122 137
123 // 获取PDF内容 138 // 获取PDF内容
124 $pdfContent = $dompdf->output(); 139 $pdfContent = $dompdf->output();
125 - $pdf_path = public_path('PDF/');  
126 - if (!file_exists($pdf_path)) {  
127 - mkdir($pdf_path, 0777, true);  
128 - }  
129 - // 指定保存路径和文件名  
130 - $savePath = $pdf_path . $filename . '.pdf'; 140 +
  141 + $fileController = new FileController();
131 142
132 // 将PDF内容保存到文件 143 // 将PDF内容保存到文件
133 - file_put_contents($savePath, $pdfContent); 144 + @file_put_contents($savePath, $pdfContent);
134 145
135 - // 输出保存成功消息  
136 - return $savePath; 146 + // 创建一个文件实例
  147 + $file = new File($savePath);
  148 +var_dump($file->getFilename());
  149 +exit();
  150 + return $fileController->single($file);
137 } 151 }
138 152
139 /** 153 /**
@@ -7,6 +7,8 @@ use Illuminate\Console\Command; @@ -7,6 +7,8 @@ use Illuminate\Console\Command;
7 7
8 class WebsiteData extends Command 8 class WebsiteData extends Command
9 { 9 {
  10 + use CmdSignal;
  11 +
10 /** 12 /**
11 * The name and signature of the console command. 13 * The name and signature of the console command.
12 * 14 *
@@ -21,6 +23,11 @@ class WebsiteData extends Command @@ -21,6 +23,11 @@ class WebsiteData extends Command
21 */ 23 */
22 protected $description = '向AICC推送数据'; 24 protected $description = '向AICC推送数据';
23 25
  26 + // 最大支持5个进程
  27 + public $maxRunNumber = 50;
  28 +
  29 + protected $time;
  30 +
24 /** 31 /**
25 * Create a new command instance. 32 * Create a new command instance.
26 * 33 *
@@ -28,37 +35,58 @@ class WebsiteData extends Command @@ -28,37 +35,58 @@ class WebsiteData extends Command
28 */ 35 */
29 public function __construct() 36 public function __construct()
30 { 37 {
  38 + $this->time = date('y-d');
31 parent::__construct(); 39 parent::__construct();
32 } 40 }
33 41
  42 +
  43 + public function start(): int
  44 + {
  45 + $status = 0;
  46 + $lists = DataFile::query()->where('status', $status)
  47 + ->where('created_at', 'like', $this->time . '%')->first();
  48 + if (is_null($lists)) {
  49 + $this->debug_echo('没有任务,等待中');
  50 + sleep(60);
  51 + return 0;
  52 + }
  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 +
  60 + }
  61 +
34 /** 62 /**
35 * Execute the console command. 63 * Execute the console command.
36 * 64 *
37 * @return int 65 * @return int
38 */ 66 */
39 - public function handle()  
40 - {  
41 - $DataFile = new DataFile();  
42 - $data = $DataFile->allData();  
43 - # 详细数据  
44 - $items = $data['items'];  
45 - # 总分页  
46 - $totalPage = $data['totalPage'];  
47 - $this->post_data($items);  
48 - if ($totalPage > 1) {  
49 - for ($page = 2; $page <= $totalPage; $page++) {  
50 - $da = $DataFile->allData($page);  
51 - $this->post_data($da['items']);  
52 - }  
53 - }  
54 - $this->info('项目文件数据推送完成!');  
55 - return 0;  
56 - } 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 +// }
57 85
58 public function post_data($data) 86 public function post_data($data)
59 { 87 {
60 $url = env('AICC_URL'); 88 $url = env('AICC_URL');
61 - $msg = http_post("{$url}/api/save_file_data", json_encode(compact('data'))); 89 + $msg = http_post($url, json_encode(compact('data')));
62 print_r($msg); 90 print_r($msg);
63 } 91 }
64 92
@@ -107,7 +107,8 @@ class FileController @@ -107,7 +107,8 @@ class FileController
107 */ 107 */
108 public function single(&$files){ 108 public function single(&$files){
109 $hash = hash_file('md5', $files->getPathname()); 109 $hash = hash_file('md5', $files->getPathname());
110 - $name = $files->getClientOriginalName(); 110 +// $name = $files->getClientOriginalName();
  111 + $name = $files->getFilename();
111 //查看文件是否存在 112 //查看文件是否存在
112 $fileModel = new File(); 113 $fileModel = new File();
113 //查看图片是否已上传 114 //查看图片是否已上传
@@ -120,7 +121,8 @@ class FileController @@ -120,7 +121,8 @@ class FileController
120 return $this->response('资源',Code::SUCCESS,$this->responseData($file_hash['path'], $name)); 121 return $this->response('资源',Code::SUCCESS,$this->responseData($file_hash['path'], $name));
121 } 122 }
122 $url = $this->config['root'].$this->path; 123 $url = $this->config['root'].$this->path;
123 - $fileName = uniqid().rand(10000,99999).'.'.$files->getClientOriginalExtension(); 124 +// $fileName = uniqid().rand(10000,99999).'.'.$files->getClientOriginalExtension();
  125 + $fileName = uniqid().rand(10000,99999).'.'.$files->getExtension();
124 //同步数据到cos 126 //同步数据到cos
125 if($this->upload_location == 1){ 127 if($this->upload_location == 1){
126 $cosService = new CosService(); 128 $cosService = new CosService();