AttachmentHelper.php 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. <?php
  2. namespace App\Helper;
  3. use App\Models\SystemConfig;
  4. use FFMpeg;
  5. use Illuminate\Http\Request;
  6. use Illuminate\Http\UploadedFile;
  7. use Illuminate\Support\Facades\Storage;
  8. use OSS\OssClient;
  9. use PHPUnit\Util\Exception;
  10. use Symfony\Component\HttpFoundation\File\Exception\FileException;
  11. use App\Services\Base\ErrorCode;
  12. use App\Models\BaseAttachment;
  13. trait AttachmentHelper
  14. {
  15. public function __construct()
  16. {
  17. //在 .env 文件里配置下面可测试文件上传OSS
  18. //ALI_OSS_ACCESS_ID=LTAI5tHMYxyoEkmGqQZjbpmk
  19. //ALI_OSS_ACCESS_KEY=Fqj8J1JH0yyRpLvOjNFj5usjvfvHns
  20. //ALI_OSS_BUCKET=zhengda
  21. //ALI_OSS_ENDPOINT=oss-cn-chengdu.aliyuncs.com
  22. $this->fileDriver = env('FILESYSTEM_DRIVER');
  23. $this->bucket = env('ALI_OSS_BUCKET');
  24. $this->accessId = env('ALI_OSS_ACCESS_ID');
  25. $this->accessKey = env('ALI_OSS_ACCESS_KEY');
  26. $this->endPoint = env('ALI_OSS_ENDPOINT');
  27. $this->ossClient = new OssClient($this->accessId, $this->accessKey, $this->endPoint);
  28. }
  29. /**
  30. * @param Request $request
  31. * @param $key
  32. * @param string $tag
  33. * @param float|int $size
  34. * @param array $mimeType
  35. * @return array|mixed
  36. * @throws \Exception
  37. */
  38. public function uploadAttachment(Request $request, $key, $tag = 'files', $size = 200 * 1024 * 1024, array $mimeType = [])
  39. {
  40. if ($request->hasFile($key)) {
  41. $files = $request->file($key);
  42. if ($files === null) {
  43. throw new \Exception(trans('api.ATTACHMENT_FILE_NULL'));
  44. }
  45. if ($files instanceof UploadedFile) {
  46. $files = [$files];
  47. }
  48. $result = [];
  49. foreach ($files as $idx => $file) {
  50. if (!$file->isValid()) {
  51. throw new \Exception(trans('api.ATTACHMENT_TYPE_ERROR'));
  52. continue;
  53. }
  54. $fileSize = $file->getSize();
  55. if ($fileSize > $size) {
  56. throw new \Exception(trans('api.ATTACHMENT_SIZE_EXCEEDED'));
  57. continue;
  58. }
  59. $fileMimeType = $file->getMimeType();
  60. if (!empty($mimeType) && !in_array($fileMimeType, $mimeType)) {
  61. throw new \Exception(trans('api.ATTACHMENT_TYPE_ERROR'));
  62. continue;
  63. }
  64. $clientName = $file->getClientOriginalName();
  65. $md5 = md5($clientName . time());
  66. $md5_filename = $md5 . '.' . $file->getClientOriginalExtension();
  67. try {
  68. //本地上传
  69. if (env('FILESYSTEM_DRIVER') == 'local') {
  70. $rel_path = '/upload/' . $tag . '/' . date('Ymd');
  71. $path = public_path() . $rel_path;
  72. if (!file_exists($path)) {
  73. if (!@mkdir($path, 0755, true)) {
  74. throw new \Exception(trans('api.ATTACHMENT_MAKE_FOLDER_ERROR'));
  75. }
  76. }
  77. $file->move($path, $md5_filename);
  78. $realPath = $path . '/' . $md5_filename;
  79. $urlPath = $rel_path . '/' . $md5_filename;
  80. if ($fileMimeType == "video/mp4" || $fileMimeType == "video/quicktime") {
  81. $ffmpeg = FFMpeg\FFMpeg::create(array(
  82. 'ffmpeg.binaries' => '/usr/bin/ffmpeg',
  83. 'ffprobe.binaries' => '/usr/bin/ffprobe'
  84. ));
  85. $video = $ffmpeg->open($realPath);
  86. $vpath = public_path() . '/upload/vpic/';
  87. if (!file_exists($vpath)) {
  88. if (!@mkdir($vpath, 0755, true)) {
  89. return trans('api.ATTACHMENT_MAKE_FOLDER_ERROR');
  90. }
  91. }
  92. $pic = $vpath . $md5 . '.jpg';
  93. $video->frame(FFMpeg\Coordinate\TimeCode::fromSeconds(1))->save($pic);
  94. }
  95. $result[$idx] = 'http://' . $_SERVER['HTTP_HOST'] . $urlPath;
  96. } elseif (env('FILESYSTEM_DRIVER') == 'oss') {
  97. $tmppath = $file->getRealPath(); //获取上传图片的临时地址
  98. $fileName = date('YmdHis') .rand(10000, 99999). '.' . $file->getClientOriginalExtension(); //生成文件名
  99. $pathName = $tag . '/' . date('Y-m') . '/' . $fileName;
  100. $upResult = $this->ossClient->uploadFile($this->bucket, $pathName, $tmppath, ['ContentType' => $file->getClientMimeType()]); //上传图片到阿里云OSS
  101. $url = $upResult['info']['url'];
  102. $realPath = $url;
  103. $urlPath = $url;
  104. $result[$idx] = $url;
  105. }
  106. //将上传的图片存入到数据表作为记录
  107. $attachment = new BaseAttachment();
  108. $attachment->name = $clientName;
  109. $attachment->md5 = $md5;
  110. $attachment->path = $realPath;
  111. $attachment->url = $urlPath;
  112. $attachment->size = $fileSize;
  113. $attachment->file_type = $fileMimeType;
  114. if (!$attachment->save()) {
  115. @unlink($realPath);
  116. throw new \Exception(trans('api.ATTACHMENT_SAVE_ERROR'));
  117. }
  118. } catch (FileException $e) {
  119. throw new \Exception(trans('api.ATTACHMENT_UPLOAD_INVALID'));
  120. }
  121. }
  122. if (count($result) == 1) {
  123. return array_shift($result);
  124. }
  125. return $result;
  126. } else {
  127. throw new \Exception(trans('api.ATTACHMENT_UPLOAD_INVALID'));
  128. }
  129. }
  130. /**
  131. * 删除附件
  132. *
  133. * @param $picUrl 图片地址
  134. * @return int 错误码or 0(成功)
  135. */
  136. public function deleteAttachment($picUrl)
  137. {
  138. if ($this->fileDriver == 'local') {
  139. $attachment = BaseAttachment::where(['path' => $picUrl])->first();
  140. if (!$attachment) {
  141. return false;
  142. }
  143. if (file_exists($attachment->path)) {
  144. if (@unlink($attachment->path)) {
  145. if (!$attachment->delete()) {
  146. return false;
  147. }
  148. } else {
  149. return false;
  150. }
  151. } else {
  152. return false;
  153. }
  154. } elseif ($this->fileDriver == 'oss') {
  155. $this->ossClient->deleteObject($this->bucket, $picUrl);
  156. }
  157. return true;
  158. }
  159. }