Merge remote-tracking branch 'origin/master' into akun
正在显示
24 个修改的文件
包含
624 行增加
和
135 行删除
app/Console/Commands/CmdSignal.php
0 → 100644
| 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,14 +2,19 @@ | @@ -2,14 +2,19 @@ | ||
| 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; |
| 8 | +use App\Services\CosService; | ||
| 7 | use Dompdf\Dompdf; | 9 | use Dompdf\Dompdf; |
| 8 | use Dompdf\Options; | 10 | use Dompdf\Options; |
| 9 | use Illuminate\Console\Command; | 11 | use Illuminate\Console\Command; |
| 12 | +use Illuminate\Http\File; | ||
| 10 | 13 | ||
| 11 | class ProjectFilePDF extends Command | 14 | class ProjectFilePDF extends Command |
| 12 | { | 15 | { |
| 16 | + use CmdSignal; | ||
| 17 | + | ||
| 13 | /** | 18 | /** |
| 14 | * The name and signature of the console command. | 19 | * The name and signature of the console command. |
| 15 | * | 20 | * |
| @@ -24,12 +29,19 @@ class ProjectFilePDF extends Command | @@ -24,12 +29,19 @@ class ProjectFilePDF extends Command | ||
| 24 | */ | 29 | */ |
| 25 | protected $description = '网站项目数据,生成PDF文件'; | 30 | protected $description = '网站项目数据,生成PDF文件'; |
| 26 | 31 | ||
| 27 | - protected $AiccWechat; | 32 | + protected $ProjectAssociation; |
| 28 | 33 | ||
| 29 | protected $DataFile; | 34 | protected $DataFile; |
| 30 | 35 | ||
| 31 | protected $time; | 36 | protected $time; |
| 32 | 37 | ||
| 38 | + protected $fileController; | ||
| 39 | + | ||
| 40 | + protected $CosService; | ||
| 41 | + | ||
| 42 | + // 最大支持5个进程 | ||
| 43 | + public $maxRunNumber = 50; | ||
| 44 | + | ||
| 33 | /** | 45 | /** |
| 34 | * Create a new command instance. | 46 | * Create a new command instance. |
| 35 | * | 47 | * |
| @@ -37,81 +49,90 @@ class ProjectFilePDF extends Command | @@ -37,81 +49,90 @@ class ProjectFilePDF extends Command | ||
| 37 | */ | 49 | */ |
| 38 | public function __construct() | 50 | public function __construct() |
| 39 | { | 51 | { |
| 40 | - $this->AiccWechat = new ProjectAssociation(); | 52 | + $this->ProjectAssociation = new ProjectAssociation(); |
| 41 | $this->DataFile = new DataFile(); | 53 | $this->DataFile = new DataFile(); |
| 42 | - $this->time = date("Y-m-d"); | 54 | + $this->time = date("Y-m"); |
| 55 | + $this->fileController = new FileController(); | ||
| 56 | + $this->CosService = new CosService(); | ||
| 43 | parent::__construct(); | 57 | parent::__construct(); |
| 44 | } | 58 | } |
| 45 | 59 | ||
| 46 | - /** | ||
| 47 | - * Execute the console command. | ||
| 48 | - * | ||
| 49 | - * @return int | ||
| 50 | - */ | ||
| 51 | - public function handle() | 60 | + public function start(): int |
| 52 | { | 61 | { |
| 53 | - $data = $this->get_data(); | ||
| 54 | - # 详细数据 | ||
| 55 | - $items = $data['items']; | ||
| 56 | - # 总分页 | ||
| 57 | - $totalPage = $data['totalPage']; | ||
| 58 | - $this->dataPush($items); | ||
| 59 | - if ($totalPage > 1) { | ||
| 60 | - for ($page = 2; $page <= $totalPage; $page++) { | ||
| 61 | - $da = $this->get_data(); | ||
| 62 | - $this->dataPush($da['items']); | ||
| 63 | - } | ||
| 64 | - } | ||
| 65 | - $this->info('生成pdf完成'); | 62 | + # 0 - 未生成 |
| 63 | + # 1 - 已生成 | ||
| 64 | + # 2 - 其它问题 | ||
| 65 | + $is_pdf = 0; | ||
| 66 | + $lists = $this->ProjectAssociation::query()->where('is_pdf', $is_pdf) | ||
| 67 | + ->where('project_id', '!=', 0) | ||
| 68 | + ->where('friend_id', '!=', 0) | ||
| 69 | + ->where('user_id', '!=', 0) | ||
| 70 | + ->where('created_at', 'like', $this->time . '%')->first(); | ||
| 71 | + | ||
| 72 | + if (is_null($lists)) { | ||
| 73 | + $this->debug_echo('没有任务,等待中'); | ||
| 74 | + sleep(30); | ||
| 66 | return 0; | 75 | return 0; |
| 67 | } | 76 | } |
| 77 | + $key = $this->signature . '-' . $lists->id; | ||
| 78 | + $count = redis_get($key); | ||
| 68 | 79 | ||
| 69 | - /** | ||
| 70 | - * 数据生成并保存 | ||
| 71 | - * @param array $items | ||
| 72 | - * @return void | ||
| 73 | - */ | ||
| 74 | - public function dataPush(array $items) | ||
| 75 | - { | ||
| 76 | - foreach ($items as $item) { | ||
| 77 | - $project_id = $item->project_id; | ||
| 78 | - $user_id = $item->user_id; | ||
| 79 | - $friend_id = $item->friend_id; | 80 | + $project_id = $lists->project_id; |
| 81 | + $user_id = $lists->user_id; | ||
| 82 | + $friend_id = $lists->friend_id; | ||
| 80 | // todo 根据项目查询数据 | 83 | // todo 根据项目查询数据 |
| 81 | $project_data = []; | 84 | $project_data = []; |
| 82 | $html = $this->html($project_data); | 85 | $html = $this->html($project_data); |
| 83 | $filename = hash('md5', $this->time . '-' . $project_id . '-' . $friend_id . '-' . $user_id); | 86 | $filename = hash('md5', $this->time . '-' . $project_id . '-' . $friend_id . '-' . $user_id); |
| 87 | + | ||
| 84 | $file_path = $this->savePDF($html, $filename); | 88 | $file_path = $this->savePDF($html, $filename); |
| 85 | - $this->DataFile->saveData(compact('project_id', 'user_id', 'friend_id', 'file_path') + ['time' => $this->time]); | 89 | + if (empty($file_path)) { |
| 90 | + $this->debug_echo('pdf生成失败!'); | ||
| 91 | + return 0; | ||
| 86 | } | 92 | } |
| 93 | + $isRes = $this->DataFile->saveData(compact('project_id', 'user_id', 'friend_id', 'file_path') + ['time' => $this->time]); | ||
| 94 | + if (!$isRes) { | ||
| 95 | + if ($count == 2) { | ||
| 96 | + $lists->is_pdf = 2; | ||
| 97 | + $lists->save(); | ||
| 98 | + $this->debug_echo('项目文件数据保存失败! - 其他原因 - ' . $key); | ||
| 99 | + } else { | ||
| 100 | + redis_set($key, $count + 1); | ||
| 101 | + $this->debug_echo('项目文件数据保存失败! - ' . $key); | ||
| 87 | } | 102 | } |
| 88 | - | ||
| 89 | - | ||
| 90 | - public function get_data($page = 1, $perPage = 20) | ||
| 91 | - { | ||
| 92 | - $data = $this->AiccWechat->allData($page, $perPage); | ||
| 93 | - # 总条数 | ||
| 94 | - $total = $data['total']; | ||
| 95 | - if (empty($total)) { | ||
| 96 | - $this->error('暂无绑定AICC微信数据'); | ||
| 97 | - return 0; | ||
| 98 | } | 103 | } |
| 99 | - # 详细数据 | ||
| 100 | - $items = $data['items']; | ||
| 101 | - # 总分页 | ||
| 102 | - $totalPage = $data['totalPage']; | ||
| 103 | - # 当前页 | ||
| 104 | - $currentPage = $data['currentPage']; | ||
| 105 | - return compact('total', 'items', 'totalPage', 'currentPage'); | 104 | + $lists->is_pdf = 1; |
| 105 | + $lists->save(); | ||
| 106 | + $this->info('项目文件数据保存成功!'); | ||
| 107 | + return 0; | ||
| 106 | } | 108 | } |
| 107 | 109 | ||
| 110 | + | ||
| 111 | + /** | ||
| 112 | + * @param $html | ||
| 113 | + * @param $filename | ||
| 114 | + * @return string | ||
| 115 | + */ | ||
| 108 | public function savePDF($html, $filename) | 116 | public function savePDF($html, $filename) |
| 109 | { | 117 | { |
| 118 | + | ||
| 119 | + $pdf_path = public_path('PDF/'); | ||
| 120 | + if (!file_exists($pdf_path)) { | ||
| 121 | + mkdir($pdf_path, 0777, true); | ||
| 122 | + } | ||
| 123 | + | ||
| 124 | + // 指定保存路径和文件名 | ||
| 125 | + $savePath = $pdf_path . $filename . '.pdf'; | ||
| 126 | + if (file_exists($savePath)) { | ||
| 127 | + echo '文件已经存在'; | ||
| 128 | +// return 0; | ||
| 129 | + } | ||
| 110 | // todo 生成中文有问题 | 130 | // todo 生成中文有问题 |
| 111 | # 实例化并使用dompdf类 | 131 | # 实例化并使用dompdf类 |
| 112 | - $options = new Options(); | ||
| 113 | - $options->setDefaultFont('arial'); | ||
| 114 | - $dompdf = new Dompdf($options); | 132 | +// $options = new Options(); |
| 133 | +// $options->setDefaultFont('arial'); | ||
| 134 | +// $dompdf = new Dompdf($options); | ||
| 135 | + $dompdf = new Dompdf(); | ||
| 115 | $dompdf->loadHtml($html); | 136 | $dompdf->loadHtml($html); |
| 116 | #(可选)设置纸张大小和方向 | 137 | #(可选)设置纸张大小和方向 |
| 117 | $dompdf->setPaper('A4', 'landscape'); | 138 | $dompdf->setPaper('A4', 'landscape'); |
| @@ -121,15 +142,13 @@ class ProjectFilePDF extends Command | @@ -121,15 +142,13 @@ class ProjectFilePDF extends Command | ||
| 121 | 142 | ||
| 122 | // 获取PDF内容 | 143 | // 获取PDF内容 |
| 123 | $pdfContent = $dompdf->output(); | 144 | $pdfContent = $dompdf->output(); |
| 124 | - | ||
| 125 | - // 指定保存路径和文件名 | ||
| 126 | - $savePath = public_path('PDF/' . $filename . '.pdf'); | 145 | + $path = '/V6/PDF/' . $this->time; |
| 127 | 146 | ||
| 128 | // 将PDF内容保存到文件 | 147 | // 将PDF内容保存到文件 |
| 129 | - file_put_contents($savePath, $pdfContent); | ||
| 130 | - | ||
| 131 | - // 输出保存成功消息 | ||
| 132 | - return $savePath; | 148 | + @file_put_contents($savePath, $pdfContent); |
| 149 | + // 创建一个文件实例 | ||
| 150 | + $file = new File($savePath); | ||
| 151 | + return $this->CosService->uploadFile($file, $path, $filename . '.pdf'); | ||
| 133 | } | 152 | } |
| 134 | 153 | ||
| 135 | /** | 154 | /** |
| @@ -142,7 +161,7 @@ class ProjectFilePDF extends Command | @@ -142,7 +161,7 @@ class ProjectFilePDF extends Command | ||
| 142 | $html = '<html>'; | 161 | $html = '<html>'; |
| 143 | $html .= '<body style="font-family:arial">'; | 162 | $html .= '<body style="font-family:arial">'; |
| 144 | $html .= '<h1>Hello, World!</h1>'; | 163 | $html .= '<h1>Hello, World!</h1>'; |
| 145 | - $html .= '<p>中文内容</p>'; | 164 | + $html .= '<p>中文内容ffffff</p>'; |
| 146 | $html .= '</body>'; | 165 | $html .= '</body>'; |
| 147 | $html .= '</html>'; | 166 | $html .= '</html>'; |
| 148 | return $html; | 167 | return $html; |
| @@ -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,53 @@ class WebsiteData extends Command | @@ -28,37 +35,53 @@ class WebsiteData extends Command | ||
| 28 | */ | 35 | */ |
| 29 | public function __construct() | 36 | public function __construct() |
| 30 | { | 37 | { |
| 38 | + $this->time = date('Y-m'); | ||
| 31 | parent::__construct(); | 39 | parent::__construct(); |
| 32 | } | 40 | } |
| 33 | 41 | ||
| 34 | - /** | ||
| 35 | - * Execute the console command. | ||
| 36 | - * | ||
| 37 | - * @return int | ||
| 38 | - */ | ||
| 39 | - public function handle() | 42 | + public function start(): int |
| 40 | { | 43 | { |
| 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']); | 44 | + # 0 - 未推送 |
| 45 | + # 1 - 已推送 | ||
| 46 | + # 2 - 其他问题 | ||
| 47 | + $status = 0; | ||
| 48 | + $lists = DataFile::query()->where('status', $status) | ||
| 49 | + ->where('created_at', 'like', $this->time . '%')->first(); | ||
| 50 | + if (is_null($lists)) { | ||
| 51 | + $this->debug_echo('没有任务,等待中'); | ||
| 52 | + sleep(30); | ||
| 53 | + return 0; | ||
| 54 | + } | ||
| 55 | + | ||
| 56 | + $key = $this->signature . '-' . $lists->id; | ||
| 57 | + $count = redis_get($key); | ||
| 58 | + $data = $lists; | ||
| 59 | + $url = env('AICC_URL'); | ||
| 60 | + $msg = http_post($url, json_encode(compact('data'))); | ||
| 61 | + $status_code = 0; | ||
| 62 | + if ($msg) { | ||
| 63 | + $status_code = (int)$msg['status']; | ||
| 64 | + } | ||
| 65 | + if ($status_code != 200) { | ||
| 66 | + if ($count == 2) { | ||
| 67 | + $lists->status = 2; | ||
| 68 | + $lists->save(); | ||
| 69 | + $this->debug_echo('项目文件数据保存失败! - 其他原因 - ' . $key); | ||
| 70 | + } else { | ||
| 71 | + redis_set($key, $count + 1); | ||
| 72 | + $this->debug_echo('项目文件数据保存失败! - ' . $key); | ||
| 52 | } | 73 | } |
| 53 | } | 74 | } |
| 54 | - $this->info('项目文件数据推送完成!'); | 75 | + $lists->status = 1; |
| 76 | + $lists->save(); | ||
| 77 | + $this->info('项目文件数据保存成功!'); | ||
| 55 | return 0; | 78 | return 0; |
| 56 | } | 79 | } |
| 57 | 80 | ||
| 58 | public function post_data($data) | 81 | public function post_data($data) |
| 59 | { | 82 | { |
| 60 | $url = env('AICC_URL'); | 83 | $url = env('AICC_URL'); |
| 61 | - $msg = http_post("{$url}/api/save_file_data", json_encode(compact('data'))); | 84 | + $msg = http_post($url, json_encode(compact('data'))); |
| 62 | print_r($msg); | 85 | print_r($msg); |
| 63 | } | 86 | } |
| 64 | 87 |
| @@ -38,8 +38,8 @@ class Kernel extends ConsoleKernel | @@ -38,8 +38,8 @@ class Kernel extends ConsoleKernel | ||
| 38 | $schedule->command('last_inquiry')->dailyAt('04:00')->withoutOverlapping(1);// 最近一次询盘信息 | 38 | $schedule->command('last_inquiry')->dailyAt('04:00')->withoutOverlapping(1);// 最近一次询盘信息 |
| 39 | $schedule->command('update_progress')->everyThirtyMinutes()->withoutOverlapping(1);//监控更新 | 39 | $schedule->command('update_progress')->everyThirtyMinutes()->withoutOverlapping(1);//监控更新 |
| 40 | $schedule->command('update_seo_tdk_crontab')->dailyAt('00:00')->withoutOverlapping(1); //更新上线项目TDK | 40 | $schedule->command('update_seo_tdk_crontab')->dailyAt('00:00')->withoutOverlapping(1); //更新上线项目TDK |
| 41 | - $schedule->command('website_data')->everyMinute()->withoutOverlapping(1); // 向AICC推送数据 | ||
| 42 | - $schedule->command('project_file_pdf')->everyMinute()->withoutOverlapping(1); // 网站项目数据,生成PDF文件 | 41 | + $schedule->command('website_data')->dailyAt('01:00')->withoutOverlapping(1); // 向AICC推送数据 |
| 42 | + $schedule->command('project_file_pdf')->dailyAt('00:00')->withoutOverlapping(1); // 网站项目数据,生成PDF文件 | ||
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | /** | 45 | /** |
| @@ -9,6 +9,7 @@ use GuzzleHttp\Client; | @@ -9,6 +9,7 @@ use GuzzleHttp\Client; | ||
| 9 | use GuzzleHttp\Exception\GuzzleException; | 9 | use GuzzleHttp\Exception\GuzzleException; |
| 10 | use Illuminate\Support\Carbon; | 10 | use Illuminate\Support\Carbon; |
| 11 | use App\Models\File\File; | 11 | use App\Models\File\File; |
| 12 | +use Illuminate\Support\Facades\Redis; | ||
| 12 | 13 | ||
| 13 | define('HTTP_OPENAI_URL', 'http://openai.waimaoq.com/'); | 14 | define('HTTP_OPENAI_URL', 'http://openai.waimaoq.com/'); |
| 14 | /** | 15 | /** |
| @@ -616,3 +617,29 @@ function getRouteMap($source,$source_id){ | @@ -616,3 +617,29 @@ function getRouteMap($source,$source_id){ | ||
| 616 | } | 617 | } |
| 617 | return $route; | 618 | return $route; |
| 618 | } | 619 | } |
| 620 | + | ||
| 621 | +function redis_get($key){ | ||
| 622 | + return Redis::connection()->client()->get($key); | ||
| 623 | +} | ||
| 624 | +function redis_del(...$key){ | ||
| 625 | + return Redis::connection()->client()->del(...$key); | ||
| 626 | +} | ||
| 627 | + | ||
| 628 | +function redis_set($key,$val,$ttl=3600){ | ||
| 629 | + return Redis::connection()->client()->set($key,$val,$ttl); | ||
| 630 | +} | ||
| 631 | + | ||
| 632 | +/** | ||
| 633 | + * 添加缓存,存在则失败 | ||
| 634 | + * @param $key | ||
| 635 | + * @param $val | ||
| 636 | + * @param int $ttl | ||
| 637 | + * @return mixed | ||
| 638 | + * @author:dc | ||
| 639 | + * @time 2023/10/25 9:48 | ||
| 640 | + */ | ||
| 641 | +function redis_add($key,$val,$ttl=3600){ | ||
| 642 | + return Redis::connection()->client()->eval( | ||
| 643 | + "return redis.call('exists',KEYS[1])<1 and redis.call('setex',KEYS[1],ARGV[2],ARGV[1])", [$key, $val, $ttl], 1 | ||
| 644 | + ); | ||
| 645 | +} |
| @@ -25,6 +25,9 @@ class KeywordPrefixController extends BaseController | @@ -25,6 +25,9 @@ class KeywordPrefixController extends BaseController | ||
| 25 | */ | 25 | */ |
| 26 | public function getKeywordPrefix(){ | 26 | public function getKeywordPrefix(){ |
| 27 | $keywordPrefixModel = new KeywordPrefix(); | 27 | $keywordPrefixModel = new KeywordPrefix(); |
| 28 | + if(isset($this->map['project_id']) && !empty($this->map['project_id'])){ | ||
| 29 | + $this->map['project_id'] = ['in',[0,$this->map['project_id']]]; | ||
| 30 | + } | ||
| 28 | $list = $keywordPrefixModel->list($this->map); | 31 | $list = $keywordPrefixModel->list($this->map); |
| 29 | $this->response('success',Code::SUCCESS,$list); | 32 | $this->response('success',Code::SUCCESS,$list); |
| 30 | } | 33 | } |
| @@ -33,9 +33,21 @@ class CNoticeController extends BaseController | @@ -33,9 +33,21 @@ class CNoticeController extends BaseController | ||
| 33 | /** | 33 | /** |
| 34 | * 更新通知C端 | 34 | * 更新通知C端 |
| 35 | * @param Request $request | 35 | * @param Request $request |
| 36 | - * @param WebSettingLogic $webSettingLogic | 36 | + * @return \Illuminate\Http\JsonResponse |
| 37 | */ | 37 | */ |
| 38 | - public function sendNotify(){ | 38 | + public function sendNotify(Request $request) |
| 39 | + { | ||
| 40 | + $url = $this->user['domain'].'api/update_page/'; | ||
| 41 | + $param = [ | ||
| 42 | + 'project_id' => $this->user['project_id'], | ||
| 43 | + 'type' => intval($request->input('type', 1)), | ||
| 44 | + 'route' => intval($request->input('page', 1)), | ||
| 45 | + 'url' => $request->input('url', []), | ||
| 46 | + 'language'=> $request->input('language', []), | ||
| 47 | + ]; | ||
| 48 | + $result = http_post($url, json_encode($param)); | ||
| 49 | + return $this->response('更新中请稍后, 更新完成将会发送站内信通知更新结果!'); | ||
| 50 | + | ||
| 39 | $updateProgressModel = new UpdateProgress(); | 51 | $updateProgressModel = new UpdateProgress(); |
| 40 | $progressInfo = $updateProgressModel->formatQuery(['project_id'=>$this->user['project_id'],'type'=>$this->param['type']])->orderBy('id','desc')->first(); | 52 | $progressInfo = $updateProgressModel->formatQuery(['project_id'=>$this->user['project_id'],'type'=>$this->param['type']])->orderBy('id','desc')->first(); |
| 41 | if((!empty($progressInfo))){ | 53 | if((!empty($progressInfo))){ |
| @@ -24,7 +24,7 @@ class BlogController extends BaseController | @@ -24,7 +24,7 @@ class BlogController extends BaseController | ||
| 24 | * @time :2023/9/14 10:45 | 24 | * @time :2023/9/14 10:45 |
| 25 | */ | 25 | */ |
| 26 | public function lists(BlogModel $blogModel){ | 26 | public function lists(BlogModel $blogModel){ |
| 27 | - $filed = ['id','category_id','operator_id','status','created_at','label_id','image','updated_at','name','sort','url','release_at']; | 27 | + $filed = ['id','category_id','operator_id','status','created_at','label_id','image','updated_at','name','sort','url','release_at','is_upgrade']; |
| 28 | $this->order = 'sort'; | 28 | $this->order = 'sort'; |
| 29 | $query = $blogModel->orderBy($this->order ,'desc')->orderBy('id','desc'); | 29 | $query = $blogModel->orderBy($this->order ,'desc')->orderBy('id','desc'); |
| 30 | $query = $this->searchParam($query); | 30 | $query = $this->searchParam($query); |
| @@ -24,7 +24,7 @@ class NewsController extends BaseController | @@ -24,7 +24,7 @@ class NewsController extends BaseController | ||
| 24 | * @method | 24 | * @method |
| 25 | */ | 25 | */ |
| 26 | public function lists(NewsModel $news){ | 26 | public function lists(NewsModel $news){ |
| 27 | - $filed = ['id','category_id','operator_id','status','created_at','image','updated_at','name','sort','url', 'release_at']; | 27 | + $filed = ['id','category_id','operator_id','status','created_at','image','updated_at','name','sort','url', 'release_at','is_upgrade']; |
| 28 | $this->order = 'sort'; | 28 | $this->order = 'sort'; |
| 29 | $query = $news->orderBy($this->order ,'desc')->orderBy('id','desc'); | 29 | $query = $news->orderBy($this->order ,'desc')->orderBy('id','desc'); |
| 30 | $query = $this->searchParam($query); | 30 | $query = $this->searchParam($query); |
| @@ -36,6 +36,7 @@ class NewsController extends BaseController | @@ -36,6 +36,7 @@ class NewsController extends BaseController | ||
| 36 | $user = new User(); | 36 | $user = new User(); |
| 37 | foreach ($lists['list'] as $k => $v){ | 37 | foreach ($lists['list'] as $k => $v){ |
| 38 | $v['category_name'] = $this->categoryName($v['category_id'],$data); | 38 | $v['category_name'] = $this->categoryName($v['category_id'],$data); |
| 39 | + $v['seo_mate'] = | ||
| 39 | $v['url'] = $this->user['domain'].getRouteMap(RouteMap::SOURCE_NEWS,$v['id']); | 40 | $v['url'] = $this->user['domain'].getRouteMap(RouteMap::SOURCE_NEWS,$v['id']); |
| 40 | $v['image_link'] = getImageUrl($v['image']); | 41 | $v['image_link'] = getImageUrl($v['image']); |
| 41 | $v['operator_name'] = $user->getName($v['operator_id']); | 42 | $v['operator_name'] = $user->getName($v['operator_id']); |
| @@ -43,7 +43,7 @@ class ProductController extends BaseController | @@ -43,7 +43,7 @@ class ProductController extends BaseController | ||
| 43 | public function index(Product $product) | 43 | public function index(Product $product) |
| 44 | { | 44 | { |
| 45 | $filed = ['id', 'project_id', 'title', 'sort' ,'thumb', 'gallery' ,'product_type' , 'route' , | 45 | $filed = ['id', 'project_id', 'title', 'sort' ,'thumb', 'gallery' ,'product_type' , 'route' , |
| 46 | - 'category_id', 'keyword_id', 'status', 'created_uid', 'created_at', 'updated_at']; | 46 | + 'category_id', 'keyword_id', 'status', 'created_uid', 'is_upgrade' ,'created_at', 'updated_at']; |
| 47 | $this->order = 'sort'; | 47 | $this->order = 'sort'; |
| 48 | $query = $product->orderBy($this->order ,'desc')->orderBy('id','desc'); | 48 | $query = $product->orderBy($this->order ,'desc')->orderBy('id','desc'); |
| 49 | $query = $this->searchParam($query); | 49 | $query = $this->searchParam($query); |
| @@ -3,8 +3,12 @@ | @@ -3,8 +3,12 @@ | ||
| 3 | namespace App\Http\Controllers\Bside\Setting; | 3 | namespace App\Http\Controllers\Bside\Setting; |
| 4 | 4 | ||
| 5 | use App\Enums\Common\Code; | 5 | use App\Enums\Common\Code; |
| 6 | +use App\Helper\Translate; | ||
| 6 | use App\Http\Controllers\Bside\BaseController; | 7 | use App\Http\Controllers\Bside\BaseController; |
| 7 | use App\Http\Logic\Bside\Setting\ProofreadingLogic; | 8 | use App\Http\Logic\Bside\Setting\ProofreadingLogic; |
| 9 | +use App\Models\WebSetting\Proofreading; | ||
| 10 | +use App\Models\WebSetting\WebSettingCountry; | ||
| 11 | +use Illuminate\Support\Facades\DB; | ||
| 8 | 12 | ||
| 9 | class ProofreadingController extends BaseController | 13 | class ProofreadingController extends BaseController |
| 10 | { | 14 | { |
| @@ -16,18 +20,125 @@ class ProofreadingController extends BaseController | @@ -16,18 +20,125 @@ class ProofreadingController extends BaseController | ||
| 16 | * @method :post | 20 | * @method :post |
| 17 | * @time :2023/6/12 10:52 | 21 | * @time :2023/6/12 10:52 |
| 18 | */ | 22 | */ |
| 19 | - public function lists(ProofreadingLogic $proofreadingLogic){ | ||
| 20 | - //默认显示语言为英语 | ||
| 21 | - if(!isset($this->map['language_id']) || empty($this->map['language_id'])){ | ||
| 22 | - $this->map['language_id'] = $this::LANGUAGE_ID; | 23 | + public function lists(){ |
| 24 | + //获取语种信息 | ||
| 25 | + $webSettingCountryModel = new WebSettingCountry(); | ||
| 26 | + $countryInfo = $webSettingCountryModel->read(['id'=>$this->param['language_id']]); | ||
| 27 | + //获取当前链接和语种的校队列表 | ||
| 28 | + $proofreadingModel = new Proofreading(); | ||
| 29 | + $list = $proofreadingModel->list(['url'=>$this->param['url'],'language_id'=>$this->param['language_id'],'type'=>1],'created_at',['text','translate']); | ||
| 30 | + //获取当前URl的所有文本内容 | ||
| 31 | + $new_list = $this->getUrlRead($this->param['url']); | ||
| 32 | + if(empty($list)){ | ||
| 33 | + $data = []; | ||
| 34 | + $translate_list = Translate::tran($new_list, $countryInfo['alias']); | ||
| 35 | + foreach ($new_list as $k=>$v){ | ||
| 36 | + $data[] = [ | ||
| 37 | + 'text'=>trim($v), | ||
| 38 | + 'translate'=>$translate_list[$k], | ||
| 39 | + ]; | ||
| 23 | } | 40 | } |
| 24 | - $lists = $proofreadingLogic->proofreadingList($this->map,$this->page,$this->row); | ||
| 25 | - if(!empty($lists['list']) && ($this->param['type'] == $this::TYPE_IMAGE)){ | ||
| 26 | - foreach ($lists['list'] as $k => $v){ | ||
| 27 | - $lists['list'][$k]['image_link'] = getImageUrl($v['translate']); | 41 | + return $this->response('success',Code::SUCCESS,$data); |
| 28 | } | 42 | } |
| 43 | + $data = [];//返回数据 | ||
| 44 | + $old_list = []; | ||
| 45 | + foreach ($list as $v){ | ||
| 46 | + $old_list[] = $v['text']; | ||
| 47 | + $data[] = [ | ||
| 48 | + 'text'=>$v['text'], | ||
| 49 | + 'translate'=>$v['translate'], | ||
| 50 | + ]; | ||
| 29 | } | 51 | } |
| 30 | - $this->response('success',Code::SUCCESS,$lists); | 52 | + $arr2 = array_values(array_diff($new_list, $old_list)); |
| 53 | + if(!empty($arr2)){ | ||
| 54 | + $translate_list = Translate::tran($arr2, $countryInfo['alias']); | ||
| 55 | + foreach ($arr2 as $k1=>$v1){ | ||
| 56 | + $data[] = [ | ||
| 57 | + 'text'=>$v1, | ||
| 58 | + 'translate'=>$translate_list[$k1] | ||
| 59 | + ]; | ||
| 60 | + } | ||
| 61 | + } | ||
| 62 | + $this->response('success',Code::SUCCESS,$data); | ||
| 63 | + } | ||
| 64 | + | ||
| 65 | + /** | ||
| 66 | + * @remark :获取图片列表 | ||
| 67 | + * @name :imageList | ||
| 68 | + * @author :lyh | ||
| 69 | + * @method :post | ||
| 70 | + * @time :2023/11/23 17:29 | ||
| 71 | + */ | ||
| 72 | + public function imageList(){ | ||
| 73 | + $proofreadingModel = new Proofreading(); | ||
| 74 | + $list = $proofreadingModel->list(['url'=>$this->param['url'],'language_id'=>$this->param['language_id'],'type'=>2],'created_at',['text','translate']); | ||
| 75 | + if(empty($list)){ | ||
| 76 | + $new_list = $this->getUrlImageRead($this->param['url']); | ||
| 77 | + foreach ($new_list as $k=>$v){ | ||
| 78 | + $data[] = [ | ||
| 79 | + 'text'=>$v, | ||
| 80 | + 'translate'=>$v, | ||
| 81 | + ]; | ||
| 82 | + } | ||
| 83 | + return $this->response('success',Code::SUCCESS,$data); | ||
| 84 | + } | ||
| 85 | + $new_list = $this->getUrlImageRead($this->param['url']); | ||
| 86 | + $data = [];//返回数据 | ||
| 87 | + $old_list = []; | ||
| 88 | + foreach ($list as $v){ | ||
| 89 | + $old_list[] = $v['text']; | ||
| 90 | + $data[] = [ | ||
| 91 | + 'text'=>$v['text'], | ||
| 92 | + 'translate'=>$v['translate'], | ||
| 93 | + ]; | ||
| 94 | + } | ||
| 95 | + $arr2 = array_values(array_diff($new_list, $old_list)); | ||
| 96 | + if(!empty($arr2)){ | ||
| 97 | + foreach ($arr2 as $v1){ | ||
| 98 | + $data[] = [ | ||
| 99 | + 'text'=>$v1, | ||
| 100 | + 'translate'=>$v1 | ||
| 101 | + ]; | ||
| 102 | + } | ||
| 103 | + } | ||
| 104 | + $this->response('success',Code::SUCCESS,$data); | ||
| 105 | + } | ||
| 106 | + | ||
| 107 | + /** | ||
| 108 | + * @name :(新增/更新多语言)save | ||
| 109 | + * @author :lyh | ||
| 110 | + * @method :post | ||
| 111 | + * @time :2023/6/12 10:52 | ||
| 112 | + */ | ||
| 113 | + public function save(){ | ||
| 114 | + //清除以前的翻译校队数据,重新添加 | ||
| 115 | + $param = [ | ||
| 116 | + 'type'=>1, | ||
| 117 | + 'project_id'=>$this->user['project_id'], | ||
| 118 | + 'url'=>$this->param['url'], | ||
| 119 | + 'language_id'=>$this->param['language_id'], | ||
| 120 | + 'alias'=>$this->param['alias'], | ||
| 121 | + 'created_at'=>date('Y-m-d H:i:s'), | ||
| 122 | + 'updated_at'=>date('Y-m-d H:i:s') | ||
| 123 | + ]; | ||
| 124 | + $proofreadingModel = new Proofreading(); | ||
| 125 | + DB::beginTransaction(); | ||
| 126 | + try { | ||
| 127 | + $proofreadingModel->del(['language_id'=>$this->param['language_id'],'url'=>$this->param['url'],'type'=>1]); | ||
| 128 | + //删除成功后,重新添加 | ||
| 129 | + $save_data = []; | ||
| 130 | + foreach ($this->param['data'] as $k => $v){ | ||
| 131 | + $param['text'] = $v['text']; | ||
| 132 | + $param['translate'] = $v['translate']; | ||
| 133 | + $save_data[] = $param; | ||
| 134 | + } | ||
| 135 | + $proofreadingModel->insert($save_data); | ||
| 136 | + DB::commit(); | ||
| 137 | + }catch (\Exception $e){ | ||
| 138 | + DB::rollBack(); | ||
| 139 | + $this->fail('系统错误请联系管理员'); | ||
| 140 | + } | ||
| 141 | + $this->response('success'); | ||
| 31 | } | 142 | } |
| 32 | 143 | ||
| 33 | /** | 144 | /** |
| @@ -36,8 +147,34 @@ class ProofreadingController extends BaseController | @@ -36,8 +147,34 @@ class ProofreadingController extends BaseController | ||
| 36 | * @method :post | 147 | * @method :post |
| 37 | * @time :2023/6/12 10:52 | 148 | * @time :2023/6/12 10:52 |
| 38 | */ | 149 | */ |
| 39 | - public function save(ProofreadingLogic $proofreadingLogic){ | ||
| 40 | - $proofreadingLogic->proofreadingSave(); | 150 | + public function saveImage(){ |
| 151 | + //清除以前的翻译校队数据,重新添加 | ||
| 152 | + $param = [ | ||
| 153 | + 'type'=>2, | ||
| 154 | + 'project_id'=>$this->user['project_id'], | ||
| 155 | + 'url'=>$this->param['url'], | ||
| 156 | + 'language_id'=>$this->param['language_id'], | ||
| 157 | + 'alias'=>$this->param['alias'], | ||
| 158 | + 'created_at'=>date('Y-m-d H:i:s'), | ||
| 159 | + 'updated_at'=>date('Y-m-d H:i:s') | ||
| 160 | + ]; | ||
| 161 | + $proofreadingModel = new Proofreading(); | ||
| 162 | + DB::beginTransaction(); | ||
| 163 | + try { | ||
| 164 | + $proofreadingModel->del(['language_id'=>$this->param['language_id'],'url'=>$this->param['url'],'type'=>2]); | ||
| 165 | + //删除成功后,重新添加 | ||
| 166 | + $save_data = []; | ||
| 167 | + foreach ($this->param['data'] as $k => $v){ | ||
| 168 | + $param['text'] = $v['text']; | ||
| 169 | + $param['translate'] = $v['translate']; | ||
| 170 | + $save_data[] = $param; | ||
| 171 | + } | ||
| 172 | + $proofreadingModel->insert($save_data); | ||
| 173 | + DB::commit(); | ||
| 174 | + }catch (\Exception $e){ | ||
| 175 | + DB::rollBack(); | ||
| 176 | + $this->fail('系统错误请联系管理员'); | ||
| 177 | + } | ||
| 41 | $this->response('success'); | 178 | $this->response('success'); |
| 42 | } | 179 | } |
| 43 | 180 | ||
| @@ -60,8 +197,68 @@ class ProofreadingController extends BaseController | @@ -60,8 +197,68 @@ class ProofreadingController extends BaseController | ||
| 60 | * @time :2023/11/22 10:02 | 197 | * @time :2023/11/22 10:02 |
| 61 | */ | 198 | */ |
| 62 | public function getUrlRead($url){ | 199 | public function getUrlRead($url){ |
| 63 | - $sourceCode = file_get_contents($url); | ||
| 64 | - $strippedContent = strip_tags($sourceCode); // 删除所有HTML标签 | ||
| 65 | - var_dump($strippedContent); | 200 | + $contextOptions = [ |
| 201 | + 'ssl' => [ | ||
| 202 | + 'verify_peer' => false, | ||
| 203 | + 'verify_peer_name' => false, | ||
| 204 | + ], | ||
| 205 | + ]; | ||
| 206 | + $context = stream_context_create($contextOptions); | ||
| 207 | + $sourceCode = file_get_contents($url, false, $context); | ||
| 208 | + $pattern = '/<style\b[^>]*>(.*?)<\/style>/s'; // 定义匹配`<style>`标签及其内容的正则表达式 | ||
| 209 | + $strippedContent = preg_replace($pattern, '', $sourceCode); // 删除`<style>`标签及其内容 | ||
| 210 | + $pattern = '/<script\b[^>]*>(.*?)<\/script>/s'; // 定义匹配`<script>`标签及其内容的正则表达式 | ||
| 211 | + $strippedContent = preg_replace($pattern, '', $strippedContent); // 删除`<script>`标签及其内容 | ||
| 212 | + $pattern = '/<link\b[^>]*>/'; // 定义匹配 `<link>` 标签的正则表达式 | ||
| 213 | + $strippedContent = preg_replace($pattern, '', $strippedContent); // 删除 `<link>` 标签 | ||
| 214 | + $pattern = '/<footer\b[^>]*>(.*?)<\/footer>/s'; // 定义匹配`<script>`标签及其内容的正则表达式 | ||
| 215 | + $strippedContent = preg_replace($pattern, '', $strippedContent); // 删除`<script>`标签及其内容 | ||
| 216 | + $pattern = '/>([^<]+)</'; // 定义匹配中间内容不是标签的正则表达式 | ||
| 217 | + $matches = array(); | ||
| 218 | + preg_match_all($pattern, $strippedContent, $matches); | ||
| 219 | + $textContentArray = array_filter($matches[1], function($item) { | ||
| 220 | + return !empty(trim($item)); | ||
| 221 | + }); | ||
| 222 | + $data = []; | ||
| 223 | + foreach ($textContentArray as $v){ | ||
| 224 | + $content = trim($v); | ||
| 225 | + $trimmedString = preg_replace('/\s+/', ' ', $content); | ||
| 226 | + $data[] = $trimmedString; | ||
| 227 | + } | ||
| 228 | + $data = array_values($data); | ||
| 229 | + $uniqueArray = array_unique($data); | ||
| 230 | + $data = array_values($uniqueArray); | ||
| 231 | + return $data; | ||
| 232 | + } | ||
| 233 | + | ||
| 234 | + /** | ||
| 235 | + * @remark :获取Url内容 | ||
| 236 | + * @name :getUrlRead | ||
| 237 | + * @author :lyh | ||
| 238 | + * @method :post | ||
| 239 | + * @time :2023/11/22 10:02 | ||
| 240 | + */ | ||
| 241 | + public function getUrlImageRead($url){ | ||
| 242 | + $contextOptions = [ | ||
| 243 | + 'ssl' => [ | ||
| 244 | + 'verify_peer' => false, | ||
| 245 | + 'verify_peer_name' => false, | ||
| 246 | + ], | ||
| 247 | + ]; | ||
| 248 | + $pattern = '/<img.*?src="(.*?)".*?>/i'; | ||
| 249 | + $matches = array(); | ||
| 250 | + $context = stream_context_create($contextOptions); | ||
| 251 | + $sourceCode = file_get_contents($url, false, $context); | ||
| 252 | + preg_match_all($pattern, $sourceCode, $matches); | ||
| 253 | + $textContentArray = $matches[1]; | ||
| 254 | + $data = []; | ||
| 255 | + foreach ($textContentArray as $v){ | ||
| 256 | + if(!empty($v)){ | ||
| 257 | + $data[] = $v; | ||
| 258 | + } | ||
| 259 | + } | ||
| 260 | + $uniqueArray = array_unique($data); | ||
| 261 | + $data = array_values($uniqueArray); | ||
| 262 | + return $data; | ||
| 66 | } | 263 | } |
| 67 | } | 264 | } |
| @@ -12,7 +12,6 @@ namespace App\Http\Controllers\Bside\Template; | @@ -12,7 +12,6 @@ namespace App\Http\Controllers\Bside\Template; | ||
| 12 | use App\Enums\Common\Code; | 12 | use App\Enums\Common\Code; |
| 13 | use App\Http\Controllers\Bside\BaseController; | 13 | use App\Http\Controllers\Bside\BaseController; |
| 14 | use App\Http\Logic\Bside\BTemplate\VisualizationLogic; | 14 | use App\Http\Logic\Bside\BTemplate\VisualizationLogic; |
| 15 | -use App\Models\Visualization\Visualization; | ||
| 16 | 15 | ||
| 17 | /** | 16 | /** |
| 18 | * @remark :定制项目处理 | 17 | * @remark :定制项目处理 |
| @@ -132,7 +132,54 @@ class FileController | @@ -132,7 +132,54 @@ class FileController | ||
| 132 | } | 132 | } |
| 133 | } | 133 | } |
| 134 | $this->saveMysql($fileModel,$files->getSize(),$files->getClientOriginalExtension(),$fileName,$hash,$this->upload_location,$files->getMimeType(),$name); | 134 | $this->saveMysql($fileModel,$files->getSize(),$files->getClientOriginalExtension(),$fileName,$hash,$this->upload_location,$files->getMimeType(),$name); |
| 135 | - return $this->response('资源',Code::SUCCESS,$this->responseData($this->path.'/'.$fileName, $name)); | 135 | + $this->response('资源',Code::SUCCESS,$this->responseData($this->path.'/'.$fileName, $name)); |
| 136 | + } | ||
| 137 | + | ||
| 138 | + /** | ||
| 139 | + * 接口上传单文件 | ||
| 140 | + * @param $files | ||
| 141 | + * @return array | ||
| 142 | + */ | ||
| 143 | + public function api_upload_single(&$files) | ||
| 144 | + { | ||
| 145 | + $hash = hash_file('md5', $files->getPathname()); | ||
| 146 | + $name = $files->getFilename(); | ||
| 147 | + //查看文件是否存在 | ||
| 148 | + $fileModel = new File(); | ||
| 149 | + //查看图片是否已上传 | ||
| 150 | + $param = ['hash' => $hash, 'refer' => $this->param['refer'] ?? 0]; | ||
| 151 | + if (isset($this->cache['project_id']) && !empty($this->cache['project_id'])) { | ||
| 152 | + $param['project_id'] = $this->cache['project_id']; | ||
| 153 | + } | ||
| 154 | + $file_hash = $fileModel->read($param); | ||
| 155 | + if ($file_hash !== false) { | ||
| 156 | + return [ | ||
| 157 | + 'message' => '资源', | ||
| 158 | + 'code' => Code::SUCCESS, | ||
| 159 | + 'data' => $this->responseData($file_hash['path'], $name) | ||
| 160 | + ]; | ||
| 161 | + } | ||
| 162 | + $url = $this->config['root'] . $this->path; | ||
| 163 | + $fileName = uniqid() . rand(10000, 99999) . '.' . $files->getExtension(); | ||
| 164 | + //同步数据到cos | ||
| 165 | + if ($this->upload_location == 1) { | ||
| 166 | + $cosService = new CosService(); | ||
| 167 | + $cosService->uploadFile($files, $this->path, $fileName); | ||
| 168 | + } else { | ||
| 169 | + $res = $files->move($url, $fileName); | ||
| 170 | + if ($res === false) { | ||
| 171 | + return [ | ||
| 172 | + 'message' => $files->getError(), | ||
| 173 | + 'code' => Code::USER_ERROR | ||
| 174 | + ]; | ||
| 175 | + } | ||
| 176 | + } | ||
| 177 | + $this->saveMysql($fileModel, $files->getSize(), $files->getExtension(), $fileName, $hash, $this->upload_location, $files->getMimeType(), $name); | ||
| 178 | + return [ | ||
| 179 | + 'message' => '资源', | ||
| 180 | + 'code' => Code::SUCCESS, | ||
| 181 | + 'data' => $this->responseData($this->path . '/' . $fileName, $name) | ||
| 182 | + ]; | ||
| 136 | } | 183 | } |
| 137 | 184 | ||
| 138 | /** | 185 | /** |
| @@ -380,12 +380,12 @@ class ImageController extends Controller | @@ -380,12 +380,12 @@ class ImageController extends Controller | ||
| 380 | if(is_array($files)){ | 380 | if(is_array($files)){ |
| 381 | foreach ($files as $file){ | 381 | foreach ($files as $file){ |
| 382 | if ($file->getSize() > $max) { | 382 | if ($file->getSize() > $max) { |
| 383 | - return $this->response('图片最大为500K',Code::SYSTEM_ERROR); | 383 | + $this->response('图片最大为500K',Code::SYSTEM_ERROR); |
| 384 | } | 384 | } |
| 385 | } | 385 | } |
| 386 | }else{ | 386 | }else{ |
| 387 | if ($files->getSize() > $max) { | 387 | if ($files->getSize() > $max) { |
| 388 | - return $this->response('图片最大为500K',Code::SYSTEM_ERROR); | 388 | + $this->response('图片最大为500K',Code::SYSTEM_ERROR); |
| 389 | } | 389 | } |
| 390 | } | 390 | } |
| 391 | if(!isset($this->param['upload_method'])){ | 391 | if(!isset($this->param['upload_method'])){ |
| @@ -402,16 +402,16 @@ class VisualizationLogic extends BaseLogic | @@ -402,16 +402,16 @@ class VisualizationLogic extends BaseLogic | ||
| 402 | 'template_id' => $template_id, | 402 | 'template_id' => $template_id, |
| 403 | 'project_id' => $this->user['project_id'] | 403 | 'project_id' => $this->user['project_id'] |
| 404 | ]; | 404 | ]; |
| 405 | - if ($source == 2) {//产品页 | 405 | + if ($source == BTemplate::SOURCE_PRODUCT) {//产品页 |
| 406 | if($source_id != 0){$data['type'] = 2;if ($pageInfo['product_details'] != 0) {$commonInfo = $commonTemplateModel->read($data);}} | 406 | if($source_id != 0){$data['type'] = 2;if ($pageInfo['product_details'] != 0) {$commonInfo = $commonTemplateModel->read($data);}} |
| 407 | else {$data['type'] = 3;if ($pageInfo['product_list'] != 0) {$commonInfo = $commonTemplateModel->read($data);}}} | 407 | else {$data['type'] = 3;if ($pageInfo['product_list'] != 0) {$commonInfo = $commonTemplateModel->read($data);}}} |
| 408 | - if ($source == 3) {//博客页 | 408 | + if ($source == BTemplate::SOURCE_BLOG) {//博客页 |
| 409 | if ($source_id != 0) {$data['type'] = 4;if ($pageInfo['blog_details'] != 0) {$commonInfo = $commonTemplateModel->read($data);}} | 409 | if ($source_id != 0) {$data['type'] = 4;if ($pageInfo['blog_details'] != 0) {$commonInfo = $commonTemplateModel->read($data);}} |
| 410 | else {$data['type'] = 5;if ($pageInfo['blog_list'] != 0) {$commonInfo = $commonTemplateModel->read($data);}}} | 410 | else {$data['type'] = 5;if ($pageInfo['blog_list'] != 0) {$commonInfo = $commonTemplateModel->read($data);}}} |
| 411 | - if ($source == 4) {//新闻页 | 411 | + if ($source == BTemplate::SOURCE_NEWS) {//新闻页 |
| 412 | if ($source_id != 0) {$data['type'] = 6;if ($pageInfo['news_details'] != 0) {$commonInfo = $commonTemplateModel->read($data);}} | 412 | if ($source_id != 0) {$data['type'] = 6;if ($pageInfo['news_details'] != 0) {$commonInfo = $commonTemplateModel->read($data);}} |
| 413 | else {$data['type'] = 7;if ($pageInfo['news_list'] != 0) {$commonInfo = $commonTemplateModel->read($data);}}} | 413 | else {$data['type'] = 7;if ($pageInfo['news_list'] != 0) {$commonInfo = $commonTemplateModel->read($data);}}} |
| 414 | - if ($source == 5) {//聚合页 | 414 | + if ($source == BTemplate::SOURCE_KEYWORD) {//聚合页 |
| 415 | $data['type'] = 8;if ($pageInfo['polymerization'] != 0) {$commonInfo = $commonTemplateModel->read($data);}} | 415 | $data['type'] = 8;if ($pageInfo['polymerization'] != 0) {$commonInfo = $commonTemplateModel->read($data);}} |
| 416 | } | 416 | } |
| 417 | } | 417 | } |
| @@ -218,6 +218,8 @@ class ProductLogic extends BaseLogic | @@ -218,6 +218,8 @@ class ProductLogic extends BaseLogic | ||
| 218 | $param['icon'][$k1] = str_replace_url($v1); | 218 | $param['icon'][$k1] = str_replace_url($v1); |
| 219 | } | 219 | } |
| 220 | $param['icon'] = Arr::a2s($param['icon'] ?? []); | 220 | $param['icon'] = Arr::a2s($param['icon'] ?? []); |
| 221 | + }else{ | ||
| 222 | + $param['icon'] = Arr::a2s([]); | ||
| 221 | } | 223 | } |
| 222 | $param['created_uid'] = $this->user['id']; | 224 | $param['created_uid'] = $this->user['id']; |
| 223 | return $param; | 225 | return $param; |
| @@ -19,18 +19,6 @@ class ProofreadingLogic extends BaseLogic | @@ -19,18 +19,6 @@ class ProofreadingLogic extends BaseLogic | ||
| 19 | } | 19 | } |
| 20 | 20 | ||
| 21 | /** | 21 | /** |
| 22 | - * @name :(校队列表)proofreadingList | ||
| 23 | - * @author :lyh | ||
| 24 | - * @method :post | ||
| 25 | - * @time :2023/6/12 11:06 | ||
| 26 | - */ | ||
| 27 | - public function proofreadingList($map,$p,$row,$order = 'created_at',$filed = ['*']){ | ||
| 28 | - $map['project_id'] = $this->user['project_id']; | ||
| 29 | - $list = $this->model->lists($map,$p,$row,$order,$filed); | ||
| 30 | - return $this->success($list); | ||
| 31 | - } | ||
| 32 | - | ||
| 33 | - /** | ||
| 34 | * @name :(保存翻译校队)proofreadingSave | 22 | * @name :(保存翻译校队)proofreadingSave |
| 35 | * @author :lyh | 23 | * @author :lyh |
| 36 | * @method :post | 24 | * @method :post |
| @@ -200,6 +200,7 @@ class UserLoginLogic | @@ -200,6 +200,7 @@ class UserLoginLogic | ||
| 200 | $info['is_upload_manage'] = $project['is_upload_manage']; | 200 | $info['is_upload_manage'] = $project['is_upload_manage']; |
| 201 | $info['upload_config'] = $project['upload_config']; | 201 | $info['upload_config'] = $project['upload_config']; |
| 202 | $info['image_max'] = $project['image_max']; | 202 | $info['image_max'] = $project['image_max']; |
| 203 | + $info['is_update_language'] = $project['is_update_language']; | ||
| 203 | $info['configuration'] = $project['deploy_build']['configuration']; | 204 | $info['configuration'] = $project['deploy_build']['configuration']; |
| 204 | $info['type'] = $project['type']; | 205 | $info['type'] = $project['type']; |
| 205 | if($info['is_customized'] == 1){ | 206 | if($info['is_customized'] == 1){ |
| @@ -16,13 +16,13 @@ class DataFile extends Base | @@ -16,13 +16,13 @@ class DataFile extends Base | ||
| 16 | if (!$isRes) { | 16 | if (!$isRes) { |
| 17 | $isRes = new self(); | 17 | $isRes = new self(); |
| 18 | $isRes->project_id = $project_id; | 18 | $isRes->project_id = $project_id; |
| 19 | - } | ||
| 20 | # AICC用户ID | 19 | # AICC用户ID |
| 21 | $isRes->user_id = $data['user_id']; | 20 | $isRes->user_id = $data['user_id']; |
| 22 | # 第三方朋友ID | 21 | # 第三方朋友ID |
| 23 | $isRes->friend_id = $data['friend_id']; | 22 | $isRes->friend_id = $data['friend_id']; |
| 24 | # 生成文件路径 | 23 | # 生成文件路径 |
| 25 | $isRes->file_path = $data['file_path']; | 24 | $isRes->file_path = $data['file_path']; |
| 25 | + } | ||
| 26 | return $isRes->save(); | 26 | return $isRes->save(); |
| 27 | } | 27 | } |
| 28 | 28 |
| @@ -55,9 +55,9 @@ class ProjectAssociation extends Model | @@ -55,9 +55,9 @@ class ProjectAssociation extends Model | ||
| 55 | { | 55 | { |
| 56 | $status = 1; # 1 - 正常, 0 - 禁用 | 56 | $status = 1; # 1 - 正常, 0 - 禁用 |
| 57 | $lists = self::query()->where('status', $status) | 57 | $lists = self::query()->where('status', $status) |
| 58 | - ->whereNotNull('project_id') | ||
| 59 | - ->whereNotNull('friend_id') | ||
| 60 | - ->whereNotNull('user_id') | 58 | + ->where('project_id', '!=', 0) |
| 59 | + ->where('friend_id', '!=', 0) | ||
| 60 | + ->where('user_id', '!=', 0) | ||
| 61 | ->paginate($perPage, ['project_id', 'friend_id', 'user_id'], 'page', $page); | 61 | ->paginate($perPage, ['project_id', 'friend_id', 'user_id'], 'page', $page); |
| 62 | $items = $lists->Items(); | 62 | $items = $lists->Items(); |
| 63 | $totalPage = $lists->lastPage(); | 63 | $totalPage = $lists->lastPage(); |
| @@ -19,14 +19,14 @@ class BTemplate extends Base | @@ -19,14 +19,14 @@ class BTemplate extends Base | ||
| 19 | const SOURCE_KEYWORD = 5;//聚合页 | 19 | const SOURCE_KEYWORD = 5;//聚合页 |
| 20 | const STATUS = 0; | 20 | const STATUS = 0; |
| 21 | 21 | ||
| 22 | - const TYPE_ONE = 0; | ||
| 23 | - const TYPE_TWO = 0; | ||
| 24 | - const TYPE_THREE = 0; | ||
| 25 | - const TYPE_FOUR = 0; | ||
| 26 | - const TYPE_FIVE = 0; | ||
| 27 | - const TYPE_SIX = 0; | ||
| 28 | - const TYPE_SEVEN = 0; | ||
| 29 | - const TYPE_ = 0; | 22 | + const TYPE_ONE = 1; |
| 23 | + const TYPE_TWO = 2; | ||
| 24 | + const TYPE_THREE = 3; | ||
| 25 | + const TYPE_FOUR = 4; | ||
| 26 | + const TYPE_FIVE = 5; | ||
| 27 | + const TYPE_SIX = 6; | ||
| 28 | + const TYPE_SEVEN = 7; | ||
| 29 | + const TYPE_EIGHT = 8; | ||
| 30 | 30 | ||
| 31 | protected $table = 'gl_web_template'; | 31 | protected $table = 'gl_web_template'; |
| 32 | //连接数据库 | 32 | //连接数据库 |
| @@ -19,7 +19,8 @@ | @@ -19,7 +19,8 @@ | ||
| 19 | "mongodb/mongodb": "^1.6", | 19 | "mongodb/mongodb": "^1.6", |
| 20 | "mrgoon/aliyun-sms": "^2.0", | 20 | "mrgoon/aliyun-sms": "^2.0", |
| 21 | "phpoffice/phpspreadsheet": "^1.28", | 21 | "phpoffice/phpspreadsheet": "^1.28", |
| 22 | - "swooletw/laravel-swoole": "^2.13" | 22 | + "swooletw/laravel-swoole": "^2.13", |
| 23 | + "qcloud/cos-sdk-v5": "^v2.6.6" | ||
| 23 | }, | 24 | }, |
| 24 | "require-dev": { | 25 | "require-dev": { |
| 25 | "barryvdh/laravel-ide-helper": "^2.13", | 26 | "barryvdh/laravel-ide-helper": "^2.13", |
| @@ -167,7 +167,9 @@ Route::middleware(['bloginauth'])->group(function () { | @@ -167,7 +167,9 @@ Route::middleware(['bloginauth'])->group(function () { | ||
| 167 | //翻译校队 | 167 | //翻译校队 |
| 168 | Route::prefix('proofreading')->group(function () {//languageList | 168 | Route::prefix('proofreading')->group(function () {//languageList |
| 169 | Route::any('/', [\App\Http\Controllers\Bside\Setting\ProofreadingController::class, 'lists'])->name('web_proofreading_lists'); | 169 | Route::any('/', [\App\Http\Controllers\Bside\Setting\ProofreadingController::class, 'lists'])->name('web_proofreading_lists'); |
| 170 | + Route::any('/imageList', [\App\Http\Controllers\Bside\Setting\ProofreadingController::class, 'imageList'])->name('web_proofreading_imageList'); | ||
| 170 | Route::any('/save', [\App\Http\Controllers\Bside\Setting\ProofreadingController::class, 'save'])->name('web_proofreading_save'); | 171 | Route::any('/save', [\App\Http\Controllers\Bside\Setting\ProofreadingController::class, 'save'])->name('web_proofreading_save'); |
| 172 | + Route::any('/saveImage', [\App\Http\Controllers\Bside\Setting\ProofreadingController::class, 'saveImage'])->name('web_proofreading_saveImage'); | ||
| 171 | Route::any('/languageList', [\App\Http\Controllers\Bside\Setting\ProofreadingController::class, 'languageList'])->name('web_proofreading_languageList'); | 173 | Route::any('/languageList', [\App\Http\Controllers\Bside\Setting\ProofreadingController::class, 'languageList'])->name('web_proofreading_languageList'); |
| 172 | }); | 174 | }); |
| 173 | 175 |
-
请 注册 或 登录 后发表评论