Browse Source

文件夹和文件版本树支持容器版本查询,文件是否隐藏标记和查询

moell 10 months ago
parent
commit
d74a5cbfc2

+ 5 - 61
app/Http/Controllers/API/FolderController.php

@@ -12,6 +12,7 @@ use App\Models\Enums\FolderObjectType;
 use App\Models\File;
 use App\Models\Folder;
 use App\Models\Library;
+use App\Services\Folder\VersionFileTreeByObjectService;
 use Illuminate\Database\Eloquent\Collection;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Auth;
@@ -272,74 +273,17 @@ class FolderController extends Controller
     /**
      * 基于类型的文件夹、文件版本树
      *
+     * @param Request $request
      * @param string $objectType
      * @param string $objectId
      * @return \Illuminate\Http\JsonResponse
      */
-    public function versionFileTreeByObject(string $objectType, string $objectId)
+    public function versionFileTreeByObject(Request $request, string $objectType, string $objectId)
     {
-        $folderObjectType = FolderObjectType::from($objectType);
-
-        $folderObjectType->modelBuilderAllowed()->findOrFail($objectId);
-
-        $objectWhere = ['object_type' => $objectType, 'object_id' => $objectId,];
-
-        $folders = Folder::query()->with(['files'])->where($objectWhere)->get(['id', 'name', 'parent_id']);
-
-        $fileResourceFunction = function (File $file, $parentId, bool $isChildrenFile) {
-            return [
-                'id' => sprintf($isChildrenFile ? "children_%s" : "file_%s", $file->id),
-                'node_id' => $file->id,
-                'parent_id' => $parentId,
-                'title' => $file->title,
-                'extension' => $file->extension,
-                'size' => $file->size,
-                'created_by' => $file->createdBy ? [
-                    'id' => $file->createdBy->id,
-                    'name' => $file->createdBy->name,
-                    'username' => $file->createdBy->username,
-                ] : [],
-                'created_at' => (string)$file->created_at,
-                'version' => $file->version,
-                'type' => 'file'
-            ];
-        };
-
-        $nodes = [];
-
-        $filesFormat = function(Collection $files, $firstId) use (&$nodes, $fileResourceFunction) {
-            foreach ($files->groupBy("title") as $fileItems) {
-                $item = $fileResourceFunction($fileItems->first(), $firstId, false);
-                $nodes[] = $item;
-
-                foreach ($fileItems as $fileItem) {
-                    $nodes[] = $fileResourceFunction($fileItem, $item['id'], true);
-                }
-            }
-        };
-        foreach ($folders as &$folder) {
-            $nodes[] = [
-                'id' => $folder->id,
-                'node_id' => $folder->id,
-                'name' => $folder->name,
-                'parent_id' => $folder->parent_id,
-                'type' => 'folder',
-            ];
-
-            $filesFormat($folder->files, $folder->id);
-        }
-
-        $topFiles = File::query()->where($objectWhere)
-            ->where("source", 1)
-            ->where("folder_id", 0)
-            ->orderByDesc("version")
-            ->get();
-
-        $filesFormat($topFiles, 0);
-
+        $tree = (new VersionFileTreeByObjectService($request->all(), $objectType, $objectId))->versionFileTreeByObject();
 
         return $this->success([
-            'data' => make_tree($nodes)
+            'data' => $tree
         ]);
     }
 }

+ 151 - 0
app/Services/Folder/VersionFileTreeByObjectService.php

