AttachmentHelper.php 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. <?php
  2. namespace App\Helper;
  3. use FFMpeg;
  4. use Illuminate\Http\Request;
  5. use Illuminate\Http\UploadedFile;
  6. use OSS\OssClient;
  7. use Symfony\Component\HttpFoundation\File\Exception\FileException;
  8. use App\Services\Base\ErrorCode;
  9. use App\Models\BaseAttachment;
  10. trait AttachmentHelper
  11. {
  12. /**
  13. * @param Request $request
  14. * @param $key
  15. * @param string $tag
  16. * @param float|int $size
  17. * @param array $mimeType
  18. * @return array|mixed
  19. * @throws \OSS\Core\OssException
  20. */
  21. public function uploadAttachment(Request $request, $key, $tag = 'files', $size = 200 * 1024 * 1024, array $mimeType = []) {
  22. if ($request->hasFile($key)) {
  23. $files = $request->file($key);
  24. if ($files === null) {
  25. throw new \Exception(trans('api.ATTACHMENT_FILE_NULL'));
  26. }
  27. if ($files instanceof UploadedFile) {
  28. $files = [$files];
  29. }
  30. $result = [];
  31. foreach ($files as $idx => $file) {
  32. if (!$file->isValid()) {
  33. throw new \Exception(trans('api.ATTACHMENT_TYPE_ERROR'));
  34. continue;
  35. }
  36. $fileSize = $file->getSize();
  37. if ($fileSize > $size) {
  38. throw new \Exception(trans('api.ATTACHMENT_SIZE_EXCEEDED'));
  39. continue;
  40. }
  41. $fileMimeType = $file->getMimeType();
  42. if (!empty($mimeType) && !in_array($fileMimeType, $mimeType)) {
  43. throw new \Exception(trans('api.ATTACHMENT_TYPE_ERROR'));
  44. continue;
  45. }
  46. $clientName = $file->getClientOriginalName();
  47. $md5 = md5($clientName . time());
  48. //因为 $md5 32 位字符太长,创建群聊头像失败
  49. $md5_filename = substr($md5, 0, 20) . '.' . $file->getClientOriginalExtension();
  50. try {
  51. //本地上传
  52. if(env('FILESYSTEM_DRIVER')=='local'){
  53. $rel_path = '/upload/' . $tag . '/' . date('Ymd');
  54. $path = public_path() . $rel_path;
  55. if (!file_exists($path)) {
  56. if (!@mkdir($path, 0755, true)) {
  57. throw new \Exception(trans('api.ATTACHMENT_MAKE_FOLDER_ERROR'));
  58. }
  59. }
  60. $file->move($path, $md5_filename);
  61. $real_path = $path . '/' . $md5_filename;
  62. $url_path = $rel_path . '/' . $md5_filename;
  63. if ($fileMimeType == "video/mp4" || $fileMimeType == "video/quicktime") {
  64. $ffmpeg = FFMpeg\FFMpeg::create(array(
  65. 'ffmpeg.binaries' => '/usr/bin/ffmpeg',
  66. 'ffprobe.binaries' => '/usr/bin/ffprobe'
  67. ));
  68. $video = $ffmpeg->open($real_path);
  69. $vpath = public_path() . '/upload/vpic/';
  70. if (!file_exists($vpath)) {
  71. if (!@mkdir($vpath, 0755, true)) {
  72. return trans('api.ATTACHMENT_MAKE_FOLDER_ERROR');
  73. }
  74. }
  75. $pic = $vpath.$md5.'.jpg';
  76. $video
  77. ->frame(FFMpeg\Coordinate\TimeCode::fromSeconds(1))
  78. ->save( $pic );
  79. }
  80. $url = $url_path;
  81. $result[$idx] = 'https://'.$_SERVER['HTTP_HOST'].$url_path;
  82. }elseif (env('FILESYSTEM_DRIVER')=='oss'){
  83. //获取上传图片的临时地址
  84. $tmppath = $file->getRealPath();
  85. //生成文件名
  86. $fileName = rand(100, 999) . time() . date('ymd') . '.' . $file->getClientOriginalExtension();
  87. $pathName = 'huabook/' . date('Y-m/d') . '/' . $fileName;
  88. //上传图片到阿里云OSS
  89. $oss = new OssClient(env('ALI_OSS_ACCESS_ID'), env('ALI_OSS_ACCESS_KEY'), env('ALI_OSS_ENDPOINT'));
  90. $res = $oss->uploadFile(env('ALI_OSS_BUCKET'), $pathName, $tmppath, ['ContentType' => $file->getClientMimeType()]);
  91. $url = $res['info']['url'];
  92. $result[$idx] = $url;
  93. }
  94. $attachment = new BaseAttachment();
  95. $attachment->name = $clientName;
  96. $attachment->md5 = $md5;
  97. $attachment->path = $url;
  98. $attachment->url = $url;
  99. $attachment->size = $fileSize;
  100. $attachment->file_type = $fileMimeType;
  101. if (!$attachment->save()) {
  102. @unlink($url);
  103. throw new \Exception(trans('api.ATTACHMENT_SAVE_ERROR'));
  104. }
  105. } catch (FileException $e) {
  106. throw new \Exception(trans('api.ATTACHMENT_UPLOAD_INVALID'));
  107. }
  108. }
  109. if (count($result) == 1) {
  110. return array_shift($result);
  111. }
  112. return $result;
  113. } else {
  114. throw new \Exception(trans('api.ATTACHMENT_UPLOAD_INVALID'));
  115. }
  116. }
  117. /**
  118. * 删除附件
  119. *
  120. * @param $md5 string 删除文件的md5码
  121. * @return int 错误码or 0(成功)
  122. */
  123. public function deleteAttachment($md5) {
  124. $attachment = BaseAttachment::where(['md5' => $md5])->first();
  125. if (!$attachment) {
  126. return ErrorCode::ATTACHMENT_NOT_EXIST;
  127. }
  128. if (file_exists($attachment->path)) {
  129. if (@unlink($attachment->path)) {
  130. if ($attachment->delete()) {
  131. return 0;
  132. } else {
  133. return ErrorCode::ATTACHMENT_RECORD_DELETE_FAILED;
  134. }
  135. } else {
  136. return ErrorCode::ATTACHMENT_DELETE_FAILED;
  137. }
  138. } else {
  139. return ErrorCode::ATTACHMENT_NOT_EXIST;
  140. }
  141. }
  142. }