upload('image'); } public function uploadFile() { return $this->upload(); } /** * 富文本内文件上传 */ public function uploadRich() { $fromWangEditor = false; $file = request()->file('file'); if (! $file) { $fromWangEditor = true; $file = request()->file('wangeditor-uploaded-image'); if (! $file) { $file = request()->file('wangeditor-uploaded-video'); } } if (! $file) { return $this->response()->additional(['errno' => 1])->fail(__('admin.upload_file_error')); } $path = $file->store(Admin::config('admin.upload.directory.rich'), Admin::config('admin.upload.disk')); $link = Storage::disk(Admin::config('admin.upload.disk'))->url($path); if ($fromWangEditor) { return $this->response()->additional(['errno' => 0])->success(['url' => $link]); } return $this->response()->additional(compact('link'))->success(compact('link')); } /** * 存放临时文件目录,按日期区分; */ protected function upload($type = 'file') { $file = request()->file('file'); if (! $file) { return $this->response()->fail(__('admin.upload_file_error')); } $path = $file->storeAs(Admin::config('admin.upload.directory.'.$type).'/'.date('Ymd'), $this->hashFilename($file), Admin::config('admin.upload.disk')); if (request()->has('full-url')) { $path = Storage::disk(Admin::config('admin.upload.disk'))->url($path); } return $this->response()->success(['value' => $path]); } public function saveImage($field, $path) { return $this->saveFile($field, $path); } /** * 表单提交时,转存实际目录,并保留上传时文件名称;文件保存全路径 */ public function saveFile($field, $path) { $file = request()->file($field); if (! $file) { $file = request()->get($field); } $fileArr = []; //判断是否多个文件; if (is_string($file) || isset($file['id'])) { $files = [$file]; } else { $files = $file; } if ($files) { foreach ($files as $file) { if (is_array($file) && isset($file['state'])) { switch ($file['state']) { case 'init': if (strpos($file['value'], 'temporary') !== false) { $filePath = $path.'/'.$file['name']; $res = Storage::disk(Admin::config('admin.upload.disk'))->move($file['value'], $filePath); if ($res) { $fileArr[] = Storage::disk(Admin::config('admin.upload.disk'))->url($filePath); } else { return response()->fail(__('admin.upload_file_error')); } } else { $fileArr[] = $file['value']; } break; case 'uploaded': if (isset($file['name'])) { $filePath = $path.'/'.$file['name']; if (Str::startsWith($file['value'], ['http://', 'https://'])) { $fileUrl = parse_url($file['value']); $fileValue = ltrim($fileUrl['path'], '/storage'); } else { $fileValue = $file['value']; } $res = Storage::disk(Admin::config('admin.upload.disk'))->move($fileValue, $filePath); if ($res) { $fileArr[] = Storage::disk(Admin::config('admin.upload.disk'))->url($filePath); } else { return $this->response()->fail(__('admin.upload_file_error')); } } break; } } else { $fileArr[] = $file; } } } return $fileArr; } /** * 开始分片上传, 生成唯一ID */ public function startChunk() { $type = 'file'; $fileName = request()->get('filename', ''); $uploadId = md5(time().$fileName); //创建临时文件夹 if (Storage::disk(Admin::config('admin.upload.disk'))->exists(Admin::config('admin.upload.tem_directory.'.$type).'/'.$uploadId) === false) { if (Storage::disk(Admin::config('admin.upload.disk'))->makeDirectory(Admin::config('admin.upload.tem_directory.'.$type).'/'.$uploadId) === false) { return false; } } return $this->response()->success(['uploadId' => $uploadId]); } /** * 保存分片 */ public function saveChunk() { $type = 'file'; $file = request()->file('file'); $uploadId = request()->get('uploadId'); $partNumber = request()->get('partNumber'); $partSize = request()->get('partSize'); $fileName = $file->getClientOriginalName(); $fileName = str_replace(' ', '', $fileName); //去掉空格 //判断该分片是否已存在, $dirPath = Admin::config('admin.upload.tem_directory.'.$type).'/'.$uploadId; if (Storage::disk(Admin::config('admin.upload.disk'))->exists($dirPath.'/'.$fileName.'_'.$partNumber)) { return $this->response()->fail(__('admin.upload_file_error')); } else { //验证分片大小-todo $path = $file->storeAs($dirPath, $fileName.'_'.$partNumber, Admin::config('admin.upload.disk')); $realPath = Storage::disk(Admin::config('admin.upload.disk'))->url($path); $eTag = md5_file($realPath); return $this->response()->success(['eTag' => $eTag]); } } /** * 完成分片 */ public function finishChunk() { $type = 'file'; //合并文件 $fileName = request()->get('filename', ''); $fileName = str_replace(' ', '', $fileName); $uploadId = request()->get('uploadId', ''); $partList = request()->get('partList', []); $basePath = Admin::config('admin.upload.tem_directory.'.$type).'/'.$uploadId; $realPath = 'chunk/'.$fileName; //获取分片列表中序号,查看分片是否都完成上传 $partNumberList = Arr::pluck($partList, 'partNumber'); if (max($partNumberList) === count($partNumberList)) { //判断是否已存在同名文件,进行重命名 if (Storage::disk(Admin::config('admin.upload.disk'))->exists($realPath)) { $realPath = 'chunk/(1)'.$fileName; } for ($i = 1; $i <= count($partNumberList); $i++) { $_file = Storage::disk(Admin::config('admin.upload.disk'))->get($basePath.'/'.$fileName.'_'.$i); $res = Storage::disk(Admin::config('admin.upload.disk'))->append($realPath, $_file, null); } //删除分片文件夹 Storage::disk(Admin::config('admin.upload.disk'))->deleteDirectory($basePath); $value = Storage::disk(Admin::config('admin.upload.disk'))->url($realPath); return $this->response()->success(['value' => $value]); } else { return $this->response()->fail(__('admin.upload_file_error')); } } protected function hashFilename(UploadedFile $file): string { $hash = Str::random(40); $extension = ''; if ($originalExtension = $file->getClientOriginalExtension()) { $extension = '.'.$originalExtension; } elseif ($guessExtension = $this->guessExtension()) { $extension = '.'.$guessExtension; } return $hash.$extension; } }