126 lines
4.3 KiB
PHP
126 lines
4.3 KiB
PHP
<?php
|
|
namespace app\service;
|
|
use Aws\S3\S3Client;
|
|
use think\facade\Log;
|
|
use think\File;
|
|
|
|
class AwsUploadService
|
|
{
|
|
/**
|
|
* 处理表单文件上传并转发到目标服务器
|
|
*
|
|
* @param string $fileField 表单文件字段名
|
|
* @param array $extraFields 额外传递的字段
|
|
* @return array 包含上传结果的数组
|
|
*/
|
|
public function uploadAndForward( File $file, string $fileField,array $extraFields = []): array
|
|
{
|
|
|
|
$mimeType = $file->getMime();
|
|
$s3config = config('filesystem.disks.s3');
|
|
$s3 = new S3Client($s3config);
|
|
try {
|
|
$config = config('app.upload_conf');
|
|
$configs=[];
|
|
foreach ($config as $key=>$con){
|
|
$configs[] = $key.':'.$con;
|
|
}
|
|
|
|
// 验证文件
|
|
$validate = validate([
|
|
$fileField =>implode('|',$configs),
|
|
]);
|
|
|
|
if (!$validate->check([$fileField => $file])) {
|
|
return $this->createErrorResult($validate->getError());
|
|
}
|
|
|
|
// 根据文件类型设置 Content-Type
|
|
if (in_array($mimeType, config('app.imageMimeTypes'))) {
|
|
$contentType = $mimeType; // 使用图片的实际 MIME 类型
|
|
} else {
|
|
$contentType = 'application/octet-stream'; // 非图片文件使用默认类型
|
|
}
|
|
$checkBucket = $this->checkBucket($s3, $extraFields['Bucket']);
|
|
if (!$checkBucket) {
|
|
return $this->createErrorResult('Bucket error');
|
|
}
|
|
$s3->putObject([
|
|
'Bucket' => $extraFields['Bucket'],
|
|
'Key' => $extraFields['Key'],
|
|
'Body' => fopen($file->getRealPath(), 'r'),
|
|
'ACL' => 'public-read',
|
|
'ContentType' => $contentType, // 设置检测到的 Content-Type
|
|
]);
|
|
return [
|
|
'code' => 1,
|
|
'data' =>[
|
|
'savename'=>$s3config['endpoint'].'/'.$extraFields['Bucket'].'/'.$extraFields['Key']
|
|
] ,
|
|
];
|
|
} catch (\Exception $e) {
|
|
return $this->createErrorResult('上传过程中发生异常: ' . $e->getMessage());
|
|
}
|
|
}
|
|
public function checkBucket($s3, $bucket)
|
|
{
|
|
try {
|
|
$buckets = $s3->listBuckets()->get('Buckets');
|
|
$buckets_arr = array_column($buckets, 'Name');
|
|
if (!in_array($bucket, $buckets_arr)) {
|
|
$s3->createBucket([
|
|
'Bucket' => $bucket,
|
|
]);
|
|
$policy = [
|
|
'Version' => '2012-10-17',
|
|
'Statement' => [
|
|
[
|
|
'Effect' => 'Allow',
|
|
'Principal' => ['AWS' => ['*']],
|
|
'Action' => [
|
|
's3:GetBucketLocation',
|
|
's3:ListBucket',
|
|
's3:ListBucketMultipartUploads',
|
|
],
|
|
'Resource' => "arn:aws:s3:::$bucket",
|
|
],
|
|
[
|
|
'Effect' => 'Allow',
|
|
'Principal' => ['AWS' => ['*']],
|
|
'Action' => [
|
|
's3:DeleteObject',
|
|
's3:GetObject',
|
|
's3:ListMultipartUploadParts',
|
|
's3:PutObject',
|
|
's3:AbortMultipartUpload',
|
|
],
|
|
'Resource' => "arn:aws:s3:::$bucket/*",
|
|
],
|
|
],
|
|
];
|
|
$s3->putBucketPolicy([
|
|
'Bucket' => $bucket,
|
|
'Policy' => json_encode($policy),
|
|
]);
|
|
}
|
|
return true;
|
|
} catch (\Exception $e) {
|
|
Log::info('checkBucket error:' . $e->getMessage());
|
|
return false;
|
|
}
|
|
|
|
}
|
|
/**
|
|
* 创建错误结果数组
|
|
*
|
|
* @param string $message 错误信息
|
|
* @return array 错误结果
|
|
*/
|
|
private function createErrorResult(string $message): array
|
|
{
|
|
return [
|
|
'code' => 0,
|
|
'error' => $message
|
|
];
|
|
}
|
|
} |