作者 zhl

Merge remote-tracking branch 'origin/master' into zhl

<?php
/**
* @remark :
* @name :CropImage.php
* @author :lyh
* @method :post
* @time :2025/5/8 9:19
*/
namespace App\Console\Commands\CropImage;
use App\Enums\Common\Code;
use App\Models\Domain\DomainInfo;
use App\Models\File\Image;
use App\Models\WebSetting\AggregationSetting;
use App\Models\WebSetting\WebSettingImage;
use App\Services\CosService;
use App\Services\ProjectServer;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
class CropImage extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'crop_image {project_id}';
/**
* The console command description.
*
* @var string
*/
protected $description = '裁剪图片';
public function handle(){
echo '测试裁剪->cs-crop:'.PHP_EOL;
$project_id = $this->argument('project_id');
ProjectServer::useProject($project_id);
$data = $this->_keywordAction($project_id);
$this->_aiAction($project_id,$data[0] ?? []);
DB::disconnect('custom_mysql');
}
/**
* @remark :执行的方法
* @name :_action
* @author :lyh
* @method :post
* @time :2025/5/8 9:21
*/
public function _keywordAction($project_id){
$resData = [];
//聚合页裁剪
$data = $this->getKeywordImage($project_id);
$cosService = new CosService();
if(!empty($data)){
foreach ($data as $val){
//处理图片为相对路径
$image = str_replace_url($val);
$height = $cosService->getImageHeight($image);
if(empty($height)){
echo '未获取到图片高度。'.PHP_EOL;
continue;
}
echo '返回的图片高度:'.$height.PHP_EOL;
if($height > 220){
$result = $cosService->cropCosImage($image);
if(empty($result)){
continue;
}
$resData[] = $result['path'];
$this->saveMysql($project_id,$result['size'],$result['type'],$result['path'],$result['mime']);
}else{
$resData[] = $image;
}
}
}
$this->saveAggregationSetting($project_id,$resData);
return $resData;
}
/**
* @remark :ai执行方法
* @name :_aiAction
* @author :lyh
* @method :post
* @time :2025/5/8 16:12
*/
public function _aiAction($project_id,$keywordImage){
$cosService = new CosService();
//ai_blog裁剪
$ai_image = $this->getAiBlogImage($project_id,$keywordImage ?? '');
if(empty($ai_image)){
echo '当前图片不需要裁剪。'.PHP_EOL;
return true;
}
$height = $cosService->getImageHeight($ai_image);
if(empty($height)){
echo '未获取到AI_BLOG图片高度。'.PHP_EOL;
return true;
}
echo '返回的图片高度:'.$height.PHP_EOL;
if($height > 220){
$result = $cosService->cropCosImage($ai_image);
if(empty($result)){
return true;
}
$this->saveMysql($project_id,$result['size'],$result['type'],$result['path'],$result['mime']);
$webSettingImageModel = new WebSettingImage();
$webSettingImageModel->edit(['image'=>$result['path']],['project_id' => $project_id, 'type' => 4]);
}
return true;
}
/**
* @remark :保存数据
* @name :saveAggregationSetting
* @author :lyh
* @method :post
* @time :2025/5/8 16:24
*/
public function saveAggregationSetting($project_id,$data){
if(empty($data)){
return true;
}
//存全路径
foreach ($data as $key => $val){
$val = getImageUrl($val);
$data[$key] = $val;
}
$aggregationSettingModel = new AggregationSetting();
$info = $aggregationSettingModel->read(['project_id'=>$project_id]);
if($info === false){
$aggregationSettingModel->addReturnId(['project_id'=>$project_id,'top_banner'=>json_encode($data,true)]);
}else{
$aggregationSettingModel->edit(['top_banner'=>json_encode($data,true)],['id'=>$info['id']]);
}
return true;
}
/**
* @remark :获取aiBlog图片
* @name :getAiBlogImage
* @author :lyh
* @method :post
* @time :2025/5/8 10:42
*/
public function getAiBlogImage($project_id,$keywordImage){
// AI博客banner type:1:产品,2:博客,3:新闻,4:AIBlog
$webSettingImageModel = new WebSettingImage();
$aiBlogInfo = $webSettingImageModel->read(['project_id' => $project_id, 'type' => 4],['image']);
if($aiBlogInfo === false && !empty($keywordImage)){
$webSettingImageModel->addReturnId(['project_id'=>$project_id,'image'=>$keywordImage,'type'=>4]);
return '';
}
if(empty($aiBlogInfo['image']) && !empty($keywordImage)){
$webSettingImageModel->edit(['image'=>$keywordImage],['id'=>$aiBlogInfo['id']]);
return '';
}
$ai_image = str_replace_url($aiBlogInfo['image']);
return $ai_image;
}
/**
* @remark :获取聚合页图片
* @name :getImage
* @author :lyh
* @method :post
* @time :2025/5/8 9:21
*/
public function getKeywordImage($project_id){
$data = [];
// 聚合页banner
$aggregationSettingModel = new AggregationSetting();
$aggregationSettingInfo = $aggregationSettingModel->read(['project_id' => $project_id],['id','top_banner']);
if($aggregationSettingInfo !== false && !empty($aggregationSettingInfo['top_banner'])){
foreach ($aggregationSettingInfo['top_banner'] as $val){
if($val != 'jpg' && $val != 'png' && $val != 'webp'){
$data[] = $val;
}
}
}
if(empty($data)){
//重页面上获取首页banner
$data = $this->getDomImage($project_id);
}
return $data;
}
/**
* @remark :页面上获取图片
* @name :getDomImage
* @author :lyh
* @method :post
* @time :2025/5/8 10:32
*/
public function getDomImage($project_id){
$data = [];
echo '获取首页banner:' . $project_id . PHP_EOL;
$domainModel = new DomainInfo();
$domainInfo = $domainModel->read(['project_id' => $project_id, 'status' => 1]);
if ($domainInfo !== false) {
$dom = @file_get_html('https://' . $domainInfo['domain'] . '/');
if (empty($dom)) {
$this->output('获取HTML失败: ' . $project_id);
}else{
$banner_dom = $dom->find('main .section-banner-wrap-block img', 0);
$data[] = $banner_dom ? $banner_dom->src : '';
$dom->clear();
unset($dom);
}
}else{
$this->output('域名不存在: ' . $project_id);
}
return $data;
}
/**
* @remark :写入数据库
* @name :saveMysql
* @author :lyh
* @method :post
* @time :2025/5/8 14:59
*/
public function saveMysql($project_id,$size,$image_type,$path,$mime = ''){
$hash = md5($path);
$imageModel = new Image();
$info = $imageModel->read(['hash'=>$hash,'project_id'=>$project_id]);
$data = [
'path' => $path,
'size' => $size,
'hash' => $hash,
'type' => $image_type,
'refer'=> 0,
'mime' => $mime,
'project_id'=>$project_id,
'name'=>basename($path),
'en_name'=>basename($path)
];
if($info === false){
$imageModel->addReturnId($data);
}else{
$imageModel->edit($data,['id'=>$info['id']]);
}
return true;
}
/**
* @remark :记录日志
* @name :output
* @author :lyh
* @method :post
* @time :2025/5/8 9:57
*/
public function output($message, $log_file = 'logs/crop_image.log')
{
$message = date('Y-m-d H:i:s') . ' ' . $message . PHP_EOL;
echo $message;
file_put_contents(storage_path($log_file), $message, FILE_APPEND);
return true;
}
}
... ...
... ... @@ -82,8 +82,8 @@ class AiBlogController extends BaseController
* @method :post
* @time :2023/7/5 14:33
*/
public function save(AiBlogRequest $aiBlogRequest,AiBlogLogic $aiBlogLogic){
$aiBlogRequest->validated();
public function save(AiBlogLogic $aiBlogLogic){
// $aiBlogRequest->validated();
$aiBlogLogic->blogSave();
$this->response('success');
}
... ...
... ... @@ -312,4 +312,70 @@ class CosService
'HelveticaNeue.dfont'
];
}
/**
* @remark :获取cos图片高度
* @name :getImageHeight
* @author :lyh
* @method :post
* @time :2025/5/8 10:58
* @param :pathUrl->存储桶相对路径
*/
public function getImageHeight($pathUrl){
$cos = config('filesystems.disks.cos');
$url = 'https://' . $cos['bucket'] . '.cos.' . $cos['region'] . '.myqcloud.com/' . ltrim($pathUrl, '/') . '?image/info';
$imageInfo = @getimagesize($url);
if ($imageInfo) {
// $width = $imageInfo[0];
$height = $imageInfo[1];
return $height;
}
return '';
}
/**
* @remark :裁剪图片
* @name :cropCosImage
* @author :lyh
* @method :post
* @time :2025/5/8 11:06
*/
public function cropCosImage($cosUrl,$height = 220)
{
$cos = config('filesystems.disks.cos');
$cosClient = new Client([
'region' => $cos['region'],
'credentials' => [
'secretId' => $cos['credentials']['secretId'],
'secretKey' => $cos['credentials']['secretKey'],
],
]);
$pathInfo = pathinfo($cosUrl);
$newKey = $pathInfo['dirname'] . '/crop_' . $pathInfo['filename'] .'.'. $pathInfo['extension'];
$operations = [
'is_pic_info' => 0,
'rules' => [
[
// 注意 fileid 要 base64 编码,并与 Key 相同才能覆盖
'fileid' => $newKey,
'rule' => 'imageMogr2/crop/x'.$height.'/gravity/center'
]
]
];
// 执行裁剪并覆盖
$res = $cosClient->ImageProcess([
'Bucket' => $cos['bucket'],
'Key' => $cosUrl, // 要处理的对象路径
'PicOperations' => json_encode($operations),
]);
if($res){
return [
'path' => '/'.$res['ProcessResults']['Object'][0]['Key'] ?? '',
'size' => (int)$res['ProcessResults']['Object'][0]['Size'] ?? 0,
'mime' => 'image/'.($res['ProcessResults']['Object'][0]['Format'] ?? 'jpg'),
'type' => $res['ProcessResults']['Object'][0]['Format'] ?? 'jpg',
];
}
return [];
}
}
... ...