Переглянути джерело

下载object_type最新版本全部文件

moell 10 місяців тому
батько
коміт
724cf6d796

+ 9 - 32
app/Http/Controllers/API/FileController.php

@@ -12,6 +12,7 @@ use App\Http\Resources\API\FileUploadSuccessResource;
 use App\Models\Enums\FileObjectType;
 use App\Models\File;
 use App\Models\Folder;
+use App\Services\File\DownloadService;
 use App\Services\File\FileHideService;
 use App\Services\File\Upload\FilesUploadService;
 use App\Services\File\Upload\KeepDirectoryUploadService;
@@ -81,41 +82,17 @@ class FileController extends Controller
         return $this->noContent();
     }
 
-    public function downloadZip(DownloadZipRequest $request)
+    public function downloadZip(DownloadZipRequest $request, DownloadService $service)
     {
-        $files = File::query()->with(['folder'])->whereIn("id", $request->get("ids"))->get();
-
-        $folderIds = [];
-        foreach ($files as $file) {
-            $folderIds = [...$folderIds, ...explode(",", $file->folder?->path)];
-        }
-
-        $folders = Folder::query()->whereIn("id", $folderIds)->pluck("name", "id");
-
-        $items = [];
-        foreach ($files as $file) {
-            $object = FileObjectType::from($file->object_type)
-                ->modelBuilderAllowed($file->object_id)
-                ->find($file->object_id);
-
-            if (! $object) {
-                return $this->badRequest(sprintf("File ID: %s, no permission to access", $file->id));
-            }
-
-            $fileDownloadResource = (new FileDownloadResource($file))->toArray($request);
-
-            $folderPath = [];
-            foreach(array_filter(explode(",", $file->folder?->path)) as $folderId) {
-                $folderPath[] = $folders->get($folderId);
-            }
-
-            $fileDownloadResource['folder_path'] = "/" . implode('/', $folderPath);
-
-            $items[] = $fileDownloadResource;
-        }
+        return $this->success([
+            'data' => $service->downloadByIds($request->get("ids")),
+        ]);
+    }
 
+    protected function downloadAllLatest(DownloadService $service, string $objectType, string $objectId)
+    {
         return $this->success([
-            'data' => $items
+            'data' => $service->downloadAllLatest($objectType, $objectId),
         ]);
     }
 

+ 115 - 0
app/Services/File/DownloadService.php

@@ -0,0 +1,115 @@
+<?php
+
+namespace App\Services\File;
+
+use App\Http\Resources\API\FileDownloadResource;
+use App\Models\Enums\FileObjectType;
+use App\Models\Enums\FolderObjectType;
+use App\Models\File;
+use App\Models\Folder;
+use Illuminate\Support\Collection;
+
+class DownloadService
+{
+    public function downloadByIds(array $ids)
+    {
+        $files = File::query()->with(['folder'])->whereIn("id", $ids)->get();
+
+        return $this->filesFormat($files);
+    }
+
+    public function downloadAllLatest(string $objectType, string $objectId)
+    {
+        $folderObjectType = FolderObjectType::from($objectType);
+
+        $object = $folderObjectType->modelBuilderAllowed()->findOrFail($objectId);
+
+        $isExternalVersionControl = $this->isExternalVersionControl($folderObjectType);
+
+        $fileIds = $isExternalVersionControl ? $this->versionFileIds($folderObjectType, $object) : [];
+
+        $files = File::query()->with(['folder'])->where([
+            'object_type' => $objectType,
+            'object_id' => $objectId,
+        ])->when(! $isExternalVersionControl, fn($query) => $query->where("is_latest_version", 1))
+            ->when($fileIds, fn($query) => $query->whereIn("id", $fileIds))
+            ->orderByDesc("version")
+            ->get();
+
+        $files = $isExternalVersionControl ? $this->getLatestFiles($files, $object) : $files;
+
+        return $this->filesFormat($files);
+    }
+
+    protected function isExternalVersionControl(FolderObjectType $folderObjectType)
+    {
+        return $folderObjectType == FolderObjectType::CONTAINER && request("object_version", 0) > 0;
+    }
+
+    protected function getLatestFiles(Collection $files, $object)
+    {
+        $objectVersion = request('object_version') ?: $object->version;
+
+        $items = [];
+
+        foreach ($files->groupBy("folder_id") as $folderFiles) {
+            foreach ($folderFiles as $file) {
+                $isHide = $file->hide_object_version == 0
+                    ? (bool)$file->is_hide
+                    : $file->is_hide  && $file->hide_object_version <= $objectVersion;
+                if (! $isHide) {
+                    $items[] = $file;
+                    break;
+                }
+            }
+        }
+
+        return collect($items);
+    }
+
+    protected function versionFileIds(FolderObjectType $folderObjectType, $object)
+    {
+        $fileIds = [];
+        if ($folderObjectType == FolderObjectType::CONTAINER) {
+            $containerContent = $object->content(request('object_version') ?: $object->version)->first();
+
+            throw_validation_if(! $containerContent, "The current version does not exist");
+
+            $fileIds = explode(",", $containerContent->files);
+        }
+
+        return array_unique(array_filter($fileIds));
+    }
+
+    protected function filesFormat(Collection $files)
+    {
+        $folderIds = [];
+        foreach ($files as $file) {
+            $folderIds = [...$folderIds, ...explode(",", $file->folder?->path)];
+        }
+
+        $folders = Folder::query()->whereIn("id", array_unique(array_filter($folderIds)))->pluck("name", "id");
+
+        $items = [];
+        foreach ($files as $file) {
+            $object = FileObjectType::from($file->object_type)
+                ->modelBuilderAllowed($file->object_id)
+                ->find($file->object_id);
+
+            throw_validation_if(! $object, sprintf("File ID: %s, no permission to access", $file->id));
+
+            $fileDownloadResource = (new FileDownloadResource($file))->toArray(request());
+
+            $folderPath = [];
+            foreach(array_filter(explode(",", $file->folder?->path)) as $folderId) {
+                $folderPath[] = $folders->get($folderId);
+            }
+
+            $fileDownloadResource['folder_path'] = "/" . implode('/', $folderPath);
+
+            $items[] = $fileDownloadResource;
+        }
+
+        return $items;
+    }
+}

+ 2 - 0
routes/api.php

@@ -158,6 +158,8 @@ Route::middleware(['auth:sanctum'])->group(function () {
         Route::get("file/{object_type}/{object_id}", [API\FileController::class, "byObject"])->name("file.by-object");
         Route::post("file/{file}/download", [API\FileController::class, "download"])->name("file.download");
         Route::post("file/download-zip", [API\FileController::class, "downloadZip"])->name("file.download-zip");
+        Route::get("file/download-all-latest/{object_type}/{object_id}", [API\FileController::class, "downloadAllLatest"])
+            ->name("file.download-all-latest");
         Route::patch("file/{file}/change-name", [API\FileController::class, "changeName"])->name("file.change-name");
         Route::delete("file/{file}/destroy", [API\FileController::class, "destroy"])->name("file.destroy");
         Route::post("file/keep-directory-upload", [API\FileController::class, "keepDirectoryUpload"])->name("file.keep-directory-upload");