@@ -0,0 +1,151 @@
+<?php
+
+namespace App\Services\Folder;
+
+use App\Models\Enums\FolderObjectType;
+use App\Models\File;
+use App\Models\Folder;
+use Illuminate\Database\Eloquent\Collection;
+
+class VersionFileTreeByObjectService {
+    protected FolderObjectType $folderObjectType;
+
+    protected $object;
+
+    protected array $objectWhere = [];
+
+    protected array $fileWhere = [];
+
+    protected int $objectVersion = 0;
+
+    protected array $fileIds = [];
+
+    protected array $folderIds = [];
+
+
+    public function __construct(protected array $queryData, string $objectType, string $objectId)
+    {
+        $this->folderObjectType = FolderObjectType::from($objectType);
+
+        $this->object = $this->folderObjectType->modelBuilderAllowed()->findOrFail($objectId);
+
+        $this->objectWhere = ['object_type' => $objectType, 'object_id' => $objectId,];
+
+        $this->fileWhere = [];
+        if (($this->queryData['show_hide'] ?? null) != 1) {
+            $this->fileWhere['is_hide'] = 0;
+        }
+
+        $this->objectVersion = $this->queryData['object_version'] ?? 0;
+    }
+
+    public function versionFileTreeByObject()
+    {
+        $this->containerDataLoad();
+
+        $folders = $this->queryFolders();
+
+        $nodes = [];
+
+        foreach ($folders as &$folder) {
+            $nodes[] = [
+                'id' => $folder->id,
+                'node_id' => $folder->id,
+                'name' => $folder->name,
+                'parent_id' => $folder->parent_id,
+                'type' => 'folder',
+            ];
+
+            $this->filesFormat($folder->files, $folder->id, $nodes);
+        }
+
+        $topFiles = $this->queryTopFiles();
+
+        $this->filesFormat($topFiles, 0, $nodes);
+
+        return make_tree($nodes);
+    }
+
+    protected function queryTopFiles()
+    {
+        return File::query()->where($this->objectWhere)
+            ->where("source", 1)
+            ->where("folder_id", 0)
+            ->when($this->fileWhere, fn($query) => $query->where($this->fileWhere))
+            ->when($this->fileIds, fn($query) => $query->whereIn("id", $this->fileIds))
+            ->where(fn($query) => $query->where($this->fileWhere)->when($this->fileIds, fn($query) => $query->whereIn("id", $this->fileIds)))
+            ->orderByDesc("version")
+            ->get();
+    }
+
+    protected function queryFolders()
+    {
+        return Folder::query()
+            ->with([
+                'files' => fn($query) => $query->when($this->fileWhere, fn($query) => $query->where($this->fileWhere))
+                    ->when($this->fileIds, fn($query) => $query->whereIn("id", $this->fileIds)),
+                'files.createdBy'
+            ])
+            ->when($this->folderIds, fn($query) => $query->whereIn("id", $this->folderIds))
+            ->where($this->objectWhere)
+            ->get(['id', 'name', 'parent_id']);
+    }
+
+    protected function filesFormat(Collection $files, $firstId, &$nodes)
+    {
+        foreach ($files->groupBy("title") as $fileItems) {
+            $item = $this->fileResourceFormat($fileItems->first(), $firstId, false);
+            $nodes[] = $item;
+
+            foreach ($fileItems as $fileItem) {
+                $nodes[] = $this->fileResourceFormat($fileItem, $item['id'], true);
+            }
+        }
+    }
+
+    protected function fileResourceFormat(File $file, $parentId, bool $isChildrenFile)
+    {
+        return [
+            'id' => sprintf($isChildrenFile ? "children_%s" : "file_%s", $file->id),
+            'node_id' => $file->id,
+            'parent_id' => $parentId,
+            'title' => $file->title,
+            'extension' => $file->extension,
+            'size' => $file->size,
+            'created_by' => $file->createdBy ? [
+                'id' => $file->createdBy->id,
+                'name' => $file->createdBy->name,
+                'username' => $file->createdBy->username,
+            ] : [],
+            'created_at' => (string)$file->created_at,
+            'version' => $file->version,
+            'type' => 'file',
+            'hide' => $file->hide_object_version == 0 ? (bool)$file->is_hide : $file->is_hide  && $file->hide_object_version <= $this->objectVersion
+        ];
+    }
+
+    protected function containerDataLoad(): void
+    {
+        if ($this->folderObjectType != FolderObjectType::CONTAINER) {
+            return;
+        }
+
+        $containerContent = $this->object->content($this->queryData['object_version'] ?? $this->object->version)->first();
+
+        throw_validation_if(! $containerContent, "The current version does not exist");
+
+        $this->fileIds = explode(",", $containerContent->files);
+
+        if ($this->fileIds) {
+            $containerFolders = File::query()->whereIn("id", $this->fileIds)->pluck("folder_id")->filter()->unique();
+
+            Folder::query()->whereIn("id", $containerFolders->toArray())->pluck("path")->each(function ($item) {
+                $this->folderIds = [...$this->folderIds, ...explode(",", trim($item, ","))];
+            });
+        }
+
+        if (! $this->objectVersion) {
+            $this->objectVersion = $this->object->version;
+        }
+    }
+}