作者 李宇航

合并分支 'lyh-server' 到 'master'

Lyh server



查看合并请求 !1938
  1 +<?php
  2 +/**
  3 + * @remark :
  4 + * @name :CropImage.php
  5 + * @author :lyh
  6 + * @method :post
  7 + * @time :2025/5/8 9:19
  8 + */
  9 +
  10 +namespace App\Console\Commands\CropImage;
  11 +
  12 +use App\Models\Domain\DomainInfo;
  13 +use App\Models\WebSetting\AggregationSetting;
  14 +use App\Models\WebSetting\WebSettingImage;
  15 +use App\Services\CosService;
  16 +use App\Services\ProjectServer;
  17 +use Illuminate\Console\Command;
  18 +use Illuminate\Support\Facades\DB;
  19 +
  20 +class CropImage extends Command
  21 +{
  22 + /**
  23 + * The name and signature of the console command.
  24 + *
  25 + * @var string
  26 + */
  27 + protected $signature = 'crop_image {project_id}';
  28 +
  29 + /**
  30 + * The console command description.
  31 + *
  32 + * @var string
  33 + */
  34 + protected $description = '裁剪图片';
  35 +
  36 + public function handle(){
  37 + echo '测试裁剪->cs-crop:'.PHP_EOL;
  38 + $images ='https://ecdn6.globalso.com/upload/p/1/image_other/2025-05/1746675561075.jpg';
  39 + $image = str_replace_url($images);
  40 + $cosService = new CosService();
  41 + $new_url = $cosService->cropAndUploadFromCos($image);
  42 + return $new_url;
  43 +// $project_id = $this->argument('project_id');
  44 +// ProjectServer::useProject($project_id);
  45 +// $this->_action();
  46 +// DB::disconnect('custom_mysql');
  47 + }
  48 +
  49 + /**
  50 + * @remark :执行的方法
  51 + * @name :_action
  52 + * @author :lyh
  53 + * @method :post
  54 + * @time :2025/5/8 9:21
  55 + */
  56 + public function _action($project_id){
  57 + $data = $this->getKeywordImage($project_id);
  58 + if(!empty($data)){
  59 + $cosService = new CosService();
  60 + foreach ($data as $val){
  61 + //处理图片为相对路径
  62 + $image = str_replace_url($val);
  63 + $new_url = $cosService->cropAndUploadFromCos($image);
  64 + echo '返回的图片路径:'.$new_url.PHP_EOL;
  65 + }
  66 + }
  67 + return true;
  68 + }
  69 +
  70 + /**
  71 + * @remark :获取aiBlog图片
  72 + * @name :getAiBlogImage
  73 + * @author :lyh
  74 + * @method :post
  75 + * @time :2025/5/8 10:42
  76 + */
  77 + public function getAiBlogImage($project_id,$keywordImage){
  78 + $image = '';
  79 + // AI博客banner type:1:产品,2:博客,3:新闻,4:AIBlog
  80 + $webSettingImageModel = new WebSettingImage();
  81 + $aiBlogInfo = $webSettingImageModel->read(['project_id' => $project_id, 'type' => 4],['image']);
  82 + if($aiBlogInfo !== false && !empty($aiBlogInfo['image'])){
  83 + $image = getImageUrl($aiBlogInfo['image']);
  84 + }
  85 + if(empty($image) && !empty($keywordImage)){
  86 + $image = $keywordImage;
  87 + }
  88 + return $image;
  89 + }
  90 +
  91 + /**
  92 + * @remark :获取聚合页图片
  93 + * @name :getImage
  94 + * @author :lyh
  95 + * @method :post
  96 + * @time :2025/5/8 9:21
  97 + */
  98 + public function getKeywordImage($project_id){
  99 + $data = [];
  100 + // 聚合页banner
  101 + $aggregationSettingModel = new AggregationSetting();
  102 + $aggregationSettingInfo = $aggregationSettingModel->read(['project_id' => $project_id],['id','top_banner']);
  103 + if($aggregationSettingInfo !== false && !empty($aggregationSettingInfo['top_banner'])){
  104 + foreach ($aggregationSettingInfo['top_banner'] as $val){
  105 + if($val != 'jpg' && $val != 'png' && $val != 'webp'){
  106 + $data[] = $val;
  107 + }
  108 + }
  109 + }
  110 + if(empty($data)){
  111 + //重页面上获取首页banner
  112 + $data = $this->getDomImage($project_id);
  113 + }
  114 + return $data;
  115 + }
  116 +
  117 + /**
  118 + * @remark :页面上获取图片
  119 + * @name :getDomImage
  120 + * @author :lyh
  121 + * @method :post
  122 + * @time :2025/5/8 10:32
  123 + */
  124 + public function getDomImage($project_id){
  125 + $data = [];
  126 + echo '获取首页banner:' . $project_id . PHP_EOL;
  127 + $domainModel = new DomainInfo();
  128 + $domainInfo = $domainModel->read(['project_id' => $project_id, 'status' => 1]);
  129 + if ($domainInfo !== false) {
  130 + $dom = @file_get_html('https://' . $domainInfo['domain'] . '/');
  131 + if (empty($dom)) {
  132 + $this->output('获取HTML失败: ' . $project_id);
  133 + }else{
  134 + $banner_dom = $dom->find('main .section-banner-wrap-block img', 0);
  135 + $data[] = $banner_dom ? $banner_dom->src : '';
  136 + $dom->clear();
  137 + unset($dom);
  138 + $data[] = $banner_dom ? $banner_dom->src : '';
  139 + }
  140 + }else{
  141 + $this->output('域名不存在: ' . $project_id);
  142 + }
  143 + return $data;
  144 + }
  145 +
  146 + /**
  147 + * @remark :记录日志
  148 + * @name :output
  149 + * @author :lyh
  150 + * @method :post
  151 + * @time :2025/5/8 9:57
  152 + */
  153 + public function output($message, $log_file = 'logs/crop_image.log')
  154 + {
  155 + $message = date('Y-m-d H:i:s') . ' ' . $message . PHP_EOL;
  156 + echo $message;
  157 + file_put_contents(storage_path($log_file), $message, FILE_APPEND);
  158 + return true;
  159 + }
  160 +}
