Files
hyperf_service/app/Service/Common/OssCallbackService.php
2024-10-31 17:57:49 +08:00

311 lines
7.7 KiB
PHP

<?php
/**
* This service file is part of item.
*
* @author ctexthuang
* @contact ctexthuang@qq.com
*/
declare(strict_types=1);
namespace App\Service\Common;
use AlibabaCloud\SDK\Sts\V20150401\Sts;
use App\Cache\Redis\Common\CommonRedisKey;
use App\Cache\Redis\RedisCache;
use App\Exception\AdminException;
use App\Lib\AdminReturn;
use App\Lib\Log;
use App\Service\ServiceTrait\Common\AliStsTrait;
use Exception;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Contract\RequestInterface;
use OSS\Core\OssException;
use OSS\OssClient;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use function Hyperf\Config\config;
class OssCallbackService
{
use AliStsTrait;
/**
* 请求对象
* @var RequestInterface
*/
#[Inject]
protected RequestInterface $request;
/**
* @var AdminReturn
*/
#[Inject]
protected AdminReturn $adminReturn;
/**
* @var Log
*/
#[Inject]
protected Log $log;
/**
* @var RedisCache
*/
#[Inject]
protected RedisCache $redisCache;
/**
* 请求的值解析字段
* @var mixed
*/
private mixed $data;
/**
* oss连接类
* @var OssClient
*/
protected OssClient $ossClient;
/**
* 空间
* @var string
*/
protected string $bucket;
/**
* 文件的类型
* @var string
*/
private string $mimeType;
/**
* 文件名字
* @var string
*/
private string $fileName;
/**
* 新的文件放置区域
* @var string
*/
private string $newObjectPath;
/**
* 新的id
* @var int
*/
private int $newId;
/**
* 允许的文件夹
* @var array|string[]
*/
private array $allowType = [
'admin_avatar',
'avatar',
'menu',
];
/**
* OssCallbackService constructor.
*/
public function __construct()
{
$this->ossClient = new OssClient(
config('ali.access_key_id'),
config('ali.access_key_secret'),
config('oss.sts_endpoint')
);
$this->bucket = config('ali.bucket');
}
/**
* @return array
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws \RedisException
*/
public function process(): array
{
try {
//记录回调内容
$this->filePutContents();
//检测直传type
$this->checkType();
//检测文件格式
$this->checkMimeType();
//获取新文件名
$this->getNewFileName();
//复制旧文件到指定文件夹
try {
$this->ossClient->copyObject($this->bucket, urldecode($this->data['object']), $this->bucket, $this->newObjectPath);
} catch (OssException $e) {
throw new Exception($e->getMessage());
}
date_default_timezone_set('Asia/Shanghai');
//增加oss object数据
$this->addOssObjectData();
//删除旧的文件
$this->deleteOssObject();
}catch (Exception $exception){
$this->deleteOssObject();
throw new AdminException($exception->getMessage());
}
$this->log->callbackLog(__CLASS__.':oss回调完成'.json_encode($this->data),'oss');
return $this->adminReturn->success('上传成功',[
'id' => $this->newId,
'url' => config('ali.oss_url') . $this->newObjectPath, 'old_file_name' => $this->fileName
]);
}
/**
* 记录回调内容
* @return void
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
private function filePutContents(): void
{
$this->data = $this->request->all();
$this->log->callbackLog(__CLASS__.':oss回调'.json_encode($this->data),'oss');
}
/**
* 检测直传type
* @return void
* @throws Exception
*/
private function checkType(): void
{
if (!in_array($this->data['type'], $this->allowType)) {
throw new Exception('上传类型错误');
}
}
/**
* 检测文件格式
* @return void
* @throws Exception
*/
private function checkMimeType(): void
{
$mimeType = explode('/', $this->data['mimeType']);
switch ($this->data['mimeType']) {
case 'text/plain':
if ($mimeType[0] != 'text') {
throw new Exception("不允许此格式文件");
}
$this->mimeType = 'txt';
break;
default:
if (!in_array($mimeType[1], ['mp3', 'jpeg', 'jpg', 'png', 'gif', 'mp4', 'mpeg','aac', 'quicktime'])) {
throw new Exception("不允许此格式文件");
}
$this->mimeType = $mimeType[1];
}
}
/**
* 获取新文件名
* @return void
*/
private function getNewFileName(): void
{
$this->fileName = explode('/', urldecode($this->data['object']))[1];
switch ($this->data['type'])
{
case 'video_main':
$newFileName = date('YmdHis').md5($this->data['type'].$this->fileName);
$this->newObjectPath = sprintf("upload/%s/%s/%s/%s.%s", 'admin', $this->data['type'], $this->data['library_dir'],$newFileName,$this->mimeType);
break;
case 'avatar':
$newFileName = date('YmdHis').md5($this->data['type'].$this->fileName);
$this->newObjectPath = sprintf("upload/%s/%s/%s/%s.%s", 'user', $this->data['user_id'], $this->data['type'],$newFileName,$this->mimeType);
break;
default:
$newFileName = md5(date('YmdHis').$this->data['type'].$this->fileName);
$newMimeType = $this->mimeType;
if ($this->mimeType == 'quicktime') {
$newMimeType = 'mov';
}
$this->newObjectPath = sprintf("upload/%s/%s/%s.%s",'admin', $this->data['type'], $newFileName,$newMimeType);
break;
}
}
/**
* 增加oss object数据
* @return void
*/
private function addOssObjectData(): void
{
$type = 0;
switch ($this->mimeType) {
case 'jpg':
case 'jpeg':
case 'png':
case 'bmp':
$type = 1;
break;
case 'mp3':
$type = 2;
break;
case 'mp4':
case 'swf':
$type = 3;
break;
}
// $ossObjectModel = new OssObject();
//
// $ossObjectModel->url = $this->newObjectPath;
//// $ossObjectModel->url = urldecode($this->data['object']);
// $ossObjectModel->width = $this->data['imageInfo_width'] ?? 0;
// $ossObjectModel->height = $this->data['imageInfo_height'] ?? 0;
// $ossObjectModel->audio_second = $this->data['audio_second'] ?? 0;
// $ossObjectModel->video_duration = $this->data['video_duration'] ?? 0;
// $ossObjectModel->size = $this->data['size'] ?? 0;
//
// $ossObjectModel->type = $type;
//
// if (!$ossObjectModel->save()){
// throw new AdminException('保存图片失败');
// }
// $this->newId = $ossObjectModel->id;
}
/**
* @return void
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws \RedisException
*/
private function deleteOssObject(): void
{
//删除旧的文件
$this->redisCache->lPush(CommonRedisKey::getDeleteOssImgListByUrl(), $this->data['object']);
}
}