DownloadService.php 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. <?php
  2. namespace App\Services\File;
  3. use App\Http\Resources\API\FileDownloadResource;
  4. use App\Models\Enums\FileObjectType;
  5. use App\Models\Enums\FolderObjectType;
  6. use App\Models\Enums\ShareFileObjectType;
  7. use App\Models\File;
  8. use App\Models\Folder;
  9. use App\Models\ShareFile;
  10. use Illuminate\Support\Collection;
  11. class DownloadService
  12. {
  13. public function downloadByIds(array $ids)
  14. {
  15. $files = File::query()->with(['folder'])->whereIn("id", $ids)->get();
  16. return $this->filesFormat($files);
  17. }
  18. /**
  19. * 下载分享文件
  20. *
  21. * @param string $uuid
  22. * @return array
  23. */
  24. public function downloadShareFile(string $uuid)
  25. {
  26. $shareFile = ShareFile::query()->where("uuid", $uuid)->firstOrFail();
  27. $objectType = ShareFileObjectType::from($shareFile->object_type);
  28. $objectType->modelBuilderAllowed($shareFile->object_id)->findOrFail($shareFile->object_id);
  29. $files = File::query()->with(['folder'])->whereIn("id", $shareFile->files)->get();
  30. return $this->filesFormat($files);
  31. }
  32. public function downloadAllLatest(string $objectType, string $objectId)
  33. {
  34. $folderObjectType = FolderObjectType::from($objectType);
  35. $object = $folderObjectType->modelBuilderAllowed()->findOrFail($objectId);
  36. $isExternalVersionControl = $this->isExternalVersionControl($folderObjectType);
  37. $fileIds = $isExternalVersionControl ? $this->versionFileIds($folderObjectType, $object) : [];
  38. $files = File::query()->with(['folder'])->where([
  39. 'object_type' => $objectType,
  40. 'object_id' => $objectId,
  41. ])->when(! $isExternalVersionControl, fn($query) => $query->where("is_latest_version", 1))
  42. ->when($fileIds, fn($query) => $query->whereIn("id", $fileIds))
  43. ->orderByDesc("version")
  44. ->get();
  45. $files = $isExternalVersionControl ? $this->getLatestFiles($files, $object) : $files;
  46. return $this->filesFormat($files);
  47. }
  48. protected function isExternalVersionControl(FolderObjectType $folderObjectType)
  49. {
  50. return $folderObjectType == FolderObjectType::CONTAINER && request("object_version", 0) > 0;
  51. }
  52. protected function getLatestFiles(Collection $files, $object)
  53. {
  54. $objectVersion = request('object_version') ?: $object->version;
  55. $items = [];
  56. foreach ($files->groupBy("folder_id") as $folderFiles) {
  57. foreach ($folderFiles as $file) {
  58. $isHide = $file->hide_object_version == 0
  59. ? (bool)$file->is_hide
  60. : $file->is_hide && $file->hide_object_version <= $objectVersion;
  61. if (! $isHide) {
  62. $items[] = $file;
  63. break;
  64. }
  65. }
  66. }
  67. return collect($items);
  68. }
  69. protected function versionFileIds(FolderObjectType $folderObjectType, $object)
  70. {
  71. $fileIds = [];
  72. if ($folderObjectType == FolderObjectType::CONTAINER) {
  73. $containerContent = $object->content(request('object_version') ?: $object->version)->first();
  74. throw_validation_if(! $containerContent, "The current version does not exist");
  75. $fileIds = explode(",", $containerContent->files);
  76. }
  77. return array_unique(array_filter($fileIds));
  78. }
  79. protected function filesFormat(Collection $files)
  80. {
  81. $folderIds = [];
  82. foreach ($files as $file) {
  83. $folderIds = [...$folderIds, ...explode(",", $file->folder?->path)];
  84. }
  85. $folders = Folder::query()->whereIn("id", array_unique(array_filter($folderIds)))->pluck("name", "id");
  86. $items = [];
  87. foreach ($files as $file) {
  88. $object = FileObjectType::from($file->object_type)
  89. ->modelBuilderAllowed($file->object_id)
  90. ->find($file->object_id);
  91. throw_validation_if(! $object, sprintf("File ID: %s, no permission to access", $file->id));
  92. $fileDownloadResource = (new FileDownloadResource($file))->toArray(request());
  93. $folderPath = [];
  94. foreach(array_filter(explode(",", $file->folder?->path)) as $folderId) {
  95. $folderPath[] = $folders->get($folderId);
  96. }
  97. $fileDownloadResource['folder_path'] = "/" . implode('/', $folderPath);
  98. $items[] = $fileDownloadResource;
  99. }
  100. return $items;
  101. }
  102. }