@@ -82,8 +82,8 @@ class AiBlogController extends BaseController @@ -82,8 +82,8 @@ class AiBlogController extends BaseController
82 * @method :post 82 * @method :post
83 * @time :2023/7/5 14:33 83 * @time :2023/7/5 14:33
84 */ 84 */
85 - public function save(AiBlogRequest $aiBlogRequest,AiBlogLogic $aiBlogLogic){  
86 - $aiBlogRequest->validated(); 85 + public function save(AiBlogLogic $aiBlogLogic){
  86 +// $aiBlogRequest->validated();
87 $aiBlogLogic->blogSave(); 87 $aiBlogLogic->blogSave();
88 $this->response('success'); 88 $this->response('success');
89 } 89 }
@@ -312,4 +312,83 @@ class CosService @@ -312,4 +312,83 @@ class CosService
312 'HelveticaNeue.dfont' 312 'HelveticaNeue.dfont'
313 ]; 313 ];
314 } 314 }
  315 +
  316 + /**
  317 + * @remark :获取cos图片高度
  318 + * @name :cropAndUploadFromCos
  319 + * @author :lyh
  320 + * @method :post
  321 + * @time :2025/5/8 10:58
  322 + * @param :pathUrl->存储桶路径
  323 + */
  324 + public function cropAndUploadFromCos($pathUrl,$maxHeight = 300){
  325 + $cos = config('filesystems.disks.cos');
  326 + $cosClient = new Client([
  327 + 'region' => $cos['region'],
  328 + 'credentials' => [
  329 + 'secretId' => $cos['credentials']['secretId'],
  330 + 'secretKey' => $cos['credentials']['secretKey'],
  331 + ],
  332 + ]);
  333 + try {
  334 + $result = $cosClient->HeadObject([
  335 + 'Bucket' => $cos['bucket'],
  336 + 'Key' => $pathUrl,
  337 + 'CIProcess' => 'image/info',
  338 + ]);
  339 + $info = simplexml_load_string($result['Body']);
  340 + $height = (int) $info->ImageHeight;
  341 + if($height > $maxHeight){
  342 + return $this->cropCosImage($pathUrl);
  343 + }
  344 + }catch (\Exception $e){
  345 + @file_put_contents(storage_path('logs/crop_image_error.log'), var_export($e->getMessage(), true) . PHP_EOL, FILE_APPEND);
  346 + }
  347 + return true;
  348 + }
  349 +
  350 + /**
  351 + * @remark :裁剪图片
  352 + * @name :cropCosImage
  353 + * @author :lyh
  354 + * @method :post
  355 + * @time :2025/5/8 11:06
  356 + */
  357 + public function cropCosImage($cosUrl,$height = 200)
  358 + {
  359 + $cos = config('filesystems.disks.cos');
  360 + // 初始化 COS 客户端
  361 + $cosClient = new Client([
  362 + 'region' => $cos['region'],
  363 + 'credentials' => [
  364 + 'secretId' => $cos['credentials']['secretId'],
  365 + 'secretKey' => $cos['credentials']['secretKey'],
  366 + ],
  367 + ]);
  368 + // 定义 Pic-Operations JSON,用于裁剪并覆盖原图
  369 + $pathInfo = pathinfo($cosUrl);
  370 + $newKey = $pathInfo['dirname'] . '/' . $pathInfo['filename'] . '-'. time() . $pathInfo['extension'];
  371 + $operations = [
  372 + 'is_pic_info' => 0,
  373 + 'rules' => [
  374 + [
  375 + // 注意 fileid 要 base64 编码,并与 Key 相同才能覆盖
  376 + 'fileid' => base64_encode($newKey),
  377 + 'rule' => 'imageMogr2/crop/x'.$height.'/gravity/center'
  378 + ]
  379 + ]
  380 + ];
  381 + try {
  382 + // 执行裁剪并覆盖
  383 + $cosClient->ImageProcess([
  384 + 'Bucket' => $cos['bucket'],
  385 + 'Key' => $cosUrl, // 要处理的对象路径
  386 + 'PicOperations' => json_encode($operations),
  387 + ]);
  388 + return $newKey;
  389 + } catch (\Exception $e) {
  390 + @file_put_contents(storage_path('logs/crop_image_error.log'), var_export($e->getMessage(), true) . PHP_EOL, FILE_APPEND);
  391 + return '';
  392 + }
  393 + }
315 } 394 }