作者 李美松

优化程序

<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
/**
* TODO:: 如果想要在终止 任务时不让数据丢失或者异常,请使用此类
* @author:dc
* @time 2023/8/21 11:03
* Class CmdSignal
* @package App\Console\Commands
*/
trait CmdSignal
{
/**
* 是否停止
* @var bool
*/
public $isStop = false;
/**
* 超时未退出,强制退出 暂时未实现
* @var int
*/
public $stopTimeOut = 30;
public $debugLogFile = null;
/**
* 调试输出
* @param $msg
* @author:dc
* @time 2023/8/21 11:22
*/
public function debug_echo($msg){
if($this->debugLogFile){
@file_put_contents($this->debugLogFile,date('Y-m-d H:i:s')." ===> ".print_r($msg,1).PHP_EOL,FILE_APPEND);
}else{
echo date('Y-m-d H:i:s')." ===> ".print_r($msg,1).PHP_EOL;
}
}
/**
* @return bool
*/
public function handle()
{
if($this->isRunning()){
$this->debug_echo('脚本已运行,请无重复运行');
return 1;
}
$this->debug_echo('已启动脚本');
// 启动时
if(method_exists($this,'init')){
$this->init();
}
// 注册信号处理程序
// SIGHUP:终端控制进程时终止或挂起进程
//SIGINT:中断进程(通常由CTRL+C发出)
//SIGQUIT:退出进程并生成核心转储
//SIGILL:非法指令
//SIGABRT:由调试程序触发的异常终止信号
//SIGFPE:浮点异常
//SIGKILL:无条件终止进程
//SIGSEGV:无效的内存引用
//SIGPIPE:写入已关闭的FIFO或套接字时产生的信号
//SIGTERM:要求终止进程的信号
//SIGUSR1:用户定义的信号1
//SIGUSR2:用户定义的信号2
$handler = function ($signal){
// 可以处理其他程序
$this->isStop = true;
};
pcntl_signal(SIGTERM, $handler);
pcntl_signal(SIGINT, $handler);
// pcntl_signal(SIGHUP, $handler);
// 检查是否接收到信号
pcntl_signal_dispatch();
$tryNum = 0;
// 无限循环,模拟进程运行
while (true) {
// 做一些工作... 异常超过5次就重启下进程
if($this->isStop || $tryNum>5){
break;
}
try {
$this->start();
}catch (\Throwable $e){
$tryNum++;
// 保证此程序正常
$this->debug_echo('异常消息:'.$e->getMessage());
$this->debug_echo('异常文件:'.$e->getFile().':'.$e->getLine());
$this->debug_echo($e->getTraceAsString());
}
}
$this->debug_echo('已退出程序');
return Command::SUCCESS;
}
/**
* 获取进程启动名称
* @return mixed
* @throws \Exception
* @author:dc
* @time 2023/8/21 11:43
*/
public function getSignature(){
if(empty($this->signature)){
throw new \Exception('无法获取到启动命令');
}
return $this->signature;
}
/**
* 是否已运行
* @param int $max 最大运行多少进程
* @return bool
* @throws \Exception
* @author:dc
* @time 2023/8/21 11:54
*/
public function isRunning($max=1):bool {
$ps = "ps -ef | grep \"artisan ".$this->getSignature()."\" | grep -v grep | wc -l";
$num = exec($ps);
if(property_exists($this,'maxRunNumber')){
$max = $this->maxRunNumber;
}
if($num>$max){
return true;
}
return false;
}
}
... ...
... ... @@ -2,11 +2,13 @@
namespace App\Console\Commands;
use App\Http\Controllers\File\FileController;
use App\Models\ProjectAssociation\ProjectAssociation;
use App\Models\File\DataFile;
use Dompdf\Dompdf;
use Dompdf\Options;
use Illuminate\Console\Command;
use Illuminate\Http\File;
class ProjectFilePDF extends Command
{
... ... @@ -82,6 +84,7 @@ class ProjectFilePDF extends Command
$html = $this->html($project_data);
$filename = hash('md5', $this->time . '-' . $project_id . '-' . $friend_id . '-' . $user_id);
$file_path = $this->savePDF($html, $filename);
var_dump($file_path);
$this->DataFile->saveData(compact('project_id', 'user_id', 'friend_id', 'file_path') + ['time' => $this->time]);
}
}
... ... @@ -107,6 +110,18 @@ class ProjectFilePDF extends Command
public function savePDF($html, $filename)
{
$pdf_path = public_path('PDF/');
if (!file_exists($pdf_path)) {
mkdir($pdf_path, 0777, true);
}
// 指定保存路径和文件名
$savePath = $pdf_path . $filename . '.pdf';
if (file_exists($savePath)) {
echo '文件已经存在';
// return 0;
}
// todo 生成中文有问题
# 实例化并使用dompdf类
// $options = new Options();
... ... @@ -122,18 +137,17 @@ class ProjectFilePDF extends Command
// 获取PDF内容
$pdfContent = $dompdf->output();
$pdf_path = public_path('PDF/');
if (!file_exists($pdf_path)) {
mkdir($pdf_path, 0777, true);
}
// 指定保存路径和文件名
$savePath = $pdf_path . $filename . '.pdf';
$fileController = new FileController();
// 将PDF内容保存到文件
file_put_contents($savePath, $pdfContent);
@file_put_contents($savePath, $pdfContent);
// 输出保存成功消息
return $savePath;
// 创建一个文件实例
$file = new File($savePath);
var_dump($file->getFilename());
exit();
return $fileController->single($file);
}
/**
... ...
... ... @@ -7,6 +7,8 @@ use Illuminate\Console\Command;
class WebsiteData extends Command
{
use CmdSignal;
/**
* The name and signature of the console command.
*
... ... @@ -21,6 +23,11 @@ class WebsiteData extends Command
*/
protected $description = '向AICC推送数据';
// 最大支持5个进程
public $maxRunNumber = 50;
protected $time;
/**
* Create a new command instance.
*
... ... @@ -28,37 +35,58 @@ class WebsiteData extends Command
*/
public function __construct()
{
$this->time = date('y-d');
parent::__construct();
}
public function start(): int
{
$status = 0;
$lists = DataFile::query()->where('status', $status)
->where('created_at', 'like', $this->time . '%')->first();
if (is_null($lists)) {
$this->debug_echo('没有任务,等待中');
sleep(60);
return 0;
}
var_dump($lists);
exit();
$data = $lists['items'];
$url = env('AICC_URL');
$msg = http_post($url, json_encode(compact('data')));
}
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
$DataFile = new DataFile();
$data = $DataFile->allData();
# 详细数据
$items = $data['items'];
# 总分页
$totalPage = $data['totalPage'];
$this->post_data($items);
if ($totalPage > 1) {
for ($page = 2; $page <= $totalPage; $page++) {
$da = $DataFile->allData($page);
$this->post_data($da['items']);
}
}
$this->info('项目文件数据推送完成!');
return 0;
}
// public function handle()
// {
// $DataFile = new DataFile();
// $data = $DataFile->allData();
// # 详细数据
// $items = $data['items'];
// # 总分页
// $totalPage = $data['totalPage'];
// $this->post_data($items);
// if ($totalPage > 1) {
// for ($page = 2; $page <= $totalPage; $page++) {
// $da = $DataFile->allData($page);
// $this->post_data($da['items']);
// }
// }
// $this->info('项目文件数据推送完成!');
// return 0;
// }
public function post_data($data)
{
$url = env('AICC_URL');
$msg = http_post("{$url}/api/save_file_data", json_encode(compact('data')));
$msg = http_post($url, json_encode(compact('data')));
print_r($msg);
}
... ...
... ... @@ -107,7 +107,8 @@ class FileController
*/
public function single(&$files){
$hash = hash_file('md5', $files->getPathname());
$name = $files->getClientOriginalName();
// $name = $files->getClientOriginalName();
$name = $files->getFilename();
//查看文件是否存在
$fileModel = new File();
//查看图片是否已上传
... ... @@ -120,7 +121,8 @@ class FileController
return $this->response('资源',Code::SUCCESS,$this->responseData($file_hash['path'], $name));
}
$url = $this->config['root'].$this->path;
$fileName = uniqid().rand(10000,99999).'.'.$files->getClientOriginalExtension();
// $fileName = uniqid().rand(10000,99999).'.'.$files->getClientOriginalExtension();
$fileName = uniqid().rand(10000,99999).'.'.$files->getExtension();
//同步数据到cos
if($this->upload_location == 1){
$cosService = new CosService();
... ...