2
0

AttachmentController.php 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. <?php
  2. namespace App\Http\Controllers;
  3. use Illuminate\Http\File;
  4. use Illuminate\Support\Facades\Storage;
  5. use Illuminate\Http\Request;
  6. use Illuminate\Support\Str;
  7. use Illuminate\Support\Facades\App;
  8. use App\Http\Api\AuthApi;
  9. use App\Http\Api\StudioApi;
  10. use App\Http\Resources\AttachmentResource;
  11. use App\Models\Attachment;
  12. use Intervention\Image\ImageManagerStatic as Image;
  13. use FFMpeg\FFMpeg;
  14. class AttachmentController extends Controller
  15. {
  16. /**
  17. * Display a listing of the resource.
  18. *
  19. * @return \Illuminate\Http\Response
  20. */
  21. public function index(Request $request)
  22. {
  23. //
  24. switch ($request->get('view')) {
  25. case 'studio':
  26. $user = AuthApi::current($request);
  27. if(!$user){
  28. return $this->error(__('auth.failed'));
  29. }
  30. //判断当前用户是否有指定的studio的权限
  31. if($user['user_uid'] !== StudioApi::getIdByName($request->get('studio'))){
  32. return $this->error(__('auth.failed'));
  33. }
  34. $table = Attachment::where('owner_uid', $user["user_uid"]);
  35. break;
  36. default:
  37. return $this->error("error view",[],200);
  38. break;
  39. }
  40. if($request->has('search')){
  41. $table = $table->where('title', 'like', $request->get('search')."%");
  42. }
  43. if($request->has('content_type')){
  44. $table = $table->where('content_type', 'like', $request->get('content_type')."%");
  45. }
  46. $count = $table->count();
  47. $table = $table->orderBy($request->get('order','updated_at'),
  48. $request->get('dir','desc'));
  49. $table = $table->skip($request->get('offset',0))
  50. ->take($request->get('limit',1000));
  51. $result = $table->get();
  52. return $this->ok(["rows"=>AttachmentResource::collection($result),"count"=>$count]);
  53. }
  54. /**
  55. * Store a newly created resource in storage.
  56. *
  57. * @param \Illuminate\Http\Request $request
  58. * @return \Illuminate\Http\Response
  59. */
  60. public function store(Request $request)
  61. {
  62. $user = AuthApi::current($request);
  63. if(!$user){
  64. return $this->error(__('auth.failed'),401,401);
  65. }
  66. $request->validate([
  67. 'file' => 'required',
  68. ]);
  69. $isCreate = true;
  70. if(Str::isUuid($request->get('id'))){
  71. $attachment = Attachment::find($request->get('id'));
  72. if(!$attachment){
  73. return $this->error('no res');
  74. }
  75. $fileId = $attachment->id;
  76. $isCreate = false;
  77. }else{
  78. $fileId = Str::uuid();
  79. }
  80. $file = $request->file('file');
  81. $bucket = config('mint.attachments.bucket_name.permanent');
  82. $ext = $file->getClientOriginalExtension();
  83. if($request->get('type') === 'avatar'){
  84. $resize = Image::make($file)->fit(512);
  85. Storage::put($bucket.'/'.$fileId.'.jpg',$resize->stream());
  86. $resize = Image::make($file)->fit(256);
  87. Storage::put($bucket.'/'.$fileId.'_m.jpg',$resize->stream());
  88. $resize = Image::make($file)->fit(128);
  89. Storage::put($bucket.'/'.$fileId.'_s.jpg',$resize->stream());
  90. $name = $fileId.'.jpg';
  91. }else{
  92. //Move Uploaded File
  93. $name = $fileId.'.'.$ext;
  94. if(!$isCreate){
  95. //替换模式,先删除旧文件
  96. Storage::delete($bucket.'/'.$name);
  97. }
  98. $filename = $file->storeAs($bucket,$name);
  99. }
  100. if($isCreate){
  101. $attachment = new Attachment;
  102. $attachment->id = $fileId;
  103. $attachment->bucket = $bucket;
  104. if($request->has('studio')){
  105. $owner_uid = StudioApi::getIdByName($request->get('studio'));
  106. }else{
  107. $owner_uid = $user['user_uid'];
  108. }
  109. if($owner_uid){
  110. $attachment->owner_uid = $owner_uid;
  111. }
  112. $attachment->status = 'public';
  113. $path_parts = pathinfo($file->getClientOriginalName());
  114. $attachment->title = $path_parts['filename'];
  115. }
  116. $attachment->user_uid = $user['user_uid'];
  117. $attachment->name = $name;
  118. $attachment->filename = $file->getClientOriginalName();
  119. $attachment->size = $file->getSize();
  120. $attachment->content_type = $file->getMimeType();
  121. $attachment->save();
  122. $type = explode('/',$file->getMimeType());
  123. switch ($type[0]) {
  124. case 'image':
  125. $thumbnail = Image::make($file);
  126. break;
  127. case 'video':
  128. $tmpFile = $file->storeAs($bucket,$name,'local');
  129. $path = storage_path('app/'.$tmpFile);
  130. if (App::environment('local')) {
  131. $ffmpeg = FFMpeg::create();
  132. }else{
  133. $ffmpeg = FFMpeg::create(array(
  134. 'ffmpeg.binaries' => '/usr/bin/ffmpeg',
  135. 'ffprobe.binaries' => '/usr/bin/ffprobe',
  136. 'timeout' => 3600,
  137. 'ffmpeg.threads' => 1,
  138. ));
  139. }
  140. $video = $ffmpeg->open($path);
  141. $frame = $video->frame(\FFMpeg\Coordinate\TimeCode::fromSeconds(1));
  142. $screenShot = storage_path("app/tmp/{$fileId}.jpg");
  143. $frame->save($screenShot);
  144. $thumbnail = Image::make($screenShot);
  145. break;
  146. default:
  147. # code...
  148. break;
  149. }
  150. if(isset($thumbnail)){
  151. //生成缩略图
  152. $thumbnail->resize(256, 256, function ($constraint) {
  153. $constraint->aspectRatio();
  154. });
  155. Storage::put($bucket.'/'.$fileId.'_m.jpg',$thumbnail->stream());
  156. $thumbnail->resize(128, 128, function ($constraint) {
  157. $constraint->aspectRatio();
  158. });
  159. Storage::put($bucket.'/'.$fileId.'_s.jpg',$thumbnail->stream());
  160. //销毁图片资源
  161. $thumbnail->destroy();
  162. }
  163. return $this->ok(new AttachmentResource($attachment));
  164. }
  165. /**
  166. * Display the specified resource.
  167. *
  168. * @param \App\Models\Attachment $attachment
  169. * @return \Illuminate\Http\Response
  170. */
  171. public function show(Attachment $attachment)
  172. {
  173. //
  174. return $this->ok(new AttachmentResource($attachment));
  175. }
  176. /**
  177. * Update the specified resource in storage.
  178. *
  179. * @param \Illuminate\Http\Request $request
  180. * @param \App\Models\Attachment $attachment
  181. * @return \Illuminate\Http\Response
  182. */
  183. public function update(Request $request, Attachment $attachment)
  184. {
  185. //
  186. $user = AuthApi::current($request);
  187. if(!$user){
  188. return $this->error(__('auth.failed'),401,401);
  189. }
  190. $attachment->title = $request->get('title');
  191. $attachment->save();
  192. return $this->ok(new AttachmentResource($attachment));
  193. }
  194. /**
  195. * Remove the specified resource from storage.
  196. *
  197. * @param string $id
  198. * @return \Illuminate\Http\Response
  199. */
  200. public function destroy(Request $request,string $id)
  201. {
  202. //
  203. $user = AuthApi::current($request);
  204. if(!$user){
  205. return $this->error(__('auth.failed'),401,401);
  206. }
  207. if(Str::isUuid($id)){
  208. $res = Attachment::where('id',$id)->first();
  209. }else{
  210. /**
  211. * 从文件名获取bucket和name
  212. */
  213. $pos = mb_strrpos($request->get('name'),'/',0,"UTF-8");
  214. if($pos === false){
  215. return $this->error('无效的文件名',500,500);
  216. }
  217. $bucket = mb_substr($request->get('name'),0,$pos,'UTF-8');
  218. $name = mb_substr($request->get('name'),$pos+1,NULL,'UTF-8');
  219. $res = Attachment::where('bucket',$bucket)
  220. ->where('name',$name)
  221. ->first();
  222. }
  223. if(!$res){
  224. return $this->error('no res');
  225. }
  226. if($user['user_uid'] !== $res->user_uid){
  227. return $this->error(__('auth.failed'),403,403);
  228. }
  229. //删除文件
  230. $filename = $res->bucket . '/' . $res->name;
  231. $path_parts = pathinfo($res->name);
  232. Storage::delete($filename);
  233. Storage::delete($res->bucket.'/'.$path_parts['filename'].'_m.jpg');
  234. Storage::delete($res->bucket.'/'.$path_parts['filename'].'_s.jpg');
  235. $del = $res->delete();
  236. return $this->ok($del);
  237. }
  238. }