123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- <?php
- namespace App\Libraries\ChunkedUpload\Disks;
- use App\Libraries\ChunkedUpload\Contacts\ChunkedUploadContact;
- use App\Libraries\ChunkedUpload\Exceptions\UploadFailedException;
- use App\Services\File\Upload\ProgressBar;
- use Illuminate\Http\UploadedFile;
- use Illuminate\Support\Facades\Log;
- use Qcloud\Cos\Client;
- use QCloud\COSSTS\Sts;
- class Cos implements ChunkedUploadContact
- {
- public function uploadDirectly(string $key, string $content, array $options = [])
- {
- if (empty($options)) {
- $options = [
- 'ACL' => 'private',
- ];
- }
- $cosClient = new Client([
- 'region' => config('filesystems.disks.cos.region'),
- 'credentials' => [
- 'secretId' => config('filesystems.disks.cos.secret_id'),
- 'secretKey' => config('filesystems.disks.cos.secret_key')
- ]
- ]);
- $result = $cosClient->upload(
- sprintf("%s-%s", config('filesystems.disks.cos.bucket'), config('filesystems.disks.cos.app_id')),
- $key,
- $content,
- $options,
- );
- return $result->toArray();
- }
- public function upload(UploadedFile $file, string $savePath, string $name, ?ProgressBar $progressBar): string
- {
- $pathname = sprintf("%s/%s", $savePath, $name);
- $cosClient = new Client([
- 'region' => config('filesystems.disks.cos.region'),
- 'credentials' => [
- 'secretId' => config('filesystems.disks.cos.secret_id'),
- 'secretKey' => config('filesystems.disks.cos.secret_key')
- ]
- ]);
- try {
- $notUploadedSize = $file->getSize();
- $options = [
- 'PartSize' => 1 * 1024 * 1024,
- 'Progress' => function ($totalSize, $uploadedSize) use (&$notUploadedSize, $progressBar) {
- $partSize = $uploadedSize - ($totalSize - $notUploadedSize);
- $notUploadedSize = $totalSize - $uploadedSize;
- $progressBar?->increment($partSize);
- },
- 'ACL' => 'private',
- ];
- $cosClient->upload(
- sprintf("%s-%s", config('filesystems.disks.cos.bucket'), config('filesystems.disks.cos.app_id')),
- $pathname,
- fopen($file->getRealPath(), 'rb'),
- $options,
- );
- if ($notUploadedSize > 0) {
- $progressBar?->increment($notUploadedSize);
- }
- } catch (\Exception $exception) {
- Log::error('File upload failed messge:' . $exception->getMessage());
- throw new UploadFailedException("File upload failed.");
- }
- return $pathname;
- }
- /**
- * 获取临时密钥
- * @return array
- */
- public function getTempKeys(string $pathPrefix = ''): array
- {
- $sts = new Sts();
- $cosConfig = config('filesystems.disks.cos');
- $bucket = $cosConfig['bucket'] . '-' . $cosConfig['app_id'];
- $prefixArr = explode('/', $pathPrefix);
- $config = [
- 'url' => 'https://sts.tencentcloudapi.com/',
- 'secretId' => $cosConfig['secret_id'],
- 'secretKey' => $cosConfig['secret_key'],
- 'bucket' => $bucket,
- 'region' => $cosConfig['region'],
- 'durationSeconds' => 600, // 密钥有效期(秒)
- 'allowPrefix' => [($prefixArr[0] ?? '') . '/*'], // 这里改成允许的路径前缀,可以根据自己网站的用户登录态判断允许上传的具体路径,例子: a.jpg 或者 a/* 或者 * (使用通配符*存在重大安全风险, 请谨慎评估使用)
- // 密钥的权限列表。简单上传和分片需要以下的权限,其他权限列表请看 https://cloud.tencent.com/document/product/436/31923
- 'allowActions' => [
- // 简单上传
- 'name/cos:PutObject',
- 'name/cos:PostObject',
- // 分片上传
- 'name/cos:InitiateMultipartUpload',
- 'name/cos:ListMultipartUploads',
- 'name/cos:ListParts',
- 'name/cos:UploadPart',
- 'name/cos:CompleteMultipartUpload',
- //取消分块上传操作
- "name/cos:AbortMultipartUpload",
- "name/cos:DeleteObject"
- ],
- // 临时密钥生效条件,关于condition的详细设置规则和COS支持的condition类型可以参考 https://cloud.tencent.com/document/product/436/71306
- "condition" => []
- ];
- $data = $sts->getTempKeys($config);
- $data['bucket'] = $bucket;
- $data['region'] = $cosConfig['region'];
- $data['pathPrefix'] = $pathPrefix;
- return $data;
- }
- }
|