Cos.php 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. <?php
  2. namespace App\Libraries\ChunkedUpload\Disks;
  3. use App\Libraries\ChunkedUpload\Contacts\ChunkedUploadContact;
  4. use App\Libraries\ChunkedUpload\Exceptions\UploadFailedException;
  5. use App\Services\File\Upload\ProgressBar;
  6. use Illuminate\Http\UploadedFile;
  7. use Illuminate\Support\Facades\Log;
  8. use Qcloud\Cos\Client;
  9. use QCloud\COSSTS\Sts;
  10. class Cos implements ChunkedUploadContact
  11. {
  12. public function uploadDirectly(string $key, string $content, array $options = [])
  13. {
  14. if (empty($options)) {
  15. $options = [
  16. 'ACL' => 'private',
  17. ];
  18. }
  19. $cosClient = new Client([
  20. 'region' => config('filesystems.disks.cos.region'),
  21. 'credentials' => [
  22. 'secretId' => config('filesystems.disks.cos.secret_id'),
  23. 'secretKey' => config('filesystems.disks.cos.secret_key')
  24. ]
  25. ]);
  26. $result = $cosClient->upload(
  27. sprintf("%s-%s", config('filesystems.disks.cos.bucket'), config('filesystems.disks.cos.app_id')),
  28. $key,
  29. $content,
  30. $options,
  31. );
  32. return $result->toArray();
  33. }
  34. public function upload(UploadedFile $file, string $savePath, string $name, ?ProgressBar $progressBar): string
  35. {
  36. $pathname = sprintf("%s/%s", $savePath, $name);
  37. $cosClient = new Client([
  38. 'region' => config('filesystems.disks.cos.region'),
  39. 'credentials' => [
  40. 'secretId' => config('filesystems.disks.cos.secret_id'),
  41. 'secretKey' => config('filesystems.disks.cos.secret_key')
  42. ]
  43. ]);
  44. try {
  45. $notUploadedSize = $file->getSize();
  46. $options = [
  47. 'PartSize' => 1 * 1024 * 1024,
  48. 'Progress' => function ($totalSize, $uploadedSize) use (&$notUploadedSize, $progressBar) {
  49. $partSize = $uploadedSize - ($totalSize - $notUploadedSize);
  50. $notUploadedSize = $totalSize - $uploadedSize;
  51. $progressBar?->increment($partSize);
  52. },
  53. 'ACL' => 'private',
  54. ];
  55. $cosClient->upload(
  56. sprintf("%s-%s", config('filesystems.disks.cos.bucket'), config('filesystems.disks.cos.app_id')),
  57. $pathname,
  58. fopen($file->getRealPath(), 'rb'),
  59. $options,
  60. );
  61. if ($notUploadedSize > 0) {
  62. $progressBar?->increment($notUploadedSize);
  63. }
  64. } catch (\Exception $exception) {
  65. Log::error('File upload failed messge:' . $exception->getMessage());
  66. throw new UploadFailedException("File upload failed.");
  67. }
  68. return $pathname;
  69. }
  70. /**
  71. * 获取临时密钥
  72. * @return array
  73. */
  74. public function getTempKeys(string $pathPrefix = ''): array
  75. {
  76. $sts = new Sts();
  77. $cosConfig = config('filesystems.disks.cos');
  78. $bucket = $cosConfig['bucket'] . '-' . $cosConfig['app_id'];
  79. $prefixArr = explode('/', $pathPrefix);
  80. $config = [
  81. 'url' => 'https://sts.tencentcloudapi.com/',
  82. 'secretId' => $cosConfig['secret_id'],
  83. 'secretKey' => $cosConfig['secret_key'],
  84. 'bucket' => $bucket,
  85. 'region' => $cosConfig['region'],
  86. 'durationSeconds' => 600, // 密钥有效期(秒)
  87. 'allowPrefix' => [($prefixArr[0] ?? '') . '/*'], // 这里改成允许的路径前缀,可以根据自己网站的用户登录态判断允许上传的具体路径,例子: a.jpg 或者 a/* 或者 * (使用通配符*存在重大安全风险, 请谨慎评估使用)
  88. // 密钥的权限列表。简单上传和分片需要以下的权限,其他权限列表请看 https://cloud.tencent.com/document/product/436/31923
  89. 'allowActions' => [
  90. // 简单上传
  91. 'name/cos:PutObject',
  92. 'name/cos:PostObject',
  93. // 分片上传
  94. 'name/cos:InitiateMultipartUpload',
  95. 'name/cos:ListMultipartUploads',
  96. 'name/cos:ListParts',
  97. 'name/cos:UploadPart',
  98. 'name/cos:CompleteMultipartUpload',
  99. //取消分块上传操作
  100. "name/cos:AbortMultipartUpload",
  101. "name/cos:DeleteObject"
  102. ],
  103. // 临时密钥生效条件,关于condition的详细设置规则和COS支持的condition类型可以参考 https://cloud.tencent.com/document/product/436/71306
  104. "condition" => []
  105. ];
  106. $data = $sts->getTempKeys($config);
  107. $data['bucket'] = $bucket;
  108. $data['region'] = $cosConfig['region'];
  109. $data['pathPrefix'] = $pathPrefix;
  110. return $data;
  111. }
  112. }